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;
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;
&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];
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
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;
}
}
// 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;