]> git.mdlowis.com Git - proto/labwc.git/commitdiff
view: honor automatic placement when adjusting floating geometry
authorAndrew J. Hesford <ajh@sideband.org>
Sat, 30 Dec 2023 16:19:27 +0000 (11:19 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sat, 30 Dec 2023 16:50:09 +0000 (16:50 +0000)
The view_adjust_floating_geometry function is called when un-maximizing
a window or changing the output layout to ensure that views are well
placed. Rather than always centering these views should they fall
offscren, use the automatic placement strategy if so configured.

include/placement.h
src/action.c
src/placement.c
src/view.c

index ccbbe4b9726b54047dc5643450a2d254ce999733..99f1ca28fac31cc59dd7e693ab59e476abb8b50f 100644 (file)
@@ -3,8 +3,9 @@
 #define LABWC_PLACEMENT_H
 
 #include <stdbool.h>
+#include <wlr/util/box.h>
 #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 */
index 2259ba7d22b089a7fe35605e17add6de9f4d94cb..dabb31c92d1c4a577b2e9cfab38acc99130fc607 100644 (file)
@@ -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;
index 1643cdb8c64888168d27b0bc22090446c8288af7..c2a724af079a542bec44eeff3e91c872c414192f 100644 (file)
@@ -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. */
index f0562f9f1d6fb86cc0095f0c30571fd9a7c82eea..f521b449028bfb45c654648f2358f9239d934dba 100644 (file)
@@ -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;
                }
        }