From 6cd72bdee6c2b11f7cab15df9afb0ed92a7f8ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 26 Feb 2021 20:54:42 +0100 Subject: [PATCH 1/2] input: do not include consumed modifiers in the set sent to the client When sending a key escape sequence to the client application, do not include consumed modifiers. Fixes part of #376 --- CHANGELOG.md | 2 ++ input.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc90b279..d1d9629e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,8 @@ **must** now be written as either `Control+C` or `Control+Shift+c`, the latter being the preferred variant. (https://codeberg.org/dnkl/foot/issues/376) +* Consumed modifiers are no longer sent to the client application + (https://codeberg.org/dnkl/foot/issues/376). * The minimum version requirement for the libxkbcommon dependency is now 1.0.0. diff --git a/input.c b/input.c index 98abac9c..110bd378 100644 --- a/input.c +++ b/input.c @@ -1026,10 +1026,10 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, */ enum modifier keymap_mods = MOD_NONE; - keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE; - keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE; - keymap_mods |= seat->kbd.ctrl ? MOD_CTRL : MOD_NONE; - keymap_mods |= seat->kbd.meta ? MOD_META : MOD_NONE; + keymap_mods |= mods & ~consumed & shift ? MOD_SHIFT : MOD_NONE; + keymap_mods |= mods & ~consumed & alt ? MOD_ALT : MOD_NONE; + keymap_mods |= mods & ~consumed & ctrl ? MOD_CTRL : MOD_NONE; + keymap_mods |= mods & ~consumed & meta ? MOD_META : MOD_NONE; const struct key_data *keymap; if (sym == XKB_KEY_Escape && keymap_mods == MOD_NONE && term->modify_escape_key) { @@ -1113,7 +1113,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, } else { - if (mods & alt) { + if (mods & ~consumed & alt) { /* * When the alt modifier is pressed, we do one out of three things: * -- 2.30.2 From e4f164d9585d4e84de15061de6430d5c1c1a12ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Feb 2021 11:50:05 +0100 Subject: [PATCH 2/2] keymap: handle shift+tab combos correctly, after consuming modifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shift+Tab is an odd bird in XKB; it produces a shifted variant of tab, ISO_Left_Tab, with Shift being a consumed modifier. From a terminal perspective, Tab and ISO_Left_Tab are the same key, with Shift+Tab generating ‘CSI Z’, and all other combos generating a ‘CSI 27;mods;9~’ escape. Before, when we didn’t filter out consumed modifiers, we could simply re-use the keymap for Tab when translating ISO_Left_Tab. This is no longer possible, since shift has been filtered out. As a result, Shift+Tab no longer generated ‘CSI Z’, but ‘\t’. I.e as if shift wasn’t being pressed. This patch adds a separate keymap table for ISO_Left_Tab. It’s MOD_ANY entry corresponds to Shift+Tab, and emits ‘CSI Z’. All its other entries *exclude* shift (since it has been consumed), *but*, the encoded modifier (in the escape sequences) *include* shift. --- input.c | 4 ++-- keymap.h | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/input.c b/input.c index 110bd378..bc28bbf2 100644 --- a/input.c +++ b/input.c @@ -770,8 +770,8 @@ keymap_data_for_sym(xkb_keysym_t sym, size_t *count) switch (sym) { case XKB_KEY_Escape: *count = ALEN(key_escape); return key_escape; case XKB_KEY_Return: *count = ALEN(key_return); return key_return; - case XKB_KEY_Tab: /* FALLTHROUGH */ - case XKB_KEY_ISO_Left_Tab: *count = ALEN(key_tab); return key_tab; + case XKB_KEY_ISO_Left_Tab: *count = ALEN(key_iso_left_tab); return key_iso_left_tab; + case XKB_KEY_Tab: *count = ALEN(key_tab); return key_tab; case XKB_KEY_BackSpace: *count = ALEN(key_backspace); return key_backspace; case XKB_KEY_Up: *count = ALEN(key_up); return key_up; case XKB_KEY_Down: *count = ALEN(key_down); return key_down; diff --git a/keymap.h b/keymap.h index 8a8c968e..f1b4a0ea 100644 --- a/keymap.h +++ b/keymap.h @@ -78,6 +78,25 @@ static const struct key_data key_tab[] = { {MOD_ANY, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\t"}, }; +/* + * Shift+Tab produces ISO_Left_Tab + * + * However, all combos (except Shift+Tab) acts as if we pressed + * mods+shift+tab. XKB “consumes” shift for us, hence MOD_SHIFT isn’t + * present in any of the entries below. However, the entries still map + * to sequences that indicate shift has been pressed. + */ +static const struct key_data key_iso_left_tab[] = { + {MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;4;9~"}, + {MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;6;9~"}, + {MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;8;9~"}, + {MOD_META, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;10;9~"}, + {MOD_META | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;12;9~"}, + {MOD_META | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;14;9~"}, + {MOD_META | MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;16;9~"}, + {MOD_ANY, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[Z"}, +}; + static const struct key_data key_backspace[] = { {MOD_SHIFT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"}, {MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"}, -- 2.30.2