summaryrefslogtreecommitdiff
path: root/gdk/win32
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2011-11-01 22:25:26 +0100
committerAlexander Larsson <alexl@redhat.com>2011-11-10 17:41:09 +0100
commitd441044569f4fcf4e5f97d3c84056f1f6099d09b (patch)
tree4f5f7727b4ed810a34c7bd1bb4e25050a0fad3a6 /gdk/win32
parent487ace0aca86cb65f1e8987a1e041c527572a2e0 (diff)
downloadgtk+-d441044569f4fcf4e5f97d3c84056f1f6099d09b.tar.gz
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.
Diffstat (limited to 'gdk/win32')
-rw-r--r--gdk/win32/gdkevents-win32.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 4f5aa62c1b..b3932a1e62 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -90,6 +90,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,
@@ -122,6 +124,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;
@@ -1898,6 +1901,7 @@ gdk_event_translate (MSG *msg,
BYTE key_state[256];
HIMC himc;
WINDOWPOS *windowpos;
+ gboolean ignore_leave;
GdkEvent *event;
@@ -2357,6 +2361,7 @@ gdk_event_translate (MSG *msg,
msg->time,
FALSE);
assign_object (&mouse_window, new_window);
+ mouse_window_ignored_leave = NULL;
}
}
@@ -2410,9 +2415,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));
@@ -2456,24 +2471,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 (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;
@@ -2491,6 +2520,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 (msg->hwnd)) == NULL)