diff --git a/include/view.h b/include/view.h index 5353686b..f5590fa2 100644 --- a/include/view.h +++ b/include/view.h @@ -514,10 +514,17 @@ int view_effective_height(struct view *view, bool use_pending); */ void view_center(struct view *view, const struct wlr_box *ref); -/* - * Like view_place_by_policy() but doesn't actually move the view. - * Returns false if position could not be computed (for example, if no - * outputs are connected). In that case, @geom is not modified. +/** + * view_compute_position_by_policy() - compute view placement + * @view: view to be placed + * @geom: floating view geometry to update (in/out) + * @allow_cursor: set to false to ignore center-on-cursor policy + * @policy: placement policy to apply + * + * Computes floating view placement according to configured strategy. + * Unlike view_place_by_policy(), this function doesn't actually move + * the view. It returns false if position could not be computed (e.g. + * if no outputs are connected). In that case, @geom is not modified. */ bool view_compute_position_by_policy(struct view *view, struct wlr_box *geom, bool allow_cursor, enum lab_placement_policy policy); @@ -527,6 +534,10 @@ bool view_compute_position_by_policy(struct view *view, struct wlr_box *geom, * @view: view to be placed * @allow_cursor: set to false to ignore center-on-cursor policy * @policy: placement policy to apply + * + * Places a floating view according to configured placement strategy. + * Clears any maximized/fullscreen/tiled state and restores natural + * geometry of the view before positioning. */ void view_place_by_policy(struct view *view, bool allow_cursor, enum lab_placement_policy policy); diff --git a/src/view.c b/src/view.c index 94c5c2a9..ecbcb7a1 100644 --- a/src/view.c +++ b/src/view.c @@ -652,7 +652,11 @@ view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) int x = (int)seat->cursor->x - (total_width / 2); int y = (int)seat->cursor->y - (total_height / 2); - /* Order of MIN/MAX is significant here */ + /* + * Order of MIN/MAX is significant here (so that the top-left + * corner of the view remains visible even if the view is larger + * than the usable output area) + */ x = MIN(x, usable.x + usable.width - total_width); geom->x = MAX(x, usable.x) + margin.left; y = MIN(y, usable.y + usable.height - total_height); diff --git a/src/xdg.c b/src/xdg.c index a756f9de..b2889a21 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -264,8 +264,9 @@ handle_commit(struct wl_listener *listener, void *data) /* * 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 + * (2) when leaving fullscreen or un-maximizing, if the view + * was initially fullscreen/maximized and the natural + * geometry isn't known yet */ if (wlr_box_empty(&view->pending) && !wlr_box_empty(&size)) { view->pending.width = size.width; diff --git a/src/xwayland.c b/src/xwayland.c index d04d7768..5ddff9df 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -772,6 +772,14 @@ set_initial_position(struct view *view, * View is maximized/fullscreen. Place the * stored natural geometry without actually * moving the view. + * + * FIXME: this positioning will be slightly off + * since it uses border widths computed for the + * current (non-floating) state of the view. + * Possible fixes would be (1) adjust the natural + * geometry earlier, while still floating, or + * (2) add a variant of ssd_thickness() that + * disregards the current view state. */ view_compute_position_by_policy(view, &view->natural_geometry, /* allow_cursor */ true, rc.placement_policy);