mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
input: add support for modifyOtherKeys=2
Similar to modifyOtherKeys=1 (foot’s default, and only, mode), except that: * All modifiers (and not just Ctrl) generate \E[27;m;n~ escapes * Regular keys (with modifiers) also generate \E[27;m;n~ escapes (for example, C-h no longer generates ^H, but \E[27;5;104~) For our keymap based lookups, this is handled by adding MOD_MODIFY_OTHER_KEYS_STATE<N> variants. For “generic” keys, we simply adjust the conditions for when to emit a \E[27;m;n~ escape - the only requirement is that at least one modifier is active.
This commit is contained in:
parent
9412389051
commit
4a74050999
5 changed files with 90 additions and 32 deletions
|
|
@ -46,6 +46,7 @@
|
|||
* Color schemes are now installed to `${datadir}/foot/themes`.
|
||||
* `[csd].border-width` and `[csd].border-color`, allowing you to
|
||||
configure the width and color of the CSD border.
|
||||
* Support for `XTMODKEYS` with `Pp=4` and `Pv=2` (_modifyOtherKeys=2_).
|
||||
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
20
csi.c
20
csi.c
|
|
@ -1509,19 +1509,21 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
case 1: /* modifyCursorKeys */
|
||||
case 2: /* modifyFunctionKeys */
|
||||
case 4: /* modifyOtherKeys */
|
||||
/* Ignored, we always report modifiers */
|
||||
if (value != 2 && value != -1 &&
|
||||
!(resource == 4 && value == 1))
|
||||
{
|
||||
LOG_WARN("unimplemented: %s = %d",
|
||||
resource == 1 ? "modifyCursorKeys" :
|
||||
resource == 2 ? "modifyFunctionKeys" :
|
||||
resource == 4 ? "modifyOtherKeys" : "<invalid>",
|
||||
value);
|
||||
if (value != 2 && value != -1) {
|
||||
LOG_WARN(
|
||||
"unimplemented: %s = %d",
|
||||
resource == 1 ? "modifyCursorKeys" :
|
||||
resource == 2 ? "modifyFunctionKeys" : "<invalid>",
|
||||
value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* modifyOtherKeys */
|
||||
term->modify_other_keys_2 = value == 2;
|
||||
LOG_DBG("modifyOtherKeys=%d", value);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_WARN("invalid resource %d in %s",
|
||||
resource, csi_as_string(term, final, -1));
|
||||
|
|
|
|||
44
input.c
44
input.c
|
|
@ -901,7 +901,20 @@ keymap_lookup(struct terminal *term, xkb_keysym_t sym, enum modifier mods)
|
|||
LOG_DBG("keypad mode: %d", keypad_keys_mode);
|
||||
|
||||
for (size_t j = 0; j < count; j++) {
|
||||
if (info[j].modifiers != MOD_ANY && info[j].modifiers != mods)
|
||||
enum modifier modifiers = info[j].modifiers;
|
||||
|
||||
if (modifiers & MOD_MODIFY_OTHER_KEYS_STATE1) {
|
||||
if (term->modify_other_keys_2)
|
||||
continue;
|
||||
modifiers &= ~MOD_MODIFY_OTHER_KEYS_STATE1;
|
||||
}
|
||||
if (modifiers & MOD_MODIFY_OTHER_KEYS_STATE2) {
|
||||
if (!term->modify_other_keys_2)
|
||||
continue;
|
||||
modifiers &= ~MOD_MODIFY_OTHER_KEYS_STATE2;
|
||||
}
|
||||
|
||||
if (modifiers != MOD_ANY && modifiers != mods)
|
||||
continue;
|
||||
|
||||
if (info[j].cursor_keys_mode != CURSOR_KEYS_DONTCARE &&
|
||||
|
|
@ -927,9 +940,26 @@ UNITTEST
|
|||
};
|
||||
|
||||
const struct key_data *info = keymap_lookup(&term, XKB_KEY_ISO_Left_Tab, MOD_SHIFT | MOD_CTRL);
|
||||
xassert(info != NULL);
|
||||
xassert(strcmp(info->seq, "\033[27;6;9~") == 0);
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
struct terminal term = {
|
||||
.modify_other_keys_2 = false,
|
||||
};
|
||||
|
||||
const struct key_data *info = keymap_lookup(&term, XKB_KEY_Return, MOD_ALT);
|
||||
xassert(info != NULL);
|
||||
xassert(strcmp(info->seq, "\033\r") == 0);
|
||||
|
||||
term.modify_other_keys_2 = true;
|
||||
info = keymap_lookup(&term, XKB_KEY_Return, MOD_ALT);
|
||||
xassert(info != NULL);
|
||||
xassert(strcmp(info->seq, "\033[27;3;13~") == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
get_current_modifiers(const struct seat *seat,
|
||||
xkb_mod_mask_t *effective,
|
||||
|
|
@ -1139,10 +1169,14 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
#define is_control_key(x) ((x) >= 0x40 && (x) <= 0x7f)
|
||||
#define IS_CTRL(x) ((x) < 0x20 || ((x) >= 0x7f && (x) <= 0x9f))
|
||||
|
||||
if ((keymap_mods & MOD_CTRL) &&
|
||||
!is_control_key(sym) &&
|
||||
(count == 1 && !IS_CTRL(utf8[0])) &&
|
||||
sym < 256)
|
||||
LOG_DBG("term->modify_other_keys=%d, count=%d, is_ctrl=%d (utf8=0x%02x), sym=%d",
|
||||
term->modify_other_keys_2, count, IS_CTRL(utf8[0]), utf8[0], sym);
|
||||
|
||||
bool ctrl_is_in_effect = (keymap_mods & MOD_CTRL) != 0;
|
||||
bool ctrl_seq = is_control_key(sym) || (count == 1 && IS_CTRL(utf8[0]));
|
||||
|
||||
if (keymap_mods != MOD_NONE && (term->modify_other_keys_2 ||
|
||||
(ctrl_is_in_effect && !ctrl_seq)))
|
||||
{
|
||||
static const int mod_param_map[32] = {
|
||||
[MOD_SHIFT] = 2,
|
||||
|
|
|
|||
56
keymap.h
56
keymap.h
|
|
@ -11,6 +11,8 @@ enum modifier {
|
|||
MOD_ALT = 0x4,
|
||||
MOD_CTRL = 0x8,
|
||||
MOD_META = 0x10,
|
||||
MOD_MODIFY_OTHER_KEYS_STATE1 = 0x20,
|
||||
MOD_MODIFY_OTHER_KEYS_STATE2 = 0x40,
|
||||
};
|
||||
|
||||
struct key_data {
|
||||
|
|
@ -41,7 +43,8 @@ static const struct key_data key_escape[] = {
|
|||
|
||||
static const struct key_data key_return[] = {
|
||||
{MOD_SHIFT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;2;13~"},
|
||||
{MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\r"},
|
||||
{MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\r"},
|
||||
{MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;3;13~"},
|
||||
{MOD_SHIFT | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;4;13~"},
|
||||
{MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;5;13~"},
|
||||
{MOD_SHIFT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;6;13~"},
|
||||
|
|
@ -60,7 +63,8 @@ static const struct key_data key_return[] = {
|
|||
|
||||
/* Tab isn't covered by the regular "modifyOtherKeys" handling */
|
||||
static const struct key_data key_tab[] = {
|
||||
{MOD_SHIFT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[Z"},
|
||||
{MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[Z"},
|
||||
{MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;2;9~"},
|
||||
{MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;3;9~"},
|
||||
{MOD_SHIFT | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;4;9~"},
|
||||
{MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;5;9~"},
|
||||
|
|
@ -96,22 +100,38 @@ static const struct key_data key_iso_left_tab[] = {
|
|||
};
|
||||
|
||||
static const struct key_data key_backspace[] = {
|
||||
{MOD_SHIFT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_SHIFT | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_SHIFT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_SHIFT | MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_META, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_META | MOD_SHIFT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_META | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_META | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_META | MOD_SHIFT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_META | MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT | MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_ANY, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_SHIFT | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_SHIFT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_SHIFT | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_META | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_META | MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
{MOD_META | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x7f"},
|
||||
{MOD_META | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_META | MOD_SHIFT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_META | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE1, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033\x08"},
|
||||
|
||||
{MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;2;127~"},
|
||||
{MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;3;127~"},
|
||||
{MOD_SHIFT | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;4;127~"},
|
||||
{MOD_SHIFT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;6;8~"},
|
||||
{MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;7;8~"},
|
||||
{MOD_SHIFT | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;8;8~"},
|
||||
{MOD_META | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;9;127~"},
|
||||
{MOD_META | MOD_SHIFT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;10;127~"},
|
||||
{MOD_META | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;11;127~"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;12;127~"},
|
||||
{MOD_META | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;13;8~"},
|
||||
{MOD_META | MOD_SHIFT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;14;8~"},
|
||||
{MOD_META | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;15;8~"},
|
||||
{MOD_META | MOD_SHIFT | MOD_ALT | MOD_CTRL | MOD_MODIFY_OTHER_KEYS_STATE2, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\033[27;16;8~"},
|
||||
|
||||
{MOD_CTRL, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x08"},
|
||||
{MOD_ANY, CURSOR_KEYS_DONTCARE, KEYPAD_DONTCARE, "\x7f"},
|
||||
};
|
||||
|
||||
#define DEFAULT_MODS_FOR_SINGLE(sym) \
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ struct terminal {
|
|||
bool focus_events;
|
||||
bool alt_scrolling;
|
||||
bool modify_escape_key;
|
||||
bool modify_other_keys_2; /* True when modifyOtherKeys=2 (i.e. “CSI >4;2m”) */
|
||||
enum cursor_origin origin;
|
||||
enum cursor_keys cursor_keys_mode;
|
||||
enum keypad_keys keypad_keys_mode;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue