view: ensure midpoint is visible on layout change

Fixes: #1476.
This commit is contained in:
Andrew J. Hesford 2024-01-25 10:45:59 -05:00 committed by Consolatis
parent 21d816edb2
commit 9ecd8c2b43
2 changed files with 43 additions and 29 deletions

View file

@ -392,7 +392,6 @@ void view_moved(struct view *view);
void view_minimize(struct view *view, bool minimized); void view_minimize(struct view *view, bool minimized);
bool view_compute_centered_position(struct view *view, bool view_compute_centered_position(struct view *view,
const struct wlr_box *ref, int w, int h, int *x, int *y); const struct wlr_box *ref, int w, int h, int *x, int *y);
bool view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry);
void view_store_natural_geometry(struct view *view); void view_store_natural_geometry(struct view *view);
/** /**

View file

@ -611,10 +611,12 @@ view_compute_centered_position(struct view *view, const struct wlr_box *ref,
return true; return true;
} }
bool static bool
view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry) adjust_floating_geometry(struct view *view, struct wlr_box *geometry,
bool midpoint_visibility)
{ {
assert(view); assert(view);
if (!output_is_usable(view->output)) { if (!output_is_usable(view->output)) {
wlr_log(WLR_ERROR, "view has no output, not positioning"); wlr_log(WLR_ERROR, "view has no output, not positioning");
return false; return false;
@ -627,16 +629,10 @@ view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry)
} }
bool adjusted = false; bool adjusted = false;
/* bool onscreen = false;
* First check whether the view is the target screen, meaning that at
* least one client pixel is on the screen.
*/
if (wlr_output_layout_intersects(view->server->output_layout, if (wlr_output_layout_intersects(view->server->output_layout,
view->output->wlr_output, geometry)) { view->output->wlr_output, geometry)) {
/* /* Always make sure the titlebar starts within the usable area */
* If onscreen, then make sure the titlebar is also
* visible (and not overlapping any panels/docks)
*/
struct border margin = ssd_get_margin(view->ssd); struct border margin = ssd_get_margin(view->ssd);
struct wlr_box usable = struct wlr_box usable =
output_usable_area_in_layout_coords(view->output); output_usable_area_in_layout_coords(view->output);
@ -645,15 +641,33 @@ view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry)
geometry->x = usable.x + margin.left; geometry->x = usable.x + margin.left;
adjusted = true; adjusted = true;
} }
if (geometry->y < usable.y + margin.top) { if (geometry->y < usable.y + margin.top) {
geometry->y = usable.y + margin.top; geometry->y = usable.y + margin.top;
adjusted = true; adjusted = true;
} }
} else {
if (!midpoint_visibility) {
/* /*
* Reposition offscreen views; if automatic placement is * If midpoint visibility is not required, the view is
* configured, try to automatically place the windows. * on screen if at least one pixel is visible.
*/ */
onscreen = true;
} else {
/* Otherwise, make sure the midpoint is on screen */
int mx = geometry->x + geometry->width / 2;
int my = geometry->y + geometry->height / 2;
onscreen = mx <= usable.x + usable.width &&
my <= usable.y + usable.height;
}
}
if (onscreen) {
return adjusted;
}
/* Reposition offscreen automatically if configured to do so */
if (rc.placement_policy == LAB_PLACE_AUTOMATIC) { if (rc.placement_policy == LAB_PLACE_AUTOMATIC) {
if (placement_find_best(view, geometry)) { if (placement_find_best(view, geometry)) {
return true; return true;
@ -661,12 +675,10 @@ view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry)
} }
/* If automatic placement failed or was not enabled, just center */ /* If automatic placement failed or was not enabled, just center */
adjusted = view_compute_centered_position(view, NULL, return view_compute_centered_position(view, NULL,
geometry->width, geometry->height, geometry->width, geometry->height,
&geometry->x, &geometry->y); &geometry->x, &geometry->y);
} }
return adjusted;
}
static void static void
set_fallback_geometry(struct view *view) set_fallback_geometry(struct view *view)
@ -797,7 +809,8 @@ view_apply_natural_geometry(struct view *view)
assert(view_is_floating(view)); assert(view_is_floating(view));
struct wlr_box geometry = view->natural_geometry; struct wlr_box geometry = view->natural_geometry;
view_adjust_floating_geometry(view, &geometry); adjust_floating_geometry(view, &geometry,
/* midpoint_visibility */ false);
view_move_resize(view, geometry); view_move_resize(view, geometry);
} }
@ -1352,7 +1365,8 @@ apply_last_layout_geometry(struct view *view, bool force_update)
} }
view->natural_geometry = view->last_layout_geometry; view->natural_geometry = view->last_layout_geometry;
view_adjust_floating_geometry(view, &view->natural_geometry); adjust_floating_geometry(view, &view->natural_geometry,
/* midpoint_visibility */ true);
return true; return true;
} }
@ -1432,7 +1446,8 @@ view_adjust_for_layout_change(struct view *view)
} else { } else {
/* Otherwise, just ensure the view is on screen. */ /* Otherwise, just ensure the view is on screen. */
struct wlr_box geometry = view->pending; struct wlr_box geometry = view->pending;
if (view_adjust_floating_geometry(view, &geometry)) { if (adjust_floating_geometry(view, &geometry,
/* midpoint_visibility */ true)) {
view_move_resize(view, geometry); view_move_resize(view, geometry);
} }
} }