[mutter/wip/gestures: 11/16] display: Set an X11 passive touch grab on the root window



commit 8030a2972ec04cc728cf0faf0922d027b953c171
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jun 19 23:13:38 2014 +0200

    display: Set an X11 passive touch grab on the root window
    
    Touch events will be caught first by the compositor this way,
    whenever the MetaGestureTracker notifies of the accepted/rejected
    state of a sequence, XIAllowTouchEvents() will be called on it
    accordingly, so it is handled exclusively by the compositor or
    punted to clients.

 src/core/display.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 07d05b4..42bf5a3 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -51,6 +51,8 @@
 #include "meta-cursor-tracker-private.h"
 #include "meta-backend.h"
 #include "backends/x11/meta-backend-x11.h"
+#include <clutter/x11/clutter-x11.h>
+#include "compositor-private.h"
 
 #ifdef HAVE_RANDR
 #include <X11/extensions/Xrandr.h>
@@ -146,6 +148,11 @@ static void    update_window_grab_modifiers (MetaDisplay *display);
 static void    prefs_changed_callback    (MetaPreference pref,
                                           void          *data);
 
+static void meta_display_grab_window_touch   (MetaDisplay *display,
+                                              Window       xwindow);
+static void meta_display_ungrab_window_touch (MetaDisplay *display,
+                                              Window       xwindow);
+
 static void
 meta_display_get_property(GObject         *object,
                           guint            prop_id,
@@ -413,6 +420,28 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
   gnome_wm_keybindings = wm_keybindings;
 }
 
+static void
+gesture_tracker_state_changed (MetaGestureTracker   *tracker,
+                               ClutterEventSequence *sequence,
+                               MetaSequenceState     state,
+                               MetaDisplay          *display)
+{
+  MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
+  int event_mode;
+
+  if (state == META_SEQUENCE_ACCEPTED)
+    event_mode = XIAcceptTouch;
+  else if (state == META_SEQUENCE_REJECTED)
+    event_mode = XIRejectTouch;
+  else
+    return;
+
+  XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
+                      META_VIRTUAL_CORE_POINTER_ID,
+                      clutter_x11_event_sequence_get_touch_detail (sequence),
+                      DefaultRootWindow (display->xdisplay), event_mode);
+}
+
 /**
  * meta_display_open:
  *
@@ -810,6 +839,10 @@ meta_display_open (void)
 
   /* Set up touch support */
   the_display->gesture_tracker = meta_gesture_tracker_new (0);
+  g_signal_connect (the_display->gesture_tracker, "state-changed",
+                    G_CALLBACK (gesture_tracker_state_changed), the_display);
+  meta_display_grab_window_touch (the_display,
+                                  DefaultRootWindow (the_display->xdisplay));
 
   /* We know that if mutter is running as a Wayland compositor,
    * we start out with no windows.
@@ -980,6 +1013,10 @@ meta_display_close (MetaDisplay *display,
 
   meta_display_remove_autoraise_callback (display);
 
+  meta_display_ungrab_window_touch (display,
+                                    DefaultRootWindow (display->xdisplay));
+  g_clear_object (&display->gesture_tracker);
+
   if (display->focus_timeout_id)
     g_source_remove (display->focus_timeout_id);
   display->focus_timeout_id = 0;
@@ -2058,6 +2095,35 @@ meta_display_ungrab_window_buttons  (MetaDisplay *display,
     }
 }
 
+static void
+meta_display_grab_window_touch (MetaDisplay *display,
+                                Window       xwindow)
+{
+  MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
+  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
+  XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
+  XIGrabModifiers mods = { XIAnyModifier, 0 };
+
+  XISetMask (mask.mask, XI_TouchBegin);
+  XISetMask (mask.mask, XI_TouchUpdate);
+  XISetMask (mask.mask, XI_TouchEnd);
+
+  XIGrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
+                    META_VIRTUAL_CORE_POINTER_ID,
+                    xwindow, False, &mask, 1, &mods);
+}
+
+static void
+meta_display_ungrab_window_touch (MetaDisplay *display,
+                                  Window       xwindow)
+{
+  MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
+  XIGrabModifiers mods = { XIAnyModifier, 0 };
+
+  XIUngrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
+                      META_VIRTUAL_CORE_POINTER_ID, xwindow, 1, &mods);
+}
+
 /* Grab buttons we only grab while unfocused in click-to-focus mode */
 #define MAX_FOCUS_BUTTON 4
 void


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