[gtk+/xi2: 834/1239] GdkWindow: Add gdk_window_[gs]et_support_multidevice.



commit 183cb1ff64f70902284b727464f83666862b3ed6
Author: Carlos Garnacho <carlos lanedo com>
Date:   Sun Aug 23 16:32:35 2009 +0200

    GdkWindow: Add gdk_window_[gs]et_support_multidevice.
    
    This is now used to determine whether all device enter/leave events are
    propagated or not. If this variable is disabled, enter/leave events will be
    blocked if there are already any devices inside the window.

 gdk/gdkinternals.h |    3 ++
 gdk/gdkwindow.c    |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 gdk/gdkwindow.h    |    6 +++++
 3 files changed, 67 insertions(+), 2 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index ade95ba..c14e43b 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -241,6 +241,7 @@ struct _GdkWindowObject
   guint accept_focus : 1;
   guint focus_on_map : 1;
   guint shaped : 1;
+  guint support_multidevice : 1;
   
   GdkEventMask event_mask;
 
@@ -277,6 +278,8 @@ struct _GdkWindowObject
   GdkRegion *input_shape;
   
   cairo_surface_t *cairo_surface;
+
+  GList *devices_inside;
 };
 
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index cf9f783..944105a 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8287,6 +8287,38 @@ gdk_window_beep (GdkWindow *window)
     gdk_display_beep (display);
 }
 
+void
+gdk_window_set_support_multidevice (GdkWindow *window,
+                                    gboolean   support_multidevice)
+{
+  GdkWindowObject *private = (GdkWindowObject *) window;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (private->support_multidevice == support_multidevice)
+    return;
+
+  private->support_multidevice = support_multidevice;
+
+  /* FIXME: What to do if called when some pointers are inside the window ? */
+}
+
+gboolean
+gdk_window_get_support_multidevice (GdkWindow *window)
+{
+  GdkWindowObject *private = (GdkWindowObject *) window;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return FALSE;
+
+  return private->support_multidevice;
+}
+
 static const guint type_masks[] = {
   GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE                 = 0  */
   GDK_STRUCTURE_MASK, /* GDK_DESTROY                   = 1  */
@@ -8525,6 +8557,7 @@ send_crossing_event (GdkDisplay                 *display,
   GdkEvent *event;
   guint32 event_mask;
   GdkPointerGrabInfo *grab;
+  gboolean block_event = FALSE;
 
   grab = _gdk_display_has_pointer_grab (display, serial);
 
@@ -8534,9 +8567,32 @@ send_crossing_event (GdkDisplay                 *display,
     return;
 
   if (type == GDK_LEAVE_NOTIFY)
-    event_mask = GDK_LEAVE_NOTIFY_MASK;
+    {
+      event_mask = GDK_LEAVE_NOTIFY_MASK;
+      window->devices_inside = g_list_remove (window->devices_inside, device);
+
+      if (!window->support_multidevice && window->devices_inside)
+        {
+          /* Block leave events unless it's the last pointer */
+          block_event = TRUE;
+        }
+    }
   else
-    event_mask = GDK_ENTER_NOTIFY_MASK;
+    {
+      event_mask = GDK_ENTER_NOTIFY_MASK;
+
+      if (!window->support_multidevice && window->devices_inside)
+        {
+          /* Only emit enter events for the first device */
+          block_event = TRUE;
+        }
+
+      if (!g_list_find (window->devices_inside, device))
+        window->devices_inside = g_list_prepend (window->devices_inside, device);
+    }
+
+  if (block_event)
+    return;
 
   if (window->extension_events != 0)
     GDK_WINDOW_IMPL_GET_IFACE (window->impl)->input_window_crossing ((GdkWindow *)window,
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 7b48b62..79142b0 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -308,6 +308,7 @@ struct _GdkWindowObject
   guint accept_focus : 1;
   guint focus_on_map : 1;
   guint shaped : 1;
+  guint support_multidevice : 1;
   
   GdkEventMask event_mask;
 
@@ -684,6 +685,11 @@ void       gdk_window_redirect_to_drawable   (GdkWindow     *window,
                                               gint           height);
 void       gdk_window_remove_redirection     (GdkWindow     *window);
 
+/* Multidevice support */
+void       gdk_window_set_support_multidevice (GdkWindow *window,
+                                               gboolean   support_multidevice);
+gboolean   gdk_window_get_support_multidevice (GdkWindow *window);
+
 #ifndef GDK_DISABLE_DEPRECATED
 #define GDK_ROOT_PARENT()             (gdk_get_default_root_window ())
 #define gdk_window_get_size            gdk_drawable_get_size



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