mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-18 17:30:10 +00:00
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.
This commit is contained in:
parent
718af6870f
commit
1a624ea818
@ -84,6 +84,8 @@
|
|||||||
* Private function declarations
|
* Private function declarations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define SYNAPSIS_ICON_WINDOW_CLASS "SynTrackCursorWindowClass"
|
||||||
|
|
||||||
static gboolean gdk_event_translate (MSG *msg,
|
static gboolean gdk_event_translate (MSG *msg,
|
||||||
gint *ret_valp);
|
gint *ret_valp);
|
||||||
static void handle_wm_paint (MSG *msg,
|
static void handle_wm_paint (MSG *msg,
|
||||||
@ -115,6 +117,7 @@ static GSourceFuncs event_funcs = {
|
|||||||
GPollFD event_poll_fd;
|
GPollFD event_poll_fd;
|
||||||
|
|
||||||
static GdkWindow *mouse_window = NULL;
|
static GdkWindow *mouse_window = NULL;
|
||||||
|
static GdkWindow *mouse_window_ignored_leave = NULL;
|
||||||
static gint current_x, current_y;
|
static gint current_x, current_y;
|
||||||
static gint current_root_x, current_root_y;
|
static gint current_root_x, current_root_y;
|
||||||
static UINT client_message;
|
static UINT client_message;
|
||||||
@ -2044,6 +2047,7 @@ gdk_event_translate (MSG *msg,
|
|||||||
BYTE key_state[256];
|
BYTE key_state[256];
|
||||||
HIMC himc;
|
HIMC himc;
|
||||||
WINDOWPOS *windowpos;
|
WINDOWPOS *windowpos;
|
||||||
|
gboolean ignore_leave;
|
||||||
|
|
||||||
GdkEvent *event;
|
GdkEvent *event;
|
||||||
|
|
||||||
@ -2490,6 +2494,7 @@ gdk_event_translate (MSG *msg,
|
|||||||
msg->time,
|
msg->time,
|
||||||
FALSE);
|
FALSE);
|
||||||
assign_object (&mouse_window, new_window);
|
assign_object (&mouse_window, new_window);
|
||||||
|
mouse_window_ignored_leave = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2544,9 +2549,19 @@ gdk_event_translate (MSG *msg,
|
|||||||
msg->time,
|
msg->time,
|
||||||
FALSE);
|
FALSE);
|
||||||
assign_object (&mouse_window, new_window);
|
assign_object (&mouse_window, new_window);
|
||||||
|
mouse_window_ignored_leave = NULL;
|
||||||
if (new_window != NULL)
|
if (new_window != NULL)
|
||||||
track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (new_window));
|
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));
|
assign_object (&window, find_window_for_mouse_event (window, msg));
|
||||||
|
|
||||||
@ -2590,24 +2605,38 @@ gdk_event_translate (MSG *msg,
|
|||||||
|
|
||||||
new_window = NULL;
|
new_window = NULL;
|
||||||
hwnd = WindowFromPoint (msg->pt);
|
hwnd = WindowFromPoint (msg->pt);
|
||||||
|
ignore_leave = FALSE;
|
||||||
if (hwnd != NULL)
|
if (hwnd != NULL)
|
||||||
{
|
{
|
||||||
|
char classname[64];
|
||||||
|
|
||||||
POINT client_pt = msg->pt;
|
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);
|
ScreenToClient (hwnd, &client_pt);
|
||||||
GetClientRect (hwnd, &rect);
|
GetClientRect (hwnd, &rect);
|
||||||
if (PtInRect (&rect, client_pt))
|
if (PtInRect (&rect, client_pt))
|
||||||
new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
|
new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
synthesize_crossing_events (_gdk_display,
|
if (!ignore_leave)
|
||||||
mouse_window, new_window,
|
synthesize_crossing_events (_gdk_display,
|
||||||
GDK_CROSSING_NORMAL,
|
mouse_window, new_window,
|
||||||
&msg->pt,
|
GDK_CROSSING_NORMAL,
|
||||||
0, /* TODO: Set right mask */
|
&msg->pt,
|
||||||
msg->time,
|
0, /* TODO: Set right mask */
|
||||||
FALSE);
|
msg->time,
|
||||||
|
FALSE);
|
||||||
assign_object (&mouse_window, new_window);
|
assign_object (&mouse_window, new_window);
|
||||||
|
mouse_window_ignored_leave = ignore_leave ? new_window : NULL;
|
||||||
|
|
||||||
|
|
||||||
return_val = TRUE;
|
return_val = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -2626,6 +2655,30 @@ gdk_event_translate (MSG *msg,
|
|||||||
if ((hwnd = WindowFromPoint (point)) == NULL)
|
if ((hwnd = WindowFromPoint (point)) == NULL)
|
||||||
break;
|
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;
|
msg->hwnd = hwnd;
|
||||||
if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
|
if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user