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.
This commit is contained in:
Andrew J. Hesford 2023-12-27 11:56:48 -05:00 committed by Johan Malm
parent 7c91f36c13
commit c59aeb5673

View file

@ -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 */
}