diff --git a/layout.c b/layout.c index 21d78880c..377fdea33 100644 --- a/layout.c +++ b/layout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout.c,v 1.99 2026/09/09 07:03:39 nicm Exp $ */ +/* $OpenBSD: layout.c,v 1.100 2026/09/11 08:16:14 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -768,6 +768,49 @@ layout_free(struct window *w, int only_nodes) layout_free_cell(w->layout_root, only_nodes); } +/* Move and resize floating panes so they stay inside the window. */ +static void +layout_clamp_floating_panes(struct window *w, u_int sx, u_int sy) +{ + struct window_pane *wp; + struct layout_cell *lc; + u_int pad, avail, csx, csy; + + TAILQ_FOREACH(wp, &w->z_index, zentry) { + lc = wp->layout_cell; + if (lc == NULL || (~lc->flags & LAYOUT_CELL_FLOATING)) + continue; + if (window_pane_get_pane_lines(wp) == PANE_LINES_NONE) + pad = 0; + else + pad = 1; + + csx = lc->g.sx; + avail = (sx > 2 * pad) ? sx - 2 * pad : 0; + if (csx > avail) + csx = (avail > PANE_MINIMUM) ? avail : PANE_MINIMUM; + csy = lc->g.sy; + avail = (sy > 2 * pad) ? sy - 2 * pad : 0; + if (csy > avail) + csy = (avail > PANE_MINIMUM) ? avail : PANE_MINIMUM; + if (csx != lc->g.sx || csy != lc->g.sy) + layout_set_size(lc, csx, csy, lc->g.xoff, lc->g.yoff); + + if (lc->g.xoff + lc->g.sx + pad > sx) { + if (lc->g.sx + 2 * pad >= sx) + lc->g.xoff = pad; + else + lc->g.xoff = sx - lc->g.sx - pad; + } + if (lc->g.yoff + lc->g.sy + pad > sy) { + if (lc->g.sy + 2 * pad >= sy) + lc->g.yoff = pad; + else + lc->g.yoff = sy - lc->g.sy - pad; + } + } +} + /* Resize the entire layout after window resize. */ void layout_resize(struct window *w, u_int sx, u_int sy) @@ -788,8 +831,11 @@ layout_resize(struct window *w, u_int sx, u_int sy) * out proportionately - this should leave the layout fitting the new * window size. */ - if (lc->type == LAYOUT_WINDOWPANE && (lc->flags & LAYOUT_CELL_FLOATING)) + if (lc->type == LAYOUT_WINDOWPANE && (lc->flags & LAYOUT_CELL_FLOATING)) { + layout_clamp_floating_panes(w, sx, sy); + layout_fix_panes(w, NULL); return; + } xchange = sx - lc->g.sx; xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT); if (xchange < 0 && xchange < -xlimit) @@ -819,6 +865,7 @@ layout_resize(struct window *w, u_int sx, u_int sy) /* Fix cell offsets. */ layout_fix_offsets(w); + layout_clamp_floating_panes(w, sx, sy); layout_fix_panes(w, NULL); }