[mutter/wip/gestures: 4/16] x11/events: Filter out all pointer/touch GDK events



commit 66d18fcc552aaa02b70554f9a64a3c4262608200
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jun 19 21:54:01 2014 +0200

    x11/events: Filter out all pointer/touch GDK events
    
    Mutter does its own input event processing, including for the places
    where interaction is wanted with the remaining GTK UI elements
    (frames), so GDK is largely disposable.
    
    Even though the GDK display connection remains, and events will
    be delivered over there due to event selections on that display,
    all pointer and touch events will be handled and filtered out by
    the GDK filter function.
    
    The dedicated event processing meant for frames in src/ui/ui.c
    now hooks to the display connection through
    meta_display_events_x11_add_func(), added to let all event filters
    run and stop processing at a single point.

 src/ui/ui.c      |   15 ++++------
 src/x11/events.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/x11/events.h |    5 +++
 3 files changed, 84 insertions(+), 12 deletions(-)
---
diff --git a/src/ui/ui.c b/src/ui/ui.c
index cb1f36b..a11adbb 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -26,6 +26,7 @@
 #include <meta/util.h>
 #include "core.h"
 #include "theme-private.h"
+#include "x11/events.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -232,15 +233,11 @@ maybe_redirect_mouse_event (XEvent *xevent)
   return TRUE;
 }
 
-static GdkFilterReturn
-ui_filter_func (GdkXEvent *xevent,
-                GdkEvent *event,
+static void
+ui_filter_func (gpointer xevent,
                 gpointer data)
 {
-  if (maybe_redirect_mouse_event (xevent))
-    return GDK_FILTER_REMOVE;
-  else
-    return GDK_FILTER_CONTINUE;
+  maybe_redirect_mouse_event (xevent);
 }
 
 MetaUI*
@@ -266,7 +263,7 @@ meta_ui_new (Display *xdisplay,
    */
   gtk_widget_show (GTK_WIDGET (ui->frames));
 
-  gdk_window_add_filter (NULL, ui_filter_func, NULL);
+  meta_display_events_x11_add_func (ui_filter_func, NULL);
 
   g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
 
@@ -283,7 +280,7 @@ meta_ui_free (MetaUI *ui)
   gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
   g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
 
-  gdk_window_remove_filter (NULL, ui_filter_func, NULL);
+  meta_display_events_x11_add_func (ui_filter_func, NULL);
 
   g_free (ui);
 }
diff --git a/src/x11/events.c b/src/x11/events.c
index 7355714..66a1068 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -38,6 +38,16 @@
 #include "wayland/meta-xwayland.h"
 #include "wayland/meta-wayland-private.h"
 
+typedef struct _EventFuncData EventFuncData;
+
+struct _EventFuncData
+{
+  GFunc func;
+  gpointer data;
+};
+
+static GList *event_funcs = NULL;
+
 static XIEvent *
 get_input_event (MetaDisplay *display,
                  XEvent      *event)
@@ -1801,11 +1811,37 @@ xevent_filter (GdkXEvent *xevent,
                gpointer   data)
 {
   MetaDisplay *display = data;
+  EventFuncData *event_data;
+  XIEvent *input_event;
+  GList *l;
 
-  if (meta_display_handle_xevent (display, xevent))
-    return GDK_FILTER_REMOVE;
-  else
+  meta_display_handle_xevent (display, xevent);
+
+  for (l = event_funcs; l; l = l->next)
+    {
+      event_data = l->data;
+      event_data->func (xevent, event_data->data);
+    }
+
+  input_event = get_input_event (display, xevent);
+
+  if (!input_event)
     return GDK_FILTER_CONTINUE;
+
+  /* Filter all pointer and touch events, those are emulated
+   * above by the filters, and Gdk is bypassed there on purpose.
+   */
+  if (input_event->evtype == XI_ButtonPress ||
+      input_event->evtype == XI_ButtonRelease ||
+      input_event->evtype == XI_Motion ||
+      input_event->evtype == XI_Enter ||
+      input_event->evtype == XI_Leave ||
+      input_event->evtype == XI_TouchBegin ||
+      input_event->evtype == XI_TouchUpdate ||
+      input_event->evtype == XI_TouchEnd)
+    return GDK_FILTER_REMOVE;
+
+  return GDK_FILTER_CONTINUE;
 }
 
 void
@@ -1819,3 +1855,37 @@ meta_display_free_events_x11 (MetaDisplay *display)
 {
   gdk_window_remove_filter (NULL, xevent_filter, display);
 }
+
+void
+meta_display_events_x11_add_func (GFunc    func,
+                                  gpointer user_data)
+{
+  EventFuncData *data;
+
+  data = g_slice_new0 (EventFuncData);
+  data->func = func;
+  data->data = user_data;
+  event_funcs = g_list_prepend (event_funcs, data);
+}
+
+void
+meta_display_events_x11_remove_func (GFunc    func,
+                                     gpointer user_data)
+{
+  EventFuncData *data;
+  GList *l;
+
+  data = g_slice_new0 (EventFuncData);
+
+  for (l = event_funcs; l; l = l->next)
+    {
+      data = l->data;
+
+      if (data->func != func || data->data != user_data)
+        continue;
+
+      event_funcs = g_list_delete_link (event_funcs, l);
+      g_slice_free (EventFuncData, data);
+      break;
+    }
+}
diff --git a/src/x11/events.h b/src/x11/events.h
index 6aa073b..cc12ddb 100644
--- a/src/x11/events.h
+++ b/src/x11/events.h
@@ -28,4 +28,9 @@
 void meta_display_init_events_x11 (MetaDisplay *display);
 void meta_display_free_events_x11 (MetaDisplay *display);
 
+void meta_display_events_x11_add_func    (GFunc    func,
+                                          gpointer user_data);
+void meta_display_events_x11_remove_func (GFunc    func,
+                                          gpointer user_data);
+
 #endif


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