From c7db234c11ed79de602aeab464771ec00eb4f30b Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Sat, 18 Aug 2018 19:41:15 +0200 Subject: wayland/xdg-shell: Intersect set geometry with subsurface tree geometry Currently xdg-shell applies a geometry set with set_window_geometry unconditionally. But the specification requires: > When applied, the effective window geometry will be > the set window geometry clamped to the bounding rectangle of the > combined geometry of the surface of the xdg_surface and the > associated subsurfaces. This is especially important to implement viewporter and transformation. --- src/wayland/meta-wayland-legacy-xdg-shell.c | 5 +++-- src/wayland/meta-wayland-shell-surface.c | 17 +++++++++++++++++ src/wayland/meta-wayland-shell-surface.h | 4 ++++ src/wayland/meta-wayland-xdg-shell.c | 5 +++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c index e871be972..fdae10e25 100644 --- a/src/wayland/meta-wayland-legacy-xdg-shell.c +++ b/src/wayland/meta-wayland-legacy-xdg-shell.c @@ -1304,8 +1304,9 @@ meta_wayland_zxdg_surface_v6_commit (MetaWaylandSurfaceRole *surface_role, if (pending->has_new_geometry) { - /* If we have new geometry, use it. */ - priv->geometry = pending->new_geometry; + meta_wayland_shell_surface_determine_geometry (shell_surface, + &pending->new_geometry, + &priv->geometry); priv->has_set_geometry = TRUE; } else if (!priv->has_set_geometry) diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c index c1e2bd7c1..88bfc21a5 100644 --- a/src/wayland/meta-wayland-shell-surface.c +++ b/src/wayland/meta-wayland-shell-surface.c @@ -64,6 +64,23 @@ meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_su *out_geometry = geometry; } +void +meta_wayland_shell_surface_determine_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *set_geometry, + MetaRectangle *out_geometry) +{ + MetaRectangle bounding_geometry = { 0 }; + MetaRectangle intersected_geometry = { 0 }; + + meta_wayland_shell_surface_calculate_geometry (shell_surface, + &bounding_geometry); + + meta_rectangle_intersect (set_geometry, &bounding_geometry, + &intersected_geometry); + + *out_geometry = intersected_geometry; +} + void meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface, MetaWindow *window) diff --git a/src/wayland/meta-wayland-shell-surface.h b/src/wayland/meta-wayland-shell-surface.h index fbed72908..39a5e4a50 100644 --- a/src/wayland/meta-wayland-shell-surface.h +++ b/src/wayland/meta-wayland-shell-surface.h @@ -64,6 +64,10 @@ void meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface, void meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface, MetaRectangle *out_geometry); +void meta_wayland_shell_surface_determine_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *set_geometry, + MetaRectangle *out_geometry); + void meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface, MetaWindow *window); diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 41cdfc86b..b5f347095 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -1369,8 +1369,9 @@ meta_wayland_xdg_surface_commit (MetaWaylandSurfaceRole *surface_role, if (pending->has_new_geometry) { - /* If we have new geometry, use it. */ - priv->geometry = pending->new_geometry; + meta_wayland_shell_surface_determine_geometry (shell_surface, + &pending->new_geometry, + &priv->geometry); priv->has_set_geometry = TRUE; } else if (!priv->has_set_geometry) -- cgit v1.2.1