"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Dave Voutila <dv@sisu.io>
Subject:
Re: switch printing newline on exit to
To:
Mark Jamsek <mark@jamsek.com>
Cc:
Christian Weisgerber <naddy@mips.inka.de>, gameoftrees@openbsd.org
Date:
Sat, 21 Jan 2023 11:18:49 -0500

Download raw body.

Thread
Mark Jamsek <mark@jamsek.com> 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++)