xdg: unify initial positioning logic

This commit is contained in:
John Lindgren 2026-02-21 15:36:47 -05:00 committed by Hiroaki Yamamoto
parent 658df83280
commit 3f223fe5b0

View file

@ -121,17 +121,32 @@ set_fullscreen_from_request(struct view *view,
view_set_fullscreen(view, requested->fullscreen);
}
/* Called from commit handler and updates view->pending.x/y directly */
static void
do_late_positioning(struct view *view)
set_initial_position(struct view *view)
{
if (!view_is_floating(view)) {
return;
}
view_constrain_size_to_that_of_usable_area(view);
struct server *server = view->server;
if (server->input_mode == LAB_INPUT_STATE_MOVE
&& view == server->grabbed_view) {
/* Reposition the view while anchoring it to cursor */
interactive_anchor_to_cursor(server, &view->pending);
} else {
view_compute_position_by_policy(view, &view->pending,
/* allow_cursor */ true, rc.placement_policy);
struct view *parent = xdg_toplevel_view_get_parent(view);
if (parent) {
/* Center relative to parent view */
view_compute_centered_position(view, &parent->pending,
view->pending.width, view->pending.height,
&view->pending.x, &view->pending.y);
} else {
view_compute_position_by_policy(view, &view->pending,
/* allow_cursor */ true, rc.placement_policy);
}
}
}
@ -247,15 +262,15 @@ handle_commit(struct wl_listener *listener, void *data)
bool update_required = false;
/*
* If we didn't know the natural size when leaving fullscreen or
* unmaximizing, then the pending size will be 0x0. In this case,
* the pending x/y is also unset and we still need to position
* the window.
* The pending size will be empty in two cases:
* (1) when the view is first mapped
* (2) when leaving fullscreen or un-maximizing,
* if natural geometry wasn't known
*/
if (wlr_box_empty(&view->pending) && !wlr_box_empty(&size)) {
view->pending.width = size.width;
view->pending.height = size.height;
do_late_positioning(view);
set_initial_position(view);
update_required = true;
}
@ -789,22 +804,6 @@ xdg_toplevel_view_notify_tiled(struct view *view)
}
}
static void
set_initial_position(struct view *view)
{
view_constrain_size_to_that_of_usable_area(view);
struct view *parent = xdg_toplevel_view_get_parent(view);
if (parent) {
/* Child views are center-aligned relative to their parents */
view_center(view, &parent->pending);
return;
}
/* All other views are placed according to a configured strategy */
view_place_by_policy(view, /* allow_cursor */ true, rc.placement_policy);
}
static void
handle_map(struct wl_listener *listener, void *data)
{
@ -821,36 +820,6 @@ handle_map(struct wl_listener *listener, void *data)
} else {
view_set_ssd_mode(view, LAB_SSD_MODE_NONE);
}
/*
* Set initial "pending" dimensions. "Current"
* dimensions remain zero until handle_commit().
*/
if (wlr_box_empty(&view->pending)) {
struct wlr_xdg_surface *xdg_surface =
xdg_surface_from_view(view);
view->pending.width = xdg_surface->geometry.width;
view->pending.height = xdg_surface->geometry.height;
}
/*
* Set initial "pending" position for floating views.
*/
if (view_is_floating(view)) {
set_initial_position(view);
}
/* Disable background fill at map (paranoid?) */
disable_fullscreen_bg(view);
/*
* Set initial "current" position directly before
* calling view_moved() to reduce flicker
*/
view->current.x = view->pending.x;
view->current.y = view->pending.y;
view_moved(view);
}
view_impl_map(view);