[gnome-settings-daemon/gnome-3-18] mouse, common: Fix Wacom buttons not receiving events



commit 552258b12e393c317e104efba4f668ed3d1c3941
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Mar 16 13:17:13 2016 +0100

    mouse, common: Fix Wacom buttons not receiving events
    
    When configuring mice and touchpads, we might stumble upon a Wacom pad
    device. To check whether it's a synaptics device, we open the device,
    get the properties, and close it back up.
    
    But when we close it, we end up releasing whatever grab the wacom plugin
    might have had on the pad buttons:
    
               When a client makes an XCloseDevice request, any active grabs
               that the client has on the device are released.  Any event
               selections that the client has are deleted, as well as any
               passive grabs. If the requesting client is the last client
               accessing the device, the server may disable all access by X to
               the device.
    
    As we cannot change that behaviour, we'll use a call that doesn't
    require opening the device so we don't have to close it.
    
    See https://bugs.freedesktop.org/show_bug.cgi?id=94487
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763092

 plugins/common/gsd-input-helper.c |   36 ++++++----------
 plugins/common/gsd-input-helper.h |    2 +-
 plugins/mouse/gsd-mouse-manager.c |   84 ++++++++++++++-----------------------
 3 files changed, 47 insertions(+), 75 deletions(-)
---
diff --git a/plugins/common/gsd-input-helper.c b/plugins/common/gsd-input-helper.c
index e3fe2d8..84f496a 100644
--- a/plugins/common/gsd-input-helper.c
+++ b/plugins/common/gsd-input-helper.c
@@ -164,31 +164,31 @@ supports_xinput2_devices (int *opcode)
 }
 
 gboolean
-xdevice_is_synaptics (XDevice *xdevice)
+device_is_synaptics (int deviceid)
 {
-        Atom realtype, prop;
+        GdkDisplay *display = gdk_display_get_default ();
+        Atom realtype;
         int realformat;
         unsigned long nitems, bytes_after;
         unsigned char *data;
+        gboolean rc;
 
         /* we don't check on the type being XI_TOUCHPAD here,
          * but having a "Synaptics Off" property should be enough */
 
-        prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Off", False);
-        if (!prop)
-                return FALSE;
-
         gdk_error_trap_push ();
-        if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, 0, 1, 
False,
-                                XA_INTEGER, &realtype, &realformat, &nitems,
-                                &bytes_after, &data) == Success) && (realtype != None)) {
-                gdk_error_trap_pop_ignored ();
+
+        /* Lookup a synaptics driver specific property */
+        rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display), deviceid,
+                            gdk_x11_get_xatom_by_name ("Synaptics Off"),
+                            0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data);
+
+        if (rc == Success)
                 XFree (data);
-                return TRUE;
-        }
+
         gdk_error_trap_pop_ignored ();
 
-        return FALSE;
+        return rc == Success && realtype != None;
 }
 
 gboolean
@@ -206,15 +206,7 @@ synaptics_is_present (void)
                 return FALSE;
 
         for (i = 0; i < n_devices; i++) {
-                XDevice *device;
-
-                gdk_error_trap_push ();
-                device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id);
-                if (gdk_error_trap_pop () || (device == NULL))
-                        continue;
-
-                retval = xdevice_is_synaptics (device);
-                xdevice_close (device);
+                retval = device_is_synaptics (device_info[i].id);
                 if (retval)
                         break;
         }
diff --git a/plugins/common/gsd-input-helper.h b/plugins/common/gsd-input-helper.h
index aadd790..1bfd850 100644
--- a/plugins/common/gsd-input-helper.h
+++ b/plugins/common/gsd-input-helper.h
@@ -60,7 +60,7 @@ gboolean set_device_enabled       (int device_id,
 gboolean  set_synaptics_device_enabled (int device_id,
                                         gboolean enabled);
 
-gboolean  xdevice_is_synaptics       (XDevice                *xdevice);
+gboolean  device_is_synaptics     (int deviceid);
 
 gboolean  synaptics_is_present    (void);
 gboolean  touchpad_is_present     (void);
diff --git a/plugins/mouse/gsd-mouse-manager.c b/plugins/mouse/gsd-mouse-manager.c
index 70a8507..8ba9128 100644
--- a/plugins/mouse/gsd-mouse-manager.c
+++ b/plugins/mouse/gsd-mouse-manager.c
@@ -42,6 +42,7 @@
 #include <gdk/gdkkeysyms.h>
 #include <X11/keysym.h>
 #include <X11/Xatom.h>
+#include <X11/extensions/XInput2.h>
 
 #include <gdesktop-enums.h>
 
@@ -337,23 +338,22 @@ bail:
 }
 
 static gboolean
-touchpad_has_single_button (XDevice *device)
+touchpad_has_single_button (int deviceid)
 {
-        Atom type, prop;
+        GdkDisplay *display = gdk_display_get_default ();
+        Atom type;
         int format;
         unsigned long nitems, bytes_after;
         unsigned char *data;
         gboolean is_single_button = FALSE;
         int rc;
 
-        prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Capabilities", 
False);
-        if (!prop)
-                return FALSE;
-
         gdk_error_trap_push ();
-        rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop, 0, 1, 
False,
-                                XA_INTEGER, &type, &format, &nitems,
-                                &bytes_after, &data);
+
+        rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display), deviceid,
+                            gdk_x11_get_xatom_by_name ("Synaptics Capabilities"),
+                            0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, &data);
+
         if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3)
                 is_single_button = (data[0] == 1 && data[1] == 0 && data[2] == 0);
 
@@ -383,19 +383,13 @@ set_left_handed (GsdMouseManager *manager,
         if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
 
-        xdevice = open_gdk_device (device);
-        if (xdevice == NULL)
-                return;
-
        g_debug ("setting handedness on %s", gdk_device_get_name (device));
 
-        buttons = g_new (guchar, buttons_capacity);
-
         /* If the device is a touchpad, swap tap buttons
          * around too, otherwise a tap would be a right-click */
-        if (xdevice_is_synaptics (xdevice)) {
+        if (device_is_synaptics (gdk_x11_device_get_id (device))) {
                 gboolean tap = g_settings_get_boolean (manager->priv->touchpad_settings, KEY_TAP_TO_CLICK);
-                gboolean single_button = touchpad_has_single_button (xdevice);
+                gboolean single_button = touchpad_has_single_button (gdk_x11_device_get_id (device));
 
                 left_handed = touchpad_left_handed;
 
@@ -403,13 +397,18 @@ set_left_handed (GsdMouseManager *manager,
                         set_tap_to_click (device, tap, left_handed);
 
                 if (single_button)
-                        goto out;
+                        return;
         } else {
                 left_handed = mouse_left_handed;
         }
 
+        xdevice = open_gdk_device (device);
+        if (xdevice == NULL)
+                return;
+
         gdk_error_trap_push ();
 
+        buttons = g_new (guchar, buttons_capacity);
         n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
                                              buttons,
                                              buttons_capacity);
@@ -429,7 +428,6 @@ set_left_handed (GsdMouseManager *manager,
         XSetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, buttons, 
n_buttons);
         gdk_error_trap_pop_ignored ();
 
-out:
         xdevice_close (xdevice);
         g_free (buttons);
 }
@@ -458,7 +456,7 @@ set_motion (GsdMouseManager *manager,
 
        g_debug ("setting motion on %s", gdk_device_get_name (device));
 
-        if (xdevice_is_synaptics (xdevice))
+        if (device_is_synaptics (gdk_x11_device_get_id (device)))
                 settings = manager->priv->touchpad_settings;
         else
                 settings = manager->priv->mouse_settings;
@@ -630,6 +628,8 @@ set_tap_to_click (GdkDevice *device,
 
         if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
+        if (!device_is_synaptics (gdk_x11_device_get_id (device)))
+                return;
 
         prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Tap Action", 
False);
         prop_capabilities = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics 
Capabilities", False);
@@ -640,11 +640,6 @@ set_tap_to_click (GdkDevice *device,
         if (xdevice == NULL)
                 return;
 
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
-                return;
-        }
-
        g_debug ("setting tap to click on %s", gdk_device_get_name (device));
 
         gdk_error_trap_push ();
@@ -694,6 +689,8 @@ set_horiz_scroll (GdkDevice *device,
 
         if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
+        if (!device_is_synaptics (gdk_x11_device_get_id (device)))
+                return;
 
         prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Edge 
Scrolling", False);
         prop_twofinger = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics 
Two-Finger Scrolling", False);
@@ -705,11 +702,6 @@ set_horiz_scroll (GdkDevice *device,
         if (xdevice == NULL)
                 return;
 
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
-                return;
-        }
-
        g_debug ("setting horiz scroll on %s", gdk_device_get_name (device));
 
         gdk_error_trap_push ();
@@ -763,6 +755,8 @@ set_scroll_method (GsdMouseManager         *manager,
 
         if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
+        if (!device_is_synaptics (gdk_x11_device_get_id (device)))
+                return;
 
         prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Capabilities", 
True);
         prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Edge 
Scrolling", False);
@@ -775,11 +769,6 @@ set_scroll_method (GsdMouseManager         *manager,
         if (xdevice == NULL)
                 return;
 
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
-                return;
-        }
-
        g_debug ("setting edge scroll on %s", gdk_device_get_name (device));
 
         gdk_error_trap_push ();
@@ -839,6 +828,8 @@ set_touchpad_disabled (GdkDevice *device)
 
         if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
+        if (!device_is_synaptics (gdk_x11_device_get_id (device)))
+                return;
 
         g_object_get (G_OBJECT (device), "device-id", &id, NULL);
 
@@ -848,11 +839,6 @@ set_touchpad_disabled (GdkDevice *device)
         if (xdevice == NULL)
                 return;
 
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
-                return;
-        }
-
         if (set_synaptics_device_enabled (id, FALSE) == FALSE)
                 g_warning ("Error disabling device \"%s\" (%d)", gdk_device_get_name (device), id);
         else
@@ -868,6 +854,8 @@ set_touchpad_enabled (int id)
 
         if (xdevice_is_libinput (id))
                 return;
+        if (!device_is_synaptics (id))
+                return;
 
         g_debug ("Trying to set device enabled for %d", id);
 
@@ -876,11 +864,6 @@ set_touchpad_enabled (int id)
         if (gdk_error_trap_pop () != 0)
                 return;
 
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
-                return;
-        }
-
         if (set_synaptics_device_enabled (id, TRUE) == FALSE)
                 g_warning ("Error enabling device \"%d\"", id);
         else
@@ -983,16 +966,13 @@ set_natural_scroll (GsdMouseManager *manager,
         unsigned char *data;
         glong *ptr;
 
-        xdevice = open_gdk_device (device);
-        if (xdevice == NULL)
+        if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
                 return;
-
-        if (!xdevice_is_synaptics (xdevice)) {
-                xdevice_close (xdevice);
+        if (!device_is_synaptics (gdk_x11_device_get_id (device)))
                 return;
-        }
 
-        if (xdevice_is_libinput (gdk_x11_device_get_id (device)))
+        xdevice = open_gdk_device (device);
+        if (xdevice == NULL)
                 return;
 
         g_debug ("Trying to set %s for \"%s\"",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]