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: 6afb392823.

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.
This commit is contained in:
Krzysztof Małysa 2022-07-13 16:39:30 +02:00
parent 8d8a21c9c3
commit 964e0e2301
2 changed files with 18 additions and 6 deletions

View file

@ -20,7 +20,12 @@ struct sway_switch *sway_switch_create(struct sway_seat *seat,
return switch_device; 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) { enum wlr_switch_state state) {
switch (trigger) { switch (trigger) {
case SWAY_SWITCH_TRIGGER_ON: 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: case SWAY_SWITCH_TRIGGER_OFF:
return state == WLR_SWITCH_STATE_OFF; return state == WLR_SWITCH_STATE_OFF;
case SWAY_SWITCH_TRIGGER_TOGGLE: case SWAY_SWITCH_TRIGGER_TOGGLE:
return true; return false;
} }
abort(); // unreachable 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; struct sway_seat* seat = sway_switch->seat_device->sway_seat;
bool input_inhibited = seat->exclusive_client != NULL || bool input_inhibited = seat->exclusive_client != NULL ||
server.session_lock.locked; 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) { static void handle_switch_toggle(struct wl_listener *listener, void *data) {
struct sway_switch *sway_switch = struct sway_switch *sway_switch =
wl_container_of(listener, sway_switch, switch_toggle); 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->type = event->switch_type;
sway_switch->state = event->switch_state; sway_switch->state = event->switch_state;
execute_binding(sway_switch); execute_bindings(sway_switch);
} }
void sway_switch_configure(struct sway_switch *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) { if (input_device->wlr_device->type != WLR_INPUT_DEVICE_SWITCH) {
continue; continue;
} }
execute_binding(seat_device->switch_device); execute_bindings(seat_device->switch_device);
}; };
} }
} }

View file

@ -464,7 +464,8 @@ runtime.
switches. Valid values for _state_ are _on_, _off_ and _toggle_. These 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 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 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 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 screen locking program is active. If there is a matching binding with