dankamongmen / notcurses

blingful character graphics/TUI library. definitely not curses.
https://nick-black.com/dankwiki/index.php/Notcurses
Other
3.61k stars 114 forks source link

Terminal private mode 8452 left enabled on exit #1533

Closed dnkl closed 3 years ago

dnkl commented 3 years ago

Running e.g. notcurses-demo on a terminal with sixel support causes notcurses to enable the private mode 8452 (cursor left to the right of newly emitted sixels).

This mode is left enabled upon exit.

While I do believe all sixel capable applications should explicitly set the modes they need, I also consider it good manners to restore things to the defaults when you're done.

Mode 8452 is one of the lesser known modes, and it's default setting is disabled.

lsix is one example of an application that doesn't set, or reset, mode 8452. Running it after notcurses breaks when it needs to emit more than one "row" of images.

dankamongmen commented 3 years ago

wow, great catch, thanks!

dankamongmen commented 3 years ago

the correct place to fix this will be notcurses_stop_minimal().

dankamongmen commented 3 years ago

so to reset it, what ought i be sending? all i see in the xterm control sequences document is

CSI ? Pm h
          Set Mode, xterm.  xterm has these additional private Set Mode
          values:
            Ps = 8 0  ⇒  Sixel scrolling.
            Ps = 1 0 7 0  ⇒  use private color registers for each
          graphic.
            Ps = 8 4 5 2  ⇒  Sixel scrolling leaves cursor to right of
          graphic.

(and doesn't he want Pm there, not Ps?)

dnkl commented 3 years ago

All private modes are enabled and disabled in the same way; using h as the "final" character enables the mode, and l disables it.

So in this case, \E[?8452l.

dnkl commented 3 years ago

(and you can enable/disable multiple modes at the same time: \E[?1;2;3;4;5h)

dankamongmen commented 3 years ago
CSI ? Pm l
          DEC Private Mode Reset (DECRST).
            Ps = 1  ⇒  Normal Cursor Keys (DECCKM), VT100.
            Ps = 2  ⇒  Designate VT52 mode (DECANM), VT100.
            Ps = 3  ⇒  80 Column Mode (DECCOLM), VT100.
            Ps = 4  ⇒  Jump (Fast) Scroll (DECSCLM), VT100.
            Ps = 5  ⇒  Normal Video (DECSCNM), VT100.
            Ps = 6  ⇒  Normal Cursor Mode (DECOM), VT100.
            Ps = 7  ⇒  No Auto-Wrap Mode (DECAWM), VT100.
            Ps = 8  ⇒  No Auto-Repeat Keys (DECARM), VT100.
            Ps = 9  ⇒  Don't send Mouse X & Y on button press, xterm.
            Ps = 1 0  ⇒  Hide toolbar (rxvt).
            Ps = 1 2  ⇒  Stop blinking cursor (AT&T 610).
            Ps = 1 3  ⇒  Disable blinking cursor (reset only via
          resource or menu).
            Ps = 1 4  ⇒  Disable XOR of blinking cursor control sequence
          and menu.
            Ps = 1 8  ⇒  Don't Print Form Feed (DECPFF), VT220.
            Ps = 1 9  ⇒  Limit print to scrolling region (DECPEX),
          VT220.
            Ps = 2 5  ⇒  Hide cursor (DECTCEM), VT220.
            Ps = 3 0  ⇒  Don't show scrollbar (rxvt).
            Ps = 3 5  ⇒  Disable font-shifting functions (rxvt).
            Ps = 4 0  ⇒  Disallow 80 ⇒  132 mode, xterm.
            Ps = 4 1  ⇒  No more(1) fix (see curses resource).
            Ps = 4 2  ⇒  Disable National Replacement Character sets
          (DECNRCM), VT220.
            Ps = 4 3  ⇒  Disable Graphics Expanded Print Mode (DECGEPM).
            Ps = 4 4  ⇒  Turn off margin bell, xterm.
            Ps = 4 4  ⇒  Disable Graphics Print Color Mode (DECGPCM).
            Ps = 4 5  ⇒  No Reverse-wraparound mode, xterm.
            Ps = 4 5  ⇒  Disable Graphics Print ColorSpace (DECGPCS).
            Ps = 4 6  ⇒  Stop logging, xterm.  This is normally disabled
          by a compile-time option.
            Ps = 4 7  ⇒  Use Normal Screen Buffer, xterm.
            Ps = 4 7  ⇒  Disable Graphics Rotated Print Mode (DECGRPM).
            Ps = 6 6  ⇒  Numeric keypad mode (DECNKM), VT320.
            Ps = 6 7  ⇒  Backarrow key sends delete (DECBKM), VT340,
          VT420.  This sets the backarrowKey resource to "false".
            Ps = 6 9  ⇒  Disable left and right margin mode (DECLRMM),
          VT420 and up.
            Ps = 8 0  ⇒  Disable Sixel Scrolling (DECSDM).
            Ps = 9 5  ⇒  Clear screen when DECCOLM is set/reset
          (DECNCSM), VT510 and up.
            Ps = 1 0 0 0  ⇒  Don't send Mouse X & Y on button press and
          release.  See the section Mouse Tracking.
            Ps = 1 0 0 1  ⇒  Don't use Hilite Mouse Tracking, xterm.
            Ps = 1 0 0 2  ⇒  Don't use Cell Motion Mouse Tracking,
          xterm.  See the section Button-event tracking.
            Ps = 1 0 0 3  ⇒  Don't use All Motion Mouse Tracking, xterm.
          See the section Any-event tracking.
            Ps = 1 0 0 4  ⇒  Don't send FocusIn/FocusOut events, xterm.
            Ps = 1 0 0 5  ⇒  Disable UTF-8 Mouse Mode, xterm.
            Ps = 1 0 0 6  ⇒  Disable SGR Mouse Mode, xterm.
            Ps = 1 0 0 7  ⇒  Disable Alternate Scroll Mode, xterm.  This
          corresponds to the alternateScroll resource.
            Ps = 1 0 1 0  ⇒  Don't scroll to bottom on tty output
          (rxvt).  This sets the scrollTtyOutput resource to "false".
            Ps = 1 0 1 1  ⇒  Don't scroll to bottom on key press (rxvt).
          This sets the scrollKey resource to "false".
            Ps = 1 0 1 5  ⇒  Disable urxvt Mouse Mode.
            Ps = 1 0 1 6  ⇒  Disable SGR Mouse Pixel-Mode, xterm.
            Ps = 1 0 3 4  ⇒  Don't interpret "meta" key, xterm.  This
          disables the eightBitInput resource.
            Ps = 1 0 3 5  ⇒  Disable special modifiers for Alt and
          NumLock keys, xterm.  This disables the numLock resource.
            Ps = 1 0 3 6  ⇒  Don't send ESC  when Meta modifies a key,
          xterm.  This disables the metaSendsEscape resource.
            Ps = 1 0 3 7  ⇒  Send VT220 Remove from the editing-keypad
          Delete key, xterm.
            Ps = 1 0 3 9  ⇒  Don't send ESC when Alt modifies a key,
          xterm.  This disables the altSendsEscape resource.
            Ps = 1 0 4 0  ⇒  Do not keep selection when not highlighted,
          xterm.  This disables the keepSelection resource.
            Ps = 1 0 4 1  ⇒  Use the PRIMARY selection, xterm.  This
          disables the selectToClipboard resource.
            Ps = 1 0 4 2  ⇒  Disable Urgency window manager hint when
          Control-G is received, xterm.  This disables the bellIsUrgent
          resource.
            Ps = 1 0 4 3  ⇒  Disable raising of the window when Control-
          G is received, xterm.  This disables the popOnBell resource.
            Ps = 1 0 4 6  ⇒  Disable switching to/from Alternate Screen
          Buffer, xterm.  This works for terminfo-based systems,
          updating the titeInhibit resource.  If currently using the
          Alternate Screen Buffer, xterm switches to the Normal Screen
          Buffer.
            Ps = 1 0 4 7  ⇒  Use Normal Screen Buffer, xterm.  Clear the
          screen first if in the Alternate Screen Buffer.  This may be
          disabled by the titeInhibit resource.
            Ps = 1 0 4 8  ⇒  Restore cursor as in DECRC, xterm.  This
          may be disabled by the titeInhibit resource.
            Ps = 1 0 4 9  ⇒  Use Normal Screen Buffer and restore cursor
          as in DECRC, xterm.  This may be disabled by the titeInhibit
          resource.  This combines the effects of the 1 0 4 7  and 1 0 4
          8  modes.  Use this with terminfo-based applications rather
          than the 4 7  mode.
            Ps = 1 0 5 0  ⇒  Reset terminfo/termcap function-key mode,
          xterm.
            Ps = 1 0 5 1  ⇒  Reset Sun function-key mode, xterm.
            Ps = 1 0 5 2  ⇒  Reset HP function-key mode, xterm.
            Ps = 1 0 5 3  ⇒  Reset SCO function-key mode, xterm.
            Ps = 1 0 6 0  ⇒  Reset legacy keyboard emulation, i.e,
          X11R6, xterm.
            Ps = 1 0 6 1  ⇒  Reset keyboard emulation to Sun/PC style,
          xterm.
            Ps = 2 0 0 4  ⇒  Reset bracketed paste mode, xterm.
dankamongmen commented 3 years ago

I believe this to be fixed, in both direct and rendered mode. Thanks for the report!

dnkl commented 3 years ago

Verified, thanks for the super quick fix!

dnkl commented 3 years ago

Hmm, looking at this:

int sixel_shutdown(int fd){
fprintf(stderr, "ERP?\n");
  return tty_emit("\e[?80;8452l", fd);
}

I don't think we should disable mode 80 (that's sixel scrolling). It is enabled by default. With current master, lsix works because it actually does enable mode 80 explicitly. But cat:ing a raw sixel sequence behaves differently before and after running notcurses.

Alternatively, instead of explicitly enabling/disabling modes at exit, use XTSAVE at startup, and XTRESTORE on exit. But will say right away that I'm not sure how well supported those two are. A technique I've used before is to issue XTSAVE on startup, do my thing, and then on exit, first, explicitly enable/disable private modes to what I think they should be set to, then emit XTRESTORE. Terminals that doesn't implement XTSAVE+XTRESTORE should ignore them.

Edit: formatting

dnkl commented 3 years ago

XTSAVE+XTRESTORE work just like set and reset: \E[?1;2;3;4s to save, \E[?1;2;3;4r to restore.

dankamongmen commented 3 years ago

Alternatively, instead of explicitly enabling/disabling modes at exit, use XTSAVE at startup, and XTRESTORE on exit. But will say right away that I'm not sure how well supported those two are. A technique I've used before is to issue XTSAVE on startup, do my thing, and then on exit, first, explicitly enable/disable private modes to what I think they should be set to, then emit XTRESTORE. Terminals that doesn't implement XTSAVE+XTRESTORE should ignore them.

yep, just what i was thinking