Closed morgen-peschke closed 10 months ago
Are you running this from OS X's terminal app?
During setting up the default terminal object, it sends a couple escape sequences to the terminal to switch the terminal to private mode, hide the cursor, send it to far right down, then query the location to determine screen-size. Then it sends the cursor to home position. For the querying of location, it sends an escape which normally causes the terminal to respond with an escape-sequence on its own (as if typed by the user), thereby telling your application the current cursor position.
From your symptoms it seems like the app doesn't ever receive that reply, and eventually aborts after a few seconds of not receiving the screen size. Reasons are likely that the call to "stty" misbehaves, thus fails to set the terminal to raw mode.
I don't recognize the language (it aint java), and I don't know if it could be made to show some call stack dump on failure. Or maybe it has some debugger that would allow you to single-step through it, while the application under inspection is connected to the terminal - it wouldn't work with the usual "stdin/stdout/stderr"-panels of typical IDEs.
On Wed, Jan 17, 2024 at 9:10 PM Morgen Peschke @.***> wrote:
This came up while working through the tutorials.
Here's the code for rendering a very simple gut check:
— Reply to this email directly, view it on GitHub https://github.com/mabe02/lanterna/issues/591, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIDBMT54ZLZ6YXPUDKTTQLYPAV3RAVCNFSM6AAAAABB7EFLGCVHI2DSMVQWIX3LMV43ASLTON2WKOZSGA4DMOJQGA4DENY . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Are you running this from OS X's terminal app?
I tried it in Terminal and iTerm2, and didn't notice any behavior differences between the two.
I don't recognize the language (it aint java)
Fair 🤷🏻 , it's Scala
and I don't know if it could be made to show some call stack dump on failure.
That shouldn't be a problem (it's the default behavior), however I'm not sure if it's relevant here as (other than rendering weirdly) there aren't any exceptions thrown.
It'll wait for until the next input and then shut down.
Reasons are likely that the call to "stty" misbehaves, thus fails to set the terminal to raw mode.
Not sure where it looks for stty
, but if it helps, calling it directly seems ok:
$ /bin/stty
speed 38400 baud;
lflags: echoe echok echoke echoctl pendin
iflags: iutf8
oflags: -oxtabs
cflags: cs8 -parenb
I was playing around with Tutorial3, to see if the higher-level constructs worked (trying to reduce the chance that this is a problem with my code), and found something kind of interesting.
Every couple of times, it'll work as expected on 3.1.1, and when it doesn't work I noticed two differences:
TerminalScreen#readInput()
only returns when I press [Enter]
, rather than when any non-modifier key is pressedThe symptoms you describe (waits for [Enter]
key, reports 80x24, ...) all point towards stty failing.
Either stty fails silently, or failures of stty are suppressed. Could you add some code to obtain return-code from stty call, or any stderr-output?
iirc, stty gets called three times in total, once with option "-g" to report current state of terminal in some platform-specific syntax. Then it gets called to set terminal to raw mode -- that one appears to be failing. Finally, at the end of the program, it'll use the result of "stty -g" to restore terminal to original mode.
Try to identify these calls. Eventually, you could write a shell script by name of "stty" that will call the original stty and do some extra logging of output, errors and return code, and make sure your script is found in PATH before the real stty when you start the lanterna app.
I don't have access to any OS X machine myself, so I cannot do the experiments there. On Linux it always worked for me.
(if you need help with the stty script, just ask...)
checking into the git, I noticed a late change, where lanterna now calls "/usr/bin/env stty ..." rather than previously "/bin/stty ..."
could it be, that /usr/bin/env is flaky or missing on OS X ? It is supposed to find stty on the PATH and call it.
... or could it be, that you have some other tool named stty and lanterna maybe picks up the wrong stty from PATH ?
Found the issue, looks like it's due to how the build tooling was forking during run 🤦🏻
The version I used to test (3.1.1) was still using the direct call to /bin/stty
, but there was support for using com.googlecode.lanterna.terminal.UnixTerminal.sttyCommand
to override this (thanks for adding that btw, saved a bunch of time 😄).
I used this script to capture the output of stty
and stuck it in a directory on the path named local-bin
:
#!/usr/bin/env bash
# Filter path to avoid /usr/bin/env finding this wrapper again
export PATH=$(tr ':' '\n' <<< "$PATH" | ag -v local-bin | tr '\n' ':' | sed 's/:$//')
{
printf '=================================================\n'
set -x
which stty
hash stty
/usr/bin/env -v stty "$@"
} &>> stty.log.txt
/usr/bin/env stty "$@"
stty
was called 7 times, so I'll omit the full log, this is a representative portion:
+ /usr/bin/env -v stty min 1
#env executing: stty
#env arg[0]= 'stty'
#env arg[1]= 'min'
#env arg[2]= '1'
stty: tcsetattr: Input/output error
This turned out to have been because of the way the build tooling (mill
) was forking to run the process.
This way does not work:
mill scratch.runMain --mainClass cli.Bug
This way works:
mill scratch.publishLocal &&
coursier launch \
--scala 2.13.8 \
-D com.googlecode.lanterna.terminal.UnixTerminal.sttyCommand=stty \
com.example.morgen::scratch::0.0.1 \
--main cli.Bug
The assumption that, because input worked, there was a functional tty turns out to have been a bad one.
Thanks for your help getting me pointed the right direction :)
I've updated UnixTerminal so the STTY path can be specified directly in the code, see https://github.com/mabe02/lanterna/commit/2f4e3b7f37d8645ef001c0dcc05d7ef2ad749044
This came up while working through the tutorials.
Here's the code for rendering a very simple gut check:
On 3.0.4, it immediately renders correctly in terminal:
On 3.1.x, it renders like this:
If you wait close to 10 seconds, it'll update to this: