diff --git a/include/placement.h b/include/placement.h index ccbbe4b9..99f1ca28 100644 --- a/include/placement.h +++ b/include/placement.h @@ -3,8 +3,9 @@ #define LABWC_PLACEMENT_H #include +#include #include "view.h" -bool placement_find_best(struct view *view, int *x, int *y); +bool placement_find_best(struct view *view, struct wlr_box *geometry); #endif /* LABWC_PLACEMENT_H */ diff --git a/src/action.c b/src/action.c index 2259ba7d..dabb31c9 100644 --- a/src/action.c +++ b/src/action.c @@ -945,9 +945,9 @@ actions_run(struct view *activator, struct server *server, 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; diff --git a/src/placement.c b/src/placement.c index 1643cdb8..c2a724af 100644 --- a/src/placement.c +++ b/src/placement.c @@ -396,11 +396,13 @@ compute_overlap(struct overlap_bitmap *bmp, int i, int j, } /* - * 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); @@ -416,16 +418,16 @@ placement_find_best(struct view *view, int *x, int *y) /* 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; @@ -484,18 +486,18 @@ placement_find_best(struct view *view, int *x, int *y) 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. */ diff --git a/src/view.c b/src/view.c index f0562f9f..f521b449 100644 --- a/src/view.c +++ b/src/view.c @@ -636,7 +636,17 @@ view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry) 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); @@ -698,9 +708,9 @@ view_place_initial(struct view *view) 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; } }