···176176177177 if transition != Transition::None {
178178 app_mgr.apply_transition(transition, &mut self.handle());
179179+ tasks::request_hold_reset();
179180 }
180181181182 false
···323324 // because ch_cached stays false until the full write completes.
324325 // the TICK_MS timeout ensures is_busy is re-checked regularly
325326 // even during long background operations.
327327+ //
328328+ // first non-None transition wins; hold is reset so the held button
329329+ // doesn't re-fire LongPress/Repeat for the remainder of the waveform
326330 async fn busy_wait_with_background<A: AppLayer>(
327331 &mut self,
328332 app_mgr: &mut A,
···357361 let t = app_mgr.dispatch_event(hw_event, &mut *self.bm_cache);
358362 if t != Transition::None && deferred.is_none() {
359363 deferred = Some(t);
364364+ tasks::request_hold_reset();
360365 }
361366 }
362367 }
+12
kernel/src/kernel/tasks.rs
···1212pub static INPUT_EVENTS: Channel<CriticalSectionRawMutex, Event, INPUT_CHANNEL_CAP> =
1313 Channel::new();
14141515+// signal input_task to reset hold timers after a navigation event is consumed
1616+pub static RESET_HOLD: Signal<CriticalSectionRawMutex, ()> = Signal::new();
1717+1818+#[inline]
1919+pub fn request_hold_reset() {
2020+ RESET_HOLD.signal(());
2121+}
2222+1523pub static BATTERY_MV: Signal<CriticalSectionRawMutex, u16> = Signal::new();
16241725const BATTERY_INTERVAL_TICKS: u32 = 3000; // 3000 x 10 ms = 30 s
···26342735 loop {
2836 ticker.next().await;
3737+3838+ if RESET_HOLD.try_take().is_some() {
3939+ input.reset_hold_state();
4040+ }
29413042 if let Some(ev) = input.poll() {
3143 let _ = INPUT_EVENTS.try_send(ev);