markbt / streampager

A pager for command output or large files
MIT License
45 stars 11 forks source link

Cursor disappears in tmux #37

Closed martinvonz closed 3 years ago

martinvonz commented 3 years ago

When running in tmux, a simple echo foo | sp (and quitting it) will make the cursor disappear for me. I don't know enough about terminal emulators to guess if it's just that the background color (normally gray for me) is lost or something else. Let me know if it doesn't reproduce for you. I don't know what other details about my environment may be relevant.

markbt commented 3 years ago

It looks like this is a bug in tmux. It sets TERM to screen, but doesn't support screen's escape sequence for cursor_visible. If you run infocmp -L1 | grep cursor_visible you'll see the escape code that termwiz (and thus streampager) will use to make the cursor visible, but tmux doesn't support that.

If you set TERM=screen.xterm-256color then the escape seqence in that terminfo file does work on tmux.

Cc @wez - this is probably a common issue for termwiz as lots of people use tmux. I'm not really sure what to do here, as we're doing what tmux is asking of us, it's just asking for the wrong thing.

wez commented 3 years ago

I believe that the recommendation/best practice these days is to set TERM=tmux if you have a new enough ncurses installation.

I suppose we could add a little bit of a special case in the termwiz probe code that checks if $TERM == 'screen' && isset($TMUX) and if so, try to resolve the tmux terminfo entry. If that is successful, it could pretend that the environment actually specified tmux instead. I don't feel super great about this, but it is a fairly well constrained check that is likely good in all cases.

@nicm do you have recommendations on how best to handle this?

nicm commented 3 years ago

You should use cursor_normal not cursor_visible to turn the cursor on after turning it off. Or you could use both if you really do want "very visible".

tmux does not support a "very visible" cursor, although probably it should treat it like a normal cursor rather than ignoring it. I will check what xterm does later on, although any fix will not be until the next tmux version of course.

markbt commented 3 years ago

cursor_normal also resets the cursor shape, which we don't want to do. In fact we used to use that until I got a complaint from a user that streampager was resetting their cursor shape.

We now use the cursor_invisible cursor_visible pair to toggle visibility, which seems to work fine everywhere other than tmux.

I think setting TERM to tmux might not be sufficient. I need to check again, but it looked like it had the same definition for cursor_visible as screen on my machine.

nicm commented 3 years ago

It seems odd for cnorm to affect the cursor shape, do you remember which terminfo entry and which terminal does this?

Note that there is no guarantee cnorm will reset the cursor shape and cvvis will not, the interpretation of what is "normal" and what is "very visible" is pretty much up to the person who wrote the terminfo entry.

For example - with xterm, cvvis will leave the cursor the same shape, but it will turn on cursor blinking.

If you want to change the cursor shape, there is DECSCUSR (capabilities Ss and Se).

Anyway - for screen, cvvis is set to SM 34 which looks to be a screen extension that simply sends cvvis to the outside terminal. I think I chose not to include this because "very visible" is pretty useless and hardly anyone uses it, but tmux should probably at least turn the cursor on again.

nicm commented 3 years ago

Er sorry, I'm wrong!

tmux does support SM 34, and it does use it to send cvvis to the terminal outside tmux. However, we send cnorm after cvvis which for at least some entries will reset the effect. I think the intent was to send them the other way round, so that even if cvvis doesn't turn the cursor on (and only makes it blink, or change colour, or does nothing, or whatever else), we send cnorm first to make sure.

Although I'm a bit tempted to drop the whole thing since clearly nobody has noticed this for years...

nicm commented 3 years ago

I'm surprised nobody has complained about you leaving blinking on, but apart from xterm none of the modern terminals I have to hand support cursor blinking so I guess nobody has noticed.

nicm commented 3 years ago

OK, I don't really see how this works for you with screen, because cvvis (SM 34) does not turn the cursor on in screen 4.00.03. Try this:

tput civis; tput cvvis

The cursor will remain off.

markbt commented 3 years ago

OK, I don't really see how this works for you with screen, because cvvis (SM 34) does not turn the cursor on in screen 4.00.03. Try this:

tput civis; tput cvvis

The cursor will remain off.

In Screen 4.08.00 this does work: the cursor is visible.

tput civis; tput cvvis also works in pure gnome-terminal and iterm2. It works in xterm, but makes the cursor flash as you point out. Probably it should work in tmux, too.

But I think I might have gotten confused about cnorm when I originally wrote the visibility support in termwiz. It was actually ResetCursorStyle causing the problem. Termwiz emits both with CursorShape::Default, which was the source of the originally reported bug.

It looks like cnorm alone is, and always would have been, fine. I wasn't aware of the distinction between cvvis and cnorm at the time (the long name is cursor_visible which made me assume it was effectively the same as cnorm, and certainly for all the terminals I tried it made no difference).

So the right solution might be to make CursorVisible::Visible in termwiz emit cnorm (and only cnorm; no ResetCursorStyle). We could also add CursorVisible::VeryVisible for cvvis, although that's maybe less useful as only xterm supports it.

@wez: sorry for the hassle here. I will prep a PR for termwiz to do what I've just suggested.

@nicm: thanks for your help here. This has been enlightening.

nicm commented 3 years ago

Hmm tput civis; tput cvvis doesn't leave the cursor on for me in screen, that's weird, I'm not sure why that would be.

But I think you're right - the right thing to do is to send cnorm if you just want the cursor back to normal.

cvvis turns the cursor on when you use the xterm terminfo entry and not in the screen one, which makes things very confusing and does seem like a mistake, but even if it was fixed today it would be years before it was distributed widely.

I was getting more confused because there is a separate issue with tmux where it does not correctly send cvvis. But once I fix that, with the existing screen terminfo entry it will still not turn on the cursor with cvvis.

Anyway glad I could help, thanks!

wez commented 3 years ago

Thanks for your help @nicm!

markbt commented 3 years ago

This should be fixed in 0.9.6. Let me know if it's still happening.