From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/message.c | 63 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d303f32aa9b..547bc5543b1 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2403,49 +2403,43 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, return TRUE; }
+static HWND find_hardware_message_window( MSG *msg, GUITHREADINFO *info, INT *hittest ) +{ + HWND target; + + if (!is_mouse_message( msg->message )) return msg->hwnd; + + /* find the window to dispatch this mouse message to */ + + if ((target = info->hwndCapture)) *hittest = HTCLIENT; + else if (!(target = window_from_point( msg->hwnd, msg->pt, hittest, 0 /* per-monitor DPI */ ))) + { + /* As a heuristic, try the next window if it's the owner of orig */ + HWND next = get_window_relative( msg->hwnd, GW_HWNDNEXT ); + if (next && get_window_relative( msg->hwnd, GW_OWNER ) == next && is_current_thread_window( next )) + target = window_from_point( next, msg->pt, hittest, 0 /* per-monitor DPI */ ); + } + + return target; +} + /*********************************************************************** * process_mouse_message * * returns TRUE if the contents of 'msg' should be passed to the application */ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, HWND hwnd_filter, - UINT first, UINT last, BOOL remove ) + UINT first, UINT last, BOOL remove, GUITHREADINFO *info, INT hittest ) { static MSG clk_msg;
POINT pt; UINT message; - INT hittest; EVENTMSG event; - GUITHREADINFO info; MOUSEHOOKSTRUCTEX hook; BOOL eat_msg; WPARAM wparam;
- /* find the window to dispatch this mouse message to */ - - info.cbSize = sizeof(info); - NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ); - if (info.hwndCapture) - { - hittest = HTCLIENT; - msg->hwnd = info.hwndCapture; - } - else - { - HWND orig = msg->hwnd; - - msg->hwnd = window_from_point( msg->hwnd, msg->pt, &hittest, 0 /* per-monitor DPI */ ); - if (!msg->hwnd) /* As a heuristic, try the next window if it's the owner of orig */ - { - HWND next = get_window_relative( orig, GW_HWNDNEXT ); - - if (next && get_window_relative( orig, GW_OWNER ) == next && - is_current_thread_window( next )) - msg->hwnd = window_from_point( next, msg->pt, &hittest, 0 /* per-monitor DPI */ ); - } - } - if (!msg->hwnd || !is_current_thread_window( msg->hwnd )) { accept_hardware_message( hw_id ); @@ -2480,7 +2474,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H { /* coordinates don't get translated while tracking a menu */ /* FIXME: should differentiate popups and top-level menus */ - if (!(info.flags & GUI_INMENUMODE)) + if (!(info->flags & GUI_INMENUMODE)) screen_to_client( msg->hwnd, &pt ); } } @@ -2499,7 +2493,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H * note that ...MOUSEMOVEs can slip in between * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
- if ((info.flags & (GUI_INMENUMODE|GUI_INMOVESIZE)) || + if ((info->flags & (GUI_INMENUMODE|GUI_INMOVESIZE)) || hittest != HTCLIENT || (get_class_long( msg->hwnd, GCL_STYLE, FALSE ) & CS_DBLCLKS)) { @@ -2556,7 +2550,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H
if (remove) accept_hardware_message( hw_id );
- if (!remove || info.hwndCapture) + if (!remove || info->hwndCapture) { msg->message = message; return TRUE; @@ -2577,7 +2571,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H
/* Activate the window if needed */
- if (msg->hwnd != info.hwndActive) + if (msg->hwnd != info->hwndActive) { HWND hwndTop = NtUserGetAncestor( msg->hwnd, GA_ROOT );
@@ -2626,12 +2620,17 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar HWND hwnd_filter, UINT first, UINT last, BOOL remove ) { struct ntuser_thread_info *thread_info = NtUserGetThreadInfo(); + GUITHREADINFO info = {.cbSize = sizeof(info)}; UINT context; BOOL ret = FALSE; + INT hittest;
thread_info->msg_source.deviceType = msg_data->source.device; thread_info->msg_source.originId = msg_data->source.origin;
+ NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ); + msg->hwnd = find_hardware_message_window( msg, &info, &hittest ); + /* hardware messages are always in physical coords */ context = set_thread_dpi_awareness_context( NTUSER_DPI_PER_MONITOR_AWARE );
@@ -2640,7 +2639,7 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar else if (is_keyboard_message( msg->message )) ret = process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove ); else if (is_mouse_message( msg->message )) - ret = process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove ); + ret = process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove, &info, hittest ); else if (msg->message >= WM_POINTERUPDATE && msg->message <= WM_POINTERLEAVE) ret = process_pointer_message( msg, hw_id, msg_data ); else if (msg->message == WM_WINE_CLIPCURSOR)