From f38558ee125df79bc0a84e686c54b22f95ceb2be 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 | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/layout.c b/layout.c index e992a3066..74c3c29bb 100644 --- a/layout.c +++ b/layout.c @@ -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); }