From ed2406621a5e815e0eb5123a35af722e3cfbf72b Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Tue, 15 Apr 2025 12:01:16 +0300 Subject: [PATCH] xdg-surface: don't disconnect clients for bad effective geom yet Preferably, the geometry computation would've been done at the client commit time, but this requires correct subsurface state management which we don't have at the moment. The next best solution, which is computing the geometry on server commit time, doesn't currently have a way to prevent user commit handlers from firing, meaning that compositors might get an invalid surface state. Additionally, Chromium and gtk-layer-shell turned out to violate the protocol in this regard, so client disconnection leads to really bad UX. As such, complain via a log message instead, and ignore invalid geometry, falling back to the bounding rectangle. --- types/xdg_shell/wlr_xdg_surface.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 3d3299f93..e492405d3 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -257,17 +257,22 @@ static const struct xdg_surface_interface xdg_surface_implementation = { // the surface, in which case it's updated on map, so that subsurfaces are // mapped and surface extents are computed correctly. static void update_geometry(struct wlr_xdg_surface *surface) { - if (!wlr_box_empty(&surface->current.geometry)) { - if ((surface->current.committed & WLR_XDG_SURFACE_STATE_WINDOW_GEOMETRY) != 0) { - wlr_surface_get_extents(surface->surface, &surface->geometry); - wlr_box_intersection(&surface->geometry, - &surface->current.geometry, &surface->geometry); - if (wlr_box_empty(&surface->geometry)) { - wl_resource_post_error(surface->resource, XDG_SURFACE_ERROR_INVALID_SIZE, - "the effective window geometry is empty"); - } + if ((surface->current.committed & WLR_XDG_SURFACE_STATE_WINDOW_GEOMETRY) != 0) { + wlr_surface_get_extents(surface->surface, &surface->geometry); + + struct wlr_box effective; + wlr_box_intersection(&effective, &surface->geometry, &surface->current.geometry); + + if (wlr_box_empty(&effective)) { + wlr_log(WLR_INFO, + "A client has committed an invalid effective window geometry (%d,%d %dx%d); " + "this will result in client disconnection in the future", + effective.x, effective.y, effective.width, effective.height); + // The extents are used instead + } else { + surface->geometry = effective; } - } else { + } else if (wlr_box_empty(&surface->geometry)) { wlr_surface_get_extents(surface->surface, &surface->geometry); } }