[gtk+/gtk-2-24-quartz] win32: Fix synaptics trackpad issues



commit fe6280fdcb9bf3127c62f3805f9e1599c1bca070
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Nov 1 22:25:26 2011 +0100

    win32: Fix synaptics trackpad issues
    
    The synaptics trackpad driver has some weird behaviour on scroll.
    It pops up a window over the mouse pointer (looking like a scrollbar).
    This has two problems:
    * We get extra enter/leave events for the trackpad window
    * We get back the trackpad window when we look for the window
      under the mouse to deliver the mousewheel message.
    
    So, we add some trackpad specific hacks to avoid this (sigh) based
    on the trackpad window window class.
    
    This fixes bug #542777 and was partially based on a patch there
    from Peter Clifton.

 gdk/win32/gdkevents-win32.c |   67 ++++++++++++++++++++++++++++++++++++++----
 1 files changed, 60 insertions(+), 7 deletions(-)
---
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 854758d..fc980f6 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -84,6 +84,8 @@
  * Private function declarations
  */
 
+#define SYNAPSIS_ICON_WINDOW_CLASS "SynTrackCursorWindowClass"
+
 static gboolean gdk_event_translate (MSG        *msg,
 				     gint       *ret_valp);
 static void     handle_wm_paint     (MSG        *msg,
@@ -115,6 +117,7 @@ static GSourceFuncs event_funcs = {
 GPollFD event_poll_fd;
 
 static GdkWindow *mouse_window = NULL;
+static GdkWindow *mouse_window_ignored_leave = NULL;
 static gint current_x, current_y;
 static gint current_root_x, current_root_y;
 static UINT client_message;
@@ -2044,6 +2047,7 @@ gdk_event_translate (MSG  *msg,
   BYTE key_state[256];
   HIMC himc;
   WINDOWPOS *windowpos;
+  gboolean ignore_leave;
 
   GdkEvent *event;
 
@@ -2490,6 +2494,7 @@ gdk_event_translate (MSG  *msg,
 					  msg->time,
 					  FALSE);
 	      assign_object (&mouse_window, new_window);
+	      mouse_window_ignored_leave = NULL;
 	    }
 	}
 
@@ -2544,9 +2549,19 @@ gdk_event_translate (MSG  *msg,
 				      msg->time,
 				      FALSE);
 	  assign_object (&mouse_window, new_window);
+	  mouse_window_ignored_leave = NULL;
 	  if (new_window != NULL)
 	    track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (new_window));
 	}
+      else if (new_window != NULL && 
+	       new_window == mouse_window_ignored_leave)
+	{
+	  /* If we ignored a leave event for this window and we're now getting
+	     input again we need to re-arm the mouse tracking, as that was
+	     cancelled by the mouseleave. */
+	  mouse_window_ignored_leave = NULL;
+	  track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (new_window));
+	}
 
       assign_object (&window, find_window_for_mouse_event (window, msg));
 
@@ -2590,24 +2605,38 @@ gdk_event_translate (MSG  *msg,
 
       new_window = NULL;
       hwnd = WindowFromPoint (msg->pt);
+      ignore_leave = FALSE;
       if (hwnd != NULL)
 	{
+	  char classname[64];
+
 	  POINT client_pt = msg->pt;
 
+	  /* The synapitics trackpad drivers have this irritating
+	     feature where it pops up a window right under the pointer
+	     when you scroll. We ignore the leave and enter events for 
+	     this window */
+	  if (GetClassNameA (hwnd, classname, sizeof(classname)) &&
+	      strcmp (classname, SYNAPSIS_ICON_WINDOW_CLASS) == 0)
+	    ignore_leave = TRUE;
+
 	  ScreenToClient (hwnd, &client_pt);
 	  GetClientRect (hwnd, &rect);
 	  if (PtInRect (&rect, client_pt))
 	    new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
 	}
 
-      synthesize_crossing_events (_gdk_display,
-				  mouse_window, new_window,
-				  GDK_CROSSING_NORMAL,
-				  &msg->pt,
-				  0, /* TODO: Set right mask */
-				  msg->time,
-				  FALSE);
+      if (!ignore_leave)
+	synthesize_crossing_events (_gdk_display,
+				    mouse_window, new_window,
+				    GDK_CROSSING_NORMAL,
+				    &msg->pt,
+				    0, /* TODO: Set right mask */
+				    msg->time,
+				    FALSE);
       assign_object (&mouse_window, new_window);
+      mouse_window_ignored_leave = ignore_leave ? new_window : NULL;
+
 
       return_val = TRUE;
       break;
@@ -2625,6 +2654,30 @@ gdk_event_translate (MSG  *msg,
 
       if ((hwnd = WindowFromPoint (point)) == NULL)
 	break;
+      
+      {
+	char classname[64];
+
+	/* The synapitics trackpad drivers have this irritating
+	   feature where it pops up a window right under the pointer
+	   when you scroll. We backtrack and to the toplevel and
+	   find the innermost child instead. */
+	if (GetClassNameA (hwnd, classname, sizeof(classname)) &&
+	    strcmp (classname, SYNAPSIS_ICON_WINDOW_CLASS) == 0)
+	  {
+	    HWND hwndc;
+
+	    /* Find our toplevel window */
+	    hwnd = GetAncestor (msg->hwnd, GA_ROOT);
+
+	    /* Walk back up to the outermost child at the desired point */
+	    do {
+	      ScreenToClient (hwnd, &point);
+	      hwndc = ChildWindowFromPoint (hwnd, point);
+	      ClientToScreen (hwnd, &point);
+	    } while (hwndc != hwnd && (hwnd = hwndc, 1));
+	  }
+      }
 
       msg->hwnd = hwnd;
       if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)



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