Add -S and -s options to style floating panes.

This commit is contained in:
Michael Grant
2026-03-24 17:49:55 +00:00
parent ef01e9daf8
commit 75ed7b27c6
5 changed files with 147 additions and 20 deletions

View File

@@ -35,10 +35,10 @@ const struct cmd_entry cmd_new_pane_entry = {
.name = "new-pane", .name = "new-pane",
.alias = "newp", .alias = "newp",
.args = { "bc:de:fF:h:Iklm:p:Pt:w:x:y:Z", 0, -1, NULL }, .args = { "bc:de:fF:h:Iklm:p:Ps:S:t:w:x:y:Z", 0, -1, NULL },
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] [-m message] " CMD_TARGET_PANE_USAGE "[-F format] [-l size] [-m message] [-s style] [-S border-style] "
" [shell-command [argument ...]]", CMD_TARGET_PANE_USAGE " [shell-command [argument ...]]",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -62,7 +62,7 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
struct layout_cell *lc; struct layout_cell *lc;
struct cmd_find_state fs; struct cmd_find_state fs;
int flags, input; int flags, input;
const char *template; const char *template, *style;
char *cause = NULL, *cp; char *cause = NULL, *cp;
struct args_value *av; struct args_value *av;
u_int count = args_count(args); u_int count = args_count(args);
@@ -204,6 +204,27 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
environ_free(sc.environ); environ_free(sc.environ);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
style = args_get(args, 's');
if (style != NULL) {
if (options_set_string(new_wp->options, "window-style", 0,
"%s", style) == NULL) {
cmdq_error(item, "bad style: %s", style);
return (CMD_RETURN_ERROR);
}
options_set_string(new_wp->options, "window-active-style", 0,
"%s", style);
new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED|PANE_THEMECHANGED);
}
style = args_get(args, 'S');
if (style != NULL) {
if (options_set_string(new_wp->options, "pane-border-style", 0,
"%s", style) == NULL) {
cmdq_error(item, "bad border style: %s", style);
return (CMD_RETURN_ERROR);
}
options_set_string(new_wp->options, "pane-active-border-style",
0, "%s", style);
}
if (args_has(args, 'k') || args_has(args, 'm')) { if (args_has(args, 'k') || args_has(args, 'm')) {
options_set_number(new_wp->options, "remain-on-exit", 3); options_set_number(new_wp->options, "remain-on-exit", 3);
if (args_has(args, 'm')) if (args_has(args, 'm'))

View File

@@ -1207,6 +1207,28 @@ const struct options_table_entry options_table[] = {
.text = "Character used to fill unused parts of window." .text = "Character used to fill unused parts of window."
}, },
{ .name = "floating-pane-border-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "default",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Default border style for floating panes. "
"Overrides pane-border-style for floating panes unless "
"a per-pane style is set."
},
{ .name = "floating-pane-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "default",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Default content style for floating panes. "
"Overrides window-style for floating panes unless "
"a per-pane style is set."
},
{ .name = "main-pane-height", { .name = "main-pane-height",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
@@ -1283,7 +1305,7 @@ const struct options_table_entry options_table[] = {
{ .name = "pane-active-border-style", { .name = "pane-active-border-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "#{?pane_in_mode,fg=yellow,#{?synchronize-panes,fg=red,fg=green}}", .default_str = "#{?pane_in_mode,fg=yellow,#{?synchronize-panes,fg=red,fg=green}}",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",
@@ -1335,7 +1357,7 @@ const struct options_table_entry options_table[] = {
{ .name = "pane-border-style", { .name = "pane-border-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "default", .default_str = "default",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",

View File

@@ -600,7 +600,7 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp,
{ {
struct window *w = wp->window; struct window *w = wp->window;
struct grid_cell gc; struct grid_cell gc;
const char *fmt; const char *fmt, *border_opt;
struct format_tree *ft; struct format_tree *ft;
char *expanded; char *expanded;
int pane_status = rctx->pane_status, sb_w = 0; int pane_status = rctx->pane_status, sb_w = 0;
@@ -616,10 +616,19 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp,
ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS); ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS);
format_defaults(ft, c, c->session, c->session->curw, wp); format_defaults(ft, c, c->session, c->session->curw, wp);
if (wp == server_client_get_pane(c)) border_opt = (wp == server_client_get_pane(c)) ?
style_apply(&gc, w->options, "pane-active-border-style", ft); "pane-active-border-style" : "pane-border-style";
else
style_apply(&gc, w->options, "pane-border-style", ft); /* Window-level baseline. */
style_apply(&gc, w->options, border_opt, ft);
/* Floating pane window default overrides window baseline. */
if (wp->flags & PANE_FLOATING)
style_add(&gc, w->options, "floating-pane-border-style", ft);
/* Per-pane override (set via new-pane -S or set-option -p). */
if (options_get_only(wp->options, border_opt) != NULL)
style_add(&gc, wp->options, border_opt, ft);
fmt = options_get_string(wp->options, "pane-border-format"); fmt = options_get_string(wp->options, "pane-border-format");
expanded = format_expand_time(ft, fmt); expanded = format_expand_time(ft, fmt);
@@ -885,7 +894,8 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
struct session *s = c->session; struct session *s = c->session;
struct window *w = s->curw->window; struct window *w = s->curw->window;
struct window_pane *active = server_client_get_pane(c); struct window_pane *active = server_client_get_pane(c);
struct options *oo = w->options; struct options *wo = w->options;
const char *border_opt;
struct format_tree *ft; struct format_tree *ft;
if (wp->border_gc_set) if (wp->border_gc_set)
@@ -894,12 +904,21 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
ft = format_create_defaults(NULL, c, s, s->curw, wp); ft = format_create_defaults(NULL, c, s, s->curw, wp);
if (screen_redraw_check_is(ctx, x, y, active)) border_opt = screen_redraw_check_is(ctx, x, y, active) ?
style_apply(&wp->border_gc, oo, "pane-active-border-style", ft); "pane-active-border-style" : "pane-border-style";
else
style_apply(&wp->border_gc, oo, "pane-border-style", ft);
format_free(ft);
/* Window-level baseline. */
style_apply(&wp->border_gc, wo, border_opt, ft);
/* Floating pane window default overrides window baseline. */
if (wp->flags & PANE_FLOATING)
style_add(&wp->border_gc, wo, "floating-pane-border-style", ft);
/* Per-pane override (set via new-pane -S or set-option -p). */
if (options_get_only(wp->options, border_opt) != NULL)
style_add(&wp->border_gc, wp->options, border_opt, ft);
format_free(ft);
return (&wp->border_gc); return (&wp->border_gc);
} }

44
tmux.1
View File

@@ -3278,6 +3278,8 @@ but a different format may be specified with
.Op Fl l Ar size .Op Fl l Ar size
.Op Fl m Ar message .Op Fl m Ar message
.Op Fl p Ar percentage .Op Fl p Ar percentage
.Op Fl s Ar style
.Op Fl S Ar border-style
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl w Ar width .Op Fl w Ar width
.Op Fl x Ar x-position .Op Fl x Ar x-position
@@ -3334,6 +3336,12 @@ flag (if
is not specified or empty) is not specified or empty)
will create an empty pane and forward any output from stdin to it. will create an empty pane and forward any output from stdin to it.
.Pp .Pp
.Fl s
sets the style for the pane and
.Fl S
sets the style for the pane border (see
.Sx STYLES ) .
.Pp
All other options have the same meaning as for the All other options have the same meaning as for the
.Ic new-window .Ic new-window
command. command.
@@ -5178,6 +5186,42 @@ Set clock hour format.
.It Ic fill-character Ar character .It Ic fill-character Ar character
Set the character used to fill areas of the terminal unused by a window. Set the character used to fill areas of the terminal unused by a window.
.Pp .Pp
.It Ic floating-pane-border-style Ar style
Set the default border style for all floating panes in the window.
This overrides
.Ic pane-border-style
for floating panes.
A per-pane style set with
.Fl S
on the
.Ic new-pane
command or with
.Ic set-option Fl p
takes priority over this option.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic floating-pane-style Ar style
Set the default content style for all floating panes in the window.
This overrides
.Ic window-style
for floating panes.
A per-pane style set with
.Fl s
on the
.Ic new-pane
command or with
.Ic select-pane Fl P
takes priority over this option.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic main-pane-height Ar height .It Ic main-pane-height Ar height
.It Ic main-pane-width Ar width .It Ic main-pane-width Ar width
Set the width or height of the main (left or top) pane in the Set the width or height of the main (left or top) pane in the

27
tty.c
View File

@@ -3221,7 +3221,8 @@ tty_window_default_style(struct grid_cell *gc, struct window_pane *wp)
void void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp) tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{ {
struct options *oo = wp->options; struct window *w = wp->window;
struct options *wo = w->options;
struct format_tree *ft; struct format_tree *ft;
memcpy(gc, &grid_default_cell, sizeof *gc); memcpy(gc, &grid_default_cell, sizeof *gc);
@@ -3233,10 +3234,30 @@ tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, ft = format_create(NULL, NULL, FORMAT_PANE|wp->id,
FORMAT_NOJOBS); FORMAT_NOJOBS);
format_defaults(ft, NULL, NULL, NULL, wp); format_defaults(ft, NULL, NULL, NULL, wp);
/* Window-level baseline. */
tty_window_default_style(&wp->cached_active_gc, wp); tty_window_default_style(&wp->cached_active_gc, wp);
style_add(&wp->cached_active_gc, oo, "window-active-style", ft); style_add(&wp->cached_active_gc, wo, "window-active-style", ft);
/* Floating pane window default overrides window baseline. */
if (wp->flags & PANE_FLOATING)
style_add(&wp->cached_active_gc, wo,
"floating-pane-style", ft);
/* Per-pane override (set via new-pane -s or select-pane -P). */
if (options_get_only(wp->options, "window-active-style") != NULL)
style_add(&wp->cached_active_gc, wp->options,
"window-active-style", ft);
/* Window-level baseline. */
tty_window_default_style(&wp->cached_gc, wp); tty_window_default_style(&wp->cached_gc, wp);
style_add(&wp->cached_gc, oo, "window-style", ft); style_add(&wp->cached_gc, wo, "window-style", ft);
/* Floating pane window default overrides window baseline. */
if (wp->flags & PANE_FLOATING)
style_add(&wp->cached_gc, wo, "floating-pane-style", ft);
/* Per-pane override (set via new-pane -s or select-pane -P). */
if (options_get_only(wp->options, "window-style") != NULL)
style_add(&wp->cached_gc, wp->options,
"window-style", ft);
format_free(ft); format_free(ft);
} }