From c739772436aef2aeb6f008def73584d348d012e7 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 16 Sep 2019 09:01:56 +0100 Subject: [PATCH 01/22] 3.0-rc5. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 21e8926d..fb15e09f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], 3.0-rc4) +AC_INIT([tmux], 3.0-rc5) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) From 6f8f4bb2063ccc72ed665a13215accc72a75d55f Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Sep 2019 09:58:58 +0000 Subject: [PATCH 02/22] Make select-pane -P set window-active-style also to match previous behaviour, reported by Thomas Sattler. --- cmd-select-pane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 52c58dbc..b46f7cd9 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -151,6 +151,8 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "bad style: %s", style); return (CMD_RETURN_ERROR); } + options_set_style(wp->options, "window-active-style", 0, + style); wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED); } if (args_has(self->args, 'g')) { From a74e37d32d5cd6654444d6517add43e3a91f14f0 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Sep 2019 14:50:08 +0000 Subject: [PATCH 03/22] Mouse formats don't work in copy mode so don't try to use them. --- format.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/format.c b/format.c index eb7a9e53..6d85f3fc 100644 --- a/format.c +++ b/format.c @@ -737,6 +737,8 @@ format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe) wp = cmd_mouse_pane(&ft->m, NULL, NULL); if (wp == NULL) return; + if (!TAILQ_EMPTY (&wp->modes)) + return; if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) return; gd = wp->base.grid; @@ -813,6 +815,8 @@ format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) wp = cmd_mouse_pane(&ft->m, NULL, NULL); if (wp == NULL) return; + if (!TAILQ_EMPTY (&wp->modes)) + return; if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) return; gd = wp->base.grid; From e6995196f22c24fc76ffe1d83d987ae5fd270619 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 16 Sep 2019 13:27:14 +0000 Subject: [PATCH 04/22] Change menu key bindings to Up and Down and also close it on any mouse press if opened by key. --- key-bindings.c | 4 ++-- menu.c | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/key-bindings.c b/key-bindings.c index 0c9ba67b..afb07ce6 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -329,10 +329,10 @@ key_bindings_init(void) "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\" " DEFAULT_CLIENT_MENU, "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\" " DEFAULT_SESSION_MENU, "bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, - "bind C-m display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, + "bind Up display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, "bind -n MouseDown3Pane if -Ft= '#{||:#{mouse_any_flag},#{pane_in_mode}}' 'select-pane -t=; send-keys -M' {display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU "}", "bind -n M-MouseDown3Pane display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, - "bind M-m display-menu -xP -yP -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, + "bind Down display-menu -xP -yP -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, "bind -Tcopy-mode C-Space send -X begin-selection", "bind -Tcopy-mode C-a send -X start-of-line", diff --git a/menu.c b/menu.c index da8d89c4..6024ba02 100644 --- a/menu.c +++ b/menu.c @@ -185,8 +185,11 @@ menu_key_cb(struct client *c, struct key_event *event) const char *name; if (KEYC_IS_MOUSE(event->key)) { - if (md->flags & MENU_NOMOUSE) + if (md->flags & MENU_NOMOUSE) { + if (MOUSE_BUTTONS(m->b) != 0) + return (1); return (0); + } if (m->x < md->px || m->x > md->px + 4 + menu->width || m->y < md->py + 1 || From 9d1cecea8ef4ddafc666e0d3dcad4fae21170be8 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 18 Sep 2019 15:09:05 +0000 Subject: [PATCH 05/22] Up and Down are already used, use < and > instead. --- key-bindings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/key-bindings.c b/key-bindings.c index afb07ce6..ea793a2f 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -329,10 +329,10 @@ key_bindings_init(void) "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\" " DEFAULT_CLIENT_MENU, "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\" " DEFAULT_SESSION_MENU, "bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, - "bind Up display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, + "bind < display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, "bind -n MouseDown3Pane if -Ft= '#{||:#{mouse_any_flag},#{pane_in_mode}}' 'select-pane -t=; send-keys -M' {display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU "}", "bind -n M-MouseDown3Pane display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, - "bind Down display-menu -xP -yP -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, + "bind > display-menu -xP -yP -T \"#[align=centre]#{pane_index} (#{pane_id})\" " DEFAULT_PANE_MENU, "bind -Tcopy-mode C-Space send -X begin-selection", "bind -Tcopy-mode C-a send -X start-of-line", From f0712a7569c4a14276567bad123e18214c9137db Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 18 Sep 2019 11:37:58 +0000 Subject: [PATCH 06/22] Do not set uninitialized signal mask when creating an empty pane. --- spawn.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spawn.c b/spawn.c index 2a588b6b..b8397b75 100644 --- a/spawn.c +++ b/spawn.c @@ -330,14 +330,6 @@ spawn_pane(struct spawn_context *sc, char **cause) cmd_log_argv(new_wp->argc, new_wp->argv, "%s", __func__); environ_log(child, "%s: environment ", __func__); - /* If the command is empty, don't fork a child process. */ - if (sc->flags & SPAWN_EMPTY) { - new_wp->flags |= PANE_EMPTY; - new_wp->base.mode &= ~MODE_CURSOR; - new_wp->base.mode |= MODE_CRLF; - goto complete; - } - /* Initialize the window size. */ memset(&ws, 0, sizeof ws); ws.ws_col = screen_size_x(&new_wp->base); @@ -347,6 +339,14 @@ spawn_pane(struct spawn_context *sc, char **cause) sigfillset(&set); sigprocmask(SIG_BLOCK, &set, &oldset); + /* If the command is empty, don't fork a child process. */ + if (sc->flags & SPAWN_EMPTY) { + new_wp->flags |= PANE_EMPTY; + new_wp->base.mode &= ~MODE_CURSOR; + new_wp->base.mode |= MODE_CRLF; + goto complete; + } + /* Fork the new process. */ new_wp->pid = fdforkpty(ptm_fd, &new_wp->fd, new_wp->tty, NULL, &ws); if (new_wp->pid == -1) { From 47c0405b332e080e483e04752fd93955a8140505 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Oct 2019 09:16:48 +0000 Subject: [PATCH 07/22] Some old tmux versions can sometimes generate layout strings which have the incorrect size for the top cell. Previously tmux didn't care but now that panes can be partly hidden, the size matters and is checked more strictly. So add some code to fix up the most common problem and a sanity check to reject layouts with any other size problems. Reported by Aleksandrs Ledovskis in GitHub issue 1930. --- layout-custom.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/layout-custom.c b/layout-custom.c index d759c206..e02eead3 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -116,13 +116,49 @@ layout_append(struct layout_cell *lc, char *buf, size_t len) return (0); } +/* Check layout sizes fit. */ +static int +layout_check(struct layout_cell *lc) +{ + struct layout_cell *lcchild; + u_int n = 0; + + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sy != lc->sy) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sx + 1; + } + if (n - 1 != lc->sx) + return (0); + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sx != lc->sx) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sy + 1; + } + if (n - 1 != lc->sy) + return (0); + break; + } + return (1); +} + /* Parse a layout string and arrange window as layout. */ int layout_parse(struct window *w, const char *layout) { struct layout_cell *lc, *lcchild; struct window_pane *wp; - u_int npanes, ncells; + u_int npanes, ncells, sx = 0, sy = 0; u_short csum; /* Check validity. */ @@ -153,6 +189,37 @@ layout_parse(struct window *w, const char *layout) layout_destroy_cell(w, lcchild, &lc); } + /* + * It appears older versions of tmux were able to generate layouts with + * an incorrect top cell size - if it is larger than the top child then + * correct that (if this is still wrong the check code will catch it). + */ + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sy = lcchild->sy + 1; + sx += lcchild->sx + 1; + } + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sx = lcchild->sx + 1; + sy += lcchild->sy + 1; + } + break; + } + if (lc->sx != sx || lc->sy != sy) { + log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy); + layout_print_cell(lc, __func__, 0); + lc->sx = sx - 1; lc->sy = sy - 1; + } + + /* Check the new layout. */ + if (!layout_check(lc)) + return (-1); + /* Resize to the layout size. */ window_resize(w, lc->sx, lc->sy); From bbcb19917447b960b355ace88ce25c70cf2fd245 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 26 Nov 2019 13:16:51 +0000 Subject: [PATCH 08/22] 3.0 version. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fb15e09f..8b7f171e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], 3.0-rc5) +AC_INIT([tmux], 3.0) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) From b2fd161b071a7076d33119c0ff9aefdd548ff25f Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 19 Oct 2019 12:40:42 +0000 Subject: [PATCH 09/22] Do not crash trying to fix layout size if only one cell, from Azat Khuzhin. --- layout-custom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout-custom.c b/layout-custom.c index e02eead3..7d731d19 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -210,7 +210,7 @@ layout_parse(struct window *w, const char *layout) } break; } - if (lc->sx != sx || lc->sy != sy) { + if (lc->type != LAYOUT_WINDOWPANE && (lc->sx != sx || lc->sy != sy)) { log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy); layout_print_cell(lc, __func__, 0); lc->sx = sx - 1; lc->sy = sy - 1; From 5afe7eb850eeb812bdd92cebf1ab21f45c6dd814 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 3 Oct 2019 10:24:05 +0000 Subject: [PATCH 10/22] Do not lazily use BUFSIZ for "I don't care what size" when building strings because it is only guaranteed to be 256 bytes and even the default 1024 is not always enough. Reported by Gregory Pakosz. --- cmd-list-keys.c | 2 +- cmd-parse.y | 4 ++-- cmd.c | 2 +- layout-custom.c | 2 +- tty-term.c | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 57f65c8e..ef862101 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -61,7 +61,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) struct key_table *table; struct key_binding *bd; const char *tablename, *r; - char *key, *cp, tmp[BUFSIZ]; + char *key, *cp, tmp[8192]; int repeat, width, tablewidth, keywidth; if (self->entry == &cmd_list_commands_entry) diff --git a/cmd-parse.y b/cmd-parse.y index 6d2b970c..a51e4f6e 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1245,7 +1245,7 @@ yylex_token_variable(char **buf, size_t *len) { struct environ_entry *envent; int ch, brackets = 0; - char name[BUFSIZ]; + char name[1024]; size_t namelen = 0; const char *value; @@ -1297,7 +1297,7 @@ yylex_token_tilde(char **buf, size_t *len) { struct environ_entry *envent; int ch; - char name[BUFSIZ]; + char name[1024]; size_t namelen = 0; struct passwd *pw; const char *home = NULL; diff --git a/cmd.c b/cmd.c index 96cedc97..f77176c9 100644 --- a/cmd.c +++ b/cmd.c @@ -384,7 +384,7 @@ cmd_find(const char *name, char **cause) { const struct cmd_entry **loop, *entry, *found = NULL; int ambiguous; - char s[BUFSIZ]; + char s[8192]; ambiguous = 0; for (loop = cmd_table; *loop != NULL; loop++) { diff --git a/layout-custom.c b/layout-custom.c index 7d731d19..d7371292 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -60,7 +60,7 @@ layout_checksum(const char *layout) char * layout_dump(struct layout_cell *root) { - char layout[BUFSIZ], *out; + char layout[8192], *out; *layout = '\0'; if (layout_append(root, layout, sizeof layout) != 0) diff --git a/tty-term.c b/tty-term.c index 182edd7d..c7c3d11f 100644 --- a/tty-term.c +++ b/tty-term.c @@ -281,7 +281,7 @@ static char * tty_term_strip(const char *s) { const char *ptr; - static char buf[BUFSIZ]; + static char buf[8192]; size_t len; /* Ignore strings with no padding. */ @@ -309,7 +309,7 @@ tty_term_strip(const char *s) static char * tty_term_override_next(const char *s, size_t *offset) { - static char value[BUFSIZ]; + static char value[8192]; size_t n = 0, at = *offset; if (s[at] == '\0') From c942f11ba89cfb8dc74908609669fd78f1276ba7 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 27 Nov 2019 20:48:30 +0000 Subject: [PATCH 11/22] Use a malloc'd buffer for lsk since commands can be very long, from Gregory Pakosz. --- cmd-list-keys.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index ef862101..8636b70a 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -61,8 +61,9 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) struct key_table *table; struct key_binding *bd; const char *tablename, *r; - char *key, *cp, tmp[8192]; + char *key, *cp, *tmp; int repeat, width, tablewidth, keywidth; + size_t tmpsize, tmpused, cplen; if (self->entry == &cmd_list_commands_entry) return (cmd_list_keys_commands(self, item)); @@ -101,6 +102,9 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) table = key_bindings_next_table(table); } + tmpsize = 256; + tmp = xmalloc(tmpsize); + table = key_bindings_first_table (); while (table != NULL) { if (tablename != NULL && strcmp(table->name, tablename) != 0) { @@ -117,20 +121,35 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) r = "-r "; else r = " "; - xsnprintf(tmp, sizeof tmp, "%s-T ", r); + tmpused = xsnprintf(tmp, tmpsize, "%s-T ", r); cp = utf8_padcstr(table->name, tablewidth); - strlcat(tmp, cp, sizeof tmp); - strlcat(tmp, " ", sizeof tmp); + cplen = strlen(cp) + 1; + while (tmpused + cplen + 1 >= tmpsize) { + tmpsize *= 2; + tmp = xrealloc(tmp, tmpsize); + } + tmpused = strlcat(tmp, cp, tmpsize); + tmpused = strlcat(tmp, " ", tmpsize); free(cp); cp = utf8_padcstr(key, keywidth); - strlcat(tmp, cp, sizeof tmp); - strlcat(tmp, " ", sizeof tmp); + cplen = strlen(cp) + 1; + while (tmpused + cplen + 1 >= tmpsize) { + tmpsize *= 2; + tmp = xrealloc(tmp, tmpsize); + } + tmpused = strlcat(tmp, cp, tmpsize); + tmpused = strlcat(tmp, " ", tmpsize); free(cp); cp = cmd_list_print(bd->cmdlist, 1); - strlcat(tmp, cp, sizeof tmp); + cplen = strlen(cp); + while (tmpused + cplen + 1 >= tmpsize) { + tmpsize *= 2; + tmp = xrealloc(tmp, tmpsize); + } + strlcat(tmp, cp, tmpsize); free(cp); cmdq_print(item, "bind-key %s", tmp); @@ -141,6 +160,8 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) table = key_bindings_next_table(table); } + free(tmp); + return (CMD_RETURN_NORMAL); } From 0134574a67051b862ea25123bb24d6b557dbdad9 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 27 Nov 2019 20:49:59 +0000 Subject: [PATCH 12/22] 3.0a. --- CHANGES | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index f4ff86d2..e38b859b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ CHANGES FROM 2.9 to 3.0 +* Workaround invalid layout strings generated by older tmux versions and add + some additional sanity checks + * xterm 348 now disables margins when resized, so send DECLRMM again after resize. diff --git a/configure.ac b/configure.ac index 8b7f171e..57c3fd73 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], 3.0) +AC_INIT([tmux], 3.0a) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) From 640149337f54cc298cc7ff2e296545af04aed3bf Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 28 Nov 2019 10:55:45 +0000 Subject: [PATCH 13/22] Missing after-kill-pane option. --- options-table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/options-table.c b/options-table.c index ba7db3e1..67fe553a 100644 --- a/options-table.c +++ b/options-table.c @@ -794,6 +794,7 @@ const struct options_table_entry options_table[] = { OPTIONS_TABLE_HOOK("after-copy-mode", ""), OPTIONS_TABLE_HOOK("after-display-message", ""), OPTIONS_TABLE_HOOK("after-display-panes", ""), + OPTIONS_TABLE_HOOK("after-kill-pane", ""), OPTIONS_TABLE_HOOK("after-list-buffers", ""), OPTIONS_TABLE_HOOK("after-list-clients", ""), OPTIONS_TABLE_HOOK("after-list-keys", ""), From ad98fad9a3130b60ee2eba5312506ef531500117 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 28 Nov 2019 21:18:38 +0000 Subject: [PATCH 14/22] Do not crash when a format doesn't exist, reported by Thomas Sattler. --- format.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/format.c b/format.c index 6d85f3fc..7da6c802 100644 --- a/format.c +++ b/format.c @@ -1104,11 +1104,10 @@ format_find(struct format_tree *ft, const char *key, int modifiers) xasprintf(&found, "%lld", (long long)fe->t); goto found; } - if (fe->value == NULL && fe->cb != NULL) { + if (fe->value == NULL && fe->cb != NULL) fe->cb(ft, fe); - if (fe->value == NULL) - fe->value = xstrdup(""); - } + if (fe->value == NULL) + fe->value = xstrdup(""); found = xstrdup(fe->value); goto found; } From 48897fbc44ebd19362ec51bc88490790618daa81 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 7 Oct 2019 07:14:07 +0000 Subject: [PATCH 15/22] Fix respawn-pane/window if default-command is set, reported by Janos Barbero. --- spawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spawn.c b/spawn.c index b8397b75..348a4e5e 100644 --- a/spawn.c +++ b/spawn.c @@ -250,7 +250,7 @@ spawn_pane(struct spawn_context *sc, char **cause) * Now we have a pane with nothing running in it ready for the new * process. Work out the command and arguments. */ - if (sc->argc == 0) { + if (sc->argc == 0 && (~sc->flags & SPAWN_RESPAWN)) { cmd = options_get_string(s->options, "default-command"); if (cmd != NULL && *cmd != '\0') { argc = 1; From a52fe9cf7facfe201ad12dc171a6c51d15ca317c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 1 Dec 2019 08:50:45 +0000 Subject: [PATCH 16/22] Add to CHANGES. --- CHANGES | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index e38b859b..ec57776d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +CHANGES FROM 3.0 to 3.0a + +* Respawn panes or windows correctly if default-command is set. + +* Add missing option for after-kill-pane hook. + +* Fix for crash with a format variable that doesn't exist. + +* Do not truncate list-keys output on some platforms. + +* Do not crash when restoring a layout with only one pane. + CHANGES FROM 2.9 to 3.0 * Workaround invalid layout strings generated by older tmux versions and add From 1b0cc4503e14932e5f14167102cb2504b7af69da Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 Nov 2019 20:54:30 +0000 Subject: [PATCH 17/22] REG_STARTEND is not portable, but it turns out we don't actually need it. From Evan Green, GitHub issue 1982. --- regsub.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/regsub.c b/regsub.c index 89355bef..8de3fa3a 100644 --- a/regsub.c +++ b/regsub.c @@ -77,10 +77,7 @@ regsub(const char *pattern, const char *with, const char *text, int flags) end = strlen(text); while (start <= end) { - m[0].rm_so = start; - m[0].rm_eo = end; - - if (regexec(&r, text, nitems(m), m, REG_STARTEND) != 0) { + if (regexec(&r, text + start, nitems(m), m, 0) != 0) { regsub_copy(&buf, &len, text, start, end); break; } @@ -89,22 +86,25 @@ regsub(const char *pattern, const char *with, const char *text, int flags) * Append any text not part of this match (from the end of the * last match). */ - regsub_copy(&buf, &len, text, last, m[0].rm_so); + regsub_copy(&buf, &len, text, last, m[0].rm_so + start); /* * If the last match was empty and this one isn't (it is either * later or has matched text), expand this match. If it is * empty, move on one character and try again from there. */ - if (empty || m[0].rm_so != last || m[0].rm_so != m[0].rm_eo) { - regsub_expand(&buf, &len, with, text, m, nitems(m)); + if (empty || + start + m[0].rm_so != last || + m[0].rm_so != m[0].rm_eo) { + regsub_expand(&buf, &len, with, text + start, m, + nitems(m)); - last = m[0].rm_eo; - start = m[0].rm_eo; + last = start + m[0].rm_eo; + start += m[0].rm_eo; empty = 0; } else { - last = m[0].rm_eo; - start = m[0].rm_eo + 1; + last = start + m[0].rm_eo; + start += m[0].rm_eo + 1; empty = 1; } } From 25ae02869544b84b639b25b0aa69baa6ea2d3a6a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 1 Dec 2019 08:53:10 +0000 Subject: [PATCH 18/22] Add to CHANGES. --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index ec57776d..4399ba6d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ CHANGES FROM 3.0 to 3.0a +* Do not require REG_STARTEND. + * Respawn panes or windows correctly if default-command is set. * Add missing option for after-kill-pane hook. From 2173365f4f5713a65845f3e993d3092da956746d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 1 Dec 2019 21:15:21 +0000 Subject: [PATCH 19/22] Fix keys in CHANGES. --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 876d9173..051c8e05 100644 --- a/CHANGES +++ b/CHANGES @@ -163,7 +163,7 @@ CHANGES FROM 2.9 to 3.0 * Add the ability to create simple menus. Introduces new command display-menu. Default menus are bound to MouseDown3 on the status line; MouseDown3 or M-MouseDown3 on panes; MouseDown3 in tree, client and - buffer modes; and C-b C-m and C-b M-m. + buffer modes; and C-b < and >. * Allow panes to be empty (no command). They can be created either by piping to split-window -I, or by passing an empty command ('') to split-window. Output From ec1b8e5f05fa26b3ef9d0cd6cb810446b66bc0ac Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 2 Dec 2019 19:25:52 +0000 Subject: [PATCH 20/22] Remove client menu, I don't think it adds anything. --- key-bindings.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/key-bindings.c b/key-bindings.c index 175af8f4..d4fada6a 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -24,12 +24,6 @@ #include "tmux.h" -#define DEFAULT_CLIENT_MENU \ - " 'Detach' 'd' {detach-client}" \ - " 'Detach & Kill' 'X' {detach-client -P}" \ - " 'Detach Others' 'o' {detach-client -a}" \ - " ''" \ - " 'Lock' 'l' {lock-client}" #define DEFAULT_SESSION_MENU \ " 'Next' 'n' {switch-client -n}" \ " 'Previous' 'p' {switch-client -p}" \ @@ -325,7 +319,6 @@ key_bindings_init(void) "bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'", "bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'", - "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\" " DEFAULT_CLIENT_MENU, "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\" " DEFAULT_SESSION_MENU, "bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, "bind < display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU, From 7826d40ff997e76d7cc4153ddde8bac6273e3a26 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 3 Dec 2019 10:47:22 +0000 Subject: [PATCH 21/22] Style nits in function arguments. --- attributes.c | 4 ++-- grid.c | 2 +- options.c | 2 +- server-client.c | 2 +- window-buffer.c | 4 ++-- window-client.c | 2 +- window-tree.c | 8 ++++---- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/attributes.c b/attributes.c index 5849af2b..ca88a056 100644 --- a/attributes.c +++ b/attributes.c @@ -59,8 +59,8 @@ attributes_fromstring(const char *str) size_t end; u_int i; struct { - const char* name; - int attr; + const char *name; + int attr; } table[] = { { "bright", GRID_ATTR_BRIGHT }, { "bold", GRID_ATTR_BRIGHT }, diff --git a/grid.c b/grid.c index a016dc12..b2031045 100644 --- a/grid.c +++ b/grid.c @@ -204,7 +204,7 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg) /* Check grid y position. */ static int -grid_check_y(struct grid *gd, const char* from, u_int py) +grid_check_y(struct grid *gd, const char *from, u_int py) { if (py >= gd->hsize + gd->sy) { log_debug("%s: y out of range: %u", from, py); diff --git a/options.c b/options.c index 6bc54ef8..7402b724 100644 --- a/options.c +++ b/options.c @@ -610,7 +610,7 @@ options_match(const char *s, int *idx, int *ambiguous) struct options_entry * options_match_get(struct options *oo, const char *s, int *idx, int only, - int* ambiguous) + int *ambiguous) { char *name; struct options_entry *o; diff --git a/server-client.c b/server-client.c index c644bb01..bd256cb8 100644 --- a/server-client.c +++ b/server-client.c @@ -1581,7 +1581,7 @@ server_client_check_exit(struct client *c) /* Redraw timer callback. */ static void server_client_redraw_timer(__unused int fd, __unused short events, - __unused void* data) + __unused void *data) { log_debug("redraw timer fired"); } diff --git a/window-buffer.c b/window-buffer.c index b1115182..4091bc07 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -334,7 +334,7 @@ window_buffer_resize(struct window_mode_entry *wme, u_int sx, u_int sy) } static void -window_buffer_do_delete(void* modedata, void *itemdata, +window_buffer_do_delete(void *modedata, void *itemdata, __unused struct client *c, __unused key_code key) { struct window_buffer_modedata *data = modedata; @@ -348,7 +348,7 @@ window_buffer_do_delete(void* modedata, void *itemdata, } static void -window_buffer_do_paste(void* modedata, void *itemdata, struct client *c, +window_buffer_do_paste(void *modedata, void *itemdata, struct client *c, __unused key_code key) { struct window_buffer_modedata *data = modedata; diff --git a/window-client.c b/window-client.c index 2ca9c012..22a0f2e2 100644 --- a/window-client.c +++ b/window-client.c @@ -313,7 +313,7 @@ window_client_resize(struct window_mode_entry *wme, u_int sx, u_int sy) } static void -window_client_do_detach(void* modedata, void *itemdata, +window_client_do_detach(void *modedata, void *itemdata, __unused struct client *c, key_code key) { struct window_client_modedata *data = modedata; diff --git a/window-tree.c b/window-tree.c index 4dce1fe8..e0aa4314 100644 --- a/window-tree.c +++ b/window-tree.c @@ -317,7 +317,7 @@ window_tree_filter_pane(struct session *s, struct winlink *wl, static int window_tree_build_window(struct session *s, struct winlink *wl, - void* modedata, struct mode_tree_sort_criteria *sort_crit, + void *modedata, struct mode_tree_sort_criteria *sort_crit, struct mode_tree_item *parent, const char *filter) { struct window_tree_modedata *data = modedata; @@ -383,7 +383,7 @@ empty: } static void -window_tree_build_session(struct session *s, void* modedata, +window_tree_build_session(struct session *s, void *modedata, struct mode_tree_sort_criteria *sort_crit, const char *filter) { struct window_tree_modedata *data = modedata; @@ -973,7 +973,7 @@ window_tree_get_target(struct window_tree_itemdata *item, } static void -window_tree_command_each(void* modedata, void* itemdata, struct client *c, +window_tree_command_each(void *modedata, void *itemdata, struct client *c, __unused key_code key) { struct window_tree_modedata *data = modedata; @@ -1030,7 +1030,7 @@ window_tree_command_free(void *modedata) } static void -window_tree_kill_each(__unused void* modedata, void* itemdata, +window_tree_kill_each(__unused void *modedata, void *itemdata, __unused struct client *c, __unused key_code key) { struct window_tree_itemdata *item = itemdata; From 92ecd611f68663dfceb2494e637b3ebe51d3fd86 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 3 Dec 2019 18:53:23 +0000 Subject: [PATCH 22/22] Check each _PATH_* define individually (Solaris has paths.h but not all of the defines). From Eric N Vander Weele. --- compat.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/compat.h b/compat.h index d3617413..df1ac03c 100644 --- a/compat.h +++ b/compat.h @@ -61,12 +61,31 @@ void warn(const char *, ...); void warnx(const char *, ...); #endif -#ifndef HAVE_PATHS_H -#define _PATH_BSHELL "/bin/sh" -#define _PATH_TMP "/tmp/" +#ifdef HAVE_PATHS_H +#include +#endif + +#ifndef _PATH_BSHELL +#define _PATH_BSHELL "/bin/sh" +#endif + +#ifndef _PATH_TMP +#define _PATH_TMP "/tmp/" +#endif + +#ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" +#endif + +#ifndef _PATH_TTY #define _PATH_TTY "/dev/tty" +#endif + +#ifndef _PATH_DEV #define _PATH_DEV "/dev/" +#endif + +#ifndef _PATH_DEFPATH #define _PATH_DEFPATH "/usr/bin:/bin" #endif @@ -98,10 +117,6 @@ void warnx(const char *, ...); #include "compat/bitstring.h" #endif -#ifdef HAVE_PATHS_H -#include -#endif - #ifdef HAVE_LIBUTIL_H #include #endif