From: Omar Polo Subject: fix hscrolling in split view To: gameoftrees@openbsd.org Date: Fri, 17 Jun 2022 01:28:09 +0200 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)