From 37fce86c32fc30314f927ca3d2daef697293a9f6 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 30 Dec 2023 20:22:01 +0100 Subject: input: reconfigure send_events on output hotplug Closes: https://github.com/swaywm/sway/issues/7890 (cherry picked from commit 95265fba59bce77ed52a74fcc21abf7f668c01b2) --- include/sway/input/libinput.h | 3 +++ sway/input/input-manager.c | 7 ++++++ sway/input/libinput.c | 54 ++++++++++++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 18 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 dcaeb056..288fddc4 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -571,6 +571,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,36 +219,38 @@ static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) { return changed; } -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)) { - return false; - } - - struct libinput_device *device = - wlr_libinput_get_device_handle(input_device->wlr_device); - sway_log(SWAY_DEBUG, "sway_input_configure_libinput_device('%s' on '%s')", - ic->identifier, input_device->identifier); - - bool changed = false; +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)) { + 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); + return set_send_events(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); } else if (ic->send_events != INT_MIN) { - changed |= set_send_events(device, ic->send_events); + 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. - changed |= set_send_events(device, + 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)) { + return false; + } + struct libinput_device *device = + wlr_libinput_get_device_handle(input_device->wlr_device); + sway_log(SWAY_DEBUG, "sway_input_configure_libinput_device('%s' on '%s')", + ic->identifier, input_device->identifier); + + 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; -- cgit v1.2.3-54-g00ecf