From: Dave Voutila Subject: Re: switch printing newline on exit to To: Mark Jamsek Cc: Christian Weisgerber , gameoftrees@openbsd.org Date: Sat, 21 Jan 2023 11:18:49 -0500 Mark Jamsek writes: > [[PGP Signed Part:Undecided]] > On 23-01-20 09:33PM, Christian Weisgerber wrote: >> Tracey Emery: >> >> > Then what about this. It seems to just work in both cases. >> >> > --- tog/tog.c >> > +++ tog/tog.c >> > @@ -9438,7 +9438,6 @@ main(int argc, char *argv[]) >> > } >> > >> > endwin(); >> > - putchar('\n'); >> > if (cmd_argv) { >> > int i; >> > for (i = 0; i < argc; i++) >> >> No, this brings us full circle to the original state of affairs >> where you quit tog and then there is leftover stuff on the bottom >> line to the right of your shell prompt (if alternate screen switching >> is disabled). >> >> I tried to steal what vi(1) does, comment and all, see below, but >> that doesn't work as expected. As soon as I call refresh() before >> endwin(), the screen is cleared. I don't understand why this >> happens. Maybe it's related to tog's use of panels, which vi doesn't >> have? > > I believe this happens because when we refresh() in main, it is after > having deallocated our windows. As such, there is no output to be > redrawn. It looks like the vi code performs this line deletion to move > all lines up and insert a blank line at the bottom before releasing > window resources, so the final refresh() still has output to send to the > screen. > > A solution is to do this in the view_loop() once we know the user is > quitting tog (Q), or killing the current window (q) when it's the last > one remaining. In the first case, we need to check if there are other > windows and do the line deletion on them too. In the second case, we > also need to then make sure tog doesn't redraw the full window (i.e., > restore the line we deleted), so we set the done flag and bypass > a redraw. > > As a small optimisation, in case there is more than one window (i.e., > the user has input Q from a nested child window), use wnoutrefresh() and > then call doupdate(); this saves repeated screen updates. > > Does the below diff produce the desired behaviour? > It does for me! As well as when using what naddy mentioned: $ xterm -xrm 'XTerm*titeInhibit: 1' > An alternative solution would be to move to the bottom line and clear > it, but I like the vi approach. > > diffstat /home/mark/src/got > M tog/tog.c | 25+ 2- > > 1 file changed, 25 insertions(+), 2 deletions(-) > > diff /home/mark/src/got > commit - 96afb0d62311dd459395b8eba2216094c18dfb67 > path + /home/mark/src/got > blob - 35282ce50aa4dec0745aa6402cd0b50d87b7416b > file + tog/tog.c > --- tog/tog.c > +++ tog/tog.c > @@ -1745,6 +1745,30 @@ view_loop(struct tog_view *view) > err = view_input(&new_view, &done, view, &views); > if (err) > break; > + > + if (view->dying && view == TAILQ_FIRST(&views) && > + TAILQ_NEXT(view, entry) == NULL) > + done = 1; > + if (done) { > + struct tog_view *v; > + > + /* > + * When we quit, scroll the screen up a single line > + * so we don't lose any information. > + */ > + TAILQ_FOREACH(v, &views, entry) { > + wmove(v->window, 0, 0); > + wdeleteln(v->window); > + wnoutrefresh(v->window); > + if (v->child && !view_is_fullscreen(v)) { > + wmove(v->child->window, 0, 0); > + wdeleteln(v->child->window); > + wnoutrefresh(v->child->window); > + } > + } > + doupdate(); > + } > + > if (view->dying) { > struct tog_view *v, *prev = NULL; > > @@ -1808,7 +1832,7 @@ view_loop(struct tog_view *view) > TAILQ_INSERT_TAIL(&views, new_view, entry); > view = new_view; > } > - if (view) { > + if (view && !done) { > if (view_is_parent_view(view)) { > if (view->child && view->child->focussed) > view = view->child; > @@ -9438,7 +9462,6 @@ main(int argc, char *argv[]) > } > > endwin(); > - putchar('\n'); > if (cmd_argv) { > int i; > for (i = 0; i < argc; i++)