Events that follow a down event on the previous face should not be forwarded to the new face

This commit is contained in:
Alessandro Genova
2025-09-15 23:42:31 -04:00
parent 13a5166097
commit 02faae3d25

View 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;