From 395ea6687b2dfa334bcafcc2a78c81032ca15bd0 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 28 Sep 2026 10:10:16 +0000 Subject: [PATCH] Fix floating panes not being detected as obscuring the pane behind them, GitHub issue 5641 from Michael Grant. (cherry picked from commit bbecdc802fd79c0917a9bc742a29aa2b94afcdfc) --- screen-write.c | 12 ++---------- tmux.h | 4 +++- window.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/screen-write.c b/screen-write.c index 1b101ed94..c84e6e5fd 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.290 2026/08/24 15:05:26 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.294 2026/09/28 10:10:16 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -199,15 +199,7 @@ screen_write_pane_is_obscured(struct screen_write_ctx *ctx) } while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) { - if (window_pane_is_floating(wp) && - ((wp->yoff >= ctx->wp->yoff && - wp->yoff <= ctx->wp->yoff + (int)ctx->wp->sy) || - (wp->yoff + (int)wp->sy >= ctx->wp->yoff && - wp->yoff + wp->sy <= ctx->wp->yoff + ctx->wp->sy)) && - ((wp->xoff >= ctx->wp->xoff && - wp->xoff <= ctx->wp->xoff + (int)ctx->wp->sx) || - (wp->xoff + (int)wp->sx >= ctx->wp->xoff && - wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) { + if (window_pane_floating_overlaps(wp, ctx->wp)) { ctx->flags |= SCREEN_WRITE_OBSCURED; return (1); } diff --git a/tmux.h b/tmux.h index 4555fea2b..d58c40aa3 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1447 2026/09/22 14:10:26 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1449 2026/09/28 10:10:16 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3729,6 +3729,8 @@ struct window_pane *window_find_string(struct window *, const char *); int window_has_floating_panes(struct window *); int window_has_pane(struct window *, struct window_pane *); int window_pane_contains(struct window_pane *, u_int, u_int); +int window_pane_floating_overlaps(struct window_pane *, + struct window_pane *); int window_set_active_pane(struct window *, struct window_pane *, int); void window_fire_pane_moved(struct window_pane *, struct window *, diff --git a/window.c b/window.c index b8d9606be..dba25aba1 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.380 2026/09/28 09:56:05 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.381 2026/09/28 10:10:16 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -667,6 +667,34 @@ window_pane_contains(struct window_pane *wp, u_int x, u_int y) return (1); } +/* + * Does floating pane, including its borders and scrollbar, overlap any cell of + * another pane, including its scrollbar? + */ +int +window_pane_floating_overlaps(struct window_pane *fwp, struct window_pane *wp) +{ + int fxoff, fyoff, xoff, yoff, border = 0; + u_int fsx, fsy, sx, sy; + + if (!window_pane_is_floating(fwp)) + return (0); + + window_pane_full_size_offset(fwp, &fxoff, &fyoff, &fsx, &fsy); + window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy); + + if (window_pane_get_pane_lines(fwp) != PANE_LINES_NONE) + border = 1; + + if (fxoff - border >= xoff + (int)sx || + fxoff + (int)fsx + border <= xoff) + return (0); + if (fyoff - border >= yoff + (int)sy || + fyoff + (int)fsy + border <= yoff) + return (0); + return (1); +} + void window_update_focus(struct window *w) {