break;
case ACTION_TYPE_AUTO_PLACE:
if (view) {
- int x = 0, y = 0;
- if (placement_find_best(view, &x, &y)) {
- view_move(view, x, y);
+ struct wlr_box geometry = view->pending;
+ if (placement_find_best(view, &geometry)) {
+ view_move(view, geometry.x, geometry.y);
}
}
break;
}
/*
- * Find, in (*x, *y), the placement of *view on its output that will minimize
- * overlap with all other views.
+ * Find the placement of *view, with an expected width and height of
+ * geometry->width and geometry->height, respectively, that will minimize
+ * overlap with all other views. The values geometry->x and geometry->y will be
+ * overwritten with the optimum placement.
*/
bool
-placement_find_best(struct view *view, int *x, int *y)
+placement_find_best(struct view *view, struct wlr_box *geometry)
{
assert(view);
/* Default placement is just the upper-left corner of the output */
struct wlr_box usable = output_usable_area_in_layout_coords(output);
- *x = usable.x + margin.left;
- *y = usable.y + margin.top;
+ geometry->x = usable.x + margin.left;
+ geometry->y = usable.y + margin.top;
/* Build the placement grid and overlap bitmap */
struct overlap_bitmap bmp = { 0 };
build_grid(&bmp, view);
build_overlap(&bmp, view);
- int height = view->pending.height + margin.top + margin.bottom;
- int width = view->pending.width + margin.left + margin.right;
+ int height = geometry->height + margin.top + margin.bottom;
+ int width = geometry->width + margin.left + margin.right;
int min_overlap = INT_MAX;
if (rt) {
/* Extend window right from left edge */
- *x = bmp.cols[j] + margin.left;
+ geometry->x = bmp.cols[j] + margin.left;
} else {
/* Extend window left from right edge */
- *x = bmp.cols[j + 1] - width + margin.left;
+ geometry->x = bmp.cols[j + 1] - width + margin.left;
}
if (dn) {
/* Extend window down from top edge */
- *y = bmp.rows[i] + margin.top;
+ geometry->y = bmp.rows[i] + margin.top;
} else {
/* Extend window up from bottom edge */
- *y = bmp.rows[i + 1] - height + margin.top;
+ geometry->y = bmp.rows[i + 1] - height + margin.top;
}
/* If there is no overlap, the search is done. */
adjusted = true;
}
} else {
- /* If offscreen, then just center the view */
+ /*
+ * Reposition offscreen views; if automatic placement was is
+ * configured, try to automatically place the windows.
+ */
+ if (rc.placement_policy == LAB_PLACE_AUTOMATIC) {
+ if (placement_find_best(view, geometry)) {
+ return true;
+ }
+ }
+
+ /* If automatic placement failed or was not enabled, just center */
adjusted = view_compute_centered_position(view, NULL,
geometry->width, geometry->height,
&geometry->x, &geometry->y);
view_move_to_cursor(view);
return;
} else if (rc.placement_policy == LAB_PLACE_AUTOMATIC) {
- int x = 0, y = 0;
- if (placement_find_best(view, &x, &y)) {
- view_move(view, x, y);
+ struct wlr_box geometry = view->pending;
+ if (placement_find_best(view, &geometry)) {
+ view_move(view, geometry.x, geometry.y);
return;
}
}