From 964e0e23010d8be9a02cda378afff9b656365973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ma=C5=82ysa?= Date: Wed, 13 Jul 2022 16:39:30 +0200 Subject: [PATCH] Fix bindswitch not executing all binds If there was bindswitch on lid:toggle and either lid:on or lid:off (or both). Only one bind was executed instead of two. E.g. if the lid is closed sway should execute lid:on and lid:toggle binds. But it executed only one of them (the one that appears later in the config). This is a regression introduced here: 6afb392823d27ec69bedc8fd74263c3d072cca29. Additionally, made toggle event always happen before on or off event. This is more convenient instead of an arbitrary order. It is easier to implement and more intuitive because conceptually, toggling of the state happens before the target state is reached. --- sway/input/switch.c | 21 ++++++++++++++++----- sway/sway.5.scd | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/sway/input/switch.c b/sway/input/switch.c index fc7dfaff..d56461c2 100644 --- a/sway/input/switch.c +++ b/sway/input/switch.c @@ -20,7 +20,12 @@ struct sway_switch *sway_switch_create(struct sway_seat *seat, return switch_device; } -static bool sway_switch_trigger_test(enum sway_switch_trigger trigger, +static bool sway_switch_trigger_is_toggle(enum sway_switch_trigger trigger, + enum wlr_switch_state /*state*/) { + return trigger == SWAY_SWITCH_TRIGGER_TOGGLE; +} + +static bool sway_switch_trigger_equals_state(enum sway_switch_trigger trigger, enum wlr_switch_state state) { switch (trigger) { case SWAY_SWITCH_TRIGGER_ON: @@ -28,12 +33,13 @@ static bool sway_switch_trigger_test(enum sway_switch_trigger trigger, case SWAY_SWITCH_TRIGGER_OFF: return state == WLR_SWITCH_STATE_OFF; case SWAY_SWITCH_TRIGGER_TOGGLE: - return true; + return false; } abort(); // unreachable } -static void execute_binding(struct sway_switch *sway_switch) { +static void execute_binding_matching(struct sway_switch* sway_switch, + bool (*sway_switch_trigger_test)(enum sway_switch_trigger, enum wlr_switch_state)) { struct sway_seat* seat = sway_switch->seat_device->sway_seat; bool input_inhibited = seat->exclusive_client != NULL || server.session_lock.locked; @@ -76,6 +82,11 @@ static void execute_binding(struct sway_switch *sway_switch) { } } +static void execute_bindings(struct sway_switch *sway_switch) { + execute_binding_matching(sway_switch, sway_switch_trigger_is_toggle); + execute_binding_matching(sway_switch, sway_switch_trigger_equals_state); +} + static void handle_switch_toggle(struct wl_listener *listener, void *data) { struct sway_switch *sway_switch = wl_container_of(listener, sway_switch, switch_toggle); @@ -92,7 +103,7 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) { sway_switch->type = event->switch_type; sway_switch->state = event->switch_state; - execute_binding(sway_switch); + execute_bindings(sway_switch); } void sway_switch_configure(struct sway_switch *sway_switch) { @@ -120,7 +131,7 @@ void sway_switch_retrigger_bindings_for_all(void) { if (input_device->wlr_device->type != WLR_INPUT_DEVICE_SWITCH) { continue; } - execute_binding(seat_device->switch_device); + execute_bindings(seat_device->switch_device); }; } } diff --git a/sway/sway.5.scd b/sway/sway.5.scd index db7886f0..f6d895fb 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -464,7 +464,8 @@ runtime. switches. Valid values for _state_ are _on_, _off_ and _toggle_. These switches are on when the device lid is shut and when tablet mode is active respectively. _toggle_ is also supported to run a command both when the - switch is toggled on or off. + switch is toggled on or off. _toggle_ is always dispatched before + dispatching _on_ and _off_. Unless the flag _--locked_ is set, the command will not be run when a screen locking program is active. If there is a matching binding with