diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 54c8db7d3..5bc996c2f 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-list-panes.c,v 1.40 2026/06/01 14:01:09 nicm Exp $ */ +/* $OpenBSD: cmd-list-panes.c,v 1.41 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -97,6 +97,7 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, struct cmdq_item *item, int type) { struct args *args = cmd_get_args(self); + struct client *c = cmdq_get_client(item); struct window_pane *wp, **l; u_int i, n; struct format_tree *ft; @@ -147,7 +148,7 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, wp = l[i]; ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0); format_add(ft, "line", "%u", n); - format_defaults(ft, NULL, s, wl, wp); + format_defaults(ft, c, s, wl, wp); if (filter != NULL) { expanded = format_expand(ft, filter); diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 07a622979..30f2178ad 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-list-sessions.c,v 1.36 2026/02/27 08:25:12 nicm Exp $ */ +/* $OpenBSD: cmd-list-sessions.c,v 1.37 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -53,6 +53,7 @@ static enum cmd_retval cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = cmd_get_args(self); + struct client *c = cmdq_get_client(item); struct session **l; u_int n, i; struct format_tree *ft; @@ -76,7 +77,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item) for (i = 0; i < n; i++) { ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0); format_add(ft, "line", "%u", i); - format_defaults(ft, NULL, l[i], NULL, NULL); + format_defaults(ft, c, l[i], NULL, NULL); if (filter != NULL) { expanded = format_expand(ft, filter); diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 40f8c2db5..2cbccc1b8 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-list-windows.c,v 1.50 2026/02/27 08:25:12 nicm Exp $ */ +/* $OpenBSD: cmd-list-windows.c,v 1.51 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -60,6 +60,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); + struct client *c = cmdq_get_client(item); struct winlink *wl, **l; struct session *s; u_int i, n; @@ -94,7 +95,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item) s = wl->session; ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0); format_add(ft, "line", "%u", n); - format_defaults(ft, NULL, s, wl, NULL); + format_defaults(ft, c, s, wl, NULL); if (filter != NULL) { expanded = format_expand(ft, filter); diff --git a/cmd-parse.y b/cmd-parse.y index 4a6ec66b1..a6541c930 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-parse.y,v 1.59 2026/08/31 07:51:56 nicm Exp $ */ +/* $OpenBSD: cmd-parse.y,v 1.60 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -210,7 +210,7 @@ expanded : format cmd_find_from_client(&fs, c, 0); fsp = &fs; } - ft = format_create(NULL, pi->item, FORMAT_NONE, flags); + ft = format_create(c, pi->item, FORMAT_NONE, flags); format_defaults(ft, c, fsp->s, fsp->wl, fsp->wp); $$ = format_expand(ft, $1); diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 741dc63f4..86effb03c 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-select-layout.c,v 1.43 2026/07/10 13:38:45 nicm Exp $ */ +/* $OpenBSD: cmd-select-layout.c,v 1.44 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -90,7 +90,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item) previous = 1; oldlayout = w->old_layout; - w->old_layout = layout_dump(w, w->layout_root); + w->old_layout = layout_dump(w, w->layout_root, 0); if (next || previous) { if (next) diff --git a/control-notify.c b/control-notify.c index adfc9dcb0..9aa90662b 100644 --- a/control-notify.c +++ b/control-notify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control-notify.c,v 1.38 2026/08/03 13:38:42 nicm Exp $ */ +/* $OpenBSD: control-notify.c,v 1.39 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2012 Nicholas Marriott @@ -70,6 +70,7 @@ control_window_layout_changed_cb(__unused const char *name, struct session *s; struct winlink *wl; struct window *w = event_payload_get_window(ep, "window"); + struct format_tree *ft; const char *template; char *cp; @@ -84,19 +85,25 @@ control_window_layout_changed_cb(__unused const char *name, * and we don't need to inform the client about the layout change * because the whole window will go away soon. */ - wl = TAILQ_FIRST(&w->winlinks); - if (wl == NULL || w->layout_root == NULL) + if (TAILQ_FIRST(&w->winlinks) == NULL || w->layout_root == NULL) return; - cp = format_single(NULL, template, NULL, NULL, wl, NULL); TAILQ_FOREACH(c, &clients, entry) { if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) continue; s = c->session; - if (winlink_find_by_window_id(&s->windows, w->id) != NULL) - control_notify_write(c, "%s", cp); + wl = winlink_find_by_window_id(&s->windows, w->id); + if (wl == NULL) + continue; + + ft = format_create(c, NULL, FORMAT_NONE, 0); + format_defaults(ft, c, s, wl, NULL); + cp = format_expand(ft, template); + format_free(ft); + + control_notify_write(c, "%s", cp); + free(cp); } - free(cp); } /* Notify control clients that window pane changed. */ diff --git a/format.c b/format.c index 78e3f0fb5..f8239fd02 100644 --- a/format.c +++ b/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.415 2026/08/31 19:34:09 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.416 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -855,26 +855,42 @@ format_cb_window_active_clients_list(struct format_tree *ft) static void * format_cb_window_layout(struct format_tree *ft) { - struct window *w = ft->w; + struct client *c = ft->c; + struct window *w = ft->w; + struct layout_cell *lcroot; + int flags = 0; if (w == NULL) return (NULL); if (w->saved_layout_root != NULL) - return (layout_dump(w, w->saved_layout_root)); - return (layout_dump(w, w->layout_root)); + lcroot = w->saved_layout_root; + else + lcroot = w->layout_root; + + if (c != NULL && + (c->flags & CLIENT_CONTROL) && + (~c->flags & CLIENT_CONTROL_NEWLAYOUTS)) + flags |= LAYOUT_CUSTOM_OLD_FORMAT; + return (layout_dump(w, lcroot, flags)); } /* Callback for window_visible_layout. */ static void * format_cb_window_visible_layout(struct format_tree *ft) { + struct client *c = ft->c; struct window *w = ft->w; + int flags = 0; if (w == NULL) return (NULL); - return (layout_dump(w, w->layout_root)); + if (c != NULL && + (c->flags & CLIENT_CONTROL) && + (~c->flags & CLIENT_CONTROL_NEWLAYOUTS)) + flags |= LAYOUT_CUSTOM_OLD_FORMAT; + return (layout_dump(w, w->layout_root, flags)); } /* Callback for pane_start_command. */ @@ -5234,6 +5250,7 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt) format_log(es, "session loop: $%u", s->id); if (active != NULL && ft->c != NULL && + ft->c->session != NULL && s->id == ft->c->session->id) use = active; else diff --git a/layout-custom.c b/layout-custom.c index c58e92028..3fa30347e 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: layout-custom.c,v 1.38 2026/07/16 12:36:58 nicm Exp $ */ +/* $OpenBSD: layout-custom.c,v 1.39 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott @@ -58,7 +58,7 @@ layout_checksum(const char *layout) /* Dump layout as a string. */ char * -layout_dump(struct window *w, struct layout_cell *root) +layout_dump(struct window *w, struct layout_cell *root, __unused int flags) { char layout[8192], *out; int bracket = 0; diff --git a/server-client.c b/server-client.c index 27ae9307b..d4bf3cc07 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.510 2026/09/01 19:50:58 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.511 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -3084,6 +3084,8 @@ server_client_control_flags(struct client *c, const char *next) return (CLIENT_CONTROL_NOOUTPUT); if (strcmp(next, "wait-exit") == 0) return (CLIENT_CONTROL_WAITEXIT); + if (strcmp(next, "new-layouts") == 0) + return (CLIENT_CONTROL_NEWLAYOUTS); return (0); } @@ -3150,6 +3152,8 @@ server_client_get_flags(struct client *c) strlcat(s, "no-output,", sizeof s); if (c->flags & CLIENT_CONTROL_WAITEXIT) strlcat(s, "wait-exit,", sizeof s); + if (c->flags & CLIENT_CONTROL_NEWLAYOUTS) + strlcat(s, "new-layouts,", sizeof s); if (c->flags & CLIENT_CONTROL_PAUSEAFTER) { xsnprintf(tmp, sizeof tmp, "pause-after=%u,", c->pause_age / 1000); diff --git a/tmux.1 b/tmux.1 index 71f1afc78..00b93866f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.1166 2026/09/08 08:33:10 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.1167 2026/09/08 10:20:08 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -1116,6 +1116,8 @@ The flags are: .Bl -tag -width Ds .It ignore\-size the client does not affect the size of other clients +.It new\-layouts +use the new layout string format .It no\-detach\-on\-destroy do not detach the client when the session it is attached to is destroyed if there are any other sessions diff --git a/tmux.h b/tmux.h index 3a37fb59f..4ceaceb57 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1435 2026/09/08 08:37:56 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1436 2026/09/08 10:20:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2297,7 +2297,7 @@ struct client { #define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL #define CLIENT_CONTROL_WAITEXIT 0x200000000ULL #define CLIENT_WINDOWSIZECHANGED 0x400000000ULL -/* 0x800000000ULL unused */ +#define CLIENT_CONTROL_NEWLAYOUTS 0x800000000ULL #define CLIENT_BRACKETPASTING 0x1000000000ULL #define CLIENT_ASSUMEPASTING 0x2000000000ULL #define CLIENT_WRITE_ACK 0x4000000000ULL @@ -3914,7 +3914,8 @@ int layout_remove_tile(struct window *, struct layout_cell *); int layout_insert_tile(struct window *, struct layout_cell *); /* layout-custom.c */ -char *layout_dump(struct window *, struct layout_cell *); +#define LAYOUT_CUSTOM_OLD_FORMAT 0x1 +char *layout_dump(struct window *, struct layout_cell *, int); int layout_parse(struct window *, const char *, char **); /* layout-set.c */