summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2014-02-22 20:35:23 +0100
committerCarlos Garnacho <carlosg@gnome.org>2014-02-25 10:18:20 +0100
commit488639eb63f0c26d65db0700e94b1067da873617 (patch)
treebba58272bd7c2a83e7666f11118322a3c366e28b
parentc4372249e2b80b7623ad9ce33de2683f2ebed17c (diff)
downloadclutter-488639eb63f0c26d65db0700e94b1067da873617.tar.gz
x11: Avoid invalid ClutterInputDevice pointers in the device list
Due to the way add_device() invariably adds to the master/slave device lists, while keeping ClutterInputDevices 1:1 with device IDs, it may leave invalid pointers in the list if add_device() is called multiple times for the same device ID. There are two situations where this may happen: 1) If devices are disabled and later enabled: devices are added invariably to the master/slave lists on constructed(), but then on XIDeviceEnabled they'd get added yet again. 2) Racy cases where the ClutterDeviceManager is created around the same time XIHierarchyEvents are sent. When getting the XIDeviceInfo on constructed(), these devices may already appear as enabled, even though XIDeviceEnabled is seen through XIHierarchyEvents processed in the event loop sortly after. This last case can be seen when starting gnome-shell on a different tty, and entering in the one it's been spawned on, clutter initialization happens around the same time devices are added back because of the tty switch, and multiple extra ClutterInputDevices are created. https://bugzilla.gnome.org/show_bug.cgi?id=724971
-rw-r--r--clutter/x11/clutter-device-manager-xi2.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c
index f9614f5dd..d508026dd 100644
--- a/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/x11/clutter-device-manager-xi2.c
@@ -401,7 +401,9 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11,
for (i = 0; i < ev->num_info; i++)
{
- if (ev->info[i].flags & XIDeviceEnabled)
+ if (ev->info[i].flags & XIDeviceEnabled &&
+ !g_hash_table_lookup (manager_xi2->devices_by_id,
+ GINT_TO_POINTER (ev->info[i].deviceid)))
{
XIDeviceInfo *info;
int n_devices;
@@ -1435,6 +1437,9 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
{
XIDeviceInfo *xi_device = &info[i];
+ if (!xi_device->enabled)
+ continue;
+
add_device (manager_xi2, backend_x11, xi_device, TRUE);
if (xi_device->use == XIMasterPointer ||