input: reconfigure send_events on output hotplug

Closes: https://github.com/swaywm/sway/issues/7890
This commit is contained in:
Simon Ser 2023-12-30 20:22:01 +01:00 committed by Kenny Levinsen
parent 0aceff7469
commit 95265fba59
3 changed files with 47 additions and 19 deletions

View file

@ -4,6 +4,9 @@
bool sway_input_configure_libinput_device(struct sway_input_device *device); 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); void sway_input_reset_libinput_device(struct sway_input_device *device);
bool sway_libinput_device_is_builtin(struct sway_input_device *device); bool sway_libinput_device_is_builtin(struct sway_input_device *device);

View file

@ -534,6 +534,13 @@ void input_manager_configure_all_input_mappings(void) {
wl_list_for_each(seat, &server.input->seats, link) { wl_list_for_each(seat, &server.input->seats, link) {
seat_configure_device_mapping(seat, input_device); 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
} }
} }

View file

@ -219,6 +219,26 @@ static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
return changed; 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) { bool sway_input_configure_libinput_device(struct sway_input_device *input_device) {
struct input_config *ic = input_device_get_config(input_device); struct input_config *ic = input_device_get_config(input_device);
if (!ic || !wlr_input_device_is_libinput(input_device->wlr_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')", sway_log(SWAY_DEBUG, "sway_input_configure_libinput_device('%s' on '%s')",
ic->identifier, input_device->identifier); ic->identifier, input_device->identifier);
bool changed = false; bool changed = configure_send_events(device, 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);
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) { if (ic->tap != INT_MIN) {
changed |= set_tap(device, ic->tap); changed |= set_tap(device, ic->tap);
} }
@ -304,6 +306,22 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
return changed; 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) { void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
if (!wlr_input_device_is_libinput(input_device->wlr_device)) { if (!wlr_input_device_is_libinput(input_device->wlr_device)) {
return; return;