fix(ui): marquee-scroll never advances past 63 characters

The animated marquee that lets a selected row scroll into view instead of
truncating behind an ellipsis uses a small "is this the same text as last
frame" buffer, _marquee_text[64], compared against the current frame's
temp_str[256] via strcmp(). For any text at or past that 64-byte cutoff,
temp_str simply has more bytes than _marquee_text can hold, so strcmp
always finds a difference at the truncation point -- is_new evaluates true
on every single call, which resets _marquee_skip_cp and _marquee_phase back
to the start every frame. Short labels and names (what this was written
for) stayed under the cutoff and animated fine; a longer message-body
preview -- letting a message be read from the list without opening
fullscreen, an emergent use of the same feature -- got stuck holding at its
first frame forever.

Bumped _marquee_text to 256 to match temp_str/window's own cap in the same
function, so the comparison is exact instead of silently truncated. Static
+192 bytes on the one global DisplayDriver instance; verified against RAM
usage on all four build targets (all comfortably under headroom).

This lives in src/helpers/ui/, shared with upstream, unlike the rest of
this session's ui-new/-only work -- kept as its own commit.
This commit is contained in:
Jakub
2026-08-31 20:10:09 +02:00
parent d25fda5f32
commit 8ceb420b43
+9 -1
View File
@@ -14,7 +14,15 @@ protected:
// Only one row/label can be "selected" at a time across the whole UI, so one
// slot of state (rather than per-caller) is enough, and keeps every call
// site down to passing a bool.
char _marquee_text[64] = {0};
// Matches temp_str/window's own cap in drawTextEllipsized() below: this is
// only ever compared against that buffer (see is_new) to detect a text/width
// change, and a shorter cap here made a plain strcmp() see a mismatch at the
// truncation point on every single frame for any text past that length --
// "is_new" stuck true forever, so the marquee reset to its start position
// every call and never actually scrolled. Long message-preview rows (not
// just short labels/names) hit this once selected-row scrolling started
// being used to read them without opening fullscreen.
char _marquee_text[256] = {0};
int _marquee_max_w = -1;
uint16_t _marquee_skip_cp = 0;
uint16_t _marquee_max_skip_cp = 0;