diff --git a/gdk/win32/gdkdevice-win32.c b/gdk/win32/gdkdevice-win32.c index 190372de2d..3ca8e03a51 100644 --- a/gdk/win32/gdkdevice-win32.c +++ b/gdk/win32/gdkdevice-win32.c @@ -150,7 +150,18 @@ gdk_device_win32_query_state (GdkDevice *device, if (child_window) { - hwndc = ChildWindowFromPoint (hwnd, point); + if (window == gdk_screen_get_root_window (screen)) + { + /* Always use WindowFromPoint when searching from the root window. + * Only WindowFromPoint is able to look through transparent + * layered windows. + */ + hwndc = GetAncestor (WindowFromPoint (point), GA_ROOT); + } + else + { + hwndc = ChildWindowFromPoint (hwnd, point); + } if (hwndc && hwndc != hwnd) *child_window = gdk_win32_handle_table_lookup (hwndc); @@ -201,71 +212,46 @@ _gdk_device_win32_window_at_position (GdkDevice *device, GdkWindow *window = NULL; GdkWindowImplWin32 *impl = NULL; POINT screen_pt, client_pt; - HWND hwnd, hwndc; + HWND hwnd; RECT rect; - GetCursorPos (&screen_pt); + if (!GetCursorPos (&screen_pt)) + return NULL; + + hwnd = WindowFromPoint (screen_pt); if (get_toplevel) { - /* Only consider visible children of the desktop to avoid the various - * non-visible windows you often find on a running Windows box. These - * might overlap our windows and cause our walk to fail. As we assume - * WindowFromPoint() can find our windows, we follow similar logic - * here, and ignore invisible and disabled windows. - */ - hwnd = GetDesktopWindow (); - do { - window = gdk_win32_handle_table_lookup (hwnd); - - if (window != NULL && - GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT && - GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) - break; - - screen_to_client (hwnd, screen_pt, &client_pt); - hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED | - CWP_SKIPINVISIBLE); - - /* Verify that we're really inside the client area of the window */ - if (hwndc != hwnd) - { - GetClientRect (hwndc, &rect); - screen_to_client (hwndc, screen_pt, &client_pt); - if (!PtInRect (&rect, client_pt)) - hwndc = hwnd; - } - - } while (hwndc != hwnd && (hwnd = hwndc, 1)); - + /* Use WindowFromPoint instead of ChildWindowFromPoint(Ex). + * Only WindowFromPoint is able to look through transparent + * layered windows. + */ + hwnd = GetAncestor (hwnd, GA_ROOT); } - else + + /* Verify that we're really inside the client area of the window */ + GetClientRect (hwnd, &rect); + screen_to_client (hwnd, screen_pt, &client_pt); + if (!PtInRect (&rect, client_pt)) + hwnd = NULL; + + if (!get_toplevel && hwnd == NULL) { - hwnd = WindowFromPoint (screen_pt); + /* If we didn't hit any window, return the root window */ + /* note that the root window ain't a toplevel window */ + window = gdk_get_default_root_window (); + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - /* Verify that we're really inside the client area of the window */ - GetClientRect (hwnd, &rect); - screen_to_client (hwnd, screen_pt, &client_pt); - if (!PtInRect (&rect, client_pt)) - hwnd = NULL; + if (win_x) + *win_x = (screen_pt.x + _gdk_offset_x) / impl->window_scale; + if (win_y) + *win_y = (screen_pt.y + _gdk_offset_y) / impl->window_scale; - /* If we didn't hit any window at that point, return the desktop */ - if (hwnd == NULL) - { - window = gdk_get_default_root_window (); - impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - - if (win_x) - *win_x = (screen_pt.x + _gdk_offset_x) / impl->window_scale; - if (win_y) - *win_y = (screen_pt.y + _gdk_offset_y) / impl->window_scale; - - return window; - } - - window = gdk_win32_handle_table_lookup (hwnd); + return window; } + window = gdk_win32_handle_table_lookup (hwnd); + if (window && (win_x || win_y)) { impl = GDK_WINDOW_IMPL_WIN32 (window->impl);