From c59aeb5673f991b5b39342786b45795569ad0353 Mon Sep 17 00:00:00 2001 From: "Andrew J. Hesford" Date: Wed, 27 Dec 2023 11:56:48 -0500 Subject: [PATCH] xdg: sync pending when applying geometry Applications may respond to pending resize requests either by ignoring them or substituting alternative sizes (for example, when mpv constrains resizes to keep its aspect ratio fixed). In these cases, view->pending will fall out of sync with the actual view geometry. This will cause problems when subsequent operations (e.g., MoveToEdge) use the pending geometry to decide where to place the window. To fix this, reset view->pending to be equal view->current when either: 1. The requested size change has been commited, to the scene graph, and no subsequent changes are pending; or 2. The requested size change has been ignored by the client. --- src/xdg.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/xdg.c b/src/xdg.c index 638e111b..77afc44d 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -127,6 +127,20 @@ handle_commit(struct wl_listener *listener, void *data) if (update_required) { view_impl_apply_geometry(view, size.width, size.height); + + /* + * Some views (e.g., terminals that scale as multiples of rows + * and columns, or windows that impose a fixed aspect ratio), + * may respond to a resize but alter the width or height. When + * this happens, view->pending will be out of sync with the + * actual geometry (size *and* position, depending on the edge + * from which the resize was attempted). When no other + * configure is pending, re-sync the pending geometry with the + * actual view. + */ + if (!view->pending_configure_serial) { + view->pending = view->current; + } } } @@ -145,8 +159,11 @@ handle_configure_timeout(void *data) view->pending_configure_serial = 0; view->pending_configure_timeout = NULL; - view_impl_apply_geometry(view, view->current.width, - view->current.height); + view_impl_apply_geometry(view, + view->current.width, view->current.height); + + /* Re-sync pending view with current state */ + view->pending = view->current; return 0; /* ignored per wl_event_loop docs */ } -- 2.52.0