Download raw body.
fix hscrolling in split view
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.
diff c74541a34e628aa7d0d42da084a6f66045315aed /home/op/w/got
blob - 183c31a912c364ea95baef1534e1f5908d1fb8fe
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -763,31 +763,39 @@ 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) {
+ /*
+ * Resize parent to full screen when not in
+ * split screen.
+ */
+ 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);
}
}
+ 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 +812,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 +1095,13 @@ view_loop(struct tog_view *view)
if (view->parent) {
view->parent->child = NULL;
view->parent->focus_child = 0;
+
+ prev->ncols = COLS;
+ if (wresize(prev->window, prev->lines,
+ prev->ncols) == ERR)
+ err = got_error_from_errno("wresize");
+ if (err)
+ break;
} else
TAILQ_REMOVE(&views, view, entry);
@@ -1529,6 +1546,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 +2714,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 +2737,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 +2823,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 +5126,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 +5872,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 +5897,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 +6033,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 +6761,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 +6783,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;
fix hscrolling in split view