]> git.earman.xyz Git - sensor-watch.git/commitdiff
Events that follow a down event on the previous face should not be forwarded to the...
authorAlessandro Genova <ales.genova@gmail.com>
Tue, 16 Sep 2025 03:42:31 +0000 (23:42 -0400)
committerAlessandro Genova <ales.genova@gmail.com>
Sat, 3 Jan 2026 01:07:56 +0000 (20:07 -0500)
movement.c

index c1a5d08790600ad429b96abd779db31dae21b1d4..34e5645efa3ce0212c5f99ba39df051a24e3169d 100644 (file)
@@ -61,6 +61,11 @@ watch_date_time_t scheduled_tasks[MOVEMENT_NUM_FACES];
 const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 600, 3600, 7200, 21600, 43200, 86400, 604800};
 const int16_t movement_timeout_inactivity_deadlines[4] = {60, 120, 300, 1800};
 
+const uint32_t _movement_mode_button_events_mask = 0b1111 << EVENT_MODE_BUTTON_DOWN;
+const uint32_t _movement_light_button_events_mask = 0b1111 << EVENT_LIGHT_BUTTON_DOWN;
+const uint32_t _movement_alarm_button_events_mask = 0b1111 << EVENT_ALARM_BUTTON_DOWN;
+const uint32_t _movement_button_events_mask = _movement_mode_button_events_mask | _movement_light_button_events_mask | _movement_alarm_button_events_mask;
+
 typedef struct {
     movement_event_type_t down_event;
     watch_cb_t cb_longpress;
@@ -93,6 +98,9 @@ typedef struct {
     movement_button_t mode_button;
     movement_button_t light_button;
     movement_button_t alarm_button;
+
+    // button events that will not be passed to the current face loop, but will instead passed directly to the default loop handler.
+    volatile uint32_t passthrough_events;
 } movement_volatile_state_t;
 
 movement_volatile_state_t movement_volatile_state;
@@ -278,6 +286,12 @@ static void _movement_handle_button_presses(uint32_t pending_events) {
         &movement_volatile_state.alarm_button
     };
 
+    uint32_t button_events_masks[3] = {
+        _movement_mode_button_events_mask,
+        _movement_light_button_events_mask,
+        _movement_alarm_button_events_mask,
+    };
+
     for (uint8_t i = 0; i < 3; i++) {
         movement_button_t* button = buttons[i];
 
@@ -285,6 +299,8 @@ static void _movement_handle_button_presses(uint32_t pending_events) {
         if (pending_events & (1 << button->down_event)) {
             watch_rtc_register_comp_callback_no_schedule(button->cb_longpress, button->down_timestamp + MOVEMENT_LONG_PRESS_TICKS, button->timeout_index);
             any_down = true;
+            // this button's events will start getting passed to the face
+            movement_volatile_state.passthrough_events &= ~button_events_masks[i];
         }
 
         // If a button up or button long up occurred
@@ -1173,6 +1189,9 @@ static bool _switch_face(void) {
     movement_state.watch_face_changed = false;
     bool can_sleep = wf->loop(event, watch_face_contexts[movement_state.current_face_idx]);
 
+    // Button events that follow a down event that happened on the previous face should not be forwarded to the new face
+    movement_volatile_state.passthrough_events = _movement_button_events_mask;
+
     return can_sleep;
 }
 
@@ -1221,7 +1240,19 @@ bool app_loop(void) {
     }
 
     // Consume all the pending events
+    uint32_t passthrough_pending_events = pending_events & movement_volatile_state.passthrough_events;
+    pending_events = pending_events & ~movement_volatile_state.passthrough_events;
+
     movement_event_type_t event_type = 0;
+    while (passthrough_pending_events) {
+        uint8_t next_event = __builtin_ctz(passthrough_pending_events);
+        event.event_type = event_type + next_event;
+        can_sleep = movement_default_loop_handler(event) && can_sleep;
+        passthrough_pending_events = passthrough_pending_events >> (next_event + 1);
+        event_type = event_type + next_event + 1;
+    }
+
+    event_type = 0;
     while (pending_events) {
         uint8_t next_event = __builtin_ctz(pending_events);
         event.event_type = event_type + next_event;