mirror of
https://github.com/tmux/tmux.git
synced 2026-08-03 14:08:59 +00:00
Add control mode flag window-layout-v2 to return new list-windows layout format.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -59,6 +59,7 @@ static enum cmd_retval
|
||||
cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = cmd_get_args(self);
|
||||
struct client *c = cmdq_get_client(item);
|
||||
struct cmd_find_state *target = cmdq_get_target(item);
|
||||
struct winlink *wl, **l;
|
||||
struct session *s;
|
||||
@@ -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);
|
||||
|
||||
@@ -57,19 +57,20 @@ control_notify_window_layout_changed(struct window *w)
|
||||
* 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)
|
||||
wl = winlink_find_by_window_id(&s->windows, w->id);
|
||||
if (wl != NULL) {
|
||||
cp = format_single(NULL, template, c, s, wl, NULL);
|
||||
control_write(c, "%s", cp);
|
||||
free(cp);
|
||||
}
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
15
format.c
15
format.c
@@ -839,6 +839,15 @@ format_cb_window_active_clients_list(struct format_tree *ft)
|
||||
}
|
||||
|
||||
/* Callback for window_layout. */
|
||||
static char *
|
||||
format_window_layout(struct format_tree *ft, struct layout_cell *root)
|
||||
{
|
||||
if (ft->c != NULL && (ft->c->flags & CLIENT_CONTROL) &&
|
||||
(ft->c->flags & CLIENT_CONTROL_WINDOWLAYOUTV2) == 0)
|
||||
return (layout_dump_legacy(root));
|
||||
return (layout_dump(ft->w, root));
|
||||
}
|
||||
|
||||
static void *
|
||||
format_cb_window_layout(struct format_tree *ft)
|
||||
{
|
||||
@@ -848,8 +857,8 @@ format_cb_window_layout(struct format_tree *ft)
|
||||
return (NULL);
|
||||
|
||||
if (w->saved_layout_root != NULL)
|
||||
return (layout_dump(w, w->saved_layout_root));
|
||||
return (layout_dump(w, w->layout_root));
|
||||
return (format_window_layout(ft, w->saved_layout_root));
|
||||
return (format_window_layout(ft, w->layout_root));
|
||||
}
|
||||
|
||||
/* Callback for window_visible_layout. */
|
||||
@@ -861,7 +870,7 @@ format_cb_window_visible_layout(struct format_tree *ft)
|
||||
if (w == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (layout_dump(w, w->layout_root));
|
||||
return (format_window_layout(ft, w->layout_root));
|
||||
}
|
||||
|
||||
/* Callback for pane_start_command. */
|
||||
|
||||
@@ -54,6 +54,8 @@ static struct layout_cell *layout_find_bottomright(struct layout_cell *);
|
||||
static u_short layout_checksum(const char *, const char *);
|
||||
static int layout_append(struct window *,
|
||||
struct layout_cell *, char *, size_t);
|
||||
static int layout_append_legacy(struct layout_cell *, char *,
|
||||
size_t);
|
||||
static int layout_append_geometry(char *, size_t, u_int,
|
||||
u_int, int, int);
|
||||
static int layout_check(struct layout_cell *);
|
||||
@@ -144,6 +146,83 @@ layout_dump(struct window *w, struct layout_cell *root)
|
||||
return (out);
|
||||
}
|
||||
|
||||
/* Dump layout using the legacy syntax. */
|
||||
char *
|
||||
layout_dump_legacy(struct layout_cell *root)
|
||||
{
|
||||
char layout[LAYOUT_STRING_MAX], *out;
|
||||
|
||||
*layout = '\0';
|
||||
if (layout_append_legacy(root, layout, sizeof layout) != 0)
|
||||
return (NULL);
|
||||
|
||||
xasprintf(&out, "%04hx,%s",
|
||||
layout_checksum(layout, layout + strlen(layout)), layout);
|
||||
return (out);
|
||||
}
|
||||
|
||||
/* Append information for a single cell using the legacy syntax. */
|
||||
static int
|
||||
layout_append_legacy(struct layout_cell *lc, char *buf, size_t len)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
char tmp[96];
|
||||
const char *brackets = "][";
|
||||
size_t tmplen;
|
||||
u_int sx, sy;
|
||||
int xoff, yoff;
|
||||
|
||||
if (len == 0)
|
||||
return (-1);
|
||||
if (lc == NULL)
|
||||
return (0);
|
||||
|
||||
sx = lc->sx;
|
||||
sy = lc->sy;
|
||||
xoff = lc->xoff;
|
||||
yoff = lc->yoff;
|
||||
if (lc->flags & LAYOUT_CELL_HIDDEN) {
|
||||
if (lc->saved_sx != UINT_MAX)
|
||||
sx = lc->saved_sx;
|
||||
if (lc->saved_sy != UINT_MAX)
|
||||
sy = lc->saved_sy;
|
||||
if (lc->saved_xoff != INT_MAX)
|
||||
xoff = lc->saved_xoff;
|
||||
if (lc->saved_yoff != INT_MAX)
|
||||
yoff = lc->saved_yoff;
|
||||
}
|
||||
|
||||
if (lc->wp != NULL) {
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d,%u", sx, sy,
|
||||
xoff, yoff, lc->wp->id);
|
||||
} else {
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d", sx, sy,
|
||||
xoff, yoff);
|
||||
}
|
||||
if (tmplen > (sizeof tmp) - 1 || strlcat(buf, tmp, len) >= len)
|
||||
return (-1);
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
brackets = "}{";
|
||||
/* FALLTHROUGH */
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
if (strlcat(buf, &brackets[1], len) >= len)
|
||||
return (-1);
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
if (layout_append_legacy(lcchild, buf, len) != 0)
|
||||
return (-1);
|
||||
if (strlcat(buf, ",", len) >= len)
|
||||
return (-1);
|
||||
}
|
||||
buf[strlen(buf) - 1] = brackets[0];
|
||||
break;
|
||||
case LAYOUT_WINDOWPANE:
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Append information for a single cell. */
|
||||
static int
|
||||
layout_append(struct window *w, struct layout_cell *lc, char *buf, size_t len)
|
||||
|
||||
@@ -2851,6 +2851,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, "window-layout-v2") == 0)
|
||||
return (CLIENT_CONTROL_WINDOWLAYOUTV2);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -2919,6 +2921,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_WINDOWLAYOUTV2)
|
||||
strlcat(s, "window-layout-v2,", sizeof s);
|
||||
if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
|
||||
xsnprintf(tmp, sizeof tmp, "pause-after=%u,",
|
||||
c->pause_age / 1000);
|
||||
|
||||
30
tmux.1
30
tmux.1
@@ -1113,6 +1113,9 @@ The flags are:
|
||||
the client has an independent active pane
|
||||
.It ignore\-size
|
||||
the client does not affect the size of other clients
|
||||
.It window\-layout\-v2
|
||||
the client receives the current layout serialization in control mode rather
|
||||
than the legacy serialization
|
||||
.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
|
||||
@@ -3387,6 +3390,9 @@ format variable.
|
||||
It is repeated for each pane from the same window.
|
||||
Its format is described under
|
||||
.Ic select\-layout .
|
||||
In control mode, it uses the legacy format unless the client has the
|
||||
.Ql window\-layout\-v2
|
||||
flag.
|
||||
.Tg lsw
|
||||
.It Xo Ic list\-windows
|
||||
.Op Fl ar
|
||||
@@ -3428,6 +3434,9 @@ The default format includes the layout of each window, also available with the
|
||||
format variable.
|
||||
The format is described under
|
||||
.Ic select\-layout .
|
||||
In control mode, the legacy format is used unless the client has the
|
||||
.Ql window\-layout\-v2
|
||||
flag.
|
||||
.Pp
|
||||
Layouts for multiple windows may be produced in a form suitable for
|
||||
.Ic select\-layout
|
||||
@@ -4069,10 +4078,18 @@ accepted and checked but are not generated by
|
||||
.Ic list\-windows .
|
||||
A layout must use one form consistently.
|
||||
In a legacy layout, panes are treated as tiled, visible and unzoomed.
|
||||
.Ic list\-windows
|
||||
and the
|
||||
Outside control mode,
|
||||
.Ql window_layout
|
||||
format variable generate the current format with a checksum.
|
||||
and
|
||||
.Ql window_visible_layout
|
||||
generate the current format with a checksum.
|
||||
In control mode, they generate the legacy format by default; a client with the
|
||||
.Ql window\-layout\-v2
|
||||
flag receives the current format instead.
|
||||
.Ic list\-windows
|
||||
uses
|
||||
.Ql window_layout
|
||||
for the layout in its default output.
|
||||
.Pp
|
||||
A serialized layout is a layout snapshot, not a complete session restoration.
|
||||
It rearranges existing panes and windows but does not create panes or windows.
|
||||
@@ -7323,7 +7340,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "window_id" Ta "" Ta "Unique window ID"
|
||||
.It Li "window_index" Ta "#I" Ta "Index of window"
|
||||
.It Li "window_last_flag" Ta "" Ta "1 if window is the last used"
|
||||
.It Li "window_layout" Ta "" Ta "Window layout description, including zoom and pane flags"
|
||||
.It Li "window_layout" Ta "" Ta "Window layout description (legacy by default in control mode)"
|
||||
.It Li "window_linked" Ta "" Ta "1 if window is linked across sessions"
|
||||
.It Li "window_linked_sessions" Ta "" Ta "Number of sessions this window is linked to"
|
||||
.It Li "window_linked_sessions_list" Ta "" Ta "List of sessions this window is linked to"
|
||||
@@ -7336,7 +7353,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "window_silence_flag" Ta "" Ta "1 if window has silence alert"
|
||||
.It Li "window_stack_index" Ta "" Ta "Index in session most recent stack"
|
||||
.It Li "window_start_flag" Ta "" Ta "1 if window has the lowest index"
|
||||
.It Li "window_visible_layout" Ta "" Ta "Window layout description, respecting zoomed window panes"
|
||||
.It Li "window_visible_layout" Ta "" Ta "Visible window layout description (legacy by default in control mode)"
|
||||
.It Li "window_width" Ta "" Ta "Width of window"
|
||||
.It Li "window_zoomed_flag" Ta "" Ta "1 if window is zoomed"
|
||||
.It Li "wrap_flag" Ta "" Ta "Pane wrap flag"
|
||||
@@ -8861,6 +8878,9 @@ The window's visible layout is
|
||||
.Ar window\-visible\-layout
|
||||
and the window flags are
|
||||
.Ar window\-flags .
|
||||
The layouts use the legacy serialization unless the client has the
|
||||
.Ql window\-layout\-v2
|
||||
flag, in which case they use the current serialization.
|
||||
.It Ic %message Ar message
|
||||
A message sent with the
|
||||
.Ic display\-message
|
||||
|
||||
3
tmux.h
3
tmux.h
@@ -2245,7 +2245,7 @@ struct client {
|
||||
#define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL
|
||||
#define CLIENT_CONTROL_WAITEXIT 0x200000000ULL
|
||||
#define CLIENT_WINDOWSIZECHANGED 0x400000000ULL
|
||||
/* 0x800000000ULL unused */
|
||||
#define CLIENT_CONTROL_WINDOWLAYOUTV2 0x800000000ULL
|
||||
#define CLIENT_BRACKETPASTING 0x1000000000ULL
|
||||
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
|
||||
/* 0x4000000000ULL unused */
|
||||
@@ -3740,6 +3740,7 @@ int layout_insert_tile(struct window *, struct layout_cell *);
|
||||
/* layout-custom.c */
|
||||
struct layout_prepared;
|
||||
char *layout_dump(struct window *, struct layout_cell *);
|
||||
char *layout_dump_legacy(struct layout_cell *);
|
||||
struct layout_prepared *layout_prepare(struct window *, const char *, char **);
|
||||
void layout_free_prepared(struct layout_prepared *);
|
||||
void layout_apply_prepared(struct window *, struct layout_prepared *);
|
||||
|
||||
Reference in New Issue
Block a user