[gtk: 1/3] GdkWin32: Fix handling of WM_NCHITTEST




commit 5e299cd3d26d65b5d9a89712748e611d20dfeef3
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Fri Aug 19 19:21:17 2022 +0200

    GdkWin32: Fix handling of WM_NCHITTEST
    
    Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5114

 gdk/win32/gdkevents-win32.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)
---
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index ee5bc47b39..ed082a2076 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1433,35 +1433,42 @@ handle_nchittest (HWND hwnd,
                   gint16 screen_y,
                   int *ret_valp)
 {
-  RECT rect;
   GdkWin32Surface *impl;
+  RECT client_rect;
+  POINT client_pt;
+
+  if (window == NULL)
+    return FALSE;
 
-  if (window == NULL || window->input_region == NULL)
+  /* If the window has no particular input pass-through region,
+   * then we can simply let DefWindowProc() handle the message */
+  if (window->input_region == NULL)
     return FALSE;
 
-  /* If the window has decorations, DefWindowProc() will take
-   * care of NCHITTEST.
-   */
-  if (!_gdk_win32_surface_lacks_wm_decorations (window))
+  if (!GetClientRect (hwnd, &client_rect))
     return FALSE;
 
-  if (!GetWindowRect (hwnd, &rect))
+  client_pt.x = screen_x;
+  client_pt.y = screen_y;
+  if (!ScreenToClient (hwnd, &client_pt))
+    return FALSE;
+
+  /* Check whether the point lies within the client area */
+  if (!PtInRect (&client_rect, client_pt))
     return FALSE;
 
   impl = GDK_WIN32_SURFACE (window);
-  rect.left = screen_x - rect.left;
-  rect.top = screen_y - rect.top;
 
-  /* If it's inside the rect, return FALSE and let DefWindowProc() handle it */
+  /* If the point lies inside the input region, return HTCLIENT,
+   * otherwise return HTTRANSPARENT. */
   if (cairo_region_contains_point (window->input_region,
-                                   rect.left / impl->surface_scale,
-                                   rect.top / impl->surface_scale))
-    return FALSE;
+                                   client_pt.x / impl->surface_scale,
+                                   client_pt.y / impl->surface_scale))
+    *ret_valp = HTCLIENT;
+  else
+    *ret_valp = HTTRANSPARENT;
 
-  /* Otherwise override DefWindowProc() and tell WM that the point is not
-   * within the window
-   */
-  *ret_valp = HTNOWHERE;
+  /* We handled the message, no need to call DefWindowProc() */
   return TRUE;
 }
 


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