mirror of
https://github.com/tmux/tmux.git
synced 2026-09-21 20:37:42 +00:00
Compare commits
17 Commits
display-me
...
release_3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a34d2b6b21 | ||
|
|
550231e83a | ||
|
|
102d5185c1 | ||
|
|
1d9029c8d7 | ||
|
|
a23ff880a2 | ||
|
|
32dc7d5095 | ||
|
|
06ef15955c | ||
|
|
ce9bdf6734 | ||
|
|
757b15f2ca | ||
|
|
fcb4e9760a | ||
|
|
03436d273a | ||
|
|
7fdb1c90b7 | ||
|
|
55012ded8d | ||
|
|
de04ae2c65 | ||
|
|
3b931d9c20 | ||
|
|
6f387eec2b | ||
|
|
80f522f577 |
@@ -115,15 +115,11 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* -c is intended to be the client where the message should be
|
* -c is intended to be the client where the message should be
|
||||||
* displayed if -p is not given, but it makes sense to use it for the
|
* displayed if -p is not given. But it makes sense to use it for the
|
||||||
* client formats too. If it was given explicitly, use it even when it
|
* formats too, assuming it matches the session. If it doesn't, use the
|
||||||
* is not in the target session, since the formats should describe the
|
* best client for the session.
|
||||||
* client which was asked for; the session, window and pane formats
|
|
||||||
* still come from the target. Otherwise it is just the current client,
|
|
||||||
* so only use it if it matches the session and fall back to the best
|
|
||||||
* client for the session if not.
|
|
||||||
*/
|
*/
|
||||||
if (tc != NULL && (args_has(args, 'c') || tc->session == s))
|
if (tc != NULL && tc->session == s)
|
||||||
c = tc;
|
c = tc;
|
||||||
else if (s != NULL)
|
else if (s != NULL)
|
||||||
c = cmd_find_best_client(s);
|
c = cmd_find_best_client(s);
|
||||||
|
|||||||
@@ -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 <tmux@georgester.com>
|
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
|
||||||
@@ -133,7 +133,7 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
|
|||||||
} else if (strcmp(position, "back") == 0) {
|
} else if (strcmp(position, "back") == 0) {
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
||||||
if (!window_pane_is_floating(owp))
|
if (!window_pane_is_floating_with_hidden(owp))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (owp != NULL)
|
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);
|
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
|
||||||
} else if (strcmp(position, "forward") == 0) {
|
} else if (strcmp(position, "forward") == 0) {
|
||||||
owp = TAILQ_PREV(wp, window_panes_zindex, zentry);
|
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) {
|
if (owp != NULL) {
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
TAILQ_INSERT_BEFORE(owp, wp, zentry);
|
TAILQ_INSERT_BEFORE(owp, wp, zentry);
|
||||||
}
|
}
|
||||||
} else if (strcmp(position, "backward") == 0) {
|
} else if (strcmp(position, "backward") == 0) {
|
||||||
owp = TAILQ_NEXT(wp, zentry);
|
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)) {
|
if (owp != NULL && window_pane_is_floating(owp)) {
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry);
|
TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry);
|
||||||
}
|
}
|
||||||
} else if (strcmp(position, "forward-loop") == 0) {
|
} else if (strcmp(position, "forward-loop") == 0) {
|
||||||
owp = TAILQ_PREV(wp, window_panes_zindex, zentry);
|
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);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
if (owp != NULL)
|
if (owp != NULL)
|
||||||
TAILQ_INSERT_BEFORE(owp, wp, zentry);
|
TAILQ_INSERT_BEFORE(owp, wp, zentry);
|
||||||
else {
|
else {
|
||||||
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
||||||
if (!window_pane_is_floating(owp))
|
if (!window_pane_is_floating_with_hidden(owp))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (owp != NULL)
|
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) {
|
} else if (strcmp(position, "backward-loop") == 0) {
|
||||||
owp = TAILQ_NEXT(wp, zentry);
|
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)) {
|
if (owp != NULL && window_pane_is_floating(owp)) {
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
TAILQ_INSERT_AFTER(&w->z_index, owp, 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;
|
n = 0;
|
||||||
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
TAILQ_FOREACH(owp, &w->z_index, zentry) {
|
||||||
if (!window_pane_is_floating(owp))
|
if (!window_pane_is_floating_with_hidden(owp))
|
||||||
break;
|
break;
|
||||||
|
if (owp->layout_cell == NULL)
|
||||||
|
continue;
|
||||||
if (n >= z)
|
if (n >= z)
|
||||||
break;
|
break;
|
||||||
n++;
|
n++;
|
||||||
@@ -443,7 +453,6 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cmdq_error(item, "pane is not floating");
|
cmdq_error(item, "pane is not floating");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
server_unzoom_window(dst_w);
|
|
||||||
if ((s = args_get(args, 'P')) != NULL)
|
if ((s = args_get(args, 'P')) != NULL)
|
||||||
return (cmd_join_pane_place(item, dst_wl, dst_wp, s));
|
return (cmd_join_pane_place(item, dst_wl, dst_wp, s));
|
||||||
if ((s = args_get(args, 'z')) != NULL)
|
if ((s = args_get(args, 'z')) != NULL)
|
||||||
|
|||||||
@@ -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 <nicholas.marriott@gmail.com>
|
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -91,7 +91,8 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
return (CMD_RETURN_NORMAL);
|
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 */
|
lc = wp->layout_cell; /* may have been replaced by unzoom */
|
||||||
|
|
||||||
if (args_has(args, 'x')) {
|
if (args_has(args, 'x')) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: cmd-run-shell.c,v 1.94 2026/08/25 06:04:33 nicm Exp $ */
|
/* $OpenBSD: cmd-run-shell.c,v 1.95 2026/09/20 07:59:55 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
|
||||||
@@ -164,7 +164,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (cdata->client != NULL)
|
if (cdata->client != NULL)
|
||||||
cdata->client->references++;
|
cdata->client->references++;
|
||||||
if (args_has(args, 'c'))
|
if (args_has(args, 'c'))
|
||||||
cdata->cwd = xstrdup(args_get(args, 'c'));
|
cdata->cwd = format_single_from_target(item, args_get(args, 'c'));
|
||||||
else
|
else
|
||||||
cdata->cwd = xstrdup(server_client_get_cwd(c, s));
|
cdata->cwd = xstrdup(server_client_get_cwd(c, s));
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# configure.ac
|
# configure.ac
|
||||||
|
|
||||||
AC_INIT([tmux], next-3.9)
|
AC_INIT([tmux], 3.8-rc2)
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR(etc)
|
AC_CONFIG_AUX_DIR(etc)
|
||||||
|
|||||||
12
format.c
12
format.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: format.c,v 1.417 2026/09/08 15:42:26 nicm Exp $ */
|
/* $OpenBSD: format.c,v 1.418 2026/09/20 08:19:31 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -2876,10 +2876,10 @@ format_cb_session_activity_flag(struct format_tree *ft)
|
|||||||
|
|
||||||
if (ft->s != NULL) {
|
if (ft->s != NULL) {
|
||||||
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
||||||
if (ft->wl->flags & WINLINK_ACTIVITY)
|
if (wl->flags & WINLINK_ACTIVITY)
|
||||||
return (xstrdup("1"));
|
return (xstrdup("1"));
|
||||||
return (xstrdup("0"));
|
|
||||||
}
|
}
|
||||||
|
return (xstrdup("0"));
|
||||||
}
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@@ -2894,8 +2894,8 @@ format_cb_session_bell_flag(struct format_tree *ft)
|
|||||||
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
||||||
if (wl->flags & WINLINK_BELL)
|
if (wl->flags & WINLINK_BELL)
|
||||||
return (xstrdup("1"));
|
return (xstrdup("1"));
|
||||||
return (xstrdup("0"));
|
|
||||||
}
|
}
|
||||||
|
return (xstrdup("0"));
|
||||||
}
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@@ -2908,10 +2908,10 @@ format_cb_session_silence_flag(struct format_tree *ft)
|
|||||||
|
|
||||||
if (ft->s != NULL) {
|
if (ft->s != NULL) {
|
||||||
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
||||||
if (ft->wl->flags & WINLINK_SILENCE)
|
if (wl->flags & WINLINK_SILENCE)
|
||||||
return (xstrdup("1"));
|
return (xstrdup("1"));
|
||||||
return (xstrdup("0"));
|
|
||||||
}
|
}
|
||||||
|
return (xstrdup("0"));
|
||||||
}
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: layout-custom.c,v 1.41 2026/09/09 09:01:19 nicm Exp $ */
|
/* $OpenBSD: layout-custom.c,v 1.42 2026/09/20 08:37:47 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -283,26 +283,28 @@ layout_checksum(const char *layout)
|
|||||||
char *
|
char *
|
||||||
layout_dump(__unused struct window *w, struct layout_cell *lcroot, int flags)
|
layout_dump(__unused struct window *w, struct layout_cell *lcroot, int flags)
|
||||||
{
|
{
|
||||||
struct layout_string layout_string;
|
struct layout_string layout_string = { 0 };
|
||||||
char *out = NULL;
|
char *out;
|
||||||
|
|
||||||
if (lcroot == NULL)
|
if (lcroot == NULL)
|
||||||
return NULL;
|
goto bad;
|
||||||
|
|
||||||
layout_string_init(&layout_string);
|
layout_string_init(&layout_string);
|
||||||
|
if (layout_append(lcroot, &layout_string, flags) != 0)
|
||||||
if (layout_append(lcroot, &layout_string, flags) == 0) {
|
goto bad;
|
||||||
if (flags & LAYOUT_CUSTOM_OLD_FORMAT)
|
if (~flags & LAYOUT_CUSTOM_OLD_FORMAT)
|
||||||
xasprintf(&out, "%04hx,%s",
|
xasprintf(&out, "{\"V\":2,\"L\":%s}", layout_string.dat);
|
||||||
layout_checksum(layout_string.dat),
|
else {
|
||||||
layout_string.dat);
|
xasprintf(&out, "%04hx,%s", layout_checksum(layout_string.dat),
|
||||||
else
|
layout_string.dat);
|
||||||
xasprintf(&out, "{\"V\":2,\"L\":%s}",
|
|
||||||
layout_string.dat);
|
|
||||||
}
|
}
|
||||||
layout_string_free(&layout_string);
|
layout_string_free(&layout_string);
|
||||||
|
|
||||||
return (out);
|
return (out);
|
||||||
|
|
||||||
|
bad:
|
||||||
|
layout_string_free(&layout_string);
|
||||||
|
if (~flags & LAYOUT_CUSTOM_OLD_FORMAT)
|
||||||
|
return (NULL);
|
||||||
|
return (xstrdup("0000,"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append information for a single cell in a JSON (v2) format. */
|
/* Append information for a single cell in a JSON (v2) format. */
|
||||||
|
|||||||
69
layout.c
69
layout.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: layout.c,v 1.100 2026/09/11 08:16:14 nicm Exp $ */
|
/* $OpenBSD: layout.c,v 1.101 2026/09/20 08:42:46 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -768,49 +768,6 @@ layout_free(struct window *w, int only_nodes)
|
|||||||
layout_free_cell(w->layout_root, 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. */
|
/* Resize the entire layout after window resize. */
|
||||||
void
|
void
|
||||||
layout_resize(struct window *w, u_int sx, u_int sy)
|
layout_resize(struct window *w, u_int sx, u_int sy)
|
||||||
@@ -831,11 +788,8 @@ layout_resize(struct window *w, u_int sx, u_int sy)
|
|||||||
* out proportionately - this should leave the layout fitting the new
|
* out proportionately - this should leave the layout fitting the new
|
||||||
* window size.
|
* 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;
|
return;
|
||||||
}
|
|
||||||
xchange = sx - lc->g.sx;
|
xchange = sx - lc->g.sx;
|
||||||
xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT);
|
xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT);
|
||||||
if (xchange < 0 && xchange < -xlimit)
|
if (xchange < 0 && xchange < -xlimit)
|
||||||
@@ -865,7 +819,6 @@ layout_resize(struct window *w, u_int sx, u_int sy)
|
|||||||
|
|
||||||
/* Fix cell offsets. */
|
/* Fix cell offsets. */
|
||||||
layout_fix_offsets(w);
|
layout_fix_offsets(w);
|
||||||
layout_clamp_floating_panes(w, sx, sy);
|
|
||||||
layout_fix_panes(w, NULL);
|
layout_fix_panes(w, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1728,7 +1681,7 @@ layout_floating_args_parse(struct cmdq_item *item, struct args *args,
|
|||||||
enum pane_lines lines, struct window *w, struct layout_geometry *lg,
|
enum pane_lines lines, struct window *w, struct layout_geometry *lg,
|
||||||
char **cause)
|
char **cause)
|
||||||
{
|
{
|
||||||
int sx, sy, ox, oy;
|
int sx, sy, ox, oy, pad;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
|
|
||||||
sx = lg->sx == UINT_MAX ? w->sx / 2 : lg->sx;
|
sx = lg->sx == UINT_MAX ? w->sx / 2 : lg->sx;
|
||||||
@@ -1777,12 +1730,20 @@ layout_floating_args_parse(struct cmdq_item *item, struct args *args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!window_has_floating_panes(w)) {
|
||||||
|
w->last_new_pane_x = 0;
|
||||||
|
w->last_new_pane_y = 0;
|
||||||
|
}
|
||||||
if (ox == INT_MAX) {
|
if (ox == INT_MAX) {
|
||||||
if (w->last_new_pane_x == 0)
|
if (w->last_new_pane_x == 0)
|
||||||
ox = 4;
|
ox = 4;
|
||||||
else {
|
else {
|
||||||
|
if (lines != PANE_LINES_NONE)
|
||||||
|
pad = 1;
|
||||||
|
else
|
||||||
|
pad = 0;
|
||||||
ox = w->last_new_pane_x + 4;
|
ox = w->last_new_pane_x + 4;
|
||||||
if (w->last_new_pane_x > w->sx)
|
if (ox + sx + pad > (int)w->sx)
|
||||||
ox = 4;
|
ox = 4;
|
||||||
}
|
}
|
||||||
w->last_new_pane_x = ox;
|
w->last_new_pane_x = ox;
|
||||||
@@ -1793,8 +1754,12 @@ layout_floating_args_parse(struct cmdq_item *item, struct args *args,
|
|||||||
if (w->last_new_pane_y == 0)
|
if (w->last_new_pane_y == 0)
|
||||||
oy = 2;
|
oy = 2;
|
||||||
else {
|
else {
|
||||||
|
if (lines != PANE_LINES_NONE)
|
||||||
|
pad = 1;
|
||||||
|
else
|
||||||
|
pad = 0;
|
||||||
oy = w->last_new_pane_y + 2;
|
oy = w->last_new_pane_y + 2;
|
||||||
if (w->last_new_pane_y > w->sy)
|
if (oy + sy + pad > (int)w->sy)
|
||||||
oy = 2;
|
oy = 2;
|
||||||
}
|
}
|
||||||
w->last_new_pane_y = oy;
|
w->last_new_pane_y = oy;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: options-table.c,v 1.246 2026/09/11 10:17:16 nicm Exp $ */
|
/* $OpenBSD: options-table.c,v 1.245 2026/09/10 11:02:18 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -76,8 +76,7 @@ static const char *options_table_pane_border_indicators_list[] = {
|
|||||||
"off", "colour", "arrows", "both", NULL
|
"off", "colour", "arrows", "both", NULL
|
||||||
};
|
};
|
||||||
static const char *options_table_pane_border_lines_list[] = {
|
static const char *options_table_pane_border_lines_list[] = {
|
||||||
"single", "double", "heavy", "simple", "number", "spaces", "none",
|
"single", "double", "heavy", "simple", "number", "spaces", "none", NULL
|
||||||
"rounded", NULL
|
|
||||||
};
|
};
|
||||||
static const char *options_table_popup_border_lines_list[] = {
|
static const char *options_table_popup_border_lines_list[] = {
|
||||||
"single", "double", "heavy", "simple", "rounded", "padded", "none", NULL
|
"single", "double", "heavy", "simple", "rounded", "padded", "none", NULL
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
# monitor-activity, monitor-bell and monitor-silence: both the
|
# monitor-activity, monitor-bell and monitor-silence: both the
|
||||||
# alert-activity, alert-bell and alert-silence hooks and the winlink alert
|
# alert-activity, alert-bell and alert-silence hooks and the winlink alert
|
||||||
# flags (window_activity_flag, window_bell_flag, window_silence_flag and
|
# flags (window_activity_flag, window_bell_flag, window_silence_flag,
|
||||||
# the #, !, ~ characters in window_flags). The sessions are detached so
|
# their session equivalents and the #, !, ~ characters in window_flags).
|
||||||
|
# The sessions are detached so
|
||||||
# alert flags are set even on the current window; the *-action options
|
# alert flags are set even on the current window; the *-action options
|
||||||
# still decide whether the hooks fire. Panes run cat: activity is
|
# still decide whether the hooks fire. Panes run cat: activity is
|
||||||
# generated by the tty echo of send-keys and a bell by sending a BEL and
|
# generated by the tty echo of send-keys and a bell by sending a BEL and
|
||||||
@@ -111,6 +112,24 @@ flags_have()
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_session_flag()
|
||||||
|
{
|
||||||
|
flag="#{session_${1}_flag}"
|
||||||
|
expected=$2
|
||||||
|
|
||||||
|
# Only mon exists here. Check both window contexts and list-sessions.
|
||||||
|
for target in mon:w0 "mon:$3"; do
|
||||||
|
value=$($TMUX display -pt "$target" "$flag") ||
|
||||||
|
fail "display $flag failed"
|
||||||
|
[ "$value" = "$expected" ] ||
|
||||||
|
fail "expected $flag for $target to be '$expected' but got '$value'"
|
||||||
|
done
|
||||||
|
value=$($TMUX list-sessions -F "$flag") ||
|
||||||
|
fail "list-sessions $flag failed"
|
||||||
|
[ "$value" = "$expected" ] ||
|
||||||
|
fail "expected list-sessions $flag to be '$expected' but got '$value'"
|
||||||
|
}
|
||||||
|
|
||||||
flags_lack()
|
flags_lack()
|
||||||
{
|
{
|
||||||
target=$1
|
target=$1
|
||||||
@@ -150,10 +169,12 @@ $TMUX set-hook -g alert-silence \
|
|||||||
# alert-bell and sets the bell flag, shown as ! in window_flags.
|
# alert-bell and sets the bell flag, shown as ! in window_flags.
|
||||||
$TMUX neww -d -t mon: -n bellw cat || fail "new-window bellw failed"
|
$TMUX neww -d -t mon: -n bellw cat || fail "new-window bellw failed"
|
||||||
assert_fmt_unchanged mon:bellw '#{window_bell_flag}' 0
|
assert_fmt_unchanged mon:bellw '#{window_bell_flag}' 0
|
||||||
|
assert_session_flag bell 0 bellw
|
||||||
flags_lack mon:bellw '!'
|
flags_lack mon:bellw '!'
|
||||||
bell mon:bellw
|
bell mon:bellw
|
||||||
wait_for @log '|alert-bell:mon:bellw'
|
wait_for @log '|alert-bell:mon:bellw'
|
||||||
wait_for_fmt mon:bellw '#{window_bell_flag}' 1
|
wait_for_fmt mon:bellw '#{window_bell_flag}' 1
|
||||||
|
assert_session_flag bell 1 bellw
|
||||||
flags_have mon:bellw '!'
|
flags_have mon:bellw '!'
|
||||||
|
|
||||||
# Bells are not deduplicated: a second bell fires the hook again even
|
# Bells are not deduplicated: a second bell fires the hook again even
|
||||||
@@ -164,6 +185,7 @@ wait_for @log '|alert-bell:mon:bellw|alert-bell:mon:bellw'
|
|||||||
# Selecting the window clears the alert flags.
|
# Selecting the window clears the alert flags.
|
||||||
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
||||||
wait_for_fmt mon:bellw '#{window_bell_flag}' 0
|
wait_for_fmt mon:bellw '#{window_bell_flag}' 0
|
||||||
|
assert_session_flag bell 0 bellw
|
||||||
flags_lack mon:bellw '!'
|
flags_lack mon:bellw '!'
|
||||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||||
|
|
||||||
@@ -173,6 +195,7 @@ $TMUX set -g @log '' || fail "reset @log failed"
|
|||||||
bell mon:w0
|
bell mon:w0
|
||||||
wait_for @log '|alert-bell:mon:w0'
|
wait_for @log '|alert-bell:mon:w0'
|
||||||
wait_for_fmt mon:w0 '#{window_bell_flag}' 1
|
wait_for_fmt mon:w0 '#{window_bell_flag}' 1
|
||||||
|
assert_session_flag bell 1 bellw
|
||||||
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
$TMUX selectw -t mon:bellw || fail "select-window bellw failed"
|
||||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||||
wait_for_fmt mon:w0 '#{window_bell_flag}' 0
|
wait_for_fmt mon:w0 '#{window_bell_flag}' 0
|
||||||
@@ -199,6 +222,7 @@ $TMUX neww -d -t mon: -n actw cat || fail "new-window actw failed"
|
|||||||
$TMUX set -g @log '' || fail "reset @log failed"
|
$TMUX set -g @log '' || fail "reset @log failed"
|
||||||
activity mon:actw
|
activity mon:actw
|
||||||
assert_fmt_unchanged mon:actw '#{window_activity_flag}' 0
|
assert_fmt_unchanged mon:actw '#{window_activity_flag}' 0
|
||||||
|
assert_session_flag activity 0 actw
|
||||||
assert_unchanged @log ''
|
assert_unchanged @log ''
|
||||||
|
|
||||||
# With monitor-activity on, output fires alert-activity and sets the
|
# With monitor-activity on, output fires alert-activity and sets the
|
||||||
@@ -208,6 +232,7 @@ $TMUX set -wt mon:actw monitor-activity on ||
|
|||||||
activity mon:actw
|
activity mon:actw
|
||||||
wait_for @log '|alert-activity:mon:actw'
|
wait_for @log '|alert-activity:mon:actw'
|
||||||
wait_for_fmt mon:actw '#{window_activity_flag}' 1
|
wait_for_fmt mon:actw '#{window_activity_flag}' 1
|
||||||
|
assert_session_flag activity 1 actw
|
||||||
flags_have mon:actw '#'
|
flags_have mon:actw '#'
|
||||||
|
|
||||||
# While the flag is set further activity does not fire the hook again.
|
# While the flag is set further activity does not fire the hook again.
|
||||||
@@ -234,6 +259,7 @@ exec 3>"$OUT/fifo"
|
|||||||
wait_for_fmt mon: '#{session_attached}' 1
|
wait_for_fmt mon: '#{session_attached}' 1
|
||||||
$TMUX selectw -t mon:actw || fail "select-window actw failed"
|
$TMUX selectw -t mon:actw || fail "select-window actw failed"
|
||||||
wait_for_fmt mon:actw '#{window_activity_flag}' 0
|
wait_for_fmt mon:actw '#{window_activity_flag}' 0
|
||||||
|
assert_session_flag activity 0 actw
|
||||||
flags_lack mon:actw '#'
|
flags_lack mon:actw '#'
|
||||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||||
exec 3>&-
|
exec 3>&-
|
||||||
@@ -250,6 +276,7 @@ $TMUX set -wt mon:w0 monitor-activity on ||
|
|||||||
$TMUX set -g @log '' || fail "reset @log failed"
|
$TMUX set -g @log '' || fail "reset @log failed"
|
||||||
activity mon:w0
|
activity mon:w0
|
||||||
wait_for_fmt mon:w0 '#{window_activity_flag}' 1
|
wait_for_fmt mon:w0 '#{window_activity_flag}' 1
|
||||||
|
assert_session_flag activity 1 actw
|
||||||
assert_unchanged @log ''
|
assert_unchanged @log ''
|
||||||
$TMUX set -wut mon:w0 monitor-activity ||
|
$TMUX set -wut mon:w0 monitor-activity ||
|
||||||
fail "unset monitor-activity w0 failed"
|
fail "unset monitor-activity w0 failed"
|
||||||
@@ -273,16 +300,19 @@ $TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
|||||||
# running.
|
# running.
|
||||||
$TMUX neww -d -t mon: -n silw cat || fail "new-window silw failed"
|
$TMUX neww -d -t mon: -n silw cat || fail "new-window silw failed"
|
||||||
assert_fmt_unchanged mon:silw '#{window_silence_flag}' 0
|
assert_fmt_unchanged mon:silw '#{window_silence_flag}' 0
|
||||||
|
assert_session_flag silence 0 silw
|
||||||
$TMUX set -g @log '' || fail "reset @log failed"
|
$TMUX set -g @log '' || fail "reset @log failed"
|
||||||
$TMUX set -wt mon:silw monitor-silence 1 || fail "set monitor-silence failed"
|
$TMUX set -wt mon:silw monitor-silence 1 || fail "set monitor-silence failed"
|
||||||
wait_for @log '|alert-silence:mon:silw'
|
wait_for @log '|alert-silence:mon:silw'
|
||||||
wait_for_fmt mon:silw '#{window_silence_flag}' 1
|
wait_for_fmt mon:silw '#{window_silence_flag}' 1
|
||||||
|
assert_session_flag silence 1 silw
|
||||||
flags_have mon:silw '~'
|
flags_have mon:silw '~'
|
||||||
assert_unchanged @log '|alert-silence:mon:silw'
|
assert_unchanged @log '|alert-silence:mon:silw'
|
||||||
$TMUX set -wt mon:silw monitor-silence 0 ||
|
$TMUX set -wt mon:silw monitor-silence 0 ||
|
||||||
fail "reset monitor-silence failed"
|
fail "reset monitor-silence failed"
|
||||||
$TMUX selectw -t mon:silw || fail "select-window silw failed"
|
$TMUX selectw -t mon:silw || fail "select-window silw failed"
|
||||||
wait_for_fmt mon:silw '#{window_silence_flag}' 0
|
wait_for_fmt mon:silw '#{window_silence_flag}' 0
|
||||||
|
assert_session_flag silence 0 silw
|
||||||
flags_lack mon:silw '~'
|
flags_lack mon:silw '~'
|
||||||
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
$TMUX selectw -t mon:w0 || fail "select-window w0 failed"
|
||||||
|
|
||||||
|
|||||||
53
regress/codepoint-widths.sh
Normal file
53
regress/codepoint-widths.sh
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Width cache ranges must include their endpoint without overflowing wchar_t.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||||
|
SERVER=
|
||||||
|
WATCHDOG=
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
if [ -n "$WATCHDOG" ]; then
|
||||||
|
kill "$WATCHDOG" 2>/dev/null
|
||||||
|
wait "$WATCHDOG" 2>/dev/null
|
||||||
|
fi
|
||||||
|
[ -n "$SERVER" ] && kill -9 "$SERVER" 2>/dev/null
|
||||||
|
}
|
||||||
|
trap cleanup 0
|
||||||
|
trap 'exit 1' 1 2 15
|
||||||
|
|
||||||
|
$TMUX new-session -d 'exec sleep 60' || exit 1
|
||||||
|
SERVER=$($TMUX display-message -p '#{pid}') || exit 1
|
||||||
|
|
||||||
|
# kill-server cannot stop a server stuck rebuilding the width cache.
|
||||||
|
(
|
||||||
|
sleep 5
|
||||||
|
kill -9 "$SERVER" 2>/dev/null
|
||||||
|
) &
|
||||||
|
WATCHDOG=$!
|
||||||
|
|
||||||
|
$TMUX set -g codepoint-widths 'U+1F600=2' || exit 1
|
||||||
|
|
||||||
|
# Cover both signed and unsigned 32-bit wchar_t. Values above WCHAR_MAX
|
||||||
|
# are ignored by the parser on platforms where they cannot be represented.
|
||||||
|
for value in U+7FFFFFFF=1 U+7FFFFFFE-U+7FFFFFFF=2 \
|
||||||
|
U+FFFFFFFF=1 U+FFFFFFFE-U+FFFFFFFF=2; do
|
||||||
|
$TMUX set -g codepoint-widths "$value" || exit 1
|
||||||
|
[ "$($TMUX display-message -p alive)" = alive ] || exit 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check that an ordinary range still includes both endpoints and stops there.
|
||||||
|
$TMUX set -g codepoint-widths 'U+03B1-U+03B3=2' || exit 1
|
||||||
|
$TMUX set -g @text 'αβγδ' || exit 1
|
||||||
|
[ "$($TMUX display-message -p '#{w:@text}')" = 7 ] || exit 1
|
||||||
|
$TMUX set -gu codepoint-widths || exit 1
|
||||||
|
[ "$($TMUX display-message -p '#{w:@text}')" = 4 ] || exit 1
|
||||||
|
|
||||||
|
$TMUX kill-server || exit 1
|
||||||
|
SERVER=
|
||||||
|
exit 0
|
||||||
@@ -268,149 +268,5 @@ $TMUX kill-pane -t "$floating" || exit 1
|
|||||||
$TMUX kill-pane -t "$right" || exit 1
|
$TMUX kill-pane -t "$right" || exit 1
|
||||||
$TMUX kill-pane -t "$lower" || exit 1
|
$TMUX kill-pane -t "$lower" || exit 1
|
||||||
|
|
||||||
# --- Floating panes clamped when the window shrinks (issue #5581, PR #5582) ---
|
|
||||||
#
|
|
||||||
# layout_resize clamps floating panes back inside the window when it shrinks:
|
|
||||||
# move them and, only if they cannot fit, shrink them (never below
|
|
||||||
# PANE_MINIMUM). A floating cell is the pane's content, so with the default
|
|
||||||
# single-line border the clamp counts 1 cell of border per side, exactly as
|
|
||||||
# layout_floating_args_parse does on creation; with no border it counts 0.
|
|
||||||
# Each case below gets its own window, since resize-window fixes a window at
|
|
||||||
# a manual size for the rest of its life.
|
|
||||||
|
|
||||||
# Case 1: a lone floating pane -- break-pane -W on a window's only pane --
|
|
||||||
# takes the early-return path in layout_resize, added during PR #5582's
|
|
||||||
# review round, since there is no tiled tree to walk.
|
|
||||||
win=$($TMUX new-window -dPF '#{window_id}') ||
|
|
||||||
fail "new-window for lone float failed"
|
|
||||||
|
|
||||||
# -x 20 -y 6 -> pane 18x4; -X 60 -Y 18 -> pane_left 61, pane_top 19: with the
|
|
||||||
# border, the footprint is columns 60-79, rows 18-23, flush with the 80x24
|
|
||||||
# window's right and bottom edges, so the float fits before it is shrunk.
|
|
||||||
$TMUX break-pane -W -s "$win" -x 20 -y 6 -X 60 -Y 18 ||
|
|
||||||
fail "break-pane -W for lone float failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 61
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 19
|
|
||||||
|
|
||||||
# Shrink to 40x16. The float still fits at its own size (18 <= 40-2, 4 <=
|
|
||||||
# 16-2) so only its position moves, flush to the new right/bottom edges:
|
|
||||||
# xoff = 40 - 18 - 1 = 21; yoff = 16 - 4 - 1 = 11.
|
|
||||||
$TMUX resize-window -t "$win" -x 40 -y 16 ||
|
|
||||||
fail "resize-window (lone float) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 21
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 11
|
|
||||||
|
|
||||||
# Case 5: grow the window back. The clamp must not chase the window back
|
|
||||||
# outward -- it only ever pulls a float in, never restores where it was.
|
|
||||||
$TMUX resize-window -t "$win" -x 80 -y 24 ||
|
|
||||||
fail "resize-window grow (lone float) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 21
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 11
|
|
||||||
$TMUX kill-window -t "$win" || exit 1
|
|
||||||
|
|
||||||
# Case 2: the same float, but with a tiled sibling surviving alongside it, so
|
|
||||||
# the window's root cell stays tiled and layout_resize takes the normal path
|
|
||||||
# (the clamp call after layout_fix_offsets) instead of the early return
|
|
||||||
# above. Same geometry as case 1, so the same numbers should come out.
|
|
||||||
win=$($TMUX new-window -dPF '#{window_id}') ||
|
|
||||||
fail "new-window for tiled sibling failed"
|
|
||||||
$TMUX split-window -t "$win" 'sleep 100' ||
|
|
||||||
fail "split-window for tiled sibling failed"
|
|
||||||
$TMUX break-pane -W -s "$win" -x 20 -y 6 -X 60 -Y 18 ||
|
|
||||||
fail "break-pane -W for tiled sibling failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 61
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 19
|
|
||||||
|
|
||||||
$TMUX resize-window -t "$win" -x 40 -y 16 ||
|
|
||||||
fail "resize-window (tiled sibling) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 21
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 11
|
|
||||||
$TMUX kill-window -t "$win" || exit 1
|
|
||||||
|
|
||||||
# Case 3: new-pane float, the original repro from issue #5581 and the PR
|
|
||||||
# body -- also the normal path, via the tiled base pane new-window creates.
|
|
||||||
win=$($TMUX new-window -dPF '#{window_id}') ||
|
|
||||||
fail "new-window for new-pane repro failed"
|
|
||||||
$TMUX resize-window -t "$win" -x 120 -y 40 ||
|
|
||||||
fail "resize-window to 120x40 failed"
|
|
||||||
|
|
||||||
# -x 30 -y 10 -> pane 28x8; -X 85 -Y 25 -> pane_left 86, pane_top 26.
|
|
||||||
floating=$($TMUX new-pane -t "$win" -dPF '#{pane_id}' \
|
|
||||||
-x 30 -y 10 -X 85 -Y 25 'sleep 100') ||
|
|
||||||
fail "new-pane for new-pane repro failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_width}')" 28
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_height}')" 8
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_left}')" 86
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_top}')" 26
|
|
||||||
|
|
||||||
# Shrink to 60x20: xoff = 60 - 28 - 1 = 31; yoff = 20 - 8 - 1 = 11.
|
|
||||||
$TMUX resize-window -t "$win" -x 60 -y 20 ||
|
|
||||||
fail "resize-window (new-pane repro) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_width}')" 28
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_height}')" 8
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_left}')" 31
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_top}')" 11
|
|
||||||
$TMUX kill-window -t "$win" || exit 1
|
|
||||||
|
|
||||||
# Case 4: a float that already fits inside the shrunk window is left alone --
|
|
||||||
# assert position and size are both unchanged, not just one of them.
|
|
||||||
win=$($TMUX new-window -dPF '#{window_id}') ||
|
|
||||||
fail "new-window for untouched float failed"
|
|
||||||
|
|
||||||
# -x 20 -y 6 -> pane 18x4; -X 8 -Y 3 -> pane_left 9, pane_top 4 (as at the top
|
|
||||||
# of this file). Footprint columns 8-27, rows 3-8: well inside 60x20 too.
|
|
||||||
floating=$($TMUX new-pane -t "$win" -dPF '#{pane_id}' \
|
|
||||||
-x 20 -y 6 -X 8 -Y 3 'sleep 100') ||
|
|
||||||
fail "new-pane for untouched float failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_left}')" 9
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_top}')" 4
|
|
||||||
|
|
||||||
$TMUX resize-window -t "$win" -x 60 -y 20 ||
|
|
||||||
fail "resize-window (untouched float) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_width}')" 18
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_height}')" 4
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_left}')" 9
|
|
||||||
must_equal "$($TMUX display-message -p -t "$floating" '#{pane_top}')" 4
|
|
||||||
$TMUX kill-window -t "$win" || exit 1
|
|
||||||
|
|
||||||
# Case 6: pad = 0, via the pane-border-lines window option set to none. The
|
|
||||||
# border arithmetic differs here (no -2/+1 adjustment either on creation or
|
|
||||||
# in the clamp).
|
|
||||||
win=$($TMUX new-window -dPF '#{window_id}') ||
|
|
||||||
fail "new-window for pad=0 float failed"
|
|
||||||
$TMUX set-option -w -t "$win" pane-border-lines none ||
|
|
||||||
fail "set pane-border-lines none failed"
|
|
||||||
|
|
||||||
# No border: -x 20 -y 6 -> pane 20x6 directly; -X 60 -Y 18 -> pane_left 60,
|
|
||||||
# pane_top 18 directly. Footprint (== content, no border) is columns 60-79,
|
|
||||||
# rows 18-23: flush right/bottom of the 80x24 window, same as case 1.
|
|
||||||
$TMUX break-pane -W -s "$win" -x 20 -y 6 -X 60 -Y 18 ||
|
|
||||||
fail "break-pane -W for pad=0 float failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 20
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 6
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 60
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 18
|
|
||||||
|
|
||||||
# Shrink to 40x16 with pad=0: xoff = 40 - 20 - 0 = 20; yoff = 16 - 6 - 0 = 10.
|
|
||||||
$TMUX resize-window -t "$win" -x 40 -y 16 ||
|
|
||||||
fail "resize-window (pad=0 float) failed"
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_width}')" 20
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_height}')" 6
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_left}')" 20
|
|
||||||
must_equal "$($TMUX display-message -p -t "$win" '#{pane_top}')" 10
|
|
||||||
$TMUX kill-window -t "$win" || exit 1
|
|
||||||
|
|
||||||
$TMUX kill-server 2>/dev/null
|
$TMUX kill-server 2>/dev/null
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
28
regress/kill-session-zoomed.sh
Executable file
28
regress/kill-session-zoomed.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Killing a session whose window is zoomed must not crash the server:
|
||||||
|
# window_destroy used to unzoom the window, which resized the panes and
|
||||||
|
# fired pane-resized with the window in the payload, and releasing that
|
||||||
|
# reference destroyed the window a second time.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
$TMUX -f/dev/null new -d -sfoo || exit 1
|
||||||
|
$TMUX split-window -d -h -tfoo:0 || exit 1
|
||||||
|
$TMUX resize-pane -Z -tfoo:0 || exit 1
|
||||||
|
$TMUX new -d -sbar || exit 1
|
||||||
|
$TMUX kill-session -tfoo || exit 1
|
||||||
|
$TMUX has-session -tbar || exit 1
|
||||||
|
|
||||||
|
# The same with the zoomed window in a session killed by kill-server.
|
||||||
|
$TMUX new -d -sbaz || exit 1
|
||||||
|
$TMUX split-window -d -v -tbaz:0 || exit 1
|
||||||
|
$TMUX resize-pane -Z -tbaz:0 || exit 1
|
||||||
|
$TMUX kill-server || exit 1
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -50,7 +50,8 @@
|
|||||||
# layout it names is a single cell or a split;
|
# layout it names is a single cell or a split;
|
||||||
# - a window whose only tiled pane has been killed, which leaves it with a
|
# - a window whose only tiled pane has been killed, which leaves it with a
|
||||||
# floating cell as its layout root or with a root node holding nothing but
|
# floating cell as its layout root or with a root node holding nothing but
|
||||||
# floating cells, producing no v1 dump at all, and being parsed as v1;
|
# floating cells, producing an empty v1 body with a checksum, and being
|
||||||
|
# parsed as v1;
|
||||||
# - the %layout-change notification, in both formats at once: two control
|
# - the %layout-change notification, in both formats at once: two control
|
||||||
# clients watching one layout change, only one of which has asked for new
|
# clients watching one layout change, only one of which has asked for new
|
||||||
# layouts, and the number of notifications a change produces in each format;
|
# layouts, and the number of notifications a change produces in each format;
|
||||||
@@ -838,12 +839,12 @@ must_equal 'Panes left with one floating pane' \
|
|||||||
"$($TMUX display-message -p -t L:gone1 '#{window_panes}')" '1'
|
"$($TMUX display-message -p -t L:gone1 '#{window_panes}')" '1'
|
||||||
|
|
||||||
# The floating cell is the root and there is nothing tiled under it, so there is
|
# The floating cell is the root and there is nothing tiled under it, so there is
|
||||||
# no v1 dump to make. In particular the floating cell must not be written out on
|
# only an empty v1 body to dump. The floating cell must not be written out on
|
||||||
# its own, which would be a layout claiming the window is the size and position
|
# its own, which would be a layout claiming the window is the size and position
|
||||||
# of the floating pane with no pane in it at all.
|
# of the floating pane with no pane in it at all.
|
||||||
got=$(v1_layout L:gone1)
|
got=$(v1_layout L:gone1)
|
||||||
check_ok display-message -p alive
|
check_ok display-message -p alive
|
||||||
must_equal 'v1 dump with one floating pane and no tiled panes' "$got" ''
|
must_equal 'v1 dump with one floating pane and no tiled panes' "$got" '0000,'
|
||||||
|
|
||||||
# Two floating panes left, so the node keeps two children, does not collapse,
|
# Two floating panes left, so the node keeps two children, does not collapse,
|
||||||
# and stays the root with nothing but floating cells in it.
|
# and stays the root with nothing but floating cells in it.
|
||||||
@@ -856,11 +857,11 @@ must_equal 'Panes left with two floating panes' \
|
|||||||
"$($TMUX display-message -p -t L:gone2 '#{window_panes}')" '2'
|
"$($TMUX display-message -p -t L:gone2 '#{window_panes}')" '2'
|
||||||
|
|
||||||
# The node is the root this time rather than the floating cell, but it has no
|
# The node is the root this time rather than the floating cell, but it has no
|
||||||
# tiled cell anywhere under it either, so there is still no v1 dump to make -
|
# tiled cell anywhere under it either, so the v1 body is still empty -
|
||||||
# and making one must not take the server with it.
|
# and making one must not take the server with it.
|
||||||
got=$(v1_layout L:gone2)
|
got=$(v1_layout L:gone2)
|
||||||
check_ok display-message -p alive
|
check_ok display-message -p alive
|
||||||
must_equal 'v1 dump with two floating panes and no tiled panes' "$got" ''
|
must_equal 'v1 dump with two floating panes and no tiled panes' "$got" '0000,'
|
||||||
|
|
||||||
# Nor must parsing a v1 layout against it. There is no tiled pane for the
|
# Nor must parsing a v1 layout against it. There is no tiled pane for the
|
||||||
# layout to name, so whether it is applied or rejected is the format's business;
|
# layout to name, so whether it is applied or rejected is the format's business;
|
||||||
|
|||||||
@@ -86,11 +86,6 @@ check_value "-gv status-keys" "vi"
|
|||||||
check_fail "unknown value: bogus" set -g status-keys bogus
|
check_fail "unknown value: bogus" set -g status-keys bogus
|
||||||
check_value "-gv status-keys" "vi"
|
check_value "-gv status-keys" "vi"
|
||||||
|
|
||||||
# pane-border-lines accepts rounded as a pane border style.
|
|
||||||
check_ok set -gw pane-border-lines rounded
|
|
||||||
check_value "-gwv pane-border-lines" "rounded"
|
|
||||||
check_ok set -gw pane-border-lines single
|
|
||||||
|
|
||||||
# --- flag options ---------------------------------------------------------
|
# --- flag options ---------------------------------------------------------
|
||||||
#
|
#
|
||||||
# focus-events is an on/off flag. Setting with no value toggles it; explicit
|
# focus-events is an on/off flag. Setting with no value toggles it; explicit
|
||||||
|
|||||||
43
regress/run-shell-cwd.sh
Normal file
43
regress/run-shell-cwd.sh
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# run-shell -c should expand formats using the target pane.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||||
|
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap '$TMUX kill-server 2>/dev/null; rm -rf "$TMP"' 0 1 15
|
||||||
|
TMP=$(cd "$TMP" && pwd -P)
|
||||||
|
mkdir "$TMP/first" "$TMP/second dir" || exit 1
|
||||||
|
|
||||||
|
check_directory()
|
||||||
|
{
|
||||||
|
actual=$(cat "$TMP/out")
|
||||||
|
if [ "$actual" != "$1" ]; then
|
||||||
|
echo "Expected directory '$1', got '$actual'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Expand the current pane's directory in the same command queue as creation.
|
||||||
|
$TMUX new-session -d -s test -c "$TMP/first" 'sleep 60' \; \
|
||||||
|
run-shell -c '#{pane_current_path}' "pwd >'$TMP/out'" || exit 1
|
||||||
|
check_directory "$TMP/first"
|
||||||
|
|
||||||
|
# An explicit target must supply the format context, including with a delay.
|
||||||
|
pane=$($TMUX new-window -d -P -F '#{pane_id}' -t test \
|
||||||
|
-c "$TMP/second dir" 'sleep 60') || exit 1
|
||||||
|
$TMUX run-shell -t "$pane" -d 0.1 -c '#{pane_current_path}' \
|
||||||
|
"pwd >'$TMP/out'" || exit 1
|
||||||
|
check_directory "$TMP/second dir"
|
||||||
|
|
||||||
|
# Literal directories and the default client directory still work.
|
||||||
|
$TMUX run-shell -c "$TMP/second dir" "pwd >'$TMP/out'" || exit 1
|
||||||
|
check_directory "$TMP/second dir"
|
||||||
|
(cd "$TMP/first" && $TMUX run-shell "pwd >'$TMP/out'") || exit 1
|
||||||
|
check_directory "$TMP/first"
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -107,12 +107,6 @@ $TMUX2 new-pane -x28 -y8 -X4 -Y1 -B double \
|
|||||||
"sh -c 'printf FLOAT; exec sleep 100'" || exit 1
|
"sh -c 'printf FLOAT; exec sleep 100'" || exit 1
|
||||||
compare floating-border-double
|
compare floating-border-double
|
||||||
|
|
||||||
# Larger floating pane with rounded border lines.
|
|
||||||
new_scene 40 12
|
|
||||||
$TMUX2 new-pane -x28 -y8 -X4 -Y1 -B rounded \
|
|
||||||
"sh -c 'printf FLOAT; exec sleep 100'" || exit 1
|
|
||||||
compare floating-border-rounded
|
|
||||||
|
|
||||||
# Floating pane with no border lines: redraw_mark_pane_borders returns early so
|
# Floating pane with no border lines: redraw_mark_pane_borders returns early so
|
||||||
# the float has no border at all, only its (clipped) content over the base pane.
|
# the float has no border at all, only its (clipped) content over the base pane.
|
||||||
new_scene 40 12
|
new_scene 40 12
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
base
|
|
||||||
╭──────────────────────────╮
|
|
||||||
│FLOAT │
|
|
||||||
│ │
|
|
||||||
│ │
|
|
||||||
│ │
|
|
||||||
│ │
|
|
||||||
│ │
|
|
||||||
╰──────────────────────────╯
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -293,6 +293,16 @@ assert_key 'Escape [24@' 'C-S-F12'
|
|||||||
assert_key 'Escape [I' 'FocusIn'
|
assert_key 'Escape [I' 'FocusIn'
|
||||||
assert_key 'Escape [O' 'FocusOut'
|
assert_key 'Escape [O' 'FocusOut'
|
||||||
|
|
||||||
|
# Focus events do not leave the prefix table.
|
||||||
|
$TMUX2 bind C-c set -g @focus-prefix yes
|
||||||
|
$TMUX2 set -g focus-events on
|
||||||
|
$TMUX send-keys C-b Escape '[O' Escape '[I' C-c
|
||||||
|
sleep 0.05
|
||||||
|
if [ "$($TMUX2 show -gv @focus-prefix)" != yes ]; then
|
||||||
|
echo "[FAIL] FocusIn and FocusOut left the prefix table"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Paste keys
|
# Paste keys
|
||||||
assert_key 'Escape [200~' 'PasteStart'
|
assert_key 'Escape [200~' 'PasteStart'
|
||||||
assert_key 'Escape [201~' 'PasteEnd'
|
assert_key 'Escape [201~' 'PasteEnd'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: server-fn.c,v 1.153 2026/09/10 11:02:18 nicm Exp $ */
|
/* $OpenBSD: server-fn.c,v 1.154 2026/09/21 12:43:36 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -310,8 +310,8 @@ server_link_window(struct session *src, struct winlink *srcwl,
|
|||||||
}
|
}
|
||||||
if (killflag) {
|
if (killflag) {
|
||||||
/*
|
/*
|
||||||
* Can't use session_detach as it will destroy session
|
* Can't use session_detach as it won't detach the only
|
||||||
* if this makes it empty.
|
* window.
|
||||||
*/
|
*/
|
||||||
events_fire_winlink("window-unlinked", dstwl);
|
events_fire_winlink("window-unlinked", dstwl);
|
||||||
dstwl->flags &= ~WINLINK_ALERTFLAGS;
|
dstwl->flags &= ~WINLINK_ALERTFLAGS;
|
||||||
|
|||||||
13
session.c
13
session.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: session.c,v 1.107 2026/08/05 07:35:35 nicm Exp $ */
|
/* $OpenBSD: session.c,v 1.108 2026/09/21 12:43:36 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -336,10 +336,17 @@ session_attach(struct session *s, struct window *w, int idx, char **cause)
|
|||||||
return (wl);
|
return (wl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach a window from a session. */
|
/*
|
||||||
|
* Detach a window from a session. Returns 1 if the window has not been
|
||||||
|
* detached - the caller must destroy the session.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
session_detach(struct session *s, struct winlink *wl)
|
session_detach(struct session *s, struct winlink *wl)
|
||||||
{
|
{
|
||||||
|
if (RB_MIN(winlinks, &s->windows) == wl &&
|
||||||
|
RB_MAX(winlinks, &s->windows) == wl)
|
||||||
|
return (1);
|
||||||
|
|
||||||
if (s->curw == wl &&
|
if (s->curw == wl &&
|
||||||
session_last(s) != 0 &&
|
session_last(s) != 0 &&
|
||||||
session_previous(s, 0) != 0)
|
session_previous(s, 0) != 0)
|
||||||
@@ -352,8 +359,6 @@ session_detach(struct session *s, struct winlink *wl)
|
|||||||
|
|
||||||
session_group_synchronize_from(s);
|
session_group_synchronize_from(s);
|
||||||
|
|
||||||
if (RB_EMPTY(&s->windows))
|
|
||||||
return (1);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
spawn.c
6
spawn.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: spawn.c,v 1.52 2026/08/20 09:19:24 nicm Exp $ */
|
/* $OpenBSD: spawn.c,v 1.53 2026/09/21 12:43:36 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -166,8 +166,8 @@ spawn_window(struct spawn_context *sc, char **cause)
|
|||||||
}
|
}
|
||||||
if (wl != NULL) {
|
if (wl != NULL) {
|
||||||
/*
|
/*
|
||||||
* Can't use session_detach as it will destroy session
|
* Can't use session_detach as it won't detach the only
|
||||||
* if this makes it empty.
|
* window.
|
||||||
*/
|
*/
|
||||||
wl->flags &= ~WINLINK_ALERTFLAGS;
|
wl->flags &= ~WINLINK_ALERTFLAGS;
|
||||||
events_fire_winlink("window-unlinked", wl);
|
events_fire_winlink("window-unlinked", wl);
|
||||||
|
|||||||
14
tmux.1
14
tmux.1
@@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: tmux.1,v 1.1170 2026/09/11 10:17:16 nicm Exp $
|
.\" $OpenBSD: tmux.1,v 1.1169 2026/09/10 11:02:18 nicm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
.\"
|
.\"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 11 2026 $
|
.Dd $Mdocdate: September 10 2026 $
|
||||||
.Dt TMUX 1
|
.Dt TMUX 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -5980,8 +5980,6 @@ single lines using ACS or UTF\-8 characters
|
|||||||
double lines using UTF\-8 characters
|
double lines using UTF\-8 characters
|
||||||
.It heavy
|
.It heavy
|
||||||
heavy lines using UTF\-8 characters
|
heavy lines using UTF\-8 characters
|
||||||
.It rounded
|
|
||||||
single lines with rounded corners using UTF\-8 characters
|
|
||||||
.It simple
|
.It simple
|
||||||
simple ASCII characters
|
simple ASCII characters
|
||||||
.It number
|
.It number
|
||||||
@@ -8328,17 +8326,11 @@ Otherwise, the format of
|
|||||||
.Ar message
|
.Ar message
|
||||||
is described in the
|
is described in the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section; session, window and pane information is taken from
|
section; information is taken from
|
||||||
.Ar target\-pane
|
.Ar target\-pane
|
||||||
if
|
if
|
||||||
.Fl t
|
.Fl t
|
||||||
is given, otherwise the active pane.
|
is given, otherwise the active pane.
|
||||||
If
|
|
||||||
.Fl c
|
|
||||||
is given, the
|
|
||||||
.Ql #{client_*}
|
|
||||||
variables are taken from
|
|
||||||
.Ar target\-client .
|
|
||||||
.Pp
|
.Pp
|
||||||
If
|
If
|
||||||
.Fl j
|
.Fl j
|
||||||
|
|||||||
6
tmux.h
6
tmux.h
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux.h,v 1.1440 2026/09/11 10:17:16 nicm Exp $ */
|
/* $OpenBSD: tmux.h,v 1.1443 2026/09/21 10:33:16 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1150,8 +1150,7 @@ enum pane_lines {
|
|||||||
PANE_LINES_SIMPLE,
|
PANE_LINES_SIMPLE,
|
||||||
PANE_LINES_NUMBER,
|
PANE_LINES_NUMBER,
|
||||||
PANE_LINES_SPACES,
|
PANE_LINES_SPACES,
|
||||||
PANE_LINES_NONE,
|
PANE_LINES_NONE
|
||||||
PANE_LINES_ROUNDED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Pane border indicator option. */
|
/* Pane border indicator option. */
|
||||||
@@ -3834,6 +3833,7 @@ int window_pane_get_pane_status(struct window_pane *);
|
|||||||
struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
|
struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
|
||||||
u_int);
|
u_int);
|
||||||
int window_pane_is_floating(struct window_pane *);
|
int window_pane_is_floating(struct window_pane *);
|
||||||
|
int window_pane_is_floating_with_hidden(struct window_pane *);
|
||||||
|
|
||||||
/* window-border.c */
|
/* window-border.c */
|
||||||
void window_set_fill_cells(struct window *);
|
void window_set_fill_cells(struct window *);
|
||||||
|
|||||||
9
utf8.c
9
utf8.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: utf8.c,v 1.72 2026/09/01 12:49:49 nicm Exp $ */
|
/* $OpenBSD: utf8.c,v 1.73 2026/09/20 08:11:00 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -374,8 +374,13 @@ utf8_add_to_width_cache(const char *s)
|
|||||||
wc_end = wc_start;
|
wc_end = wc_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (wc = wc_start; wc <= wc_end; wc++)
|
wc = wc_start;
|
||||||
|
for (;;) {
|
||||||
utf8_insert_width_cache(wc, width);
|
utf8_insert_width_cache(wc, width);
|
||||||
|
if (wc == wc_end)
|
||||||
|
break;
|
||||||
|
wc++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
utf8_no_width = 1;
|
utf8_no_width = 1;
|
||||||
ud = utf8_fromcstr(copy);
|
ud = utf8_fromcstr(copy);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: window-border.c,v 1.4 2026/09/11 10:17:16 nicm Exp $ */
|
/* $OpenBSD: window-border.c,v 1.3 2026/07/23 09:38:27 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -120,10 +120,6 @@ window_get_border_cell(struct window_pane *wp, enum pane_lines pane_lines,
|
|||||||
gc->attr &= ~GRID_ATTR_CHARSET;
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
||||||
utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type));
|
utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type));
|
||||||
break;
|
break;
|
||||||
case PANE_LINES_ROUNDED:
|
|
||||||
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
||||||
utf8_copy(&gc->data, tty_acs_rounded_borders(cell_type));
|
|
||||||
break;
|
|
||||||
case PANE_LINES_SIMPLE:
|
case PANE_LINES_SIMPLE:
|
||||||
gc->attr &= ~GRID_ATTR_CHARSET;
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
||||||
utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]);
|
utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: window-copy.c,v 1.429 2026/09/01 13:04:29 nicm Exp $ */
|
/* $OpenBSD: window-copy.c,v 1.431 2026/09/21 10:43:37 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -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);
|
sy = screen_hsize(src) + screen_size_y(src);
|
||||||
if (trim) {
|
if (trim) {
|
||||||
while (sy > screen_hsize(src)) {
|
while (sy > screen_hsize(src) + 1) {
|
||||||
gl = grid_peek_line(src->grid, sy - 1);
|
gl = grid_peek_line(src->grid, sy - 1);
|
||||||
if (gl == NULL || gl->cellused != 0)
|
if (gl == NULL || gl->cellused != 0)
|
||||||
break;
|
break;
|
||||||
|
|||||||
24
window.c
24
window.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: window.c,v 1.374 2026/09/08 08:37:56 nicm Exp $ */
|
/* $OpenBSD: window.c,v 1.377 2026/09/21 10:33:16 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -449,9 +449,17 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
|||||||
static void
|
static void
|
||||||
window_destroy(struct window *w)
|
window_destroy(struct window *w)
|
||||||
{
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
|
||||||
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
||||||
|
|
||||||
window_unzoom(w, 0);
|
if (w->flags & WINDOW_ZOOMED) {
|
||||||
|
w->flags &= ~WINDOW_ZOOMED;
|
||||||
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
|
wp->flags &= ~PANE_ZOOMED;
|
||||||
|
wp->saved_layout_cell = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
RB_REMOVE(windows, &windows, w);
|
RB_REMOVE(windows, &windows, w);
|
||||||
|
|
||||||
layout_free_cell(w->layout_root, 0);
|
layout_free_cell(w->layout_root, 0);
|
||||||
@@ -2906,3 +2914,15 @@ window_pane_is_floating(struct window_pane *wp)
|
|||||||
return (0);
|
return (0);
|
||||||
return (1);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user