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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3031>
This commit is contained in:
Sebastian Keller 2023-05-29 20:12:19 +02:00 committed by Marge Bot
parent 30a5178204
commit 6274bb3518
2 changed files with 26 additions and 10 deletions

View File

@ -34,6 +34,7 @@
#include "x11/window-props.h" #include "x11/window-props.h"
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#define EVENT_MASK (SubstructureRedirectMask | \ #define EVENT_MASK (SubstructureRedirectMask | \
StructureNotifyMask | SubstructureNotifyMask | \ StructureNotifyMask | SubstructureNotifyMask | \
@ -107,6 +108,9 @@ meta_window_set_frame_xwindow (MetaWindow *window,
XChangeWindowAttributes (x11_display->xdisplay, XChangeWindowAttributes (x11_display->xdisplay,
frame->xwindow, CWEventMask, &attrs); 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); meta_x11_display_register_x_window (x11_display, &frame->xwindow, window);
if (window->mapped) if (window->mapped)
@ -215,6 +219,9 @@ meta_window_destroy_frame (MetaWindow *window)
window->reparents_pending += 1; window->reparents_pending += 1;
} }
if (META_X11_DISPLAY_HAS_SHAPE (x11_display))
XShapeSelectInput (x11_display->xdisplay, frame->xwindow, NoEventMask);
XDeleteProperty (x11_display->xdisplay, XDeleteProperty (x11_display->xdisplay,
window->xwindow, window->xwindow,
x11_display->atom__MUTTER_NEEDS_FRAME); x11_display->atom__MUTTER_NEEDS_FRAME);

View File

@ -2118,6 +2118,10 @@ meta_window_x11_constructed (GObject *object)
window->hidden = FALSE; window->hidden = FALSE;
priv->border_width = attrs.border_width; 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); 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; cairo_region_t *region = NULL;
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); 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->decorated)
{ {
if (window->input_region) if (!window->frame)
meta_window_set_input_region (window, NULL); {
return; 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)) 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); meta_x11_error_trap_push (x11_display);
rects = XShapeGetRectangles (x11_display->xdisplay, rects = XShapeGetRectangles (x11_display->xdisplay,
window->xwindow, xwindow,
ShapeInput, ShapeInput,
&n_rects, &n_rects,
&ordering); &ordering);
@ -2503,8 +2512,8 @@ meta_window_x11_update_input_region (MetaWindow *window)
client_area.x = 0; client_area.x = 0;
client_area.y = 0; client_area.y = 0;
client_area.width = priv->client_rect.width; client_area.width = window->buffer_rect.width;
client_area.height = priv->client_rect.height; client_area.height = window->buffer_rect.height;
/* The shape we get back from the client may have coordinates /* The shape we get back from the client may have coordinates
* outside of the frame. The X SHAPE Extension requires that * outside of the frame. The X SHAPE Extension requires that