Open hcpl opened 7 years ago
Hi, and thanks for the report!
The "Enter" key is a special one, and isn't very well supported with modifier keys - terminals just don't send the complete information to the application. Ctrl-Enter
and Shift-Enter
are just sent as simple Enter
event; though Alt+Enter
should be detectable with some modification to the input system. If you try with another key, like Home
, it should work better.
Now, there seems to be some problem detecting this modifier. Apparently Ctrl-Home
is detected as Ctrl-Shift-Home
, and some other confusion, so I'll need to have a look at that part. :S
As a note, you can use the key_codes
example to see the event generated by a key press.
Oh, I missed the example, thanks for pointing out.
Since ncurses does not support new features of modern terminals I already knew that keyboard handling is messy, but I never thought it's that messy. So I came up with a table:
No modifiers | Shift | Ctrl | Alt | Ctrl+Shift | Ctrl+Alt | Alt+Shift | Ctrl+Alt+Shift | |
---|---|---|---|---|---|---|---|---|
Enter | Key(Enter) |
Key(Enter) |
Key(Enter) |
Key(Esc) Key(Enter) |
Key(Enter) |
Key(Esc) Key(Enter) |
Key(Esc) Key(Enter) |
Key(Esc) Key(Enter) |
Home | Key(Home) |
Nothing | Key(Home) |
Key(Home) |
Nothing | Key(Home) |
Nothing | Nothing |
End | Key(End) |
Nothing | Key(End) |
Key(End) |
Nothing | Key(End) |
Nothing | Nothing |
PageUp | Key(PageUp) |
Nothing | CtrlAlt(PageDown) |
Ctrl(PageDown) |
Nothing | AltShift(PageUp) |
Nothing | Nothing |
PageDown | Key(PageDown) |
Nothing | CtrlAlt(Left) |
Ctrl(Left) |
Nothing | AltShift(PageDown) |
Nothing | Nothing |
Left | Key(Left) |
Shift(Left) |
CtrlAlt(Ins) |
Ctrl(Ins) |
Alt(Left) |
AltShift(Left) |
Unknown([31, 2, 0, 0]) |
Key(Esc) Char('[') Char('1') Char(';') Char('8') Char('D') |
Right | Key(Right) |
Shift(Right) |
CtrlAlt(PageUp) |
Ctrl(PageUp) |
Alt(Right) |
AltShift(Right) |
CtrlShift(PageUp) |
Key(Esc) Char('[') Char('1') Char(';') Char('8') Char('C') |
Up | Key(Up) |
Shift(Up) |
Unknown([53, 2, 0, 0]) |
CtrlShift(Right) |
Nothing | AltShift(Up) |
CtrlAlt(Right) |
Nothing |
Down | Key(Down) |
Shift(Down) |
Unknown([12, 2, 0, 0]) |
CtrlShift(Del) |
Nothing | AltShift(Down) |
Unknown([11, 2, 0, 0]) |
Nothing |
This shows that there are many cases where one modifier set is recognized as another one, some send an escape sequence, some are not recognized by Cursive and others are trapped entirely, though I don't know what exactly in keyboard OS event chain should be blamed for trapping.
Also your observation
Apparently
Ctrl-Home
is detected asCtrl-Shift-Home
contradicts with mine: it's detected as plain Home
. I think that's because of difference in keyboard layouts, either (or even both) in hardware and in software (I am using i3wm with modifier key bound on Alt
but to fill this table I temporarily switched it off).
Another note: the terminal used has a large impact on the events actually delivered to the application.
I just pushed a1737ca0ba1a99bffc5ec6f42e3371c9df552a91, which at least fixes most modifier+key input on my computer for the ncurses backend. I tested it locally with gnome-terminal and konsole. Not all key combinations work on both, but I didn't see any Unknown
or mislabeled event (except for Ctrl+Shift+Alt+Key, those are a bit trickier for now). If this work for you, I'll update the pancurses backend to work the same.
If this doesn't work for you, then it means the key codes are different between multiple systems (could be terminfo version, terminal used, ...), which would be a bit of a pain...
Notes:
For these reasons, I used to have in the Readme a compatibility table of the events available on various terminals, but it ended up being out-of-date, it depended on the backend used, and was overall too much work to maintain.
Yeah, I only tested on gnome-terminal. I also have xterm and urxvt installed, so I'll test your commit against them too.
After realizing that the actual key <=> code mapping was changing between ncurses versions, I understood hard-coding this table wasn't going anywhere. So now it should detect this mapping at runtime. This include the (Alt
, AltShift
, Ctrl
, CtrlShift
and CtrlAlt
) modifiers, for the (Del
, Insert
, Home
, End,
PageUp/
Down` and the arrow keys).
I'm seeing incorrect mapping with macOS Terminal and the default backend. For example, Alt(Left) appears to be an escape code of Key(Esc) Char('b'). When I get some time, I'll dig into the code to see what can be done.
What's the future of this task? Is it doable?
TLDR: Shift+Enter and Ctrl+Enter are probably impossible to differentiate from Enter, because the terminal sends the same code to the application.
Input encoding depends on the terminal used, and those can vary a lot. Recognizing the encoding scheme and parsing the input appropriately is a huge task, and ncurses is supposed to do exactly that. As much as possible, I'd like to leave most of the $TERM
-dependent work to the backend library (or, if needed, the backend module).
That being said, parsing the output from ncurses itself isn't always trivial; many key codes are correctly parsed, but the returned code isn't documented, and the actual value depends on the ncurses version. This is what can be improved here - for instance, confusing CtrlAlt(Ins)
and Ctrl(Left)
results from wrongly parsing ncurses' own output, and should be correctable. Receiving Key(Esc)
and Char('b')
instead of Alt(Left)
means ncurses is not parsing the escape sequence for this particular terminal, and is trickier to fix here.
Regarding macOS compatibility, I don't have a machine to test; https://github.com/gyscos/Cursive/issues/206 may be of interest.
Regarding variations for the Enter key, most terminals simply send the same code even if Shift or Ctrl is pressed, so cursive cannot tell the difference.
As for the termion backend, it doesn't currently check the current terminal, but there's an issue for that (https://github.com/ticki/termion/issues/106).
Same behaviour on macos terminal. i need the ctrl-enter but it does not work.
Description
Cannot process a "modifier+bare key" key combination, only a "bare key".
Configuration
Cursive version 0.6.4, the issue is relevant to all backends except BearLibTerminal which I didn't test.
Expected behaviour
Print on the upper-left corner:
ctrl+enter
on Ctrl+Enter;shift+enter
on Shift+Enter;alt+enter
on Alt+Enter.Actual behaviour
Nothing happens.
Code to reproduce
P.S. If the
Event::Key(Key::Enter) => "enter"
part is uncommented, the program will printenter
for all 4 cases.UPD: Add gnome-terminal as the terminal used and its version.