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

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

Download raw body.

Thread
Omar Polo <op@omarpolo.com> wrote:
> Omar Polo <op@omarpolo.com> wrote:
> > 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?
> 
> The diff worked, but lacked some error checking.  In addressing that,
> I've found that we failed to account correctly the size of the parent
> window in view_resize.
> 
> new diff handles wresize failures, fixes the fallback from split screen
> -> full screen when resizing and fixes the computation of the parent
> window width (ncols) in view_resize.

last attempt without the ugly hack in view_loop: just call view_resize
after removing the child view and let it recompute the sizes.

ok?

diff c74541a34e628aa7d0d42da084a6f66045315aed /home/op/w/got
blob - 183c31a912c364ea95baef1534e1f5908d1fb8fe
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -763,31 +763,36 @@ view_resize(struct tog_view *view)
 	else
 		ncols = view->ncols + (COLS - view->cols);
 
-	if (wresize(view->window, nlines, ncols) == ERR)
-		return got_error_from_errno("wresize");
-	if (replace_panel(view->panel, view->window) == ERR)
-		return got_error_from_errno("replace_panel");
-	wclear(view->window);
-
-	view->nlines = nlines;
-	view->ncols = ncols;
-	view->lines = LINES;
-	view->cols = COLS;
-
 	if (view->child) {
 		view->child->begin_x = view_split_begin_x(view->begin_x);
 		if (view->child->begin_x == 0) {
+			ncols = COLS;
+
 			view_fullscreen(view->child);
 			if (view->child->focussed)
 				show_panel(view->child->panel);
 			else
 				show_panel(view->panel);
 		} else {
+			ncols = view->child->begin_x;
+
 			view_splitscreen(view->child);
 			show_panel(view->child->panel);
 		}
-	}
+	} else if (view->parent == NULL)
+		ncols = COLS;
 
+	if (wresize(view->window, nlines, ncols) == ERR)
+		return got_error_from_errno("wresize");
+	if (replace_panel(view->panel, view->window) == ERR)
+		return got_error_from_errno("replace_panel");
+	wclear(view->window);
+
+	view->nlines = nlines;
+	view->ncols = ncols;
+	view->lines = LINES;
+	view->cols = COLS;
+
 	return NULL;
 }
 
@@ -804,11 +809,13 @@ view_close_child(struct tog_view *view)
 	return err;
 }
 
-static void
+static const struct got_error *
 view_set_child(struct tog_view *view, struct tog_view *child)
 {
 	view->child = child;
 	child->parent = view;
+
+	return view_resize(view);
 }
 
 static int
@@ -1085,6 +1092,10 @@ view_loop(struct tog_view *view)
 			if (view->parent) {
 				view->parent->child = NULL;
 				view->parent->focus_child = 0;
+
+				err = view_resize(view->parent);
+				if (err)
+					break;
 			} else
 				TAILQ_REMOVE(&views, view, entry);
 
@@ -1529,6 +1540,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)
@@ -2695,7 +2708,9 @@ input_log_view(struct tog_view **new_view, struct tog_
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, diff_view);
+			err = view_set_child(view, diff_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = diff_view;
@@ -2716,7 +2731,9 @@ input_log_view(struct tog_view **new_view, struct tog_
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, tree_view);
+			err = view_set_child(view, tree_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = tree_view;
@@ -2800,7 +2817,9 @@ input_log_view(struct tog_view **new_view, struct tog_
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, ref_view);
+			err = view_set_child(view, ref_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = ref_view;
@@ -5101,7 +5120,9 @@ input_blame_view(struct tog_view **new_view, struct to
 			err = view_close_child(view);
 			if (err)
 				break;
-			view_set_child(view, diff_view);
+			err = view_set_child(view, diff_view);
+			if (err)
+				break;
 			view->focus_child = 1;
 		} else
 			*new_view = diff_view;
@@ -5845,7 +5866,9 @@ input_tree_view(struct tog_view **new_view, struct tog
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, log_view);
+			err = view_set_child(view, log_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = log_view;
@@ -5868,7 +5891,9 @@ input_tree_view(struct tog_view **new_view, struct tog
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, ref_view);
+			err = view_set_child(view, ref_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = ref_view;
@@ -6002,7 +6027,9 @@ input_tree_view(struct tog_view **new_view, struct tog
 				err = view_close_child(view);
 				if (err)
 					return err;
-				view_set_child(view, blame_view);
+				err = view_set_child(view, blame_view);
+				if (err)
+					return err;
 				view->focus_child = 1;
 			} else
 				*new_view = blame_view;
@@ -6728,7 +6755,9 @@ input_ref_view(struct tog_view **new_view, struct tog_
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, log_view);
+			err = view_set_child(view, log_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = log_view;
@@ -6748,7 +6777,9 @@ input_ref_view(struct tog_view **new_view, struct tog_
 			err = view_close_child(view);
 			if (err)
 				return err;
-			view_set_child(view, tree_view);
+			err = view_set_child(view, tree_view);
+			if (err)
+				return err;
 			view->focus_child = 1;
 		} else
 			*new_view = tree_view;