? Birnan
? birnan
? client-motion-0.patch
? emfle
? emulate-motion-hint-rc1.patch
? emulate-motion-hint1.patch
? emulate-motion-hint2.patch
? huh
? wind
? gdk/frut
? gtk/unbirnan
Index: gdk/gdkevents.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkevents.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 gdkevents.h
--- gdk/gdkevents.h	28 Nov 2004 06:45:52 -0000	1.23
+++ gdk/gdkevents.h	29 Apr 2005 18:32:00 -0000
@@ -120,7 +120,8 @@ typedef enum
   GDK_SCROLL            = 31,
   GDK_WINDOW_STATE      = 32,
   GDK_SETTING           = 33,
-  GDK_OWNER_CHANGE      = 34
+  GDK_OWNER_CHANGE      = 34,
+  GDK_LAST_EVENT	= 34
 } GdkEventType;
 
 /* Event masks. (Used to select what types of events a window
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.146
diff -u -p -u -r1.146 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	16 Mar 2005 03:17:27 -0000	1.146
+++ gdk/x11/gdkevents-x11.c	29 Apr 2005 18:32:00 -0000
@@ -84,6 +84,20 @@ struct _GdkEventTypeX11
   gint n_events;
 };
 
+
+/* An internal event to signify that the next motion event
+ * should be dispatched to the application with ->hint set
+ * to TRUE
+ */
+
+#define GDK_INTERNAL_SEND_NEXT_MOTION  (GDK_LAST_EVENT + 1)
+
+struct _GdkEventInternalSendNextMotion
+{
+  GdkEventType type;
+  GdkWindow *window;
+};
+
 /* 
  * Private function declarations
  */
@@ -197,6 +211,16 @@ _gdk_x11_events_uninit_screen (GdkScreen
   screen_x11->xsettings_client = NULL;
 }
 
+void
+_gdk_x11_events_queue_send_motion_hint (GdkWindow *window)
+{
+  GdkEvent *event = gdk_event_new (GDK_INTERNAL_SEND_NEXT_MOTION);
+  event->any.window = g_object_ref (window);
+  event->any.send_event = FALSE;
+  
+  _gdk_event_queue_append (GDK_WINDOW_DISPLAY (window), event);
+}
+
 void 
 _gdk_events_init (GdkDisplay *display)
 {
@@ -227,7 +251,6 @@ _gdk_events_init (GdkDisplay *display)
 					 NULL);
 }
 
-
 /**
  * gdk_events_pending:
  * 
@@ -1023,6 +1046,9 @@ gdk_event_translate (GdkDisplay *display
       yoffset = 0;
     }
 
+  if (xevent->type != MotionNotify && window)
+      _gdk_x11_events_queue_send_motion_hint (window);
+  
   switch (xevent->type)
     {
     case KeyPress:
@@ -1109,7 +1135,6 @@ gdk_event_translate (GdkDisplay *display
 	  event->scroll.device = display->core_pointer;
 
 	  set_screen_from_root (display, event, xevent->xbutton.root);
-	  
           break;
           
         default:
@@ -2202,6 +2227,54 @@ gdk_event_check (GSource *source) 
   return retval;
 }
 
+static gboolean
+skip_event (GdkDisplay *display, GdkEvent *event)
+{
+  GdkWindowObject *obj;
+  GdkWindowImplX11 *impl;
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+  if (!event->any.window || display_x11->pointer_xgrab_window == event->any.window)
+    return FALSE;
+  
+  obj = (GdkWindowObject *)event->any.window;
+  impl = GDK_WINDOW_IMPL_X11 (obj->impl);
+
+  if (event->type == GDK_MOTION_NOTIFY && (obj->event_mask & GDK_POINTER_MOTION_HINT_MASK))
+    {
+      if (impl->skip_motion)
+	{
+	  return TRUE;
+	}
+      else
+	{
+	  event->motion.is_hint = TRUE;
+	  impl->skip_motion = TRUE;
+	  return FALSE;
+	}
+    }
+
+  if (event->type == GDK_ENTER_NOTIFY && !(obj->event_mask & GDK_ENTER_NOTIFY_MASK))
+    return TRUE;
+
+  if (event->type == GDK_LEAVE_NOTIFY && !(obj->event_mask & GDK_LEAVE_NOTIFY_MASK))
+    return TRUE;
+
+  if (event->type == GDK_BUTTON_PRESS && !(obj->event_mask & GDK_BUTTON_PRESS_MASK))
+    return TRUE;
+
+  if (event->type == GDK_BUTTON_RELEASE && !(obj->event_mask & GDK_BUTTON_RELEASE_MASK))
+    return TRUE;
+
+  if (event->type == GDK_KEY_PRESS && (!obj->event_mask & GDK_KEY_PRESS_MASK))
+    return TRUE;
+
+  if (event->type == GDK_KEY_RELEASE && (!obj->event_mask & GDK_KEY_RELEASE_MASK))
+    return TRUE;
+
+  return FALSE;
+}
+
 static gboolean  
 gdk_event_dispatch (GSource    *source,
 		    GSourceFunc callback,
@@ -2217,8 +2290,22 @@ gdk_event_dispatch (GSource    *source,
 
   if (event)
     {
-      if (_gdk_event_func)
-	(*_gdk_event_func) (event, _gdk_event_data);
+      if (event->type == GDK_INTERNAL_SEND_NEXT_MOTION)
+	{
+	  GdkWindowObject *obj = (GdkWindowObject *)event->any.window;
+	  GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl);
+	  
+	  if (obj->event_mask & GDK_POINTER_MOTION_HINT_MASK)
+	    impl->skip_motion = FALSE;
+	}
+      else
+	{
+	  if (!skip_event (display, event))
+	    {
+	      if (_gdk_event_func)
+		(*_gdk_event_func) (event, _gdk_event_data);
+	    }
+	}
       
       gdk_event_free (event);
     }
Index: gdk/x11/gdkprivate-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkprivate-x11.h,v
retrieving revision 1.36
diff -u -p -u -r1.36 gdkprivate-x11.h
--- gdk/x11/gdkprivate-x11.h	17 Mar 2005 01:54:39 -0000	1.36
+++ gdk/x11/gdkprivate-x11.h	29 Apr 2005 18:32:00 -0000
@@ -167,6 +167,8 @@ void _gdk_x11_precache_atoms (GdkDisplay
 void _gdk_x11_events_init_screen   (GdkScreen *screen);
 void _gdk_x11_events_uninit_screen (GdkScreen *screen);
 
+void _gdk_x11_events_queue_send_motion_hint (GdkWindow *window);
+
 void _gdk_events_init           (GdkDisplay *display);
 void _gdk_windowing_window_init (GdkScreen *screen);
 void _gdk_visual_init           (GdkScreen *screen);
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.236
diff -u -p -u -r1.236 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	17 Mar 2005 01:54:39 -0000	1.236
+++ gdk/x11/gdkwindow-x11.c	29 Apr 2005 18:32:00 -0000
@@ -644,6 +644,33 @@ setup_toplevel_window (GdkWindow *window
   ensure_sync_counter (window);
 }
 
+static gint
+gdk_event_mask_to_x_event_mask (gint gdk_mask)
+{
+  gint result, i;
+
+  result = 0;
+  for (i = 0; i < _gdk_nenvent_masks; i++)
+    {
+      if (gdk_mask & (1 << (i + 1)))
+	result |= _gdk_event_mask_table[i];
+    }
+
+  if (gdk_mask & GDK_POINTER_MOTION_HINT_MASK)
+    {
+      result &= ~PointerMotionHintMask;
+
+      result |= LeaveWindowMask;
+      result |= EnterWindowMask;
+      result |= KeyPressMask;
+      result |= KeyReleaseMask;
+      result |= ButtonPressMask;
+      result |= ButtonReleaseMask;
+    }
+  
+  return result;
+}
+
 /**
  * gdk_window_new:
  * @parent: a #GdkWindow, or %NULL to create the window as a child of
@@ -683,7 +710,6 @@ gdk_window_new (GdkWindow     *parent,
   
   unsigned int class;
   const char *title;
-  int i;
   
   g_return_val_if_fail (attributes != NULL, NULL);
   
@@ -769,11 +795,7 @@ gdk_window_new (GdkWindow     *parent,
   xvisual = ((GdkVisualPrivate*) visual)->xvisual;
   
   xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
-  for (i = 0; i < _gdk_nenvent_masks; i++)
-    {
-      if (attributes->event_mask & (1 << (i + 1)))
-	xattributes.event_mask |= _gdk_event_mask_table[i];
-    }
+  xattributes.event_mask = gdk_event_mask_to_x_event_mask (attributes->event_mask);
   private->event_mask = attributes->event_mask;
   
   if (xattributes.event_mask)
@@ -3290,6 +3312,9 @@ _gdk_windowing_window_get_pointer (GdkDi
   
   _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
 
+  if (window)
+    _gdk_x11_events_queue_send_motion_hint (window);
+
   return_val = NULL;
   if (!GDK_WINDOW_DESTROYED (window) &&
       XQueryPointer (GDK_WINDOW_XDISPLAY (window),
@@ -3450,12 +3475,8 @@ gdk_window_set_events (GdkWindow       *
   if (!GDK_WINDOW_DESTROYED (window))
     {
       GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
-      xevent_mask = StructureNotifyMask | PropertyChangeMask;
-      for (i = 0; i < _gdk_nenvent_masks; i++)
-	{
-	  if (event_mask & (1 << (i + 1)))
-	    xevent_mask |= _gdk_event_mask_table[i];
-	}
+
+      xevent_mask = gdk_event_mask_to_x_event_mask (event_mask);
       
       XSelectInput (GDK_WINDOW_XDISPLAY (window),
 		    GDK_WINDOW_XID (window),
Index: gdk/x11/gdkwindow-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.h,v
retrieving revision 1.18
diff -u -p -u -r1.18 gdkwindow-x11.h
--- gdk/x11/gdkwindow-x11.h	18 Oct 2004 21:02:37 -0000	1.18
+++ gdk/x11/gdkwindow-x11.h	29 Apr 2005 18:32:00 -0000
@@ -78,6 +78,7 @@ struct _GdkWindowImplX11
   gint8 toplevel_window_type;
   guint override_redirect : 1;
   guint use_synchronized_configure : 1;
+  guint skip_motion : 1;
 };
  
 struct _GdkWindowImplX11Class 
@@ -114,7 +115,7 @@ struct _GdkToplevelX11
   guint have_fullscreen : 1;    /* _NET_WM_STATE_FULLSCREEN */
 
   guint is_leader : 1;
-  
+
   gulong map_serial;	/* Serial of last transition from unmapped */
   
   GdkPixmap *icon_pixmap;
