From cbd419c4832975e3c8a83e9ead22d67f528bbc2b Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 29 Sep 2024 20:05:42 +0000 Subject: [PATCH 1/9] Fix grey colour, from Magnus Gross. --- colour.c | 2 +- tmux.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/colour.c b/colour.c index 0b787acb..5fd91c9c 100644 --- a/colour.c +++ b/colour.c @@ -948,7 +948,7 @@ colour_byname(const char *name) if (strncmp(name, "grey", 4) == 0 || strncmp(name, "gray", 4) == 0) { if (name[4] == '\0') - return (-1); + return (0xbebebe|COLOUR_FLAG_RGB); c = strtonum(name + 4, 0, 100, &errstr); if (errstr != NULL) return (-1); diff --git a/tmux.c b/tmux.c index a9619baf..30960245 100644 --- a/tmux.c +++ b/tmux.c @@ -408,9 +408,9 @@ main(int argc, char **argv) cfg_files[cfg_nfiles++] = xstrdup(optarg); cfg_quiet = 0; break; - case 'V': + case 'V': printf("tmux %s\n", getversion()); - exit(0); + exit(0); case 'l': flags |= CLIENT_LOGIN; break; From a1b7a3bcb32066a36367fbcd4ebbfedbd6ad8ec1 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 30 Sep 2024 07:54:51 +0000 Subject: [PATCH 2/9] Only use default-shell for popups, return to /bin/sh for run-shell, if-shell and #() - these have been documented as using /bin/sh for a long time and scripts rely on it. Pointed out by Gregory Pakosz. --- job.c | 23 +++++++++++++++-------- popup.c | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/job.c b/job.c index cab91d2c..eeb90f42 100644 --- a/job.c +++ b/job.c @@ -69,9 +69,10 @@ static LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs); /* Start a job running. */ struct job * -job_run(const char *cmd, int argc, char **argv, struct environ *e, struct session *s, - const char *cwd, job_update_cb updatecb, job_complete_cb completecb, - job_free_cb freecb, void *data, int flags, int sx, int sy) +job_run(const char *cmd, int argc, char **argv, struct environ *e, + struct session *s, const char *cwd, job_update_cb updatecb, + job_complete_cb completecb, job_free_cb freecb, void *data, int flags, + int sx, int sy) { struct job *job; struct environ *env; @@ -81,6 +82,7 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio sigset_t set, oldset; struct winsize ws; char **argvp, tty[TTY_NAME_MAX], *argv0; + struct options *oo; /* * Do not set TERM during .tmux.conf (second argument here), it is nice @@ -91,12 +93,17 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio if (e != NULL) environ_copy(e, env); - if (s != NULL) - shell = options_get_string(s->options, "default-shell"); - else - shell = options_get_string(global_s_options, "default-shell"); - if (!checkshell(shell)) + if (~flags & JOB_DEFAULTSHELL) shell = _PATH_BSHELL; + else { + if (s != NULL) + oo = s->options; + else + oo = global_s_options; + shell = options_get_string(oo, "default-shell"); + if (!checkshell(shell)) + shell = _PATH_BSHELL; + } argv0 = shell_argv0(shell, 0); sigfillset(&set); diff --git a/popup.c b/popup.c index 706295fe..97f532c0 100644 --- a/popup.c +++ b/popup.c @@ -717,7 +717,7 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px, pd->job = job_run(shellcmd, argc, argv, env, s, cwd, popup_job_update_cb, popup_job_complete_cb, NULL, pd, - JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE, jx, jy); + JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy); pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette); server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, From 868ddf5d38584c3d67ae32a23aeafc415d3d287f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 30 Sep 2024 13:09:50 +0100 Subject: [PATCH 3/9] 3.5a bits. --- CHANGES | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d88d4024..6185ddc6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +CHANGES FROM 3.5 TO 3.5a + +* Revert to using /bin/sh for #() and run-shell and if-shell; the change to use + default-shell only applies now to popups. + +* Fix grey colour without a number suffix in styles. + CHANGES FROM 3.4 TO 3.5 * Revamp extended keys support to more closely match xterm and support mode 2 diff --git a/configure.ac b/configure.ac index 2a834037..97e5ca50 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], 3.5) +AC_INIT([tmux], 3.5a) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) From 834ec91b445721211d3eb3e21b780607b78453a8 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 2 Oct 2024 08:06:45 +0000 Subject: [PATCH 4/9] Report shifted keys like S-A as A not as S-A in mode 1 extended keys, from Stanislav Kljuhhin. --- input-keys.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/input-keys.c b/input-keys.c index 4dd42e1b..05971dae 100644 --- a/input-keys.c +++ b/input-keys.c @@ -553,6 +553,10 @@ input_key_mode1(struct bufferevent *bev, key_code key) (onlykey >= '@' && onlykey <= '~'))) return (input_key_vt10x(bev, key)); + /* Avoid reporting A as Shift-A, which is not expected in mode 1. */ + if ((key & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) + return (input_key_vt10x(bev, key)); + /* * A regular key + Meta. In the absence of a standard to back this, we * mimic what iTerm 2 does. From 356887bca27b48e895eca261e0989319f432de73 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 3 Oct 2024 05:41:59 +0000 Subject: [PATCH 5/9] Improve fix for shifted keys so it works for all the keys it should, Stanislav Kljuhhin in GitHub issue 4146. --- input-keys.c | 4 ---- tty-keys.c | 30 ++++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/input-keys.c b/input-keys.c index 05971dae..4dd42e1b 100644 --- a/input-keys.c +++ b/input-keys.c @@ -553,10 +553,6 @@ input_key_mode1(struct bufferevent *bev, key_code key) (onlykey >= '@' && onlykey <= '~'))) return (input_key_vt10x(bev, key)); - /* Avoid reporting A as Shift-A, which is not expected in mode 1. */ - if ((key & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) - return (input_key_vt10x(bev, key)); - /* * A regular key + Meta. In the absence of a standard to back this, we * mimic what iTerm 2 does. diff --git a/tty-keys.c b/tty-keys.c index 3debeea1..76e26a8b 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -930,7 +930,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, u_int number, modifiers; char tmp[64]; cc_t bspace; - key_code nkey; + key_code nkey, onlykey; struct utf8_data ud; utf8_char uc; @@ -994,13 +994,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, /* Update the modifiers. */ if (modifiers > 0) { modifiers--; - /* - * The Shift modifier may not be reported in some input modes, - * which is unfortunate, as in general case determining if a - * character is shifted or not requires knowing the input - * keyboard layout. So we only fix up the trivial case. - */ - if (modifiers & 1 || (nkey >= 'A' && nkey <= 'Z')) + if (modifiers & 1) nkey |= KEYC_SHIFT; if (modifiers & 2) nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */ @@ -1014,6 +1008,26 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT)) nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~KEYC_SHIFT); + /* + * Deal with the Shift modifier when present alone. The problem is that + * in mode 2 some terminals would report shifted keys, like S-a, as + * just A, and some as S-A. + * + * Because we need an unambiguous internal representation, and because + * restoring the Shift modifier when it's missing would require knowing + * the keyboard layout, and because S-A would cause a lot of issues + * downstream, we choose to lose the Shift for all printable + * characters. + * + * That still leaves some ambiguity, such as C-S-A vs. C-A, but that's + * OK, and applications can handle that. + */ + onlykey = nkey & KEYC_MASK_KEY; + if (((onlykey > 0x20 && onlykey < 0x7f) || + KEYC_IS_UNICODE(nkey)) && + (nkey & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) + nkey &= ~KEYC_SHIFT; + if (log_get_level() != 0) { log_debug("%s: extended key %.*s is %llx (%s)", c->name, (int)*size, buf, nkey, key_string_lookup_key(nkey, 1)); From 048db82041a9866e52306ea88169b8e5352ef386 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 4 Oct 2024 14:55:17 +0000 Subject: [PATCH 6/9] Do not translate BSpace as Unicode, GitHub issue 4156. --- tty-keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tty-keys.c b/tty-keys.c index 76e26a8b..5416c78b 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -983,7 +983,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, nkey = number; /* Convert UTF-32 codepoint into internal representation. */ - if (nkey & ~0x7f) { + if (nkey != KEYC_BSPACE && nkey & ~0x7f) { if (utf8_fromwc(nkey, &ud) == UTF8_DONE && utf8_from_data(&ud, &uc) == UTF8_DONE) nkey = uc; From 7997fd315279a15e86cc1ee2649e74603007bb1b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 4 Oct 2024 18:59:53 +0100 Subject: [PATCH 7/9] Missing define. --- tmux.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tmux.h b/tmux.h index 0b14ccd0..071d9d29 100644 --- a/tmux.h +++ b/tmux.h @@ -2341,6 +2341,7 @@ typedef void (*job_free_cb) (void *); #define JOB_NOWAIT 0x1 #define JOB_KEEPWRITE 0x2 #define JOB_PTY 0x4 +#define JOB_DEFAULTSHELL 0x8 struct job *job_run(const char *, int, char **, struct environ *, struct session *, const char *, job_update_cb, job_complete_cb, job_free_cb, void *, int, int, int); From 42959db0a487ee655f53eaaf9d5d9920fca5a9e1 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 Oct 2024 07:00:22 +0100 Subject: [PATCH 8/9] Update CHANGES. --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 6185ddc6..344a1ccc 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ CHANGES FROM 3.5 TO 3.5a +* Do not translate BSpace as Unicode with extended keys. + +* Fix so that keys with Shift are represented correctly with extended keys. + * Revert to using /bin/sh for #() and run-shell and if-shell; the change to use default-shell only applies now to popups. From 549c35b06165f6ae023115eb76f83f2cbf945395 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 5 Oct 2024 07:01:16 +0100 Subject: [PATCH 9/9] Update regression tests. --- regress/capture-pane-sgr0.sh | 4 +-- regress/combine-test.result | 2 +- regress/format-strings.sh | 2 +- regress/input-keys.sh | 23 +++++++------ regress/tty-keys.sh | 62 ++++++++++++++++++------------------ 5 files changed, 48 insertions(+), 45 deletions(-) diff --git a/regress/capture-pane-sgr0.sh b/regress/capture-pane-sgr0.sh index 6a19ac8a..5d21ccc4 100644 --- a/regress/capture-pane-sgr0.sh +++ b/regress/capture-pane-sgr0.sh @@ -22,8 +22,8 @@ $TMUX -f/dev/null new -d " sleep 1 ( - printf '\033[1m\033[31m\033[42mabc\033[0m\033[31m\033[49mdef\n' - printf '\033[39m\033[100m bright bg\n' + printf '\033[1m\033[31m\033[42mabc\033[0m\033[31mdef\033[39m\n' + printf '\033[100m bright bg \033[49m\n' ) | cmp - $TMP || exit 1 $TMUX has 2>/dev/null && exit 1 diff --git a/regress/combine-test.result b/regress/combine-test.result index 8fb411ba..0d2afb5e 100644 --- a/regress/combine-test.result +++ b/regress/combine-test.result @@ -6,7 +6,7 @@ 👍🏻3 👍🏻 👍🏻4 🤷‍♂️5 -♂️ 7 +♂️7 🤷‍♂️8 🤷‍♂️9 🤷‍♂️10 diff --git a/regress/format-strings.sh b/regress/format-strings.sh index 0ae27386..bc4b00f7 100644 --- a/regress/format-strings.sh +++ b/regress/format-strings.sh @@ -172,7 +172,7 @@ test_format "#{l:#{pane_in_mode}}" "#{pane_in_mode}" test_format "#{l:#{?pane_in_mode,#{?#{==:#{session_name},Summer},ABC,XYZ},xyz}}" "#{?pane_in_mode,#{?#{==:#{session_name},Summer},ABC,XYZ},xyz}" # With escapes (which escape but are returned literally) -test_format "#{l:##{}" "##{" +test_format "#{l:##{}" "#{" test_format "#{l:#{#}}}" "#{#}}" # Invalid formats: diff --git a/regress/input-keys.sh b/regress/input-keys.sh index 262d12a6..d3b90995 100644 --- a/regress/input-keys.sh +++ b/regress/input-keys.sh @@ -6,10 +6,10 @@ TERM=screen [ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux) TMUX="$TEST_TMUX -Ltest" $TMUX kill-server 2>/dev/null - +sleep 1 $TMUX -f/dev/null new -x20 -y2 -d || exit 1 - -sleep 0.1 +sleep 1 +$TMUX set -g escape-time 0 exit_status=0 @@ -17,11 +17,14 @@ assert_key () { key=$1 expected_code=$2 - $TMUX new-window -- sh -c 'stty raw -echo && cat -tv' - $TMUX send-keys "$key" $ + W=$($TMUX new-window -P -- sh -c 'stty raw -echo && cat -tv') + $TMUX send-keys -t$W "$key" 'EOL' || exit 1 + sleep 0.2 - actual_code=$($TMUX capturep -p | head -1 | sed -e 's/\$$//') - $TMUX kill-window + actual_code=$($TMUX capturep -pt$W | \ + head -1 | \ + sed -e 's/EOL.*$//') + $TMUX kill-window -t$W || exit 1 if [ "$actual_code" = "$expected_code" ]; then if [ -n "$VERBOSE" ]; then @@ -205,7 +208,7 @@ assert_key 'PageUp' '^[[5~' assert_key 'PgUp' '^[[5~' assert_key 'BTab' '^[[Z' -assert_key 'C-S-Tab' '^[[Z' +assert_key 'C-S-Tab' '^I' assert_key 'Up' '^[[A' assert_key 'Down' '^[[B' @@ -291,8 +294,8 @@ assert_extended_key 'Insert' '^[[2;_~' assert_extended_key 'DC' '^[[3;_~' assert_extended_key 'Delete' '^[[3;_~' -assert_key 'C-Tab' "^[[9;5u" -assert_key 'C-S-Tab' "^[[1;5Z" +assert_key 'C-Tab' "^[[27;5;9~" +assert_key 'C-S-Tab' "^[[27;6;9~" $TMUX kill-server 2>/dev/null diff --git a/regress/tty-keys.sh b/regress/tty-keys.sh index 1fcc3657..0a1fe6bf 100644 --- a/regress/tty-keys.sh +++ b/regress/tty-keys.sh @@ -14,7 +14,7 @@ trap "rm -f $TMP" 0 1 15 $TMUX2 -f/dev/null new -d || exit 1 $TMUX -f/dev/null new -d "$TMUX2 attach" || exit 1 -sleep 0.1 +sleep 1 exit_status=0 @@ -60,38 +60,38 @@ assert_key () { } -assert_key 0x00 'C-Space' # -- 'Escape 0x00' 'M-C-Space' -assert_key 0x01 'C-a' -- 'Escape 0x01' 'M-C-a' -assert_key 0x02 'C-b' -- 'Escape 0x02' 'M-C-b' -assert_key 0x03 'C-c' -- 'Escape 0x03' 'M-C-c' -assert_key 0x04 'C-d' -- 'Escape 0x04' 'M-C-d' -assert_key 0x05 'C-e' -- 'Escape 0x05' 'M-C-e' -assert_key 0x06 'C-f' -- 'Escape 0x06' 'M-C-f' -assert_key 0x07 'C-g' -- 'Escape 0x07' 'M-C-g' -assert_key 0x08 'C-h' -- 'Escape 0x08' 'M-C-h' +assert_key 0x00 'C-Space' # -- 'Escape 0x00' 'C-M-Space' +assert_key 0x01 'C-a' -- 'Escape 0x01' 'C-M-a' +assert_key 0x02 'C-b' -- 'Escape 0x02' 'C-M-b' +assert_key 0x03 'C-c' -- 'Escape 0x03' 'C-M-c' +assert_key 0x04 'C-d' -- 'Escape 0x04' 'C-M-d' +assert_key 0x05 'C-e' -- 'Escape 0x05' 'C-M-e' +assert_key 0x06 'C-f' -- 'Escape 0x06' 'C-M-f' +assert_key 0x07 'C-g' -- 'Escape 0x07' 'C-M-g' +assert_key 0x08 'C-h' -- 'Escape 0x08' 'C-M-h' assert_key 0x09 'Tab' -- 'Escape 0x09' 'M-Tab' -assert_key 0x0A 'C-j' -- 'Escape 0x0A' 'M-C-j' -assert_key 0x0B 'C-k' -- 'Escape 0x0B' 'M-C-k' -assert_key 0x0C 'C-l' -- 'Escape 0x0C' 'M-C-l' +assert_key 0x0A 'C-j' -- 'Escape 0x0A' 'C-M-j' +assert_key 0x0B 'C-k' -- 'Escape 0x0B' 'C-M-k' +assert_key 0x0C 'C-l' -- 'Escape 0x0C' 'C-M-l' assert_key 0x0D 'Enter' -- 'Escape 0x0D' 'M-Enter' -assert_key 0x0E 'C-n' -- 'Escape 0x0E' 'M-C-n' -assert_key 0x0F 'C-o' -- 'Escape 0x0F' 'M-C-o' -assert_key 0x10 'C-p' -- 'Escape 0x10' 'M-C-p' -assert_key 0x11 'C-q' -- 'Escape 0x11' 'M-C-q' -assert_key 0x12 'C-r' -- 'Escape 0x12' 'M-C-r' -assert_key 0x13 'C-s' -- 'Escape 0x13' 'M-C-s' -assert_key 0x14 'C-t' -- 'Escape 0x14' 'M-C-t' -assert_key 0x15 'C-u' -- 'Escape 0x15' 'M-C-u' -assert_key 0x16 'C-v' -- 'Escape 0x16' 'M-C-v' -assert_key 0x17 'C-w' -- 'Escape 0x17' 'M-C-w' -assert_key 0x18 'C-x' -- 'Escape 0x18' 'M-C-x' -assert_key 0x19 'C-y' -- 'Escape 0x19' 'M-C-y' -assert_key 0x1A 'C-z' -- 'Escape 0x1A' 'M-C-z' +assert_key 0x0E 'C-n' -- 'Escape 0x0E' 'C-M-n' +assert_key 0x0F 'C-o' -- 'Escape 0x0F' 'C-M-o' +assert_key 0x10 'C-p' -- 'Escape 0x10' 'C-M-p' +assert_key 0x11 'C-q' -- 'Escape 0x11' 'C-M-q' +assert_key 0x12 'C-r' -- 'Escape 0x12' 'C-M-r' +assert_key 0x13 'C-s' -- 'Escape 0x13' 'C-M-s' +assert_key 0x14 'C-t' -- 'Escape 0x14' 'C-M-t' +assert_key 0x15 'C-u' -- 'Escape 0x15' 'C-M-u' +assert_key 0x16 'C-v' -- 'Escape 0x16' 'C-M-v' +assert_key 0x17 'C-w' -- 'Escape 0x17' 'C-M-w' +assert_key 0x18 'C-x' -- 'Escape 0x18' 'C-M-x' +assert_key 0x19 'C-y' -- 'Escape 0x19' 'C-M-y' +assert_key 0x1A 'C-z' -- 'Escape 0x1A' 'C-M-z' assert_key 0x1B 'Escape' -- 'Escape 0x1B' 'M-Escape' -assert_key 0x1C "C-\\" -- 'Escape 0x1C' "M-C-\\" -assert_key 0x1D 'C-]' -- 'Escape 0x1D' 'M-C-]' -assert_key 0x1E 'C-^' -- 'Escape 0x1E' 'M-C-^' -assert_key 0x1F 'C-_' -- 'Escape 0x1F' 'M-C-_' +assert_key 0x1C "C-\\" -- 'Escape 0x1C' "C-M-\\" +assert_key 0x1D 'C-]' -- 'Escape 0x1D' 'C-M-]' +assert_key 0x1E 'C-^' -- 'Escape 0x1E' 'C-M-^' +assert_key 0x1F 'C-_' -- 'Escape 0x1F' 'C-M-_' assert_key 0x20 'Space' -- 'Escape 0x20' 'M-Space' assert_key 0x21 '!' -- 'Escape 0x21' 'M-!' assert_key 0x22 '"' -- 'Escape 0x22' 'M-"' @@ -304,7 +304,7 @@ assert_extended_key () { key_name=$2 assert_key "Escape [${code};5u" "C-$key_name" - assert_key "Escape [${code};7u" "M-C-$key_name" + assert_key "Escape [${code};7u" "C-M-$key_name" } # Extended keys