tty: Alt+1..6 switches terminals, and AltGr is left alone
Alt+F1..F6 was wrong in three separate ways, and the third is the one that
matters most here.
Alt+F4 the host window manager closes the QEMU window
Alt+F2 GNOME and KDE open a run dialog
Ctrl+Alt+F1..F6 the host switches its *own* virtual terminals
AltGr+anything Polish diacritics -- a c e l n o s x z with their marks --
and on some setups AltGr is delivered as Ctrl+Alt
Ctrl+Shift+key widely bound inside applications
Scroll Lock not present on many keyboards
Alt+1..6 survives all of it: the number row, so no function key is involved,
and left Alt, so AltGr is untouched.
Right Alt is tracked as its own modifier bit now. It used to share ALT, which
is harmless for typing -- neither is used to look up a character -- and wrong
for chords, because it made AltGr indistinguishable from Alt.
And the test is an equality rather than a mask:
if ((shift & (CTL | SHIFT | ALT | RALT)) == ALT && ...)
`shift & ALT` fired on Ctrl+Alt+1 and AltGr+1 as well, so a chord aimed at the
host -- or an ordinary Polish keystroke -- would have switched terminals
behind your back. That was a real bug in what shipped yesterday.
Verified with QEMU's sendkey, comparing screendump hashes:
start (tty1) 86cee2284878
Ctrl+Alt+2 86cee2284878 identical -- did not fire
AltGr+2 86cee2284878 identical -- did not fire
Alt+2 114562804a78 switched
Alt+1 86cee2284878 back, pixel-identical to the start
schfs-check passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
parent
a5b0d5a0ef
commit
91a6d440d6
6 changed files with 71 additions and 12 deletions
|
|
@ -361,7 +361,7 @@ erase_one(struct vt *v)
|
|||
// Keyboard input
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Alt+F1..F6 switch terminals. kbd.c reports them as KEY_ALT_F1.. so that the
|
||||
// Alt+1..6 switch terminals. kbd.c reports them as KEY_ALT_F1.. so that the
|
||||
// decision of what a chord *means* is made here, where the terminals are,
|
||||
// rather than in a driver that should not know they exist.
|
||||
int
|
||||
|
|
|
|||
|
|
@ -60,12 +60,18 @@ kbdgetc(void)
|
|||
shift |= shiftcode[data];
|
||||
shift ^= togglecode[data];
|
||||
|
||||
// Alt+F1..F6 before the character tables, because there is no character to
|
||||
// Alt+1..6 before the character tables, because there is no character to
|
||||
// look up: it is a chord that means "show me a different terminal". What it
|
||||
// means is decided in console.c, which is where the terminals are; this only
|
||||
// has to name it. See console_vt_hotkey().
|
||||
if ((shift & ALT) && data >= SCAN_F1 && data < SCAN_F1 + NVT)
|
||||
return KEY_ALT_F1 + (data - SCAN_F1);
|
||||
//
|
||||
// The modifier test is an equality, not a mask. `shift & ALT` would fire on
|
||||
// Ctrl+Alt+1 and on AltGr+1 as well, so a chord aimed at the host -- or a
|
||||
// Polish keystroke -- would switch terminals behind your back. Exactly left
|
||||
// Alt, and nothing else held.
|
||||
if ((shift & (CTL | SHIFT | ALT | RALT)) == ALT &&
|
||||
data >= SCAN_1 && data < SCAN_1 + NVT)
|
||||
return KEY_ALT_F1 + (data - SCAN_1);
|
||||
|
||||
c = charcode[shift & (CTL | SHIFT)][data];
|
||||
if(shift & CAPSLOCK){
|
||||
|
|
|
|||
Loading…
Reference in a new issue