From 34e2035badecb6dbbfa343129c9e64db1d62ac24 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 19 May 2026 09:48:14 +0000 Subject: [PATCH] More bits for pane Z index tracking from floating panes, mostly by Michael Grant. --- cmd-break-pane.c | 2 ++ cmd-join-pane.c | 8 ++++++-- format.c | 18 +++++++++++------- layout-custom.c | 9 +++++++++ layout.c | 24 ++++++++++++++++++++++++ tmux.h | 1 + window.c | 49 ++++++++++++++++++++++++++++++++++++++---------- 7 files changed, 92 insertions(+), 19 deletions(-) diff --git a/cmd-break-pane.c b/cmd-break-pane.c index 790b8df2..aad23334 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -96,6 +96,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) } TAILQ_REMOVE(&w->panes, wp, entry); + TAILQ_REMOVE(&w->z_index, wp, zentry); server_client_remove_pane(wp); window_lost_pane(w, wp); layout_close_pane(wp); @@ -104,6 +105,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) options_set_parent(wp->options, w->options); wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); TAILQ_INSERT_HEAD(&w->panes, wp, entry); + TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); w->active = wp; w->latest = tc; diff --git a/cmd-join-pane.c b/cmd-join-pane.c index f8975a67..7ff8859f 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -147,14 +147,18 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) server_client_remove_pane(src_wp); window_lost_pane(src_w, src_wp); TAILQ_REMOVE(&src_w->panes, src_wp, entry); + TAILQ_REMOVE(&src_w->z_index, src_wp, zentry); src_wp->window = dst_w; options_set_parent(src_wp->options, dst_w->options); src_wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); - if (flags & SPAWN_BEFORE) + if (flags & SPAWN_BEFORE) { TAILQ_INSERT_BEFORE(dst_wp, src_wp, entry); - else + TAILQ_INSERT_BEFORE(dst_wp, src_wp, zentry); + } else { TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry); + TAILQ_INSERT_AFTER(&dst_w->z_index, dst_wp, src_wp, zentry); + } layout_assign_pane(lc, src_wp, 0); colour_palette_from_option(&src_wp->palette, src_wp->options); diff --git a/format.c b/format.c index 472316ec..6766427f 100644 --- a/format.c +++ b/format.c @@ -1170,9 +1170,9 @@ format_cb_pane_at_bottom(struct format_tree *ft) status = options_get_number(w->options, "pane-border-status"); if (status == PANE_STATUS_BOTTOM) - flag = (wp->yoff + wp->sy == w->sy - 1); + flag = (wp->yoff + (int)wp->sy == (int)w->sy - 1); else - flag = (wp->yoff + wp->sy == w->sy); + flag = (wp->yoff + (int)wp->sy == (int)w->sy); xasprintf(&value, "%d", flag); return (value); } @@ -2034,7 +2034,7 @@ static void * format_cb_pane_at_right(struct format_tree *ft) { if (ft->wp != NULL) { - if (ft->wp->xoff + ft->wp->sx == ft->wp->window->sx) + if (ft->wp->xoff + (int)ft->wp->sx == (int)ft->wp->window->sx) return (xstrdup("1")); return (xstrdup("0")); } @@ -2045,8 +2045,10 @@ format_cb_pane_at_right(struct format_tree *ft) static void * format_cb_pane_bottom(struct format_tree *ft) { - if (ft->wp != NULL) - return (format_printf("%d", ft->wp->yoff + ft->wp->sy - 1)); + struct window_pane *wp = ft->wp; + + if (wp != NULL) + return (format_printf("%d", wp->yoff + (int)wp->sy - 1)); return (NULL); } @@ -2328,8 +2330,10 @@ format_cb_pane_pb_state(struct format_tree *ft) static void * format_cb_pane_right(struct format_tree *ft) { - if (ft->wp != NULL) - return (format_printf("%d", ft->wp->xoff + ft->wp->sx - 1)); + struct window_pane *wp = ft->wp; + + if (wp != NULL) + return (format_printf("%d", wp->xoff + (int)wp->sx - 1)); return (NULL); } diff --git a/layout-custom.c b/layout-custom.c index aa36d2c4..054be77f 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -288,6 +288,15 @@ layout_parse(struct window *w, const char *layout, char **cause) if (floating_lc != NULL) layout_assign(&wp, floating_lc, PANE_FLOATING); + /* Fix pane Z indexes. */ + while (!TAILQ_EMPTY(&w->z_index)) { + wp = TAILQ_FIRST(&w->z_index); + TAILQ_REMOVE(&w->z_index, wp, zentry); + } + if (floating_lc != NULL) + layout_fix_zindexes(w, floating_lc); + layout_fix_zindexes(w, tiled_lc); + /* Update pane offsets and sizes. */ layout_fix_offsets(w); layout_fix_panes(w, NULL); diff --git a/layout.c b/layout.c index 5afd697b..407c5a05 100644 --- a/layout.c +++ b/layout.c @@ -233,6 +233,30 @@ layout_make_node(struct layout_cell *lc, enum layout_type type) lc->wp = NULL; } +/* Fix Z indexes. */ +void +layout_fix_zindexes(struct window *w, struct layout_cell *lc) +{ + struct layout_cell *lcchild; + + if (lc == NULL) + return; + + switch (lc->type) { + case LAYOUT_WINDOWPANE: + TAILQ_INSERT_TAIL(&w->z_index, lc->wp, zentry); + break; + case LAYOUT_LEFTRIGHT: + case LAYOUT_TOPBOTTOM: + case LAYOUT_FLOATING: + TAILQ_FOREACH(lcchild, &lc->cells, entry) + layout_fix_zindexes(w, lcchild); + return; + default: + fatalx("bad layout type"); + } +} + /* Fix cell offsets for a child cell. */ static void layout_fix_offsets1(struct layout_cell *lc) diff --git a/tmux.h b/tmux.h index 2209732e..5ac1d4f7 100644 --- a/tmux.h +++ b/tmux.h @@ -3438,6 +3438,7 @@ struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_int); void layout_set_size(struct layout_cell *, u_int, u_int, int, int); void layout_make_leaf(struct layout_cell *, struct window_pane *); void layout_make_node(struct layout_cell *, enum layout_type); +void layout_fix_zindexes(struct window *, struct layout_cell *); void layout_fix_offsets(struct window *); void layout_fix_panes(struct window *, struct window_pane *); void layout_resize_adjust(struct window *, struct layout_cell *, diff --git a/window.c b/window.c index 72ccb7cc..ac48246f 100644 --- a/window.c +++ b/window.c @@ -585,6 +585,14 @@ window_redraw_active_switch(struct window *w, struct window_pane *wp) wp->flags |= PANE_REDRAW; } } + + /* If the pane is floating, move to the front. */ + if (wp->flags & PANE_FLOATING) { + TAILQ_REMOVE(&w->z_index, wp, zentry); + TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); + wp->flags |= PANE_REDRAW; + } + if (wp == w->active) break; wp = w->active; @@ -600,18 +608,32 @@ window_get_active_at(struct window *w, u_int x, u_int y) pane_status = options_get_number(w->options, "pane-border-status"); - TAILQ_FOREACH(wp, &w->panes, entry) { + TAILQ_FOREACH(wp, &w->z_index, zentry) { if (!window_pane_visible(wp)) continue; window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy); - if ((int)x < xoff || x > xoff + sx) - continue; - if (pane_status == PANE_STATUS_TOP) { - if ((int)y <= yoff - 2 || y > yoff + sy - 1) + if (~wp->flags & PANE_FLOATING) { + /* Tiled - to and including bottom or right border. */ + if ((int)x < xoff || x > xoff + sx) continue; + if (pane_status == PANE_STATUS_TOP) { + if ((int)y < yoff - 1 || y > yoff + sy) + continue; + } else { + if ((int)y < yoff || y > yoff + sy) + continue; + } } else { - if ((int)y < yoff || y > yoff + sy) + /* Floating - include top or or left border. */ + if ((int)x < xoff - 1 || x > xoff + sx) continue; + if (pane_status == PANE_STATUS_TOP) { + if ((int)y <= yoff - 2 || y > yoff + sy - 1) + continue; + } else { + if ((int)y < yoff - 1 || y > yoff + sy) + continue; + } } return (wp); } @@ -762,6 +784,12 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit, else TAILQ_INSERT_AFTER(&w->panes, other, wp, entry); } + if (~flags & SPAWN_FLOATING) + TAILQ_INSERT_TAIL(&w->z_index, wp, zentry); + else { + TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); + wp->flags |= PANE_FLOATING; + } return (wp); } @@ -794,8 +822,8 @@ void window_remove_pane(struct window *w, struct window_pane *wp) { window_lost_pane(w, wp); - TAILQ_REMOVE(&w->panes, wp, entry); + TAILQ_REMOVE(&w->z_index, wp, zentry); window_pane_destroy(wp); } @@ -861,7 +889,7 @@ window_count_panes(struct window *w, int with_floating) u_int n = 0; TAILQ_FOREACH(wp, &w->panes, entry) { - if (with_floating || ~wp->flags & PANE_FLOATING) + if (with_floating || ~wp->flags & PANE_FLOATING) n++; } return (n); @@ -880,6 +908,7 @@ window_destroy_panes(struct window *w) while (!TAILQ_EMPTY(&w->panes)) { wp = TAILQ_FIRST(&w->panes); TAILQ_REMOVE(&w->panes, wp, entry); + TAILQ_REMOVE(&w->z_index, wp, zentry); window_pane_destroy(wp); } } @@ -1214,7 +1243,7 @@ window_pane_reset_mode_all(struct window_pane *wp) static void window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len) { - struct window_pane *loop; + struct window_pane *loop; TAILQ_FOREACH(loop, &wp->window->panes, entry) { if (loop != wp && @@ -1232,7 +1261,7 @@ window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len) static void window_pane_copy_key(struct window_pane *wp, key_code key) { - struct window_pane *loop; + struct window_pane *loop; TAILQ_FOREACH(loop, &wp->window->panes, entry) { if (loop != wp &&