commit 5e224a3e31ca7c4284809b162034c76cae0c3e0b from: Stefan Sperling date: Fri Feb 22 10:16:25 2019 UTC reliably switch to next commit in tog diff view; don't lose key presses commit - c0faa76da3013a3c96d1aefa48cba32ebb779306 commit + 5e224a3e31ca7c4284809b162034c76cae0c3e0b blob - 2c22a4c60d8e65974363f2d60377d26df2b31919 blob + 8f47bf49601e47b7789f05fd5d1faff678a68618 --- tog/tog.c +++ tog/tog.c @@ -1243,24 +1243,16 @@ scroll_up(struct commit_queue_entry **first_displayed_ } static const struct got_error * -scroll_down(struct commit_queue_entry **first_displayed_entry, int maxscroll, - struct commit_queue_entry **last_displayed_entry, - struct commit_queue *commits, int *log_complete, int *commits_needed, +trigger_log_thread(int load_all, int *commits_needed, int *log_complete, pthread_cond_t *need_commits) { - const struct got_error *err = NULL; - struct commit_queue_entry *pentry; - int nscrolled = 0; + int errcode; - if (*last_displayed_entry == NULL) - return NULL; + while (*commits_needed > 0) { + if (*log_complete) + break; - pentry = TAILQ_NEXT(*last_displayed_entry, entry); - if (pentry == NULL && !*log_complete) { - int errcode; - if (*commits_needed > 0) - return NULL; - (*commits_needed) = maxscroll; + /* Wake the log thread. */ errcode = pthread_cond_signal(need_commits); if (errcode) return got_error_set_errno(errcode); @@ -1271,11 +1263,41 @@ scroll_down(struct commit_queue_entry **first_displaye errcode = pthread_mutex_lock(&tog_mutex); if (errcode) return got_error_set_errno(errcode); - if (*commits_needed > 0) { - /* Thread is not done yet; lose a key press - * and let the user retry... */ + + if (*commits_needed > 0 && !load_all) { + /* + * Thread is not done yet; lose a key press + * and let the user retry... this way the GUI + * remains interactive while logging deep paths + * with few commits in history. + */ return NULL; } + } + + return NULL; +} + +static const struct got_error * +scroll_down(struct commit_queue_entry **first_displayed_entry, int maxscroll, + struct commit_queue_entry **last_displayed_entry, + struct commit_queue *commits, int *log_complete, int *commits_needed, + pthread_cond_t *need_commits) +{ + const struct got_error *err = NULL; + struct commit_queue_entry *pentry; + int nscrolled = 0; + + if (*last_displayed_entry == NULL) + return NULL; + + pentry = TAILQ_NEXT(*last_displayed_entry, entry); + if (pentry == NULL && !*log_complete) { + (*commits_needed) += maxscroll; + err = trigger_log_thread(0, commits_needed, log_complete, + need_commits); + if (err) + return err; } do { @@ -2281,6 +2303,22 @@ input_diff_view(struct tog_view **new_view, struct tog if (s->log_view == NULL) break; ls = &s->log_view->state.log; + + if (ls->thread_args.commits_needed == 0) { + ls->thread_args.commits_needed++; + + /* Display "loading..." in log view. */ + show_log_view(s->log_view); + update_panels(); + doupdate(); + } + err = trigger_log_thread(1 /* load_all */, + &ls->thread_args.commits_needed, + &ls->thread_args.log_complete, + &ls->thread_args.need_commits); + if (err) + break; + err = input_log_view(NULL, NULL, NULL, s->log_view, KEY_DOWN); if (err)