diff --git a/doc/button-debouncing-state-machine.svg b/doc/button-debouncing-state-machine.svg index 0553012f..53c08305 100644 --- a/doc/button-debouncing-state-machine.svg +++ b/doc/button-debouncing-state-machine.svg @@ -1,3 +1,3 @@ -
IS_UP
IS_UP
button
press
button<br>press
DOWN_WAITING
DOWN_WAITING
RELEASE_PENDING
RELEASE_PENDING
timeout
timeout
notify
button
release
[Not supported by viewer]
notify
button
press
[Not supported by viewer]
IS_DOWN
IS_DOWN
button
release
button<br>release
timeout
timeout
IS_UP
IS_UP
button
release
button<br>release
button
press
button<br>press
notify
button
release
[Not supported by viewer]
RELEASE_WAITING
RELEASE_WAITING
button
press
button<br>press
timeout
timeout
MAYBE_SPURIOUS
MAYBE_SPURIOUS
button
release
button<br>release
timeout
short
timeout<br>short
spurious
enabled?
spurious<br>enabled?
no
no
timeout
short
timeout<br>short
RELEASED
RELEASED
button
press
button<br>press
PRESS_PENDING
PRESS_PENDING
button
release
button<br>release
timeout
timeout
notify
button
press
[Not supported by viewer]
RELEASE_DELAYED
RELEASE_DELAYED
yes
yes
timeout
short
timeout<br>short
button
press
button<br>press
set
timer
set<br>timer
set
timer
set<br>timer
set short
timer
set short<br>timer
other
button
other<br>button
other
button
other<br>button
other
button
other<br>button
other
button
other<br>button
other
button
other<br>button
other
button
other<br>button
timeout
timeout
notify
button
press
[Not supported by viewer]
other
button
other<br>button
other
button
other<br>button
notify
button
release
[Not supported by viewer]

Entry states: IS_UP, IS_DOWN

Assumption: state is stored per-button, and OTHER BUTTON events are always processed before the actual button. Stored state per button is a single bit (up/down), a single state for the state machine across the device is sufficient.

Start the state machine with IS_UP or IS_DOWN based on the button's bit, any OTHER BUTTON event will reset it to that state anyway, so the state can be re-used for the new button.

[Not supported by viewer]
other
button
other<br>button
enable
spurious
enable<br>spurious
IS_DOWN
IS_DOWN
timeout
timeout
DISABLED
DISABLED
button
press
button<br>press
notify
button
press
[Not supported by viewer]
button
release
button<br>release
notify
button
release
[Not supported by viewer]
other
button
other<br>button

Entry state: DISABLED

Only set on devices that have button debouncing disabled. This state is effectively a noop, it just forwards the events as they come in and returns back to the same state.
[Not supported by viewer]
notify
button
release
[Not supported by viewer]
\ No newline at end of file +

Entry states: IS_UP, IS_DOWN

Assumption: state is stored per-button, and OTHER BUTTON events are always processed before the actual button. Stored state per button is a single bit (up/down), a single state for the state machine across the device is sufficient.

Start the state machine with IS_UP or IS_DOWN based on the button's bit, any OTHER BUTTON event will reset it to that state anyway, so the state can be re-used for the new button.

[Not supported by viewer]

Entry state: DISABLED

Only set on devices that have button debouncing disabled. This state is effectively a noop, it just forwards the events as they come in and returns back to the same state.
[Not supported by viewer]
button
press
button<br>press
button
release
button<br>release
DISABLED
DISABLED
button
press
button<br>press
notify
button
press
[Not supported by viewer]
button
release
button<br>release
notify
button
release
[Not supported by viewer]
other
button
other<br>button
IS_UP
IS_UP
button
press
button<br>press
IS_DOWN_WAITING
IS_DOWN_WAITING
IS_UP_DELAYING
IS_UP_DELAYING
notify
button
release
[Not supported by viewer]
notify
button
press
[Not supported by viewer]
IS_UP
IS_UP
notify
button
release
[Not supported by viewer]
IS_DOWN_DETECTING_SPURIOUS
IS_DOWN_DETECTING_SPURIOUS
spurious
enabled?
spurious<br>enabled?
no
no
yes
yes
set
timer
set<br>timer
notify
button
press
[Not supported by viewer]
other
button
other<br>button
enable
spurious
enable<br>spurious
IS_DOWN
IS_DOWN
IS_DOWN
IS_DOWN
button
release
button<br>release
set
timer
set<br>timer
set short
timer
set short<br>timer
other
button
other<br>button
IS_UP_DELAYING_SPURIOUS
IS_UP_DELAYING_SPURIOUS
IS_UP_DETECTING_SPURIOUS
IS_UP_DETECTING_SPURIOUS
button
press
button<br>press
timeout
short
timeout<br>short
other
button
other<br>button
timeout
timeout
button
release
button<br>release
timeout
short
timeout<br>short
other
button
other<br>button
timeout
timeout
timeout
timeout
other
button
other<br>button
timeout
timeout
other
button
other<br>button
IS_DOWN_DELAYING
IS_DOWN_DELAYING
notify
button
press
[Not supported by viewer]
timeout
timeout
button
press
button<br>press
other
button
other<br>button
notify
button
release
[Not supported by viewer]
notify
button
release
[Not supported by viewer]
timeout
short
timeout<br>short
button
press
button<br>press
other
button
other<br>button
IS_UP_WAITING
IS_UP_WAITING
button
release
button<br>release
timeout
timeout
other
button
other<br>button
\ No newline at end of file diff --git a/src/evdev-debounce.c b/src/evdev-debounce.c index 744debae..33ff05db 100644 --- a/src/evdev-debounce.c +++ b/src/evdev-debounce.c @@ -74,13 +74,13 @@ debounce_state_to_str(enum debounce_state state) switch(state) { CASE_RETURN_STRING(DEBOUNCE_STATE_IS_UP); CASE_RETURN_STRING(DEBOUNCE_STATE_IS_DOWN); - CASE_RETURN_STRING(DEBOUNCE_STATE_DOWN_WAITING); - CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASE_PENDING); - CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASE_DELAYED); - CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASE_WAITING); - CASE_RETURN_STRING(DEBOUNCE_STATE_MAYBE_SPURIOUS); - CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASED); - CASE_RETURN_STRING(DEBOUNCE_STATE_PRESS_PENDING); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_DOWN_WAITING); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_UP_DELAYING); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_UP_DELAYING_SPURIOUS); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_DOWN_DETECTING_SPURIOUS); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_UP_WAITING); + CASE_RETURN_STRING(DEBOUNCE_STATE_IS_DOWN_DELAYING); CASE_RETURN_STRING(DEBOUNCE_STATE_DISABLED); } @@ -115,7 +115,7 @@ debounce_set_state(struct fallback_dispatch *fallback, enum debounce_state new_state) { assert(new_state >= DEBOUNCE_STATE_IS_UP && - new_state <= DEBOUNCE_STATE_PRESS_PENDING); + new_state <= DEBOUNCE_STATE_IS_DOWN_DELAYING); fallback->debounce.state = new_state; } @@ -186,7 +186,7 @@ debounce_is_up_handle_event(struct fallback_dispatch *fallback, enum debounce_ev case DEBOUNCE_EVENT_PRESS: fallback->debounce.button_time = time; debounce_set_timer(fallback, time); - debounce_set_state(fallback, DEBOUNCE_STATE_DOWN_WAITING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_DOWN_WAITING); debounce_notify_button(fallback, LIBINPUT_BUTTON_STATE_PRESSED); break; @@ -212,9 +212,9 @@ debounce_is_down_handle_event(struct fallback_dispatch *fallback, enum debounce_ debounce_set_timer(fallback, time); debounce_set_timer_short(fallback, time); if (fallback->debounce.spurious_enabled) { - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASE_DELAYED); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_DELAYING_SPURIOUS); } else { - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASE_WAITING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS); debounce_notify_button(fallback, LIBINPUT_BUTTON_STATE_RELEASED); } @@ -229,14 +229,14 @@ debounce_is_down_handle_event(struct fallback_dispatch *fallback, enum debounce_ } static void -debounce_down_waiting_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_down_waiting_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: log_debounce_bug(fallback, event); break; case DEBOUNCE_EVENT_RELEASE: - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASE_PENDING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_DELAYING); /* Note: In the debouncing RPR case, we use the last * release's time stamp */ fallback->debounce.button_time = time; @@ -254,11 +254,11 @@ debounce_down_waiting_handle_event(struct fallback_dispatch *fallback, enum debo } static void -debounce_release_pending_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_up_delaying_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: - debounce_set_state(fallback, DEBOUNCE_STATE_DOWN_WAITING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_DOWN_WAITING); break; case DEBOUNCE_EVENT_RELEASE: case DEBOUNCE_EVENT_TIMEOUT_SHORT: @@ -274,7 +274,7 @@ debounce_release_pending_handle_event(struct fallback_dispatch *fallback, enum d } static void -debounce_release_delayed_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_up_delaying_spurious_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: @@ -287,7 +287,7 @@ debounce_release_delayed_handle_event(struct fallback_dispatch *fallback, enum d log_debounce_bug(fallback, event); break; case DEBOUNCE_EVENT_TIMEOUT_SHORT: - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASED); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_WAITING); debounce_notify_button(fallback, LIBINPUT_BUTTON_STATE_RELEASED); break; @@ -300,14 +300,14 @@ debounce_release_delayed_handle_event(struct fallback_dispatch *fallback, enum d } static void -debounce_release_waiting_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_up_detecting_spurious_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: /* Note: in a bouncing PRP case, we use the last press * event time */ fallback->debounce.button_time = time; - debounce_set_state(fallback, DEBOUNCE_STATE_MAYBE_SPURIOUS); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_DOWN_DETECTING_SPURIOUS); break; case DEBOUNCE_EVENT_RELEASE: log_debounce_bug(fallback, event); @@ -316,7 +316,7 @@ debounce_release_waiting_handle_event(struct fallback_dispatch *fallback, enum d debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP); break; case DEBOUNCE_EVENT_TIMEOUT_SHORT: - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASED); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_WAITING); break; case DEBOUNCE_EVENT_OTHERBUTTON: debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP); @@ -325,14 +325,14 @@ debounce_release_waiting_handle_event(struct fallback_dispatch *fallback, enum d } static void -debounce_maybe_spurious_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_down_detecting_spurious_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: log_debounce_bug(fallback, event); break; case DEBOUNCE_EVENT_RELEASE: - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASE_WAITING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS); break; case DEBOUNCE_EVENT_TIMEOUT_SHORT: debounce_cancel_timer(fallback); @@ -351,14 +351,14 @@ debounce_maybe_spurious_handle_event(struct fallback_dispatch *fallback, enum de } static void -debounce_released_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_up_waiting_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: /* Note: in a debouncing PRP case, we use the last press' * time */ fallback->debounce.button_time = time; - debounce_set_state(fallback, DEBOUNCE_STATE_PRESS_PENDING); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_DOWN_DELAYING); break; case DEBOUNCE_EVENT_RELEASE: case DEBOUNCE_EVENT_TIMEOUT_SHORT: @@ -372,14 +372,14 @@ debounce_released_handle_event(struct fallback_dispatch *fallback, enum debounce } static void -debounce_press_pending_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) +debounce_is_down_delaying_handle_event(struct fallback_dispatch *fallback, enum debounce_event event, uint64_t time) { switch (event) { case DEBOUNCE_EVENT_PRESS: log_debounce_bug(fallback, event); break; case DEBOUNCE_EVENT_RELEASE: - debounce_set_state(fallback, DEBOUNCE_STATE_RELEASED); + debounce_set_state(fallback, DEBOUNCE_STATE_IS_UP_WAITING); break; case DEBOUNCE_EVENT_TIMEOUT_SHORT: log_debounce_bug(fallback, event); @@ -437,26 +437,26 @@ debounce_handle_event(struct fallback_dispatch *fallback, case DEBOUNCE_STATE_IS_DOWN: debounce_is_down_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_DOWN_WAITING: - debounce_down_waiting_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_DOWN_WAITING: + debounce_is_down_waiting_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_RELEASE_PENDING: - debounce_release_pending_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_UP_DELAYING: + debounce_is_up_delaying_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_RELEASE_DELAYED: - debounce_release_delayed_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_UP_DELAYING_SPURIOUS: + debounce_is_up_delaying_spurious_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_RELEASE_WAITING: - debounce_release_waiting_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS: + debounce_is_up_detecting_spurious_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_MAYBE_SPURIOUS: - debounce_maybe_spurious_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_DOWN_DETECTING_SPURIOUS: + debounce_is_down_detecting_spurious_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_RELEASED: - debounce_released_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_UP_WAITING: + debounce_is_up_waiting_handle_event(fallback, event, time); break; - case DEBOUNCE_STATE_PRESS_PENDING: - debounce_press_pending_handle_event(fallback, event, time); + case DEBOUNCE_STATE_IS_DOWN_DELAYING: + debounce_is_down_delaying_handle_event(fallback, event, time); break; case DEBOUNCE_STATE_DISABLED: debounce_disabled_handle_event(fallback, event, time); diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h index f57c4af2..0f75827e 100644 --- a/src/evdev-fallback.h +++ b/src/evdev-fallback.h @@ -34,13 +34,13 @@ enum debounce_state { DEBOUNCE_STATE_IS_UP = 100, DEBOUNCE_STATE_IS_DOWN, - DEBOUNCE_STATE_DOWN_WAITING, - DEBOUNCE_STATE_RELEASE_PENDING, - DEBOUNCE_STATE_RELEASE_DELAYED, - DEBOUNCE_STATE_RELEASE_WAITING, - DEBOUNCE_STATE_MAYBE_SPURIOUS, - DEBOUNCE_STATE_RELEASED, - DEBOUNCE_STATE_PRESS_PENDING, + DEBOUNCE_STATE_IS_DOWN_WAITING, + DEBOUNCE_STATE_IS_UP_DELAYING, + DEBOUNCE_STATE_IS_UP_DELAYING_SPURIOUS, + DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS, + DEBOUNCE_STATE_IS_DOWN_DETECTING_SPURIOUS, + DEBOUNCE_STATE_IS_UP_WAITING, + DEBOUNCE_STATE_IS_DOWN_DELAYING, DEBOUNCE_STATE_DISABLED = 999, };