Reputation: 13691
I have a curses based application (WordGrinder). I've just had a bug report from a user saying that some keys aren't working properly on his keyboard. On investigation, he's right.
The keys in question are SHIFT+cursor keys and some of the keypad navigation keys, such as END. Investigating what's going on, it seems that curses is not sending me events for these keys. In the case of SHIFT+cursor keys, I'm not getting anything at all, and for END I'm getting a raw escape sequence.
This surprises me. All the other keys are getting interpreted and translated correctly into keysyms. I'd expect to be getting KEY_SLEFT
and KEY_END
. Why aren't I?
I've looked at some other applications where these keys work but don't spot anything obvious that I'm doing wrong; and applications like nano do really evil things like handle their own escape key parsing anyway, so I don't know if they're a good candidate for source code.
I'm initialising ncurses as follows:
initscr();
raw();
noecho();
meta(NULL, TRUE);
nonl();
idlok(stdscr, TRUE);
idcok(stdscr, TRUE);
scrollok(stdscr, FALSE);
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
I'm using gnome-terminal as the terminal emulator, and xterm as the terminal type. Locale is UTF-8 and I've got the ncursesw variant of the library.
Any ideas?
Update:
Well, many months later I try Wordgrinder with Gnome 3's gnome-terminal and discover that all these wacky keys generate valid ncurses keycodes. For example, SHIFT+LEFT now produces keycode 393. xterm produces exactly the same result. Unfortunately, CTRL+LEFT produces keycode 539, and the Curses documentation states clearly that valid keycodes are in the range KEY_MIN to KEY_MAX --- 257 to 511...
So at least things work now, but how do these weird new keycodes work? Are they defined anywhere? They're certainly not in the headers.
Upvotes: 5
Views: 3414
Reputation: 330
i believe this is a conceptual problem of the new Linux/*Nix terminals (PTY/PTS), they (i mean terminal developers) decided to follow ancient VT100-VT525 tech strategy where you get some limited set of "keycodes" from ESC sequences (without keyups).
so the X server where most PTs run sends keycodes to terminal but the terminal doesnt send them to the client (it sends only translated characters)
the "old" console TTY, like linux kernel terminal allows to read keycodes (only keycodes or only characters) so it is possible to get every possible keycode in there.
this problem is recognized by some terminals (eg kitty) and authors: http://www.leonerd.org.uk/hacks/fixterms/
here's the one of creators of this mess: https://invisible-island.net/xterm/modified-keys.html
so they were not able to come to a single concept. which is really simple for the modern developer - take X system event keystate(up/dow)/keycode/modifier and send it raw by some protocol.
they arent geniuses, ive looked into xterm code input.c
Input function's code, it looks like a copy-paste. the proposals lack replies, eg you send some magic CSI
to activate "keyboard protocol" but there is no reply, no guaranty that the terminal is switched into it. i really confused and dissapointed that the future of NIX terminals is really decided by these.
Upvotes: 0
Reputation: 345
I have done a raw [ cfmakeraw ] STDIN scan using EPOLL. And I can confirm that SHIFT+LEFT; SHIFT+RIGHT; are NOT "scanned". So how does XLib client read those keys ?
XLib client/driver uses direct keyboard drivers (using good old BIOS's multiplex Hardware INTERRUPT hooks)...There are no other ways to "scan" [Forgotten
RAW] keyboard state ) :-)
NCurses is a client of the serial /dev/TTY* for the obvious networking reasons - Not a hardware hook.
Upvotes: 0
Reputation: 4840
gnome-terminal is not an xterm. It sends different combinations for shift-arrow and control-arrow. With ncurses version 5.5 setting TERM to gnome will probably work.
Here is some information: http://invisible-island.net/xterm/xterm.faq.html#bug_gnometerm
Upvotes: 2
Reputation: 2667
There's a good chance that gnome-terminal is intercepting your SHIFT-arrow keys for its own purposes. I would suggest running your application in xterm or from the console.
Upvotes: 0