Add an option to set the character used for unused areas of the

terminal, GitHub issue 3110.
This commit is contained in:
nicm 2022-03-16 17:00:17 +00:00
parent bfbe972225
commit e6e737ac0b
6 changed files with 78 additions and 36 deletions

View File

@ -882,6 +882,13 @@ const struct options_table_entry options_table[] = {
.text = "Style of the marked line in copy mode." .text = "Style of the marked line in copy mode."
}, },
{ .name = "fill-character",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "",
.text = "Character used to fill unused parts of window."
},
{ .name = "main-pane-height", { .name = "main-pane-height",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,

View File

@ -1108,6 +1108,8 @@ options_push_changes(const char *name)
struct window_pane *wp; struct window_pane *wp;
int c; int c;
log_debug("%s: %s", __func__, name);
if (strcmp(name, "automatic-rename") == 0) { if (strcmp(name, "automatic-rename") == 0) {
RB_FOREACH(w, windows, &windows) { RB_FOREACH(w, windows, &windows) {
if (w->active == NULL) if (w->active == NULL)
@ -1130,6 +1132,10 @@ options_push_changes(const char *name)
&wp->screen->default_mode); &wp->screen->default_mode);
} }
} }
if (strcmp(name, "fill-character") == 0) {
RB_FOREACH(w, windows, &windows)
window_set_fill_character(w);
}
if (strcmp(name, "key-table") == 0) { if (strcmp(name, "key-table") == 0) {
TAILQ_FOREACH(loop, &clients, entry) TAILQ_FOREACH(loop, &clients, entry)
server_client_set_key_table(loop, NULL); server_client_set_key_table(loop, NULL);

View File

@ -47,11 +47,16 @@ enum screen_redraw_border_type {
/* Get cell border character. */ /* Get cell border character. */
static void static void
screen_redraw_border_set(struct window_pane *wp, enum pane_lines pane_lines, screen_redraw_border_set(struct window *w, struct window_pane *wp,
int cell_type, struct grid_cell *gc) enum pane_lines pane_lines, int cell_type, struct grid_cell *gc)
{ {
u_int idx; u_int idx;
if (cell_type == CELL_OUTSIDE && 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_OUTSIDE) { if (cell_type == CELL_OUTSIDE) {
@ -409,7 +414,7 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp,
else else
py = wp->yoff + wp->sy; py = wp->yoff + wp->sy;
cell_type = screen_redraw_type_of_cell(c, px, py, pane_status); cell_type = screen_redraw_type_of_cell(c, px, py, pane_status);
screen_redraw_border_set(wp, pane_lines, cell_type, &gc); screen_redraw_border_set(w, 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;
@ -690,7 +695,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
screen_redraw_check_is(x, y, pane_status, marked_pane.wp)) screen_redraw_check_is(x, y, pane_status, marked_pane.wp))
gc.attr ^= GRID_ATTR_REVERSE; gc.attr ^= GRID_ATTR_REVERSE;
} }
screen_redraw_border_set(wp, ctx->pane_lines, cell_type, &gc); screen_redraw_border_set(w, wp, ctx->pane_lines, cell_type, &gc);
if (cell_type == CELL_TOPBOTTOM && if (cell_type == CELL_TOPBOTTOM &&
(c->flags & CLIENT_UTF8) && (c->flags & CLIENT_UTF8) &&

3
tmux.1
View File

@ -4114,6 +4114,9 @@ Set clock colour.
.Xc .Xc
Set clock hour format. Set clock hour format.
.Pp .Pp
.It Ic fill-character Ar character
Set the character used to fill areas of the terminal unused by a window.
.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

66
tmux.h
View File

@ -1069,40 +1069,41 @@ RB_HEAD(window_pane_tree, window_pane);
/* Window structure. */ /* Window structure. */
struct window { struct window {
u_int id; u_int id;
void *latest; void *latest;
char *name; char *name;
struct event name_event; struct event name_event;
struct timeval name_time; struct timeval name_time;
struct event alerts_timer; struct event alerts_timer;
struct event offset_timer; struct event offset_timer;
struct timeval activity_time; struct timeval activity_time;
struct window_pane *active; struct window_pane *active;
struct window_pane *last; struct window_pane *last;
struct window_panes panes; struct window_panes panes;
int lastlayout; int lastlayout;
struct layout_cell *layout_root; struct layout_cell *layout_root;
struct layout_cell *saved_layout_root; struct layout_cell *saved_layout_root;
char *old_layout; char *old_layout;
u_int sx; u_int sx;
u_int sy; u_int sy;
u_int manual_sx; u_int manual_sx;
u_int manual_sy; u_int manual_sy;
u_int xpixel; u_int xpixel;
u_int ypixel; u_int ypixel;
u_int new_sx; u_int new_sx;
u_int new_sy; u_int new_sy;
u_int new_xpixel; u_int new_xpixel;
u_int new_ypixel; u_int new_ypixel;
int flags; struct utf8_data *fill_character;
int flags;
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
#define WINDOW_ACTIVITY 0x2 #define WINDOW_ACTIVITY 0x2
#define WINDOW_SILENCE 0x4 #define WINDOW_SILENCE 0x4
@ -1111,15 +1112,15 @@ struct window {
#define WINDOW_RESIZE 0x20 #define WINDOW_RESIZE 0x20
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
int alerts_queued; int alerts_queued;
TAILQ_ENTRY(window) alerts_entry; TAILQ_ENTRY(window) alerts_entry;
struct options *options; struct options *options;
u_int references; u_int references;
TAILQ_HEAD(, winlink) winlinks; TAILQ_HEAD(, winlink) winlinks;
RB_ENTRY(window) entry; RB_ENTRY(window) entry;
}; };
RB_HEAD(windows, window); RB_HEAD(windows, window);
@ -2976,6 +2977,7 @@ 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 *);
/* layout.c */ /* layout.c */
u_int layout_count_cells(struct layout_cell *); u_int layout_count_cells(struct layout_cell *);

View File

@ -331,6 +331,7 @@ 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);
window_update_activity(w); window_update_activity(w);
log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy, log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy,
@ -362,6 +363,7 @@ 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);
@ -1589,3 +1591,20 @@ window_pane_update_used_data(struct window_pane *wp,
size = EVBUFFER_LENGTH(wp->event->input) - used; size = EVBUFFER_LENGTH(wp->event->input) - used;
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;
}
}