input: enforce ‘numerical’ keypad mode when Num Lock override is enabled

When num lock override has been enabled via “CSI?1035h” (the default),
keypad is always considered to be in ‘numerical’ mode.

This affects how keypad keys are translated to escape sequences when
Num Lock is active.

The keypad has four modes:

* Num Lock off, numerical mode
* Num Lock off, application mode
* Num Lock on, numerical mode
* Num Lock on, application mode

The keymap is identical for numerical and application mode when Num
Lock is off, meaning the keypad effectively has three different modes.

In XTerm, numerical and application mode _can_ be the same, **if** the
‘numLock’ resource is set to true (the default). It is only when
‘numLock’ is false that the application mode is actually used.

This patch changes foot to do the same. We don’t expose an option, but
do implement “CSI ? 1035”.

Closes #194
This commit is contained in:
Daniel Eklöf 2020-11-11 18:28:37 +01:00
parent bdaf20ba71
commit deb2c2db6d
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

15
input.c
View file

@ -741,7 +741,8 @@ keymap_data_for_sym(xkb_keysym_t sym, size_t *count)
}
static const struct key_data *
keymap_lookup(struct terminal *term, xkb_keysym_t sym, enum modifier mods)
keymap_lookup(struct seat *seat, struct terminal *term,
xkb_keysym_t sym, enum modifier mods)
{
size_t count;
const struct key_data *info = keymap_data_for_sym(sym, &count);
@ -749,16 +750,22 @@ keymap_lookup(struct terminal *term, xkb_keysym_t sym, enum modifier mods)
if (info == NULL)
return NULL;
const enum cursor_keys cursor_keys_mode = term->cursor_keys_mode;
const enum keypad_keys keypad_keys_mode
= (term->num_lock_modifier && seat->kbd.num
? KEYPAD_NUMERICAL
: term->keypad_keys_mode);
for (size_t j = 0; j < count; j++) {
if (info[j].modifiers != MOD_ANY && info[j].modifiers != mods)
continue;
if (info[j].cursor_keys_mode != CURSOR_KEYS_DONTCARE &&
info[j].cursor_keys_mode != term->cursor_keys_mode)
info[j].cursor_keys_mode != cursor_keys_mode)
continue;
if (info[j].keypad_keys_mode != KEYPAD_DONTCARE &&
info[j].keypad_keys_mode != term->keypad_keys_mode)
info[j].keypad_keys_mode != keypad_keys_mode)
continue;
return &info[j];
@ -884,7 +891,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
keymap_mods |= seat->kbd.ctrl ? MOD_CTRL : MOD_NONE;
keymap_mods |= seat->kbd.meta ? MOD_META : MOD_NONE;
const struct key_data *keymap = keymap_lookup(term, sym, keymap_mods);
const struct key_data *keymap = keymap_lookup(seat, term, sym, keymap_mods);
if (keymap != NULL) {
term_to_slave(term, keymap->seq, strlen(keymap->seq));