fix(ui/input): first melody note duration; OLED joystick reset

UITask: when a key is pressed while the buzzer is playing, defer the
next screen refresh by 300 ms instead of triggering it immediately
(via _next_refresh = 100). The blocking e-ink endFrame() was extending
the first note by the full refresh duration (~150-200 ms). Subsequent
notes were unaffected because _next_refresh was already future-dated
after the first render.

DataStore: for builds where JOYSTICK_ROTATION is not defined and
FEAT_JOYSTICK_ROTATION_SETTING is 0 (OLED), always reset
joystick_rotation to 0 on prefs load. Without this, stale e-ink prefs
(which allow changing joystick rotation in Settings) could silently
leave a non-zero value that reversed all joystick directions on OLED.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-27 17:33:41 +02:00
co-authored by Claude Sonnet 4.6
parent 2e3d6381a4
commit dd9c75d4f4
2 changed files with 19 additions and 0 deletions
@@ -1590,7 +1590,18 @@ void UITask::loop() {
if (!_locked && curr) {
curr->handleInput(c);
{ uint32_t aoff = autoOffMillis(); if (aoff > 0) _auto_off = millis() + aoff; } // extend auto-off timer
#ifdef PIN_BUZZER
if (buzzer.isPlaying()) {
// Keep the next render at least 300 ms away so the blocking e-ink endFrame()
// doesn't extend the current note. 300 ms covers the slowest note at 120 BPM (1/4).
unsigned long deadline = millis() + 300;
if (_next_refresh < deadline) _next_refresh = deadline;
} else {
_next_refresh = 100; // trigger refresh immediately
}
#else
_next_refresh = 100; // trigger refresh
#endif
} else if (_locked) {
// Locked: eat all keys — wake window is set only when display first turns on
_next_refresh = 0;