From 8ceb420b4356e56707ecef04875a049be0b3ff7e Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Mon, 31 Aug 2026 20:10:09 +0200 Subject: [PATCH] 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. --- src/helpers/ui/DisplayDriver.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/helpers/ui/DisplayDriver.h b/src/helpers/ui/DisplayDriver.h index 8ad6ca20..d23e40b4 100644 --- a/src/helpers/ui/DisplayDriver.h +++ b/src/helpers/ui/DisplayDriver.h @@ -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;