tree/view: Send estimated configure before mapping

Sending 0,0 as configure dimensions indicate that the client is free to
pick its own dimensions. When tiling, the client needs to strictly
adhere to the tile dimensions. Sway's handling of this has been to send
a the appropriate dimensions in a new configure when the surface is
mapped, leading to the first buffer most likely being incorrectly sized.

Introduce a view_premap which goes through part of the mapping dance,
calculating what the container dimensions would be at this time and
sending it as a configure. This is only an estimate and inherently
racey if the user very quickly changes focused workspace between surface
role commit and first attached buffer, but when it works the client has
a chance of getting the first buffer right, when it doesn't it is no
worse than it would have been otherwise.

Fixes: https://github.com/swaywm/sway/issues/2176
This commit is contained in:
Kenny Levinsen 2024-08-24 23:43:12 +02:00
parent 7288f77bbe
commit b23e670824
5 changed files with 206 additions and 1 deletions

View file

@ -7,6 +7,7 @@ struct sway_container;
struct sway_node;
void arrange_container(struct sway_container *container);
void next_sibling_container_geometry(struct sway_container *child, struct sway_container *sibling, bool fullscreen);
void arrange_workspace(struct sway_workspace *workspace);

View file

@ -297,6 +297,21 @@ void view_begin_destroy(struct sway_view *view);
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, struct wlr_output *fullscreen_output, bool decoration);
/**
* Prepare the view for its upcoming mapping, sending the intended dimensions
* so that the first frame has a chance of being correct. If CSD preferences or
* floating tendency changes, this may turn out to be inaccurate but no worse
* than skipping the step.
*
* `fullscreen` should be set to true (and optionally `fullscreen_output`
* should be populated) if the view should be made fullscreen immediately.
*
* `decoration` should be set to true if the client prefers CSD. The client's
* preference may be ignored.
*/
void view_premap(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, struct wlr_output *fullscreen_output, bool decoration);
void view_unmap(struct sway_view *view);
void view_update_size(struct sway_view *view);