quickscreen: fix possible flickering for GUI_EVENT_NEED_UI_UPDATE

Immediately redraw when skin engine does refresh, so
themes that draw over UI viewport don't cause visible
flickering

Change-Id: I6f314cdfbd1136c710b9fee7526673e2f8b98849
This commit is contained in:
Christian Soffke 2026-05-06 09:49:52 +02:00
parent e37111c3eb
commit 7aca1d46b8

View file

@ -53,30 +53,20 @@
struct gui_quickscreen struct gui_quickscreen
{ {
const struct settings_list *items[QUICKSCREEN_ITEM_COUNT]; const struct settings_list *items[QUICKSCREEN_ITEM_COUNT];
struct viewport parent[NB_SCREENS];
struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT];
struct viewport vp_icons[NB_SCREENS];
}; };
static bool redraw; static void quickscreen_fix_viewports(struct gui_quickscreen *qs, enum screen_type screen)
static void quickscreen_update_callback(unsigned short id,
void *data, void *userdata)
{
(void)id;
(void)data;
(void)userdata;
redraw = true;
}
static void quickscreen_fix_viewports(struct gui_quickscreen *qs,
struct screen *display,
struct viewport *parent,
struct viewport
vps[QUICKSCREEN_ITEM_COUNT],
struct viewport *vp_icons)
{ {
int char_height, width, pad = 0; int char_height, width, pad = 0;
int left_width = 0, right_width = 0, vert_lines; int left_width = 0, right_width = 0, vert_lines;
unsigned char *s; unsigned char *s;
struct screen *display = &screens[screen];
struct viewport *parent = &qs->parent[screen];
struct viewport *vps = qs->vps[screen];
struct viewport *vp_icons = &qs->vp_icons[screen];
int nb_lines = viewport_get_nb_lines(parent); int nb_lines = viewport_get_nb_lines(parent);
/* nb_lines only returns the number of fully visible lines, small screens /* nb_lines only returns the number of fully visible lines, small screens
@ -181,16 +171,15 @@ static void quickscreen_fix_viewports(struct gui_quickscreen *qs,
vps[QUICKSCREEN_RIGHT].flags |= VP_FLAG_ALIGN_RIGHT; vps[QUICKSCREEN_RIGHT].flags |= VP_FLAG_ALIGN_RIGHT;
} }
static void gui_quickscreen_draw(const struct gui_quickscreen *qs, static void gui_quickscreen_draw(struct gui_quickscreen *qs, enum screen_type screen)
struct screen *display,
struct viewport *parent,
struct viewport vps[QUICKSCREEN_ITEM_COUNT],
struct viewport *vp_icons)
{ {
int i; int temp, i;
char buf[MAX_PATH]; char buf[MAX_PATH];
unsigned const char *title, *value; unsigned const char *title, *value;
int temp; struct screen *display = &screens[screen];
struct viewport *parent = &qs->parent[screen];
struct viewport *vps = qs->vps[screen];
struct viewport *vp_icons = &qs->vp_icons[screen];
struct viewport *last_vp = display->set_viewport(parent); struct viewport *last_vp = display->set_viewport(parent);
display->clear_viewport(); display->clear_viewport();
@ -246,6 +235,16 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
display->set_viewport(last_vp); display->set_viewport(last_vp);
} }
static void quickscreen_update_callback(unsigned short id,
void *data, void *userdata)
{
(void)id;
(void)data;
FOR_NB_SCREENS(i)
gui_quickscreen_draw((struct gui_quickscreen *) userdata, i);
}
static void talk_qs_option(const struct settings_list *opt, bool enqueue) static void talk_qs_option(const struct settings_list *opt, bool enqueue)
{ {
if (!global_settings.talk_menu || !opt) if (!global_settings.talk_menu || !opt)
@ -345,9 +344,6 @@ static int quickscreen_touchscreen_button(void)
static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter, bool *usb) static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter, bool *usb)
{ {
int button; int button;
struct viewport parent[NB_SCREENS];
struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT];
struct viewport vp_icons[NB_SCREENS];
int ret = QUICKSCREEN_OK; int ret = QUICKSCREEN_OK;
/* To quit we need either : /* To quit we need either :
* - a second press on the button that made us enter * - a second press on the button that made us enter
@ -357,15 +353,13 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
push_current_activity(ACTIVITY_QUICKSCREEN); push_current_activity(ACTIVITY_QUICKSCREEN);
add_event_ex(GUI_EVENT_NEED_UI_UPDATE, false, quickscreen_update_callback, NULL);
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{ {
screens[i].set_viewport(NULL); screens[i].set_viewport(NULL);
screens[i].scroll_stop(); screens[i].scroll_stop();
viewportmanager_theme_enable(i, true, &parent[i]); viewportmanager_theme_enable(i, true, &qs->parent[i]);
quickscreen_fix_viewports(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]); quickscreen_fix_viewports(qs, i);
gui_quickscreen_draw(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]); gui_quickscreen_draw(qs, i);
} }
*usb = false; *usb = false;
/* Announce current selection on entering this screen. This is all /* Announce current selection on entering this screen. This is all
@ -382,14 +376,9 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
action_gesture_reset(); action_gesture_reset();
#endif #endif
while (true) { add_event_ex(GUI_EVENT_NEED_UI_UPDATE, false, quickscreen_update_callback, qs);
if (redraw) while (true)
{ {
redraw = false;
FOR_NB_SCREENS(i)
gui_quickscreen_draw(qs, &screens[i], &parent[i],
vps[i], &vp_icons[i]);
}
button = get_action(CONTEXT_QUICKSCREEN, HZ/5); button = get_action(CONTEXT_QUICKSCREEN, HZ/5);
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
if (button == ACTION_TOUCHSCREEN) if (button == ACTION_TOUCHSCREEN)
@ -404,7 +393,8 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
{ {
ret |= QUICKSCREEN_CHANGED; ret |= QUICKSCREEN_CHANGED;
can_quit = true; can_quit = true;
redraw = true; FOR_NB_SCREENS(i)
gui_quickscreen_draw(qs, i);
} }
else if (button == button_enter) else if (button == button_enter)
can_quit = true; can_quit = true;
@ -429,12 +419,14 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
if (button == ACTION_STD_CANCEL) if (button == ACTION_STD_CANCEL)
break; break;
} }
remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, quickscreen_update_callback, qs);
/* Notify that we're exiting this screen */ /* Notify that we're exiting this screen */
cond_talk_ids_fq(VOICE_OK); cond_talk_ids_fq(VOICE_OK);
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{ /* stop scrolling before exiting */ { /* stop scrolling before exiting */
for (int j = 0; j < QUICKSCREEN_ITEM_COUNT; j++) for (int j = 0; j < QUICKSCREEN_ITEM_COUNT; j++)
screens[i].scroll_stop_viewport(&vps[i][j]); screens[i].scroll_stop_viewport(&qs->vps[i][j]);
viewportmanager_theme_undo(i, !(ret & QUICKSCREEN_GOTO_SHORTCUTS_MENU)); viewportmanager_theme_undo(i, !(ret & QUICKSCREEN_GOTO_SHORTCUTS_MENU));
} }
@ -443,8 +435,6 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
else else
pop_current_activity(); pop_current_activity();
remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, quickscreen_update_callback, NULL);
return ret; return ret;
} }