Download raw body.
tog: fix resize failure to populate log view commits
On 22-07-18 03:18pm, Stefan Sperling wrote:
> On Mon, Jul 18, 2022 at 11:12:27PM +1000, Mark Jamsek wrote:
> > On 22-07-18 02:49pm, Stefan Sperling wrote:
> > > On Mon, Jul 18, 2022 at 10:34:27PM +1000, Mark Jamsek wrote:
> > > > If resizing a log view while on the _last_ loaded commit on the bottom
> > > > edge of the screen, some of the new lines are not populated.
> > > >
> > > > repro:
> > > > $ tog # 80x24
> > > > 23j # move down to the last commit
> > > > *increase terminal height to ~30 lines then reduce back to 80x24*
> > > > ~5j # move down to the _last_ commit
> > > > *increase terminal height to ~33 lines*
> > > >
> > > > Most of the new lines are empty.
> > > >
> > > > We call request_log_commits() from view_resize()--but only when the view
> > > > has a child view. The fix simply moves this check, so that we always
> > > > call request_log_commits() if the terminal height has been increased,
> > > > irrespective of whether a child view exists.
> > >
> > > I only have a concern about style consistency:
> > >
> > > Could we add a resize function pointer to struct tog_view and call this
> > > (if not NULL) instead of checking the view type and manipulating diff
> > > view state in view_resize() directly?
> > >
> > > The code would then move into a new resize_diff_view() function.
> >
> > Sure! That would be better. Do you mean just the logic for requesting
> > commits in the event the terminal height is increased into
> > a resize_log_view() routine to be called from view_resize()?
>
> Look at how reset_diff_view and reset_blame_view work.
> Any view-specific resizing code could be called in the same way.
>
> You would probably end up with something like this in view_resize();
>
> if (view->resize) {
> err = view->resize(view, dif);
> if (err)
> return err;
> }
Yeah, np! That's what I was thinking but I was thrown with the
resize_diff_view() typo and wasn't sure if you meant a new
resize_*_view() function pointer for each view type. I was pretty sure
that wasn't what you meant as it'd mean a lot of duplicated code but
thought I'd double check.
The below diff might do it :)
diff /home/mark/src/git/got-current
commit - d2587c5f95c6edb51ccc8d4abfac838b58f3a463
path + /home/mark/src/git/got-current
blob - 97ac0690a9232815bb10bc4a237246e2ec53e069
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -517,7 +517,7 @@ struct tog_view {
int lines, cols; /* copies of LINES and COLS */
int nscrolled, offset; /* lines scrolled and hsplit line offset */
int ch, count; /* current keymap and count prefix */
- int resize; /* set when in a resize event */
+ int resized; /* set when in a resize event */
int focussed; /* Only set on one parent or child view at a time. */
int dying;
struct tog_view *parent;
@@ -549,6 +549,7 @@ struct tog_view {
const struct got_error *(*input)(struct tog_view **,
struct tog_view *, int);
const struct got_error *(*reset)(struct tog_view *);
+ const struct got_error *(*resize)(struct tog_view *, int);
const struct got_error *(*close)(struct tog_view *);
const struct got_error *(*search_start)(struct tog_view *);
@@ -731,13 +732,13 @@ view_splitscreen(struct tog_view *view)
{
const struct got_error *err = NULL;
- if (!view->resize && view->mode == TOG_VIEW_SPLIT_HRZN) {
+ if (!view->resized && view->mode == TOG_VIEW_SPLIT_HRZN) {
if (view->resized_y && view->resized_y < view->lines)
view->begin_y = view->resized_y;
else
view->begin_y = view_split_begin_y(view->nlines);
view->begin_x = 0;
- } else if (!view->resize) {
+ } else if (!view->resized) {
if (view->resized_x && view->resized_x < view->cols - 1 &&
view->cols > 119)
view->begin_x = view->resized_x;
@@ -768,8 +769,8 @@ view_fullscreen(struct tog_view *view)
const struct got_error *err = NULL;
view->begin_x = 0;
- view->begin_y = view->resize ? view->begin_y : 0;
- view->nlines = view->resize ? view->nlines : LINES;
+ view->begin_y = view->resized ? view->begin_y : 0;
+ view->nlines = view->resized ? view->nlines : LINES;
view->ncols = COLS;
view->lines = LINES;
view->cols = COLS;
@@ -875,24 +876,6 @@ view_resize(struct tog_view *view)
show_panel(view->child->panel);
}
/*
- * Request commits if terminal height was increased in a log
- * view so we have enough commits loaded to populate the view.
- */
- if (view->type == TOG_VIEW_LOG && dif > 0) {
- struct tog_log_view_state *ts = &view->state.log;
-
- if (ts->commits.ncommits < ts->selected_entry->idx +
- view->lines - ts->selected) {
- view->nscrolled = ts->selected_entry->idx +
- view->lines - ts->selected -
- ts->commits.ncommits + dif;
- err = request_log_commits(view);
- if (err)
- return err;
- }
- }
-
- /*
* XXX This is ugly and needs to be moved into the above
* logic but "works" for now and my attempts at moving it
* break either 'tab' or 'F' key maps in horizontal splits.
@@ -915,6 +898,12 @@ view_resize(struct tog_view *view)
} else if (view->parent == NULL)
ncols = COLS;
+ if (view->resize && dif > 0) {
+ err = view->resize(view, dif);
+ if (err)
+ return err;
+ }
+
if (wresize(view->window, nlines, ncols) == ERR)
return got_error_from_errno("wresize");
if (replace_panel(view->panel, view->window) == ERR)
@@ -929,6 +918,25 @@ view_resize(struct tog_view *view)
return NULL;
}
+static const struct got_error *
+resize_log_view(struct tog_view *view, int increase)
+{
+ struct tog_log_view_state *s = &view->state.log;
+ const struct got_error *err = NULL;
+ int n = s->selected_entry->idx + view->lines - s->selected;
+
+ /*
+ * Request commits to account for the increased
+ * height so we have enough to populate the view.
+ */
+ if (s->commits.ncommits < n) {
+ view->nscrolled = n - s->commits.ncommits + increase + 1;
+ err = request_log_commits(view);
+ }
+
+ return err;
+}
+
static void
view_adjust_offset(struct tog_view *view, int n)
{
@@ -962,7 +970,7 @@ view_resize_split(struct tog_view *view, int resize)
if (!v->child || !view_is_splitscreen(v->child))
return NULL;
- v->resize = v->child->resize = resize; /* lock for resize event */
+ v->resized = v->child->resized = resize; /* lock for resize event */
if (view->mode == TOG_VIEW_SPLIT_HRZN) {
int y = v->child->begin_y;
@@ -1031,7 +1039,7 @@ view_resize_split(struct tog_view *view, int resize)
else if (v->child->nscrolled)
err = request_log_commits(v->child);
- v->resize = v->child->resize = 0;
+ v->resized = v->child->resized = 0;
return err;
}
@@ -2984,6 +2992,7 @@ open_log_view(struct tog_view *view, struct got_object
view->show = show_log_view;
view->input = input_log_view;
+ view->resize = resize_log_view;
view->close = close_log_view;
view->search_start = search_start_log_view;
view->search_next = search_next_log_view;
--
Mark Jamsek <fnc.bsdbox.org>
GPG: F2FF 13DE 6A06 C471 CA80 E6E2 2930 DC66 86EE CF68
tog: fix resize failure to populate log view commits