Extend fill-character to allow inside and outside to be separate and use

a different default (filled characters rather than dots) for inside.
This commit is contained in:
nicm
2026-07-23 09:38:27 +00:00
committed by tmux update bot
parent 7277712ca8
commit 8862390c34
9 changed files with 111 additions and 54 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: cmd-break-pane.c,v 1.74 2026/07/15 13:02:33 nicm Exp $ */ /* $OpenBSD: cmd-break-pane.c,v 1.75 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -172,6 +172,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
w->name = clean_name(name, 0); w->name = clean_name(name, 0);
options_set_number(w->options, "automatic-rename", 0); options_set_number(w->options, "automatic-rename", 0);
} }
window_set_fill_cells(w);
layout_init(w, wp); layout_init(w, wp);
wp->flags |= PANE_CHANGED; wp->flags |= PANE_CHANGED;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: options-table.c,v 1.240 2026/07/21 11:52:13 nicm Exp $ */ /* $OpenBSD: options-table.c,v 1.241 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1460,8 +1460,8 @@ const struct options_table_entry options_table[] = {
{ .name = "fill-character", { .name = "fill-character",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.default_str = "", .default_str = "#{?is_inside,#[bg=themedarkgrey] ,#[fg=themelightgrey]#[acs]~}",
.text = "Character used to fill unused parts of window." .text = "Format used to fill unused parts of window."
}, },
{ .name = "main-pane-height", { .name = "main-pane-height",

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: options.c,v 1.90 2026/07/10 13:38:45 nicm Exp $ */ /* $OpenBSD: options.c,v 1.91 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1372,7 +1372,7 @@ options_push_changes(const char *name)
} }
if (strcmp(name, "fill-character") == 0) { if (strcmp(name, "fill-character") == 0) {
RB_FOREACH(w, windows, &windows) RB_FOREACH(w, windows, &windows)
window_set_fill_character(w); window_set_fill_cells(w);
} }
if (strcmp(name, "key-table") == 0) { if (strcmp(name, "key-table") == 0) {
TAILQ_FOREACH(loop, &clients, entry) TAILQ_FOREACH(loop, &clients, entry)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: screen-redraw.c,v 1.155 2026/07/21 13:27:41 nicm Exp $ */ /* $OpenBSD: screen-redraw.c,v 1.156 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>
@@ -320,7 +320,7 @@ redraw_reset_cell(struct redraw_build_ctx *bctx, u_int x, u_int y)
struct window *w = bctx->w; struct window *w = bctx->w;
memset(bc, 0, sizeof *bc); memset(bc, 0, sizeof *bc);
if (bctx->ox + x <= w->sx && bctx->oy + y <= w->sy) if (bctx->ox + x < w->sx && bctx->oy + y < w->sy)
bc->data.type = REDRAW_SPAN_EMPTY; bc->data.type = REDRAW_SPAN_EMPTY;
else else
bc->data.type = REDRAW_SPAN_OUTSIDE; bc->data.type = REDRAW_SPAN_OUTSIDE;
@@ -1232,9 +1232,15 @@ redraw_draw_border_span(struct redraw_draw_ctx *dctx,
if (wp == NULL) { if (wp == NULL) {
redraw_get_default_border_style(dctx, &gc, &pane_lines); redraw_get_default_border_style(dctx, &gc, &pane_lines);
if (span->data.type != REDRAW_SPAN_BORDER) if (span->data.type == REDRAW_SPAN_OUTSIDE)
pane_lines = PANE_LINES_SINGLE; window_get_fill_cell(w, 0, &gc);
window_get_border_cell(w, NULL, pane_lines, cell_type, &gc); else if (span->data.type == REDRAW_SPAN_EMPTY)
window_get_fill_cell(w, 1, &gc);
else {
if (span->data.type != REDRAW_SPAN_BORDER)
pane_lines = PANE_LINES_SINGLE;
window_get_border_cell(NULL, pane_lines, cell_type, &gc);
}
} else { } else {
window_pane_get_border_style(wp, c, &gc); window_pane_get_border_style(wp, c, &gc);
window_pane_get_border_cell(wp, cell_type, &gc); window_pane_get_border_cell(wp, cell_type, &gc);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: spawn.c,v 1.49 2026/07/15 13:02:33 nicm Exp $ */ /* $OpenBSD: spawn.c,v 1.50 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -224,6 +224,7 @@ spawn_window(struct spawn_context *sc, char **cause)
w->name = xstrdup(sc->name); w->name = xstrdup(sc->name);
options_set_number(w->options, "automatic-rename", 0); options_set_number(w->options, "automatic-rename", 0);
} }
window_set_fill_cells(w);
} }
/* Switch to the new window if required. */ /* Switch to the new window if required. */

13
tmux.1
View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.1148 2026/07/22 20:12:58 nicm Exp $ .\" $OpenBSD: tmux.1,v 1.1149 2026/07/23 09:38:27 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: July 22 2026 $ .Dd $Mdocdate: July 23 2026 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@@ -5712,8 +5712,13 @@ Set the time in milliseconds for which the indicators shown by the
.Ic display\-panes .Ic display\-panes
command appear. command appear.
.Pp .Pp
.It Ic fill\-character Ar character .It Ic fill\-character Ar format
Set the character used to fill areas of the terminal unused by a window. Set the format used to fill areas of the terminal unused by a pane.
The format is expanded once for areas inside the window with
.Ql is_inside
set, and once for areas outside the window with
.Ql is_outside
set.
.Pp .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

12
tmux.h
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tmux.h,v 1.1414 2026/07/22 20:12:58 nicm Exp $ */ /* $OpenBSD: tmux.h,v 1.1415 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1438,7 +1438,8 @@ struct window {
int sb; int sb;
int sb_pos; int sb_pos;
struct utf8_data *fill_character; struct grid_cell inside_cell;
struct grid_cell outside_cell;
int flags; int flags;
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
#define WINDOW_ACTIVITY 0x2 #define WINDOW_ACTIVITY 0x2
@@ -3732,7 +3733,6 @@ void *window_pane_get_new_data(struct window_pane *,
struct window_pane_offset *, size_t *); struct window_pane_offset *, size_t *);
void window_pane_update_used_data(struct window_pane *, void window_pane_update_used_data(struct window_pane *,
struct window_pane_offset *, size_t); struct window_pane_offset *, size_t);
void window_set_fill_character(struct window *);
void window_pane_default_cursor(struct window_pane *); void window_pane_default_cursor(struct window_pane *);
int window_pane_mode(struct window_pane *); int window_pane_mode(struct window_pane *);
int window_pane_show_scrollbar(struct window_pane *); int window_pane_show_scrollbar(struct window_pane *);
@@ -3760,8 +3760,10 @@ struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
int window_pane_is_floating(struct window_pane *); int window_pane_is_floating(struct window_pane *);
/* window-border.c */ /* window-border.c */
void window_get_border_cell(struct window *, struct window_pane *, void window_set_fill_cells(struct window *);
enum pane_lines, int, struct grid_cell *); void window_get_border_cell(struct window_pane *, enum pane_lines,
int, struct grid_cell *);
void window_get_fill_cell(struct window *, int, struct grid_cell *);
void window_pane_get_border_cell(struct window_pane *, int, void window_pane_get_border_cell(struct window_pane *, int,
struct grid_cell *); struct grid_cell *);
void window_pane_get_border_style(struct window_pane *, void window_pane_get_border_style(struct window_pane *,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: window-border.c,v 1.2 2026/07/17 12:42:51 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>
@@ -23,18 +23,82 @@
#include "tmux.h" #include "tmux.h"
/* Set window fill cell. */
static void
window_set_fill_cell(struct window *w, int inside, struct grid_cell *gc)
{
struct format_tree *ft;
struct screen s;
struct screen_write_ctx ctx;
struct grid_cell new_gc;
const char *value;
char *expanded;
memcpy(gc, &grid_default_cell, sizeof *gc);
gc->attr |= GRID_ATTR_CHARSET;
utf8_set(&gc->data, CELL_BORDERS[CELL_NONE]);
ft = format_create(NULL, NULL, FORMAT_WINDOW|w->id, FORMAT_NOJOBS);
format_defaults(ft, NULL, NULL, NULL, w->active);
format_add(ft, "is_inside", "%d", inside);
format_add(ft, "is_outside", "%d", !inside);
value = options_get_string(w->options, "fill-character");
expanded = format_expand(ft, value);
format_free(ft);
screen_init(&s, 1, 1, 0);
screen_write_start(&ctx, &s);
format_draw(&ctx, &grid_default_cell, 1, expanded, NULL, 0);
screen_write_stop(&ctx);
free(expanded);
grid_view_get_cell(s.grid, 0, 0, &new_gc);
if (new_gc.data.width == 1)
memcpy(gc, &new_gc, sizeof *gc);
screen_free(&s);
}
/* Set window fill cells. */
void
window_set_fill_cells(struct window *w)
{
window_set_fill_cell(w, 1, &w->inside_cell);
window_set_fill_cell(w, 0, &w->outside_cell);
}
/* Merge a window fill cell over an existing style. */
static void
window_copy_fill_cell(struct grid_cell *gc, const struct grid_cell *fill)
{
utf8_copy(&gc->data, &fill->data);
gc->attr |= fill->attr;
gc->flags |= fill->flags;
if (fill->fg != 8)
gc->fg = fill->fg;
if (fill->bg != 8)
gc->bg = fill->bg;
if (fill->us != 8)
gc->us = fill->us;
}
/* Get window fill cell. */
void
window_get_fill_cell(struct window *w, int inside, struct grid_cell *gc)
{
if (inside)
window_copy_fill_cell(gc, &w->inside_cell);
else
window_copy_fill_cell(gc, &w->outside_cell);
}
/* Get border cell. */ /* Get border cell. */
void void
window_get_border_cell(struct window *w, struct window_pane *wp, window_get_border_cell(struct window_pane *wp, enum pane_lines pane_lines,
enum pane_lines pane_lines, int cell_type, struct grid_cell *gc) int cell_type, struct grid_cell *gc)
{ {
u_int idx; u_int idx;
if (cell_type == CELL_NONE && w->fill_character != NULL) {
utf8_copy(&gc->data, &w->fill_character[0]);
return;
}
switch (pane_lines) { switch (pane_lines) {
case PANE_LINES_NUMBER: case PANE_LINES_NUMBER:
if (cell_type == CELL_NONE) { if (cell_type == CELL_NONE) {
@@ -79,7 +143,7 @@ window_pane_get_border_cell(struct window_pane *wp, int cell_type,
{ {
enum pane_lines pane_lines = window_pane_get_pane_lines(wp); enum pane_lines pane_lines = window_pane_get_pane_lines(wp);
window_get_border_cell(wp->window, wp, pane_lines, cell_type, gc); window_get_border_cell(wp, pane_lines, cell_type, gc);
} }
/* Get pane border style. */ /* Get pane border style. */
@@ -147,7 +211,7 @@ window_make_pane_status(struct window_pane *wp, struct client *c, u_int width,
pane_lines = window_pane_get_pane_lines(wp); pane_lines = window_pane_get_pane_lines(wp);
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
cell_type = redraw_get_status_border_cell_type(&span, i); cell_type = redraw_get_status_border_cell_type(&span, i);
window_get_border_cell(wp->window, wp, pane_lines, cell_type, &gc); window_get_border_cell(wp, pane_lines, cell_type, &gc);
screen_write_cell(&ctx, &gc); screen_write_cell(&ctx, &gc);
} }
gc.attr &= ~GRID_ATTR_CHARSET; gc.attr &= ~GRID_ATTR_CHARSET;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: window.c,v 1.367 2026/07/21 13:04:01 nicm Exp $ */ /* $OpenBSD: window.c,v 1.368 2026/07/23 09:38:27 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -439,8 +439,6 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
w->id = next_window_id++; w->id = next_window_id++;
RB_INSERT(windows, &windows, w); RB_INSERT(windows, &windows, w);
window_set_fill_character(w);
if (gettimeofday(&w->creation_time, NULL) != 0) if (gettimeofday(&w->creation_time, NULL) != 0)
fatal("gettimeofday failed"); fatal("gettimeofday failed");
window_update_activity(w); window_update_activity(w);
@@ -474,7 +472,6 @@ window_destroy(struct window *w)
event_del(&w->offset_timer); event_del(&w->offset_timer);
options_free(w->options); options_free(w->options);
free(w->fill_character);
free(w->name); free(w->name);
free(w); free(w);
@@ -2431,25 +2428,6 @@ window_pane_update_used_data(struct window_pane *wp,
wpo->used += size; wpo->used += size;
} }
void
window_set_fill_character(struct window *w)
{
const char *value;
struct utf8_data *ud;
free(w->fill_character);
w->fill_character = NULL;
value = options_get_string(w->options, "fill-character");
if (*value != '\0' && utf8_isvalid(value)) {
ud = utf8_fromcstr(value);
if (ud != NULL && ud[0].width == 1)
w->fill_character = ud;
else
free(ud);
}
}
void void
window_pane_default_cursor(struct window_pane *wp) window_pane_default_cursor(struct window_pane *wp)
{ {