T-Watch S3: alarm rings for the full 5 minutes, PWR key dismisses

The alarm was self-dismissing after ~10-15 seconds. Cause: AUTO_OFF_MILLIS is
15000, so the display turned off shortly after the alarm fired; UITask.cpp:2769
raise-to-wake then saw !_display->isOn() && board.tiltFired() -- the buzzing motor
on the wrist is exactly what trips the BMA423 tilt detector -- and called
setCurrScreen(lock_screen). The 'navigating away counts as a dismiss' rule added
with the alarm screen then killed it. Any tap did the same.

While ringing, UITask::loop now holds the alarm screen current and pushes
_auto_off forward each iteration. The display therefore stays on, raise-to-wake
is never reached, and checkDisplayOn() passes KEY_ENTER through to handleInput()
rather than swallowing the first press as a wake.

Dismissal is now the PWR key only (KEY_ENTER). Taps are swallowed. The
WATCH_ALARM_RINGING_MS timeout (5 minutes) is unchanged and remains the backstop.
Ringing footer updated from 'Tap to dismiss' to 'Press PWR to dismiss'.

The ordering inside loop() makes this safe: the button dispatch and
curr->handleInput() both run before the alarm hold, so a dismiss takes effect on
the same iteration and the hold is not re-applied. The 90s per-slot fire cooldown
prevents an immediate re-fire within the alarm's own minute.
This commit is contained in:
meck
2026-07-10 10:11:08 +00:00
committed by pelgraine
parent fcd8b70384
commit 006d3bd00c
2 changed files with 21 additions and 10 deletions
+9 -7
View File
@@ -2476,15 +2476,17 @@ void UITask::loop() {
// with the display off or another screen showing.
if (watch_alarm_screen) {
WatchAlarmScreen* wa = (WatchAlarmScreen*)watch_alarm_screen;
if (wa->tick()) {
setCurrScreen(watch_alarm_screen);
bool fired = wa->tick();
if (fired || wa->isRinging()) {
// Hold the screen and the display for the whole ring. Without this the
// display auto-offs after AUTO_OFF_MILLIS, the buzzing trips the BMA423
// tilt detector, and raise-to-wake below swaps in the clock screen. It
// also guarantees the PWR key reaches handleInput() as KEY_ENTER rather
// than being consumed by checkDisplayOn() as a wake.
if (curr != watch_alarm_screen) setCurrScreen(watch_alarm_screen);
if (_display != NULL && !_display->isOn()) _display->turnOn();
_auto_off = millis() + AUTO_OFF_MILLIS;
_next_refresh = 0;
} else if (wa->isRinging() && curr != watch_alarm_screen) {
// Navigating away (e.g. the status-bar tap that goes home) counts as a
// dismiss, otherwise the motor would keep buzzing off-screen.
wa->dismiss();
if (fired) _next_refresh = 0;
}
}
#endif