From f8fc53b6f8a61761cd28a75c69d8e5fd06cbe578 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 11 Sep 2026 08:16:14 +0000 Subject: [PATCH] Rather than allowing floating panes to remain outside the window and invisible after resize, move them and resize them so they are fully inside the window. GitHub issue 5582 from Noam Stolero. --- layout.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) 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); }