From b3f08597cd725ef8136fb3cfb2808be990a6fce8 Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Thu, 18 Jun 2020 22:26:27 -0400 Subject: [PATCH] input: disable events for map_to_output devices when output not present Fixes #3449. --- include/sway/input/input-manager.h | 4 +++- sway/config/output.c | 9 +-------- sway/input/input-manager.c | 25 ++++++++++++++++++------- sway/input/libinput.c | 18 +++++++++++++++++- sway/tree/output.c | 5 +++++ 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h index 5107647d..c9bd08f0 100644 --- a/include/sway/input/input-manager.h +++ b/include/sway/input/input-manager.h @@ -44,9 +44,11 @@ void input_manager_configure_xcursor(void); void input_manager_apply_input_config(struct input_config *input_config); +void input_manager_configure_all_inputs(void); + void input_manager_reset_input(struct sway_input_device *input_device); -void input_manager_reset_all_inputs(); +void input_manager_reset_all_inputs(void); void input_manager_apply_seat_config(struct seat_config *seat_config); diff --git a/sway/config/output.c b/sway/config/output.c index 713cd219..68aafbe1 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -481,14 +481,7 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { // Reconfigure all devices, since input config may have been applied before // this output came online, and some config items (like map_to_output) are // dependent on an output being present. - struct sway_input_device *input_device = NULL; - wl_list_for_each(input_device, &server.input->devices, link) { - struct sway_seat *seat = NULL; - wl_list_for_each(seat, &server.input->seats, link) { - seat_configure_device(seat, input_device); - } - } - + input_manager_configure_all_inputs(); return true; } diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index b900f666..69342c73 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -521,6 +521,22 @@ static void retranslate_keysyms(struct input_config *input_config) { } } +static void input_manager_configure_input( + struct sway_input_device *input_device) { + sway_input_configure_libinput_device(input_device); + struct sway_seat *seat = NULL; + wl_list_for_each(seat, &server.input->seats, link) { + seat_configure_device(seat, input_device); + } +} + +void input_manager_configure_all_inputs(void) { + struct sway_input_device *input_device = NULL; + wl_list_for_each(input_device, &server.input->devices, link) { + input_manager_configure_input(input_device); + } +} + void input_manager_apply_input_config(struct input_config *input_config) { struct sway_input_device *input_device = NULL; bool wildcard = strcmp(input_config->identifier, "*") == 0; @@ -531,11 +547,7 @@ void input_manager_apply_input_config(struct input_config *input_config) { if (strcmp(input_device->identifier, input_config->identifier) == 0 || wildcard || type_matches) { - sway_input_configure_libinput_device(input_device); - struct sway_seat *seat = NULL; - wl_list_for_each(seat, &server.input->seats, link) { - seat_configure_device(seat, input_device); - } + input_manager_configure_input(input_device); } } @@ -550,7 +562,7 @@ void input_manager_reset_input(struct sway_input_device *input_device) { } } -void input_manager_reset_all_inputs() { +void input_manager_reset_all_inputs(void) { struct sway_input_device *input_device = NULL; wl_list_for_each(input_device, &server.input->devices, link) { input_manager_reset_input(input_device); @@ -568,7 +580,6 @@ void input_manager_reset_all_inputs() { } } - void input_manager_apply_seat_config(struct seat_config *seat_config) { sway_log(SWAY_DEBUG, "applying seat config for seat %s", seat_config->name); if (strcmp(seat_config->name, "*") == 0) { diff --git a/sway/input/libinput.c b/sway/input/libinput.c index caaba5a1..4ec72882 100644 --- a/sway/input/libinput.c +++ b/sway/input/libinput.c @@ -4,6 +4,7 @@ #include #include "log.h" #include "sway/config.h" +#include "sway/output.h" #include "sway/input/input-manager.h" #include "sway/ipc-server.h" @@ -190,9 +191,24 @@ static bool config_libinput_pointer(struct libinput_device *device, sway_log(SWAY_DEBUG, "config_libinput_pointer('%s' on '%s')", ic->identifier, device_id); bool changed = false; - if (ic->send_events != INT_MIN) { + + if (ic->mapped_to_output && + !output_by_name_or_id(ic->mapped_to_output)) { + sway_log(SWAY_DEBUG, + "Pointer '%s' is mapped to offline output '%s'; disabling input", + ic->identifier, ic->mapped_to_output); + changed |= set_send_events(device, + LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); + } else if (ic->send_events != INT_MIN) { changed |= set_send_events(device, ic->send_events); + } else { + // Have to reset to the default mode here, otherwise if ic->send_events + // is unset and a mapped output just came online after being disabled, + // we'd remain stuck sending no events. + changed |= set_send_events(device, + libinput_device_config_send_events_get_default_mode(device)); } + if (ic->tap != INT_MIN) { changed |= set_tap(device, ic->tap); } diff --git a/sway/tree/output.c b/sway/tree/output.c index c96c3187..9a10c6a8 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -266,6 +266,11 @@ void output_disable(struct sway_output *output) { output->current_mode = NULL; arrange_root(); + + // Reconfigure all devices, since devices with map_to_output directives for + // an output that goes offline should stop sending events as long as the + // output remains offline. + input_manager_configure_all_inputs(); } void output_begin_destroy(struct sway_output *output) {