xwayland: Set wl_surface input region
Some applications that use client side decorations usually set custom input shape in order to prevent drop shadows stealing pointer events from windows below. Currently, the only way to get it is to use some XFixes APIs. On the other hand, plenty of wayland compositors use solely the wl_surface input region to decide what view can receive pointer input, which results in some pointer input issues around client side drop shadows because Xwayland doesn't set wl_surface.input_region. See-also: https://bugs.kde.org/show_bug.cgi?id=448119 Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Reviewed-by: Olivier Fourdan <ofourdan@redhat.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1510>
This commit is contained in:
parent
4053782443
commit
a4ed100c0c
|
@ -332,6 +332,32 @@ xwl_cursor_warped_to(DeviceIntPtr device,
|
||||||
xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
|
xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xwl_set_shape(WindowPtr window,
|
||||||
|
int kind)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = window->drawable.pScreen;
|
||||||
|
struct xwl_screen *xwl_screen;
|
||||||
|
struct xwl_window *xwl_window;
|
||||||
|
|
||||||
|
xwl_screen = xwl_screen_get(screen);
|
||||||
|
xwl_window = xwl_window_from_window(window);
|
||||||
|
|
||||||
|
screen->SetShape = xwl_screen->SetShape;
|
||||||
|
(*screen->SetShape) (window, kind);
|
||||||
|
xwl_screen->SetShape = screen->SetShape;
|
||||||
|
screen->SetShape = xwl_set_shape;
|
||||||
|
|
||||||
|
if (!xwl_window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (kind == ShapeInput) {
|
||||||
|
xwl_window_set_input_region(xwl_window, wInputShape(window));
|
||||||
|
if (xwl_window->allow_commits)
|
||||||
|
wl_surface_commit(xwl_window->surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct xwl_window *
|
static struct xwl_window *
|
||||||
find_matching_input_output_window(struct xwl_screen *xwl_screen,
|
find_matching_input_output_window(struct xwl_screen *xwl_screen,
|
||||||
WindowPtr window)
|
WindowPtr window)
|
||||||
|
@ -1125,6 +1151,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
|
xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
|
||||||
pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
|
pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
|
||||||
|
|
||||||
|
xwl_screen->SetShape = pScreen->SetShape;
|
||||||
|
pScreen->SetShape = xwl_set_shape;
|
||||||
|
|
||||||
pScreen->CursorWarpedTo = xwl_cursor_warped_to;
|
pScreen->CursorWarpedTo = xwl_cursor_warped_to;
|
||||||
pScreen->CursorConfinedTo = xwl_cursor_confined_to;
|
pScreen->CursorConfinedTo = xwl_cursor_confined_to;
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct xwl_screen {
|
||||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||||
MoveWindowProcPtr MoveWindow;
|
MoveWindowProcPtr MoveWindow;
|
||||||
SourceValidateProcPtr SourceValidate;
|
SourceValidateProcPtr SourceValidate;
|
||||||
|
SetShapeProcPtr SetShape;
|
||||||
|
|
||||||
int (*GrabServer) (ClientPtr client);
|
int (*GrabServer) (ClientPtr client);
|
||||||
int (*UngrabServer) (ClientPtr client);
|
int (*UngrabServer) (ClientPtr client);
|
||||||
|
|
|
@ -1502,6 +1502,8 @@ ensure_surface_for_window(WindowPtr window)
|
||||||
xwl_screen->tearing_control_manager, xwl_window->surface);
|
xwl_screen->tearing_control_manager, xwl_window->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xwl_window_set_input_region(xwl_window, wInputShape(window));
|
||||||
|
|
||||||
return xwl_window;
|
return xwl_window;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@ -1971,6 +1973,34 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
|
||||||
DamageEmpty(window_get_damage(xwl_window->surface_window));
|
DamageEmpty(window_get_damage(xwl_window->surface_window));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xwl_window_set_input_region(struct xwl_window *xwl_window,
|
||||||
|
RegionPtr input_shape)
|
||||||
|
{
|
||||||
|
struct wl_region *region;
|
||||||
|
BoxPtr box;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!input_shape) {
|
||||||
|
wl_surface_set_input_region(xwl_window->surface, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
region = wl_compositor_create_region(xwl_window->xwl_screen->compositor);
|
||||||
|
box = RegionRects(input_shape);
|
||||||
|
|
||||||
|
for (i = 0; i < RegionNumRects(input_shape); ++i, ++box) {
|
||||||
|
wl_region_add(region,
|
||||||
|
box->x1,
|
||||||
|
box->y1,
|
||||||
|
box->x2 - box->x1,
|
||||||
|
box->y2 - box->y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_surface_set_input_region(xwl_window->surface, region);
|
||||||
|
wl_region_destroy(region);
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xwl_window_init(void)
|
xwl_window_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -143,6 +143,7 @@ Bool xwl_destroy_window(WindowPtr window);
|
||||||
void xwl_window_post_damage(struct xwl_window *xwl_window);
|
void xwl_window_post_damage(struct xwl_window *xwl_window);
|
||||||
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
|
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
|
||||||
void xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface);
|
void xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface);
|
||||||
|
void xwl_window_set_input_region(struct xwl_window *xwl_window, RegionPtr input_shape);
|
||||||
|
|
||||||
Bool xwl_window_init(void);
|
Bool xwl_window_init(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue