W32: Implement rudimentary WM_NCHITTEST handling
Use (cairo) input shape of the window to check whether a point is inside or not inside the window. If it is, let the default window procedure do its thing (which seems to be working all right in all known cases). If it isn't, override the default window procedure and tell WM what we think. Don't do any of the above if the window has CSD-incompatible styles (WS_BORDER or WS_THICKFRAME). This is a crude kind of substitute for window input shape support (which W32 does not seem to have). Still probably enough to be positive about input shapes support. https://bugzilla.gnome.org/show_bug.cgi?id=733679
This commit is contained in:
parent
341108d4fc
commit
a23c29c0fb
@ -533,11 +533,8 @@ gdk_win32_display_supports_input_shapes (GdkDisplay *display)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
/* Not yet implemented. See comment in
|
/* Partially supported, see WM_NCHITTEST handler. */
|
||||||
* gdk_window_input_shape_combine_mask().
|
return TRUE;
|
||||||
*/
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1616,6 +1616,45 @@ handle_display_change (void)
|
|||||||
g_signal_emit_by_name (_gdk_screen, "size_changed");
|
g_signal_emit_by_name (_gdk_screen, "size_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_nchittest (HWND hwnd,
|
||||||
|
GdkWindow *window,
|
||||||
|
gint16 screen_x,
|
||||||
|
gint16 screen_y,
|
||||||
|
gint *ret_valp)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
LONG style;
|
||||||
|
|
||||||
|
if (window == NULL || window->input_shape == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
style = GetWindowLong (hwnd, GWL_STYLE);
|
||||||
|
|
||||||
|
/* Assume that these styles are incompatible with CSD,
|
||||||
|
* so there's no reason for us to override the defaults.
|
||||||
|
*/
|
||||||
|
if (style & (WS_BORDER | WS_THICKFRAME))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!GetWindowRect (hwnd, &rect))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
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 (cairo_region_contains_point (window->input_shape, rect.left, rect.top))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Otherwise override DefWindowProc() and tell WM that the point is not
|
||||||
|
* within the window
|
||||||
|
*/
|
||||||
|
*ret_valp = HTNOWHERE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generate_button_event (GdkEventType type,
|
generate_button_event (GdkEventType type,
|
||||||
gint button,
|
gint button,
|
||||||
@ -3236,6 +3275,12 @@ gdk_event_translate (MSG *msg,
|
|||||||
if (msg->wParam && GDK_WINDOW_IS_MAPPED (window))
|
if (msg->wParam && GDK_WINDOW_IS_MAPPED (window))
|
||||||
ensure_stacking_on_activate_app (msg, window);
|
ensure_stacking_on_activate_app (msg, window);
|
||||||
break;
|
break;
|
||||||
|
case WM_NCHITTEST:
|
||||||
|
/* TODO: pass all messages to DwmDefWindowProc() first! */
|
||||||
|
return_val = handle_nchittest (msg->hwnd, window,
|
||||||
|
GET_X_LPARAM (msg->lParam),
|
||||||
|
GET_Y_LPARAM (msg->lParam), ret_valp);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Handle WINTAB events here, as we know that gdkinput.c will
|
/* Handle WINTAB events here, as we know that gdkinput.c will
|
||||||
* use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
|
* use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
|
||||||
|
@ -3227,9 +3227,8 @@ gdk_win32_input_shape_combine_region (GdkWindow *window,
|
|||||||
gint offset_x,
|
gint offset_x,
|
||||||
gint offset_y)
|
gint offset_y)
|
||||||
{
|
{
|
||||||
/* Input shapes are not supported: input shape is always the same as
|
/* Partial input shape support is implemented by handling the
|
||||||
* the window shape; pixels with alpha == 0 are usually not clickable,
|
* WM_NCHITTEST message.
|
||||||
* clickability can be overriden by handling WM_NCHITTEST.
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user