Xi: Ensure DeviceChanged is emitted after grabs are deactivated
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 2 Jan 2014 20:33:30 +0000 (21:33 +0100)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 9 Jan 2014 03:39:05 +0000 (13:39 +1000)
When a grab on a slave device is deactivated, the master device must
be checked, just in case there were events from other devices while
the slave device was stolen away by the passive grab. This may
introduce misbehaviors on mismatching valuators and device features
later on UpdateDeviceState().

Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Xi/exevents.c

index dff0a92..528e105 100644 (file)
@@ -1783,8 +1783,25 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
         DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
                             NullGrab, NullWindow, device);
 
-    if (deactivateDeviceGrab == TRUE)
+    if (deactivateDeviceGrab == TRUE) {
         (*device->deviceGrab.DeactivateGrab) (device);
+
+        if (!IsMaster (device) && !IsFloating (device)) {
+            int flags, num_events = 0;
+            InternalEvent dce;
+
+            flags = (IsPointerDevice (device)) ?
+                DEVCHANGE_POINTER_EVENT : DEVCHANGE_KEYBOARD_EVENT;
+            UpdateFromMaster (&dce, device, flags, &num_events);
+            BUG_WARN(num_events > 1);
+
+            if (num_events == 1)
+                ChangeMasterDeviceClasses(GetMaster (device, MASTER_ATTACHED),
+                                          &dce.changed_event);
+        }
+
+    }
+
     event->detail.key = key;
 }