From 95265fba59bce77ed52a74fcc21abf7f668c01b2 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 30 Dec 2023 20:22:01 +0100 Subject: [PATCH] input: reconfigure send_events on output hotplug Closes: https://github.com/swaywm/sway/issues/7890 --- include/sway/input/libinput.h | 3 ++ sway/input/input-manager.c | 7 +++++ sway/input/libinput.c | 56 +++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/include/sway/input/libinput.h b/include/sway/input/libinput.h index e4b1acc3..1f84a8e3 100644 --- a/include/sway/input/libinput.h +++ b/include/sway/input/libinput.h @@ -4,6 +4,9 @@ bool sway_input_configure_libinput_device(struct sway_input_device *device); +void sway_input_configure_libinput_device_send_events( + struct sway_input_device *device); + void sway_input_reset_libinput_device(struct sway_input_device *device); bool sway_libinput_device_is_builtin(struct sway_input_device *device); diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index 4febc333..c1bbdde0 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -534,6 +534,13 @@ void input_manager_configure_all_input_mappings(void) { wl_list_for_each(seat, &server.input->seats, link) { seat_configure_device_mapping(seat, input_device); } + +#if WLR_HAS_LIBINPUT_BACKEND + // Input devices mapped to unavailable outputs get their libinput + // send_events setting switched to false. We need to re-enable this + // when the output appears. + sway_input_configure_libinput_device_send_events(input_device); +#endif } } diff --git a/sway/input/libinput.c b/sway/input/libinput.c index 43875634..0266c7a9 100644 --- a/sway/input/libinput.c +++ b/sway/input/libinput.c @@ -219,6 +219,26 @@ static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) { return changed; } +static bool configure_send_events(struct libinput_device *device, + struct input_config *ic) { + if (ic->mapped_to_output && + strcmp("*", ic->mapped_to_output) != 0 && + !output_by_name_or_id(ic->mapped_to_output)) { + sway_log(SWAY_DEBUG, + "%s '%s' is mapped to offline output '%s'; disabling input", + ic->input_type, ic->identifier, ic->mapped_to_output); + return set_send_events(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); + } else if (ic->send_events != INT_MIN) { + return 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. + return set_send_events(device, + libinput_device_config_send_events_get_default_mode(device)); + } +} + bool sway_input_configure_libinput_device(struct sway_input_device *input_device) { struct input_config *ic = input_device_get_config(input_device); if (!ic || !wlr_input_device_is_libinput(input_device->wlr_device)) { @@ -230,25 +250,7 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device sway_log(SWAY_DEBUG, "sway_input_configure_libinput_device('%s' on '%s')", ic->identifier, input_device->identifier); - bool changed = false; - if (ic->mapped_to_output && - strcmp("*", ic->mapped_to_output) != 0 && - !output_by_name_or_id(ic->mapped_to_output)) { - sway_log(SWAY_DEBUG, - "%s '%s' is mapped to offline output '%s'; disabling input", - ic->input_type, 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)); - } - + bool changed = configure_send_events(device, ic); if (ic->tap != INT_MIN) { changed |= set_tap(device, ic->tap); } @@ -304,6 +306,22 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device return changed; } +void sway_input_configure_libinput_device_send_events( + struct sway_input_device *input_device) { + struct input_config *ic = input_device_get_config(input_device); + if (!ic || !wlr_input_device_is_libinput(input_device->wlr_device)) { + return; + } + + struct libinput_device *device = + wlr_libinput_get_device_handle(input_device->wlr_device); + bool changed = configure_send_events(device, ic); + + if (changed) { + ipc_event_input("libinput_config", input_device); + } +} + void sway_input_reset_libinput_device(struct sway_input_device *input_device) { if (!wlr_input_device_is_libinput(input_device->wlr_device)) { return;