From 6274bb3518dfe39ea223a3220ea15976879faf24 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Mon, 29 May 2023 20:12:19 +0200 Subject: [PATCH] x11: Use input region from frame window for decorated windows Previously the input region was ignored for decorated windows, which since the introduction of the frames client meant that the entire shadow region of the frame window was considered interactive. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2706 Part-of: --- src/core/frame.c | 7 +++++++ src/x11/window-x11.c | 29 +++++++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/core/frame.c b/src/core/frame.c index fbb51a37b..57cffbf3a 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -34,6 +34,7 @@ #include "x11/window-props.h" #include +#include #define EVENT_MASK (SubstructureRedirectMask | \ StructureNotifyMask | SubstructureNotifyMask | \ @@ -107,6 +108,9 @@ meta_window_set_frame_xwindow (MetaWindow *window, XChangeWindowAttributes (x11_display->xdisplay, frame->xwindow, CWEventMask, &attrs); + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + XShapeSelectInput (x11_display->xdisplay, frame->xwindow, ShapeNotifyMask); + meta_x11_display_register_x_window (x11_display, &frame->xwindow, window); if (window->mapped) @@ -215,6 +219,9 @@ meta_window_destroy_frame (MetaWindow *window) window->reparents_pending += 1; } + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + XShapeSelectInput (x11_display->xdisplay, frame->xwindow, NoEventMask); + XDeleteProperty (x11_display->xdisplay, window->xwindow, x11_display->atom__MUTTER_NEEDS_FRAME); diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 1f71eb406..ff358f4f0 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -2118,6 +2118,10 @@ meta_window_x11_constructed (GObject *object) window->hidden = FALSE; priv->border_width = attrs.border_width; + g_signal_connect (window, "notify::decorated", + G_CALLBACK (meta_window_x11_update_input_region), + window); + G_OBJECT_CLASS (meta_window_x11_parent_class)->constructed (object); } @@ -2428,16 +2432,21 @@ meta_window_x11_update_input_region (MetaWindow *window) cairo_region_t *region = NULL; MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + Window xwindow; - /* Decorated windows don't have an input region, because - we don't shape the frame to match the client windows - (so the events are blocked by the frame anyway) - */ if (window->decorated) { - if (window->input_region) - meta_window_set_input_region (window, NULL); - return; + if (!window->frame) + { + if (window->input_region) + meta_window_set_input_region (window, NULL); + return; + } + xwindow = window->frame->xwindow; + } + else + { + xwindow = window->xwindow; } if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) @@ -2449,7 +2458,7 @@ meta_window_x11_update_input_region (MetaWindow *window) meta_x11_error_trap_push (x11_display); rects = XShapeGetRectangles (x11_display->xdisplay, - window->xwindow, + xwindow, ShapeInput, &n_rects, &ordering); @@ -2503,8 +2512,8 @@ meta_window_x11_update_input_region (MetaWindow *window) client_area.x = 0; client_area.y = 0; - client_area.width = priv->client_rect.width; - client_area.height = priv->client_rect.height; + client_area.width = window->buffer_rect.width; + client_area.height = window->buffer_rect.height; /* The shape we get back from the client may have coordinates * outside of the frame. The X SHAPE Extension requires that