]> git.mdlowis.com Git - proto/labwc.git/commitdiff
view: ensure midpoint is visible on layout change
authorAndrew J. Hesford <ajh@sideband.org>
Thu, 25 Jan 2024 15:45:59 +0000 (10:45 -0500)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 25 Jan 2024 19:22:10 +0000 (20:22 +0100)
Fixes: #1476.
include/view.h
src/view.c

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