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

From:
Omar Polo <op@omarpolo.com>
Subject:
fix hscrolling in split view
To:
gameoftrees@openbsd.org
Date:
Fri, 17 Jun 2022 01:28:09 +0200

Download raw body.

Thread
Stefan noticed that the horizontal scrolling in the split view (log +
diff) in tog had a glitch when drawing double-width character.  To
reproduce, open the ja.git repo provided by Stefan in a large enough
xterm, press ret to see the diff in a split view, then tab to focus the
log view and scroll horizontally and see the kanjis being rendered on
top of the vertical line.

tog uses a trick for the split view: it renders the child view on top of
the main view.  the main view always thinks of being as large as the
terminal.  This confuses ncurses when you add double-width character to
the equation.

The issue is that we end up in a situation like this

         |
 log... xx
         |

where "xx" is a double-width kanji and the | is the vertical line.  The
vertical line should hide half of the character, but it can't.

diff below is an attempt at fixing this.  It properly resizes the main
window when creating / destroying the split screen and accounts for the
border when drawing the commit.

(the diff was generated on top of my previous diff that simplifies
format_line and scroll_line, it should apply thought.)

ok?

diff c74541a34e628aa7d0d42da084a6f66045315aed /home/op/w/got
blob - 183c31a912c364ea95baef1534e1f5908d1fb8fe
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -809,6 +809,9 @@ view_set_child(struct tog_view *view, struct tog_view 
 {
 	view->child = child;
 	child->parent = view;
+
+	view->ncols = view->child->begin_x;
+	wresize(view->window, view->lines, view->ncols);
 }
 
 static int
@@ -1085,6 +1088,10 @@ view_loop(struct tog_view *view)
 			if (view->parent) {
 				view->parent->child = NULL;
 				view->parent->focus_child = 0;
+
+				view->parent->ncols = COLS;
+				wresize(view->parent->window,
+				    view->parent->lines, view->parent->ncols);
 			} else
 				TAILQ_REMOVE(&views, view, entry);
 
@@ -1529,6 +1536,8 @@ draw_commit(struct tog_view *view, struct got_commit_o
 	if (newline)
 		*newline = '\0';
 	limit = avail - col;
+	if (view->child)
+		limit--;	/* for the border */
 	err = format_line(&wlogmsg, &logmsg_width, &scrollx, logmsg, view->x,
 	    limit, col, 1);
 	if (err)