ab5tract / Terminal-Print

Terminal::Print is a pure Raku layer for printing to terminal screens
Other
25 stars 18 forks source link

Add terminal input libraries #19

Open japhb opened 7 years ago

japhb commented 7 years ago

Add libraries that allow working at various levels of terminal input from raw key-down/key-up messages all the way to readline / text area input.

As a bonus, support terminal mouse input as well, including chorded clicks, drags, etc.

japhb commented 7 years ago

Spent some time investigating mouse input. Turns out there are a number of different mouse event protocols that have been supported by various terminal emulators over the years, with various types of broken behavior. The current standard is 'SGR 1006', an extension of the original mouse input protocol now supported by most terminal emulators, which among other things supports ultra-large terminals, has unambiguous decoding, does not get confused about which mouse button is being released, and does not get mangled by UTF-8 processing. Because it's an extension, we should at least support the ASCII subset of the original protocol, plus the SGR 1006 extension wherever available -- and in my opinion ignore all the other variants, several of which are being actively desupported elsewhere.

To support mouse input, we will need to be able to send mode setting instructions into the output data (easy), and snoop incoming tty input to the app converting some incoming character blocks to mouse and/or button events instead (constrains the tty input handling design). We'll also need to make sure than even abnormal program exit will turn off mouse input, or the user's terminal will continue to feed mouse events into the input buffer, appearing as garbage input.

japhb commented 7 years ago

The input system will be more useful proper event bubbling, not just delivering all inputs to one place and forcing the app author to demux the input. This may be accomplished in concert with Widget (or an add-on role for it), because Widget understands parent/child relationships and the order of child compositing within the parent.

japhb commented 7 years ago

I've started sketching out raw input on the (rather obviously named) raw-input branch. There are known problems with the implementation (not least that currently I can't convert escape sequences into special keys yet), and I can't seem to get key up events using standard TTY input at all, but it's a start. Beginnings of a matching example program in examples/tris.p6.

japhb commented 7 years ago

With some clarification from jnthn++ in https://rt.perl.org/Public/Bug/Display.html?id=130716 , I've made some progress in the raw-input branch. The current structure should be more friendly to making a special key decoding layer, but there's a new problem visible in examples/tris.p6: after playing for a short while, it stops accepting keyboard input, and just continues processing the timer ticks. If the process is killed, the keyboard input that was not accepted appears at the command prompt instead.

ab5tract commented 7 years ago

Great progress, japhb!

I wonder if this might have something to do with using .merge ?

Shouldn't the timer and the raw-input-supply both be able to have their own whenever blocks without issue?

Also, thanks for your continued efforts!

geekosaur commented 7 years ago

You can't get the raw key events from the terminal interface itself. You can on X11-based terminals usually get them by looking for $*ENV<WINDOWID>, opening an X11 connection, and selecting for events on the window with that XID. OS X supports something similar (but details differing, since it's not X11-based unless the user is running an X11 terminal under XQuartz) via a different environment variable that I don't recall offhand (and my Mac is currently offline/stowed). I have no idea how you do it for Windows, and some vague recollection that the Windows Console API may make this difficult by having side effects like hiding the terminal window.

japhb commented 7 years ago

Update: In current Rakudo, examples/tris.p6 (still on the raw-input branch) works just fine, it's just stuck using normal printable character keys for input because there's not yet any escape sequence decoding.

I've been ruminating on a way to do the escape sequence decoding sanely and correctly and not coming up with much, until today I found this: http://vt100.net/emu/dec_ansi_parser . I haven't read it all the way through yet, but so far it looks sufficiently complete that that's roughly what I intend to implement.

japhb commented 7 years ago

I've merged raw-input because it seemed quite stable, and have locally started a new branch (decode-keys) for writing the key-decoding logic.

Turns out the escape sequence parser I found in the previous comment appears to be specific to the output side of the problem (what you'd need to decode commands sent from a program to the terminal if you were writing a terminal emulator). However, I think there's enough useful info there to get me started.

geekosaur commented 7 years ago

Main difference for input is there's some escapes not covered by the output side (notably the alternate mode keys using O instead of [). Otherwise, the DEC/ANSI parser is fairly regular.

On Sat, Aug 26, 2017 at 1:28 PM, japhb notifications@github.com wrote:

I've merged raw-input because it seemed quite stable, and have locally started a new branch (decode-keys) for writing the key-decoding logic.

Turns out the escape sequence parser I found in the previous comment appears to be specific to the output side of the problem (what you'd need to decode commands sent from a program to the terminal if you were writing a terminal emulator). However, I think there's enough useful info there to get me started.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ab5tract/Terminal-Print/issues/19#issuecomment-325149575, or mute the thread https://github.com/notifications/unsubscribe-auth/AB8SoPCPguzRvbqF9W9-CSzK7SHjWsILks5scFWygaJpZM4LKJJC .

-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

japhb commented 7 years ago

Well, I've now got a rough start working: https://github.com/ab5tract/Terminal-Print/blob/decode-keys/lib/Terminal/Print/DecodedInput.pm6 .

It only decodes the four cursor directional keys, it doesn't know how to handle hitting the escape key by itself with nothing else (there's no escape timeout, in other words), and there's some cleanup to do, but it seems to work otherwise. There's now an examples/decoded-input.p6 that will show the decoding in operation. Unrecognized sequences will just show up in raw form as before; decoded sequences will show they are recognized as such.

japhb commented 7 years ago

OK, that should be a mapping for all remaining special keys defined by xterm except Escape itself and the various modifiers; as a bonus I've added the Bracketed Paste markers for timotimo. :-)

Next up will probably be modifier keys (requires a change to the escape sequence parsing), and then perhaps I'll move on to mouse handling.

japhb commented 7 years ago

Modifiers and timeout for incomplete escape sequences complete; decode-keys branch now merged.

Now to refresh myself on mouse input ....

japhb commented 7 years ago

And mouse input is now implemented for three of the four basic tracking event modes (missing highlight tracking mode, which may be problematic).

The event shape mismatches (the fact that the different event types are very different) may need some API massaging, but all the basic input decoding functionality should be there.

ab5tract commented 7 years ago

Awesome!!

This puts us in a great position for a 1.0.0 release in the next few months. I'll create a proper ticket for it, but input and a proper manual are both key ingredients.

japhb commented 7 years ago

Sketched out some thoughts on the road to 1.0 in a separate issue (https://github.com/ab5tract/Terminal-Print/issues/46).

nkh commented 7 years ago

Great work!

I will be testing this as soon as the no-more-auto_create is merged.

I did not understand, reading the above comments, if the ESC key is handled yet.

japhb commented 7 years ago

nkh: Yes, the ESC key is handled, it will simply be slightly delayed (.1 second by default) in case you're just on a slow remote connection or some such and the rest of the escape sequence is still to come.

nkh commented 7 years ago

I merged "in the dark" the no-more-auto-create branch to do some tests, I hope it will be merged in master soon

ab5tract commented 7 years ago

It is merged now.

On Thu, Aug 31, 2017, 08:37 Nadim Khemir notifications@github.com wrote:

I merged "in the dark" the no-more-auto-create branch to do some tests, I hope it will be merged in master soon

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ab5tract/Terminal-Print/issues/19#issuecomment-326204104, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAKtroHiJfj_mM8132OZ0pwx55wlGlCks5sdlSmgaJpZM4LKJJC .

ab5tract commented 6 years ago

@japhb Do you consider this work finished? I'd like to start closing tickets that have been resolved as of the current implementation.

If you think input in general deserves a re-think, I'd like to create a separate ticket for that discussion.