diff --git a/cmd-display-menu.c b/cmd-display-menu.c index cb5c97df1..f9627ca67 100644 --- a/cmd-display-menu.c +++ b/cmd-display-menu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-display-menu.c,v 1.54 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: cmd-display-menu.c,v 1.55 2026/09/21 12:14:32 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -285,8 +285,8 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) enum box_lines lines = BOX_LINES_DEFAULT; char *title, *cause = NULL; int flags = 0, starting_choice = 0; - u_int px, py, i, count = args_count(args); - struct options *o = target->s->curw->window->options; + u_int px, py, sx, sy, i, count = args_count(args); + struct options *o = target->w->options; struct options_entry *oe; if (args_has(args, 'C')) { @@ -334,9 +334,6 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) } if (menu->count == 0) goto out; - if (!cmd_display_menu_get_menu_pos(tc, item, args, &px, &py, - menu->width + 4, menu->count + 2)) - goto out; value = args_get(args, 'b'); if (value != NULL) { @@ -347,7 +344,11 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "menu-border-lines %s", cause); goto fail; } - } + } else + lines = options_get_number(o, "menu-border-lines"); + menu_get_size(menu, lines, &sx, &sy); + if (!cmd_display_menu_get_menu_pos(tc, item, args, &px, &py, sx, sy)) + goto out; if (args_has(args, 'O')) flags |= MENU_STAYOPEN; diff --git a/cmd-join-pane.c b/cmd-join-pane.c index 34bc95c8e..44d79cafb 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-join-pane.c,v 1.74 2026/08/03 20:29:52 nicm Exp $ */ +/* $OpenBSD: cmd-join-pane.c,v 1.75 2026/09/21 10:33:16 nicm Exp $ */ /* * Copyright (c) 2011 George Nachman @@ -133,7 +133,7 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl, } else if (strcmp(position, "back") == 0) { TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_FOREACH(owp, &w->z_index, zentry) { - if (!window_pane_is_floating(owp)) + if (!window_pane_is_floating_with_hidden(owp)) break; } if (owp != NULL) @@ -142,24 +142,30 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl, TAILQ_INSERT_TAIL(&w->z_index, wp, zentry); } else if (strcmp(position, "forward") == 0) { owp = TAILQ_PREV(wp, window_panes_zindex, zentry); + while (owp != NULL && owp->layout_cell == NULL) + owp = TAILQ_PREV(owp, window_panes_zindex, zentry); if (owp != NULL) { TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_INSERT_BEFORE(owp, wp, zentry); } } else if (strcmp(position, "backward") == 0) { owp = TAILQ_NEXT(wp, zentry); + while (owp != NULL && owp->layout_cell == NULL) + owp = TAILQ_NEXT(owp, zentry); if (owp != NULL && window_pane_is_floating(owp)) { TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry); } } else if (strcmp(position, "forward-loop") == 0) { owp = TAILQ_PREV(wp, window_panes_zindex, zentry); + while (owp != NULL && owp->layout_cell == NULL) + owp = TAILQ_PREV(owp, window_panes_zindex, zentry); TAILQ_REMOVE(&w->z_index, wp, zentry); if (owp != NULL) TAILQ_INSERT_BEFORE(owp, wp, zentry); else { TAILQ_FOREACH(owp, &w->z_index, zentry) { - if (!window_pane_is_floating(owp)) + if (!window_pane_is_floating_with_hidden(owp)) break; } if (owp != NULL) @@ -169,6 +175,8 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl, } } else if (strcmp(position, "backward-loop") == 0) { owp = TAILQ_NEXT(wp, zentry); + while (owp != NULL && owp->layout_cell == NULL) + owp = TAILQ_NEXT(owp, zentry); if (owp != NULL && window_pane_is_floating(owp)) { TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry); @@ -347,8 +355,10 @@ cmd_join_pane_zindex(struct cmdq_item *item, struct winlink *wl, n = 0; TAILQ_FOREACH(owp, &w->z_index, zentry) { - if (!window_pane_is_floating(owp)) + if (!window_pane_is_floating_with_hidden(owp)) break; + if (owp->layout_cell == NULL) + continue; if (n >= z) break; n++; @@ -443,7 +453,6 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "pane is not floating"); return (CMD_RETURN_ERROR); } - server_unzoom_window(dst_w); if ((s = args_get(args, 'P')) != NULL) return (cmd_join_pane_place(item, dst_wl, dst_wp, s)); if ((s = args_get(args, 'z')) != NULL) diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index fc5062ab4..c644dd783 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-resize-pane.c,v 1.68 2026/08/31 07:44:39 nicm Exp $ */ +/* $OpenBSD: cmd-resize-pane.c,v 1.69 2026/09/21 10:33:16 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -91,7 +91,8 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) server_redraw_window(w); return (CMD_RETURN_NORMAL); } - server_unzoom_window(w); + if (!window_pane_is_floating(wp)) + server_unzoom_window(w); lc = wp->layout_cell; /* may have been replaced by unzoom */ if (args_has(args, 'x')) { diff --git a/menu.c b/menu.c index 2816056a4..cb087296e 100644 --- a/menu.c +++ b/menu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: menu.c,v 1.70 2026/08/17 07:33:55 nicm Exp $ */ +/* $OpenBSD: menu.c,v 1.71 2026/09/21 12:14:32 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -51,6 +51,18 @@ struct menu_data { void *data; }; +void +menu_get_size(struct menu *menu, enum box_lines lines, u_int *sx, u_int *sy) +{ + if (lines == BOX_LINES_NONE) { + *sx = menu->item_width + 2; + *sy = menu->count; + } else { + *sx = menu->width + 4; + *sy = menu->count + 2; + } +} + void menu_add_items(struct menu *menu, const struct menu_item *items, struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs) @@ -142,6 +154,8 @@ menu_add_item(struct menu *menu, const struct menu_item *item, width = format_width(new_item->name); if (*new_item->name == '-') width--; + if (width > menu->item_width) + menu->item_width = width; if (width > menu->width) menu->width = width; } @@ -238,7 +252,7 @@ menu_update(struct menu_data *md) screen_write_clearscreen(&ctx, 8); if (md->border_lines != BOX_LINES_NONE) { - screen_write_box(&ctx, menu->width + 4, menu->count + 2, + screen_write_box(&ctx, menu_width(md), menu_height(md), md->border_lines, &md->border_style_gc, menu->title); } @@ -286,11 +300,13 @@ menu_destroy(struct window *w) void menu_get_cursor(struct menu_data *md, u_int *cx, u_int *cy) { - *cx = md->px + 2; + u_int border = (md->border_lines != BOX_LINES_NONE); + + *cx = md->px + 1 + border; if (md->choice == -1) *cy = md->py; else - *cy = md->py + 1 + md->choice; + *cy = md->py + border + md->choice; } struct screen * @@ -302,13 +318,19 @@ menu_screen(struct menu_data *md) u_int menu_width(struct menu_data *md) { - return (md->menu->width + 4); + u_int sx, sy; + + menu_get_size(md->menu, md->border_lines, &sx, &sy); + return (sx); } u_int menu_height(struct menu_data *md) { - return (md->menu->count + 2); + u_int sx, sy; + + menu_get_size(md->menu, md->border_lines, &sx, &sy); + return (sy); } u_int @@ -338,6 +360,7 @@ menu_key(struct client *c, struct menu_data *md, struct key_event *event) enum cmd_parse_status status; char *error; key_code key; + u_int border; if (KEYC_IS_MOUSE(event->key)) { /* @@ -353,10 +376,10 @@ menu_key(struct client *c, struct menu_data *md, struct key_event *event) return (1); return (0); } - if (m->x < md->px || - m->x > md->px + 4 + menu->width || - m->y < md->py + 1 || - m->y > md->py + 1 + n - 1) { + border = (md->border_lines != BOX_LINES_NONE); + if (m->x < md->px || m->x >= md->px + menu_width(md) || + m->y < md->py + border || + m->y >= md->py + border + n) { if (~md->flags & MENU_STAYOPEN) { if (!move && MOUSE_RELEASE(m->b)) return (1); @@ -379,7 +402,7 @@ menu_key(struct client *c, struct menu_data *md, struct key_event *event) if (!MOUSE_WHEEL(m->b) && !MOUSE_DRAG(m->b)) goto chosen; } - md->choice = m->y - (md->py + 1); + md->choice = m->y - (md->py + border); if (md->choice != old) server_redraw_window_menu(md->w); return (0); @@ -546,20 +569,16 @@ menu_resize(struct menu_data *md, struct window *w) if (md == NULL) return; - nx = md->px; ny = md->py; - sx = md->menu->width + 4; - sy = md->menu->count + 2; - + menu_get_size(md->menu, md->border_lines, &sx, &sy); if (nx + sx > w->sx) { if (w->sx <= sx) nx = 0; else nx = w->sx - sx; } - if (ny + sy > w->sy) { if (w->sy <= sy) ny = 0; @@ -591,8 +610,9 @@ menu_display(struct menu *menu, int flags, int starting_choice, w = fs->w; o = w->options; - sx = menu->width + 4; - sy = menu->count + 2; + if (lines == BOX_LINES_DEFAULT) + lines = options_get_number(o, "menu-border-lines"); + menu_get_size(menu, lines, &sx, &sy); if (sx >= w->sx) px = 0; else if (px + sx > w->sx) @@ -604,9 +624,6 @@ menu_display(struct menu *menu, int flags, int starting_choice, w->menu_last_px = px; w->menu_last_py = py; - if (lines == BOX_LINES_DEFAULT) - lines = options_get_number(o, "menu-border-lines"); - md = xcalloc(1, sizeof *md); md->w = w; md->flags = flags; diff --git a/mode-tree.c b/mode-tree.c index 5132eb94c..bc31a5ba4 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mode-tree.c,v 1.101 2026/08/05 07:50:21 nicm Exp $ */ +/* $OpenBSD: mode-tree.c,v 1.102 2026/09/21 12:14:32 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -1375,12 +1375,14 @@ static void mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x, u_int y, int outside) { + struct window *w = mtd->wp->window; struct mode_tree_item *mti; struct menu *menu; const struct menu_item *items; struct mode_tree_menu *mtm; char *title; - u_int line; + enum box_lines lines; + u_int line, sx, sy; if (mtd->offset + y > mtd->line_size - 1) line = mtd->current; @@ -1405,14 +1407,17 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x, mtm->line = line; mtd->references++; - if (x >= (menu->width + 4) / 2) - x -= (menu->width + 4) / 2; + lines = options_get_number(w->options, "menu-border-lines"); + menu_get_size(menu, lines, &sx, &sy); + if (x >= sx / 2) + x -= sx / 2; else x = 0; x += mtd->wp->xoff; y += mtd->wp->yoff; - if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL, - NULL, NULL, NULL, mode_tree_menu_callback, mtm) != 0) { + + if (menu_display(menu, 0, 0, NULL, x, y, c, lines, NULL, NULL, NULL, + NULL, mode_tree_menu_callback, mtm) != 0) { mode_tree_remove_ref(mtd); free(mtm); menu_free(menu); diff --git a/screen-write.c b/screen-write.c index 8566206ea..b92e0a0c9 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.291 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.292 2026/09/21 12:14:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -833,34 +833,39 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice, struct screen *s = ctx->s; struct grid_cell default_gc; const struct grid_cell *gc = &default_gc; - u_int cx, cy, i, j, width = menu->width; + u_int border, cx = s->cx, cy = s->cy, i, j, width; const char *name; - cx = s->cx; - cy = s->cy; - memcpy(&default_gc, menu_gc, sizeof default_gc); - screen_write_box(ctx, menu->width + 4, menu->count + 2, lines, - border_gc, menu->title); + if (lines == BOX_LINES_NONE) { + border = 0; + width = menu->item_width; + } else { + border = 1; + width = menu->width; + screen_write_box(ctx, width + 4, menu->count + 2, lines, + border_gc, menu->title); + } for (i = 0; i < menu->count; i++) { name = menu->items[i].name; if (name == NULL) { - screen_write_cursormove(ctx, cx, cy + 1 + i, 0); - screen_write_hline(ctx, width + 4, 1, 1, lines, - border_gc); + screen_write_cursormove(ctx, cx, cy + border + i, 0); + screen_write_hline(ctx, width + 2 + (2 * border), 1, 1, + lines, border_gc); continue; } if (choice >= 0 && i == (u_int)choice && *name != '-') gc = choice_gc; - screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0); + screen_write_cursormove(ctx, cx + border, cy + border + i, 0); for (j = 0; j < width + 2; j++) screen_write_putc(ctx, gc, ' '); - screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0); + screen_write_cursormove(ctx, cx + border + 1, cy + border + i, + 0); if (*name == '-') { default_gc.attr |= GRID_ATTR_DIM; format_draw(ctx, gc, width, name + 1, NULL, 0); diff --git a/tmux.h b/tmux.h index fb7238bb8..c5a1095e3 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1442 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1444 2026/09/21 12:14:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1182,6 +1182,7 @@ struct menu { struct menu_item *items; u_int count; u_int width; + u_int item_width; }; typedef void (*menu_choice_cb)(struct menu *, u_int, key_code, void *); @@ -3804,6 +3805,7 @@ int window_pane_get_pane_status(struct window_pane *); struct style_range *window_pane_status_get_range(struct window_pane *, u_int, u_int); int window_pane_is_floating(struct window_pane *); +int window_pane_is_floating_with_hidden(struct window_pane *); /* window-border.c */ void window_set_fill_cells(struct window *); @@ -4143,6 +4145,7 @@ void menu_add_item(struct menu *, const struct menu_item *, struct cmdq_item *, struct client *, struct cmd_find_state *); void menu_free(struct menu *); +void menu_get_size(struct menu *, enum box_lines, u_int *, u_int *); int menu_display(struct menu *, int, int, struct cmdq_item *, u_int, u_int, struct client *, enum box_lines, const char *, const char *, const char *, struct cmd_find_state *, diff --git a/window-copy.c b/window-copy.c index 3d33f3f86..fd42e91bd 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.430 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.431 2026/09/21 10:43:37 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -401,7 +401,7 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx, sy = screen_hsize(src) + screen_size_y(src); if (trim) { - while (sy > screen_hsize(src)) { + while (sy > screen_hsize(src) + 1) { gl = grid_peek_line(src->grid, sy - 1); if (gl == NULL || gl->cellused != 0) break; diff --git a/window.c b/window.c index 7c55be7d5..01cdb3df1 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.376 2026/09/21 10:22:31 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.377 2026/09/21 10:33:16 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2913,3 +2913,15 @@ window_pane_is_floating(struct window_pane *wp) return (0); return (1); } + +int +window_pane_is_floating_with_hidden(struct window_pane *wp) +{ + struct layout_cell *lc = wp->layout_cell; + + if (lc == NULL) + lc = wp->saved_layout_cell; + if (lc == NULL || (lc->flags & LAYOUT_CELL_FLOATING) == 0) + return (0); + return (1); +}