[gtk: 1/2] x11/xi2: Report touchpads as TOUCHPAD, not MOUSE



commit 0ad27cc5985664437c022d42e433734742454f05
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri Mar 16 15:40:40 2018 +0800

    x11/xi2: Report touchpads as TOUCHPAD, not MOUSE
    
    is_touchpad_device() for XI2 was hardcoded to look for libinput only.
    Extend it slightly to correctly identify other Xorg touchpad drivers.
    
    https://gitlab.gnome.org/GNOME/gtk/issues/97

 gdk/x11/gdkdevicemanager-xi2.c | 23 ++++++++++++++++---
 tests/testinput.c              | 52 +++++++++++++++++++++++++++++++++---------
 2 files changed, 61 insertions(+), 14 deletions(-)
---
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 2c12bdd203..fd364151dc 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -377,8 +377,9 @@ get_device_ids (GdkDisplay    *display,
 }
 
 static gboolean
-is_touchpad_device (GdkDisplay   *display,
-                    XIDeviceInfo *info)
+has_bool_prop (GdkDisplay   *display,
+               XIDeviceInfo *info,
+               const char   *prop_name)
 {
   gulong nitems, bytes_after;
   guint32 *data;
@@ -389,7 +390,7 @@ is_touchpad_device (GdkDisplay   *display,
 
   rc = XIGetProperty (GDK_DISPLAY_XDISPLAY (display),
                       info->deviceid,
-                      gdk_x11_get_xatom_by_name_for_display (display, "libinput Tapping Enabled"),
+                      gdk_x11_get_xatom_by_name_for_display (display, prop_name),
                       0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
                       (guchar **) &data);
   gdk_x11_display_error_trap_pop_ignored (display);
@@ -402,6 +403,22 @@ is_touchpad_device (GdkDisplay   *display,
   return TRUE;
 }
 
+static gboolean
+is_touchpad_device (GdkDisplay   *display,
+                    XIDeviceInfo *info)
+{
+  /*
+   * Touchpads are heuristically recognized via XI properties that the various
+   * Xorg drivers expose:
+   *   libinput:  libinput Tapping Enabled
+   *   synaptics: Synaptics Off
+   *   cmt:       Raw Touch Passthrough
+   */
+  return has_bool_prop (display, info, "libinput Tapping Enabled") ||
+         has_bool_prop (display, info, "Synaptics Off") ||
+         has_bool_prop (display, info, "Raw Touch Passthrough");
+}
+
 static GdkDevice *
 create_device (GdkX11DeviceManagerXI2 *device_manager,
                GdkDisplay             *display,
diff --git a/tests/testinput.c b/tests/testinput.c
index 69b1230159..3a7c7c3c7a 100644
--- a/tests/testinput.c
+++ b/tests/testinput.c
@@ -121,14 +121,50 @@ draw_brush (GtkWidget *widget, GdkInputSource source,
 
 static guint32 motion_time;
 
+static const char *
+device_source_name (GdkDevice *device)
+{
+  static const struct {GdkInputSource source; const char *name;} sources[] =
+    {
+      {GDK_SOURCE_MOUSE,       "mouse"},
+      {GDK_SOURCE_PEN,         "pen"},
+      {GDK_SOURCE_ERASER,      "eraser"},
+      {GDK_SOURCE_CURSOR,      "cursor"},
+      {GDK_SOURCE_KEYBOARD,    "keyboard"},
+      {GDK_SOURCE_TOUCHSCREEN, "touchscreen"},
+      {GDK_SOURCE_TOUCHPAD,    "touchpad"},
+      {GDK_SOURCE_TRACKPOINT,  "trackpoint"},
+      {GDK_SOURCE_TABLET_PAD,  "tablet pad"},
+    };
+  GdkInputSource source = gdk_device_get_source (device);
+  int s;
+
+  for (s = 0; s < G_N_ELEMENTS (sources); ++s)
+    if (sources[s].source == source)
+      return sources[s].name;
+
+  return "unknown";
+}
+
 static void
-print_axes (GdkDevice *device, gdouble *axes)
+print_axes (GdkEvent *event)
 {
-  int i;
+  gdouble *axes;
+  guint n_axes;
+
+  gdk_event_get_axes (event, &axes, &n_axes);
   
   if (axes)
     {
-      g_print ("%s ", gdk_device_get_name (device));
+      GdkDevice *device = gdk_event_get_device (event);
+      GdkDevice *source = gdk_event_get_source_device (event);
+      int i;
+
+      g_print ("%s (%s) via %s (%s): ",
+               gdk_device_get_name (device),
+               device_source_name (device),
+               gdk_device_get_name (source),
+               device_source_name (source));
 
       for (i = 0; i < gdk_device_get_n_axes (device); i++)
        g_print ("%g ", axes[i]);
@@ -147,17 +183,14 @@ drag_begin (GtkGesture *gesture,
     {
       gdouble pressure = 0.5;
       GdkDevice *device;
-      gdouble *axes;
-      guint n_axes;
       gdouble x, y;
       GdkEvent *event;
 
       event = gtk_get_current_event ();
       device = gdk_event_get_device (event);
-      gdk_event_get_axes (event, &axes, &n_axes);
       gdk_event_get_coords (event, &x, &y);
 
-      print_axes (device, axes);
+      print_axes (event);
       gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &pressure);
       draw_brush (widget, gdk_device_get_source (device), x, y, pressure);
 
@@ -188,9 +221,7 @@ drag_update (GtkGesture *gesture,
 {
   GdkModifierType state;
   GdkDevice *device;
-  gdouble *axes;
   GdkEvent *event;
-  guint n_axes;
   double start_x, start_y;
 
   event = gtk_get_current_event ();
@@ -210,8 +241,7 @@ drag_update (GtkGesture *gesture,
       motion_time = gdk_event_get_time (event);
     }
 
-  gdk_event_get_axes (event, &axes, &n_axes);
-  print_axes (device, axes);
+  print_axes (event);
 }
 
 void


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