Reduce list title glitches when switching between menus

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 18dfd8f691a8068ab466b2b5c03bc00ef790b736
Author: Christian Soffke <[email protected]>
Date:   Wed Dec 24 11:38:39 2025 +0100

    Reduce list title glitches when switching between menus
    
    Each time viewportmanager_theme_enable (or _undo) is called,
    the SBS title is reset, even if the theme remains enabled.
    Thus switching from one menu to another, if do_menu is called
    again, briefly results in an empty title before the correct
    one is displayed. Even unchanged titles will unnecessarily
    flash for a moment. Other theme elements that are drawn using
    conditions based on the title, may also appear glitchy.
    
    This patch adds a way to make the status bar title persist by
    copying it to a static buffer. Persistent titles are not reset
    by toggle_theme (although scrolling will be stopped in
    viewportmanager_theme_undo), so that the theme can immediately
    display the appropriate title in do_menu, simplelist_show_list,
    the yesno screen, or plugins that want to keep the theme enabled.
    
    Change-Id: I1ec8f233b730321793eb7d3cad51496ee1b35440

diff --git a/apps/gui/list.c b/apps/gui/list.c
index f324e538ce..572a7757cc 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -882,7 +882,8 @@ bool simplelist_show_list(struct simplelist_info *info)
     struct gui_synclist lists;
     int action, old_line_count = simplelist_line_count;
     list_get_name *getname;
-    int line_count, ret = false;
+    int line_count;
+    bool ret = false;
 
     if (info->get_name)
     {
@@ -896,7 +897,10 @@ bool simplelist_show_list(struct simplelist_info *info)
     }
 
     FOR_NB_SCREENS(i)
+    {
+        sb_set_persistent_title(info->title, info->title_icon, i);
         viewportmanager_theme_enable(i, !info->hide_theme, NULL);
+    }
 
     gui_synclist_init(&lists, getname,  info->callback_data,
                       info->scroll_all, info->selection_size, NULL);
@@ -985,7 +989,10 @@ bool simplelist_show_list(struct simplelist_info *info)
 #endif
 
     FOR_NB_SCREENS(i)
+    {
+        sb_set_persistent_title(info->title, info->title_icon, i);
         viewportmanager_theme_undo(i, false);
+    }
     return ret;
 }
 
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index 52fc17deaf..0242016e1e 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -39,6 +39,7 @@
 #include "icon.h"
 #include "icons.h"
 #include "option_select.h"
+#include "string-extra.h"
 #ifdef HAVE_TOUCHSCREEN
 #include "sound.h"
 #include "misc.h"
@@ -49,6 +50,7 @@ static int update_delay = DEFAULT_UPDATE_DELAY;
 
 static bool sbs_has_title[NB_SCREENS];
 static const char* sbs_title[NB_SCREENS];
+static char sbs_persistent_title[NB_SCREENS][80];
 static enum themable_icons sbs_icon[NB_SCREENS];
 static bool sbs_loaded[NB_SCREENS] = { false };
 
@@ -62,6 +64,15 @@ bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_
     return sbs_has_title[screen];
 }
 
+bool sb_set_persistent_title(const char* title, enum themable_icons icon, enum screen_type screen)
+{
+    if (!title)
+        return sb_set_title_text(title, icon, screen);
+
+    strlcpy(sbs_persistent_title[screen], title, sizeof(*sbs_persistent_title));
+    return sb_set_title_text((const char *) sbs_persistent_title[screen], icon, screen);
+}
+
 void sb_skin_has_title(enum screen_type screen)
 {
     sbs_has_title[screen] = true;
@@ -71,6 +82,15 @@ const char* sb_get_title(enum screen_type screen)
 {
     return sbs_has_title[screen] ? sbs_title[screen] : NULL;
 }
+
+const char* sb_get_persistent_title(enum screen_type screen)
+{
+    return (sbs_has_title[screen] &&
+            sbs_title[screen] == sbs_persistent_title[screen]) ?
+            sbs_title[screen] : NULL;
+
+}
+
 enum themable_icons sb_get_icon(enum screen_type screen)
 {
     return sbs_has_title[screen] ? sbs_icon[screen] : Icon_NOICON + 2;
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index 4e7c461f90..905a15b369 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -39,8 +39,11 @@ void sb_skin_update(enum screen_type screen, bool force);
 
 void sb_skin_set_update_delay(int delay);
 bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_type screen);
+bool sb_set_persistent_title(const char* title, enum themable_icons icon,
+                             enum screen_type screen);
 void sb_skin_has_title(enum screen_type screen);
 const char* sb_get_title(enum screen_type screen);
+const char* sb_get_persistent_title(enum screen_type screen);
 enum themable_icons sb_get_icon(enum screen_type screen);
 
 #ifdef HAVE_TOUCHSCREEN
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index cf81f7d009..1d89467682 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -111,7 +111,8 @@ static void toggle_theme(enum screen_type screen, bool force)
     FOR_NB_SCREENS(i)
     {
         enable_event = enable_event || is_theme_enabled(i);
-        sb_set_title_text(NULL, Icon_NOICON, i);
+        if (!sb_get_persistent_title(i))
+            sb_set_title_text(NULL, Icon_NOICON, i);
     }
     toggle_events(enable_event);
 
@@ -195,6 +196,8 @@ void viewportmanager_theme_undo(enum screen_type screen, bool force_redraw)
         panicf("Stack underflow... viewportmanager");
 
     toggle_theme(screen, force_redraw);
+    if (sb_get_persistent_title(screen))
+        screens[screen].scroll_stop();
 }
 
 
diff --git a/apps/gui/yesno.c b/apps/gui/yesno.c
index bb0132e79b..4838366134 100644
--- a/apps/gui/yesno.c
+++ b/apps/gui/yesno.c
@@ -243,9 +243,8 @@ enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res
         yn[i].main_message=main_message;
         yn[i].display=&screens[i];
         screens[i].scroll_stop();
+        sb_set_persistent_title(title, Icon_NOICON, i);
         viewportmanager_theme_enable(i, true, &(yn[i].vp));
-        if (sb_set_title_text(title, Icon_NOICON, i))
-            send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
 
         yn[i].vp_lines = viewport_get_nb_lines(&(yn[i].vp));
     }
@@ -355,6 +354,7 @@ exit:
     FOR_NB_SCREENS(i)
     {
         screens[i].scroll_stop_viewport(&(yn[i].vp));
+        sb_set_persistent_title(title, Icon_NOICON, i);
         viewportmanager_theme_undo(i, true);
     }
 
diff --git a/apps/menu.c b/apps/menu.c
index 2a56292ec6..89c29f4cae 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -53,6 +53,7 @@
 #include "viewport.h"
 #include "quickscreen.h"
 #include "shortcuts.h"
+#include "statusbar-skinned.h"
 
 #include "icons.h"
 
@@ -66,6 +67,8 @@ static struct menu_item_ex *current_submenus_menu;
 static int current_subitems[MAX_MENU_SUBITEMS];
 static int current_subitems_count = 0;
 static int talk_menu_item(int selected_item, void *data);
+static char *title_buf;
+static size_t title_buf_sz;
 
 struct menu_data_t
 {
@@ -197,6 +200,34 @@ static enum themable_icons  menu_get_icon(int selected_item, void * data)
     return menu_icon;
 }
 
+static char* init_title(const struct menu_item_ex *menu, int *icon)
+{
+    char *title;
+
+    if (menu->flags&MENU_HAS_DESC)
+    {
+        *icon = menu->callback_and_desc->icon_id;
+        title = P2STR(menu->callback_and_desc->desc);
+    }
+    else if (menu->flags&MENU_DYNAMIC_DESC)
+    {
+        *icon = menu->menu_get_name_and_icon->icon_id;
+        title = menu->menu_get_name_and_icon->
+                      list_get_name(-1, menu->menu_get_name_and_icon->
+                                    list_get_name_data, title_buf, title_buf_sz);
+    }
+    else
+    {
+        *icon = Icon_NOICON;
+        title = "";
+    }
+
+    if (*icon == Icon_NOICON)
+        *icon = Icon_Submenu_Entered;
+
+    return title;
+}
+
 static int init_menu_lists(const struct menu_item_ex *menu,
                      struct gui_synclist *lists, int selected, bool callback,
                      struct viewport parent[NB_SCREENS])
@@ -236,28 +267,7 @@ static int init_menu_lists(const struct menu_item_ex *menu,
     current_submenus_menu = (struct menu_item_ex *)menu;
 
     gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,1, parent);
-
-    if (menu->flags&MENU_HAS_DESC)
-    {
-        icon = menu->callback_and_desc->icon_id;
-        title = P2STR(menu->callback_and_desc->desc);
-    }
-    else if (menu->flags&MENU_DYNAMIC_DESC)
-    {
-        char buffer[80];
-        icon = menu->menu_get_name_and_icon->icon_id;
-        title = menu->menu_get_name_and_icon->
-                      list_get_name(-1, menu->menu_get_name_and_icon->
-                                    list_get_name_data, buffer, sizeof(buffer));
-    }
-    else
-    {
-        icon = Icon_NOICON;
-        title = "";
-    }
-
-    if (icon == Icon_NOICON)
-            icon = Icon_Submenu_Entered;
+    title = init_title(menu, &icon);
     gui_synclist_set_title(lists, title, icon);
     gui_synclist_set_icon_callback(lists, global_settings.show_icons?menu_get_icon:NULL);
     if(global_settings.talk_menu)
@@ -382,6 +392,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
     int ret = 0;
     int action;
     int start_action;
+    int icon;
+    char buf[80], *title;
     struct gui_synclist lists;
     const struct menu_item_ex *temp = NULL;
     const struct menu_item_ex *menu = start_menu;
@@ -398,9 +410,14 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
     touchscreen_set_mode(global_settings.touch_mode);
 #endif
 
+    title_buf = buf;
+    title_buf_sz = sizeof buf;
+    title = init_title(menu, &icon);
     FOR_NB_SCREENS(i)
+    {
+        sb_set_persistent_title(title, icon, i);
         viewportmanager_theme_enable(i, !hide_theme, NULL);
-
+    }
     struct menu_data_t mstack[MAX_MENUS]; /* menu, selected */
     int stack_top = 0;
 
@@ -785,6 +802,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
 
     FOR_NB_SCREENS(i)
     {
+        sb_set_persistent_title(lists.title, lists.title_icon, i);
         viewportmanager_theme_undo(i, false);
         skinlist_set_cfg(i, NULL); /* Bugfix dangling reference in skin_draw() */
     }
diff --git a/apps/plugin.c b/apps/plugin.c
index 113bad7d26..0679d60f23 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -874,6 +874,7 @@ static const struct plugin_api rockbox_api = {
 
     /* new stuff at the end, sort into place next time
        the API gets incompatible */
+    sb_set_persistent_title,
 };
 
 static int plugin_buffer_handle;
diff --git a/apps/plugin.h b/apps/plugin.h
index 1402a9575c..64ae2c0449 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -1026,6 +1026,8 @@ struct plugin_api {
 
     /* new stuff at the end, sort into place next time
        the API gets incompatible */
+    bool (*sb_set_persistent_title)(const char* title, enum themable_icons icon,
+                                    enum screen_type screen);
 };
 
 /* plugin header */
diff --git a/apps/plugins/playing_time.c b/apps/plugins/playing_time.c
index 6a63c3dd8d..6504988026 100644
--- a/apps/plugins/playing_time.c
+++ b/apps/plugins/playing_time.c
@@ -560,10 +560,11 @@ enum plugin_status plugin_start(const void* parameter)
         return status;
     }
 
-    /* Only relevant if launched using hotkey from the
-       WPS. Otherwise theme should be enabled already. */
     FOR_NB_SCREENS(i)
+    {
+        rb->sb_set_persistent_title(rb->str(LANG_PLAYING_TIME), Icon_NOICON, i);
         rb->viewportmanager_theme_enable(i, true, NULL);
+    }
 
     if (playing_time())
         status = PLUGIN_USB_CONNECTED;
diff --git a/apps/plugins/text_viewer/tv_display.c b/apps/plugins/text_viewer/tv_display.c
index dfce96f3ab..62e811cbb0 100644
--- a/apps/plugins/text_viewer/tv_display.c
+++ b/apps/plugins/text_viewer/tv_display.c
@@ -300,10 +300,14 @@ static void tv_change_viewport(void)
     bool show_statusbar = preferences->statusbar;
 
     if (is_initialized_vp)
+    {
+        rb->sb_set_persistent_title(tv_get_title_text(), Icon_NOICON, SCREEN_MAIN);
         rb->viewportmanager_theme_undo(SCREEN_MAIN, false);
+    }
     else
         is_initialized_vp = true;
 
+    rb->sb_set_persistent_title(tv_get_title_text(), Icon_NOICON, SCREEN_MAIN);
     rb->viewportmanager_theme_enable(SCREEN_MAIN, show_statusbar, &vp_info);
     vp_info.flags &= ~VP_FLAG_ALIGNMENT_MASK;
     display->set_viewport(&vp_info);
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.