Commit Diff


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)