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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4210>
This commit is contained in:
Jonas Ådahl 2025-01-10 17:18:50 +01:00
parent 4d9a818321
commit 14eedb38df

View File

@ -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);