From 6a292f09ba575690c8af3ff8b5a94acbbe6acacf Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 5 Oct 2017 08:12:24 +0000 Subject: [PATCH 1/3] When writing batches of characters to the screen, we need to clear padding or later UTF-8 characters could be displayed incorrectly. GitHub issue 1090. --- screen-write.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/screen-write.c b/screen-write.c index 15f8d07f..f090d6fa 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1243,6 +1243,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx) struct screen *s = ctx->s; struct screen_write_collect_item *ci = ctx->item; struct grid_cell gc; + u_int xx; if (ci->used == 0) return; @@ -1255,9 +1256,27 @@ screen_write_collect_end(struct screen_write_ctx *ctx) log_debug("%s: %u %s (at %u,%u)", __func__, ci->used, ci->data, s->cx, s->cy); + if (s->cx != 0) { + for (xx = s->cx; xx > 0; xx--) { + grid_view_get_cell(s->grid, xx, s->cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) + break; + grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell); + } + if (gc.data.width > 1) + grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell); + } + memcpy(&gc, &ci->gc, sizeof gc); grid_view_set_cells(s->grid, s->cx, s->cy, &gc, ci->data, ci->used); s->cx += ci->used; + + for (xx = s->cx; xx < screen_size_x(s); xx++) { + grid_view_get_cell(s->grid, xx, s->cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) + break; + grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell); + } } /* Write cell data, collecting if necessary. */ @@ -1388,6 +1407,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) * already ensured there is enough room. */ for (xx = s->cx + 1; xx < s->cx + width; xx++) { + log_debug("%s: new padding at %u,%u", __func__, xx, s->cy); grid_view_set_cell(gd, xx, s->cy, &screen_write_pad_cell); skip = 0; } @@ -1537,10 +1557,12 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc, grid_view_get_cell(gd, xx, s->cy, &tmp_gc); if (~tmp_gc.flags & GRID_FLAG_PADDING) break; + log_debug("%s: padding at %u,%u", __func__, xx, s->cy); grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); } /* Overwrite the character at the start of this padding. */ + log_debug("%s: character at %u,%u", __func__, xx, s->cy); grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); done = 1; } @@ -1557,6 +1579,7 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc, grid_view_get_cell(gd, xx, s->cy, &tmp_gc); if (~tmp_gc.flags & GRID_FLAG_PADDING) break; + log_debug("%s: overwrite at %u,%u", __func__, xx, s->cy); grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); done = 1; } From 88517ceebb6cf31f661a1e265b2db6cbf61f09eb Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 5 Oct 2017 13:29:18 +0000 Subject: [PATCH 2/3] Add support for the xterm(1) title stack, from Brad Town, GitHub issue 1075. --- input.c | 25 +++++++++++++++++++-- screen.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tmux.h | 4 ++++ 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/input.c b/input.c index e4aecf7d..42ff7f3b 100644 --- a/input.c +++ b/input.c @@ -1693,12 +1693,33 @@ input_csi_dispatch_winops(struct input_ctx *ictx) /* FALLTHROUGH */ case 9: case 10: - case 22: - case 23: m++; if (input_get(ictx, m, 0, -1) == -1) return; break; + case 22: + m++; + switch (input_get(ictx, m, 0, -1)) { + case -1: + return; + case 0: + case 2: + screen_push_title(ictx->ctx.s); + break; + } + break; + case 23: + m++; + switch (input_get(ictx, m, 0, -1)) { + case -1: + return; + case 0: + case 2: + screen_pop_title(ictx->ctx.s); + server_status_window(ictx->wp->window); + break; + } + break; case 18: input_reply(ictx, "\033[8;%u;%ut", wp->sy, wp->sx); break; diff --git a/screen.c b/screen.c index ebd117a0..800dbe8f 100644 --- a/screen.c +++ b/screen.c @@ -25,17 +25,44 @@ #include "tmux.h" +struct screen_title_entry { + char *text; + + TAILQ_ENTRY(screen_title_entry) entry; +}; +TAILQ_HEAD(screen_titles, screen_title_entry); + static void screen_resize_x(struct screen *, u_int); static void screen_resize_y(struct screen *, u_int); static void screen_reflow(struct screen *, u_int); +/* Free titles stack. */ +static void +screen_free_titles(struct screen *s) +{ + struct screen_title_entry *title_entry; + + if (s->titles == NULL) + return; + + while ((title_entry = TAILQ_FIRST(s->titles)) != NULL) { + TAILQ_REMOVE(s->titles, title_entry, entry); + free(title_entry->text); + free(title_entry); + } + + free(s->titles); + s->titles = NULL; +} + /* Create a new screen. */ void screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit) { s->grid = grid_create(sx, sy, hlimit); s->title = xstrdup(""); + s->titles = NULL; s->cstyle = 0; s->ccolour = xstrdup(""); @@ -61,6 +88,7 @@ screen_reinit(struct screen *s) grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8); screen_clear_selection(s); + screen_free_titles(s); } /* Destroy a screen. */ @@ -70,7 +98,10 @@ screen_free(struct screen *s) free(s->tabs); free(s->title); free(s->ccolour); + grid_destroy(s->grid); + + screen_free_titles(s); } /* Reset tabs to default, eight spaces apart. */ @@ -111,6 +142,43 @@ screen_set_title(struct screen *s, const char *title) utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); } +/* Push the current title onto the stack. */ +void +screen_push_title(struct screen *s) +{ + struct screen_title_entry *title_entry; + + if (s->titles == NULL) { + s->titles = xmalloc(sizeof *s->titles); + TAILQ_INIT(s->titles); + } + title_entry = xmalloc(sizeof *title_entry); + title_entry->text = xstrdup(s->title); + TAILQ_INSERT_HEAD(s->titles, title_entry, entry); +} + +/* + * Pop a title from the stack and set it as the screen title. If the stack is + * empty, do nothing. + */ +void +screen_pop_title(struct screen *s) +{ + struct screen_title_entry *title_entry; + + if (s->titles == NULL) + return; + + title_entry = TAILQ_FIRST(s->titles); + if (title_entry != NULL) { + screen_set_title(s, title_entry->text); + + TAILQ_REMOVE(s->titles, title_entry, entry); + free(title_entry->text); + free(title_entry); + } +} + /* Resize screen. */ void screen_resize(struct screen *s, u_int sx, u_int sy, int reflow) diff --git a/tmux.h b/tmux.h index c3524cb8..a661a6da 100644 --- a/tmux.h +++ b/tmux.h @@ -660,8 +660,10 @@ struct screen_sel { }; /* Virtual screen. */ +struct screen_titles; struct screen { char *title; + struct screen_titles *titles; struct grid *grid; /* grid data */ @@ -2082,6 +2084,8 @@ void screen_reset_tabs(struct screen *); void screen_set_cursor_style(struct screen *, u_int); void screen_set_cursor_colour(struct screen *, const char *); void screen_set_title(struct screen *, const char *); +void screen_push_title(struct screen *); +void screen_pop_title(struct screen *); void screen_resize(struct screen *, u_int, u_int, int); void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int, u_int, struct grid_cell *); From b462063cd59647e7f98eb11bde9bb0fef41bb2bd Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 5 Oct 2017 13:43:34 +0000 Subject: [PATCH 3/3] Add -- to some key bindings so leading -s work. --- key-bindings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/key-bindings.c b/key-bindings.c index badbc0f4..76778009 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -162,13 +162,13 @@ key_bindings_init(void) "bind ! break-pane", "bind '\"' split-window", "bind '#' list-buffers", - "bind '$' command-prompt -I'#S' \"rename-session '%%'\"", + "bind '$' command-prompt -I'#S' \"rename-session -- '%%'\"", "bind % split-window -h", "bind & confirm-before -p\"kill-window #W? (y/n)\" kill-window", "bind \"'\" command-prompt -pindex \"select-window -t ':%%'\"", "bind ( switch-client -p", "bind ) switch-client -n", - "bind , command-prompt -I'#W' \"rename-window '%%'\"", + "bind , command-prompt -I'#W' \"rename-window -- '%%'\"", "bind - delete-buffer", "bind . command-prompt \"move-window -t '%%'\"", "bind 0 select-window -t:=0", @@ -192,7 +192,7 @@ key_bindings_init(void) "bind ] paste-buffer", "bind c new-window", "bind d detach-client", - "bind f command-prompt \"find-window '%%'\"", + "bind f command-prompt \"find-window -- '%%'\"", "bind i display-message", "bind l last-window", "bind m select-pane -m",