mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 03:11:11 -04:00
vt: add fallback to plain map for modifier-aware key types
When a key is pressed with modifiers (Shift, Ctrl, Alt, etc.) and the
modifier-specific keymap has no binding (K_HOLE) or doesn't exist, fall
back to the plain keymap if the plain entry is a modifier-aware type
(KT_CUR or KT_CSI).
This allows arrow keys and CSI navigation keys to automatically handle
all modifier combinations with just a single plain map entry. The key
handlers (k_cur and k_csi) read the modifier state at runtime and encode
it into the output sequence.
For example, with just:
keycode 103 = Up
keycode 104 = Csi_Home
All these combinations now work automatically:
Up -> ESC [ A
Shift+Up -> ESC [ 1 ; 2 A
Ctrl+Up -> ESC [ 1 ; 5 A
Home -> ESC [ 1 ~
Shift+Home -> ESC [ 1 ; 2 ~
Ctrl+Home -> ESC [ 1 ; 5 ~
Previously, each modifier combination required an explicit keymap entry,
which was tedious and consumed keymap slots.
Explicit modifier bindings still take precedence - the fallback only
triggers when the modifier-specific entry is empty.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Link: https://patch.msgid.link/20260203045457.1049793-4-nico@fluxnic.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5cba06c71c
commit
c1d2deb649
@@ -1498,6 +1498,21 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
|
||||
param.ledstate = kbd->ledflagstate;
|
||||
key_map = key_maps[shift_final];
|
||||
|
||||
/*
|
||||
* Fall back to the plain map if modifiers are active, the modifier-
|
||||
* specific map is missing or has no entry, and the plain map has a
|
||||
* modifier-aware key type (KT_CUR or KT_CSI). These handlers encode
|
||||
* the modifier state into the emitted escape sequence.
|
||||
*/
|
||||
if (shift_final && keycode < NR_KEYS &&
|
||||
(!key_map || key_map[keycode] == K_HOLE) && key_maps[0]) {
|
||||
unsigned short plain = key_maps[0][keycode];
|
||||
unsigned char type = KTYP(plain);
|
||||
|
||||
if (type >= 0xf0 && (type - 0xf0 == KT_CUR || type - 0xf0 == KT_CSI))
|
||||
key_map = key_maps[0];
|
||||
}
|
||||
|
||||
rc = atomic_notifier_call_chain(&keyboard_notifier_list,
|
||||
KBD_KEYCODE, ¶m);
|
||||
if (rc == NOTIFY_STOP || !key_map) {
|
||||
|
||||
Reference in New Issue
Block a user