From 14eedb38df0dc20fe5691af498dc21251c7558e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 10 Jan 2025 17:18:50 +0100 Subject: [PATCH] eis-client: Only remove MetaEisDevice when eis_device is removed When we recreate devices, or unbind device classes, don't remove the device from the hash table and free MetaEisDevice quite yet - only do so when the eis_device is actually removed. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3839 Part-of: --- src/backends/meta-eis-client.c | 83 ++++++++++++++++------------------ 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 3e482d86a..ae185ef3c 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -128,7 +128,6 @@ remove_device (MetaEisClient *client, struct eis_device *eis_device, gboolean remove_from_hashtable) { - MetaEisDevice *device = eis_device_get_user_data (eis_device); struct eis_keymap *eis_keymap = eis_device_keyboard_get_keymap (eis_device); if (eis_keymap) @@ -138,11 +137,6 @@ remove_device (MetaEisClient *client, meta_anonymous_file_free (f); } - eis_device_pause (eis_device); - eis_device_remove (eis_device); - g_clear_pointer (&device->eis_device, eis_device_unref); - g_clear_object (&device->device); - if (remove_from_hashtable) g_hash_table_remove (client->eis_devices, eis_device); } @@ -173,49 +167,50 @@ drop_device (gpointer htkey, return TRUE; } -static gboolean -drop_abs_devices (gpointer key, - gpointer value, - gpointer data) -{ - struct eis_device *eis_device = key; - - if (!eis_device_has_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) - return FALSE; - - return drop_device (key, value, data); -} - -static gboolean -drop_touch_devices (gpointer key, +static void +remove_abs_devices (gpointer key, gpointer value, gpointer data) { struct eis_device *eis_device = key; - if (!eis_device_has_capability (eis_device, EIS_DEVICE_CAP_TOUCH)) - return FALSE; + if (!eis_device_has_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) + return; - return drop_device (key, value, data); + eis_device_remove (eis_device); } -static gboolean -drop_viewport_devices (gpointer key, - gpointer value, - gpointer data) +static void +remove_touch_devices (gpointer key, + gpointer value, + gpointer data) +{ + struct eis_device *eis_device = key; + + if (!eis_device_has_capability (eis_device, EIS_DEVICE_CAP_TOUCH)) + return; + + eis_device_remove (eis_device); +} + +static void +remove_viewport_devices (gpointer key, + gpointer value, + gpointer data) { struct eis_device *eis_device = key; if (!eis_device_has_capability (eis_device, EIS_DEVICE_CAP_TOUCH) && !eis_device_has_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) - return FALSE; + return; - return drop_device (key, value, data); + eis_device_remove (eis_device); } static void meta_eis_device_free (MetaEisDevice *device) { + g_clear_object (&device->device); eis_device_unref (device->eis_device); g_hash_table_unref (device->slot_map); free (device); @@ -768,7 +763,6 @@ on_keymap_changed (MetaBackend *backend, gpointer data) { MetaEisClient *client = data; - MetaEisDevice *keyboard; /* Changing the keymap means we have to remove our device and recreate it * with the new keymap. @@ -777,9 +771,7 @@ on_keymap_changed (MetaBackend *backend, meta_topic (META_DEBUG_EIS, "Recreating keyboard device with new keyboard"); - keyboard = g_steal_pointer (&client->keyboard_device); - g_hash_table_remove (client->eis_devices, - keyboard->eis_device); + eis_device_remove (client->keyboard_device->eis_device); client->keyboard_device = add_device (client, client->eis_seat, @@ -915,7 +907,7 @@ meta_eis_client_process_event (MetaEisClient *client, "Seat %s bindings updated, destroying pointer device", eis_seat_get_name (eis_seat)); pointer = g_steal_pointer (&client->pointer_device); - remove_device (client, pointer->eis_device, TRUE); + eis_device_remove (pointer->eis_device); } if (wants_keyboard_device && !client->keyboard_device) @@ -945,7 +937,7 @@ meta_eis_client_process_event (MetaEisClient *client, eis_seat_get_name (eis_seat)); keyboard = g_steal_pointer (&client->keyboard_device); - remove_device (client, keyboard->eis_device, TRUE); + eis_device_remove (keyboard->eis_device); g_clear_signal_handler (&client->keymap_changed_handler_id, meta_eis_get_backend (client->eis)); } @@ -965,9 +957,9 @@ meta_eis_client_process_event (MetaEisClient *client, "Seat %s bindings updated, destroying absolute pointer devices", eis_seat_get_name (eis_seat)); - g_hash_table_foreach_remove (client->eis_devices, - drop_abs_devices, - client); + g_hash_table_foreach (client->eis_devices, + remove_abs_devices, + client); client->have_abs_pointer_devices = FALSE; } @@ -984,9 +976,10 @@ meta_eis_client_process_event (MetaEisClient *client, meta_topic (META_DEBUG_EIS, "Seat %s bindings updated, destroying touch devices", eis_seat_get_name (eis_seat)); - g_hash_table_foreach_remove (client->eis_devices, - drop_touch_devices, - client); + + g_hash_table_foreach (client->eis_devices, + remove_touch_devices, + client); client->have_touch_devices = FALSE; } break; @@ -1057,9 +1050,9 @@ update_viewports (MetaEisClient *client) { meta_topic (META_DEBUG_EIS, "Updating viewports"); - g_hash_table_foreach_remove (client->eis_devices, - drop_viewport_devices, - client); + g_hash_table_foreach (client->eis_devices, + remove_viewport_devices, + client); if (client->have_abs_pointer_devices) add_abs_pointer_devices (client);