Linux – Emulating VT220 escape sequences in Konsole keytab

kdekonsolelinuxplasma5terminal

After a little futile hacking, I realised that . . . I would need to properly map the HHK keyboard so that I could use the various meta-keys. Thus began my descent into hell.

Doug Palmer, An Unreliable Guide to XKB Configuration

I am attempting to configure Konsole to emit VT220-style escape sequences from the numeric keypad when application keypad mode is enabled (e.g., by echoti smkx). In particular, the following control sequences should be the output under the described conditions:

http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-VT220-Style-Function-Keys

One must be aware that munging the TERM environment variable is the same as lying to the shell about the terminal's capabilities and should generally be avoided. Simply setting TERM=xterm-vt220 is insufficient, and causes unexpected behavior.

I have a simple, but partial solution. Konsole permits configuration of its terminal key bindings in the form of .keytab files. The following additions are effective, saved into .local/share/konsole/VT220.keytab:

keyboard "VT220"
key 0+KeyPad+AppCursorKeys : "\EOp"
key 1+KeyPad+AppCursorKeys : "\EOq"
key 2+KeyPad+AppCursorKeys : "\EOr"
key 3+KeyPad+AppCursorKeys : "\EOs"
key 4+KeyPad+AppCursorKeys : "\EOt"
key 5+KeyPad+AppCursorKeys : "\EOu"
key 6+KeyPad+AppCursorKeys : "\EOv"
key 7+KeyPad+AppCursorKeys : "\EOw"
key 8+KeyPad+AppCursorKeys : "\EOx"
key 9+KeyPad+AppCursorKeys : "\EOy"
key ++KeyPad+AppCursorKeys : "\EOk"
key *+KeyPad+AppCursorKeys : "\EOj"
key .+KeyPad+AppCursorKeys : "\EOn"
key -+KeyPad+AppCursorKeys : "\EOm"
key Enter+KeyPad : "\EOM"

With these key bindings applied (along with any others that may be present), konsole will emit the same control sequences as xterm when application keypad mode is enabled and NumLock is on. These sequences are useful to applications that expect VT220 emulation because they uniquely identify keystrokes from the numeric keypad, enabling arbitrary functions to be bound to them.

One common keypad key is missing in my configuration: / (Qt::Key_Slash). The Konsole graphical key binding editor does not seem to recognize any reference to that key, either by name or expressed as a literal. If it is manually written into the .keytab file, Konsole will ignore it and the line will not appear in the GUI editor. This leaves a quite annoying hole in my keypad, where exactly one key is stubbornly unprogrammable.

I'd rather not get into the weeds with xkb and friends; but of course vanilla xterm does all of this out-of-the-box, demonstrating that it oughtn't be necessary to fiddle with key bindings at such a low level in this case. It seems instead that Konsole (or QT) is doing something unique and snowflakey on top of X.

Question: Is it possible in Konsole to re-bind the numerical keypad's / key to a different control sequence? Alternatively, is this the point where something that operates at a different level (like terminfo, xkb, or xterm-keys from tmux) would be more effective? Have I, perhaps, gone mad?

Any insight from other intrepid console commanders would be appreciated.

Best Answer

Konsole ignores that, because it relies upon a hard-coded list of keys which cannot be mapped:

// Override any of the following shortcuts because
// they are needed by the terminal
int keyCode = keyEvent->key() | modifiers;
switch (keyCode) {
    // list is taken from the QLineEdit::event() code
case Qt::Key_Tab:
case Qt::Key_Delete:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_Backspace:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Slash:
case Qt::Key_Period:
case Qt::Key_Space:
    keyEvent->accept();
    return true;
}
return false;
Related Question