summary refs log tree commit diff
path: root/ui.c
diff options
context:
space:
mode:
authorC. McEnroe2021-01-26 22:33:16 -0500
committerC. McEnroe2021-01-26 22:33:16 -0500
commitd7d4572220b234e6774d53b8e893c20e4ff55591 (patch)
treed9fb8e7aad05ba240d74e2628a7d552d5ae4667b /ui.c
parent52c58128c83a4e6207afd75318446793fd0110ff (diff)
Preserve scroll position across reflows
Finally! Changing the message visibility threshold doesn't totally
screw up scroll position. Neither do horizontal resizes, but vertical
resizes drift because the value of windowTop() changes before and
after...

The scroll position is anchored to the top of the window. It's
arbitrary whether to anchor the top or the bottom, but other scrolling
commands like M-p and C-r are anchored to the top, so this is
consistent.
Diffstat (limited to 'ui.c')
-rw-r--r--ui.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/ui.c b/ui.c
index a0083c4..5f0cb63 100644
--- a/ui.c
+++ b/ui.c
@@ -567,10 +567,25 @@ void uiFormat(
 	uiWrite(id, heat, time, buf);
 }
 
+static void scrollTo(struct Window *window, int top) {
+	window->scroll = 0;
+	windowScroll(window, top - MAIN_LINES + MarkerLines);
+}
+
 static void windowReflow(struct Window *window) {
+	uint num = 0;
+	const struct Line *line = bufferHard(window->buffer, windowTop(window));
+	if (line) num = line->num;
 	window->unreadHard = bufferReflow(
 		window->buffer, COLS, window->thresh, window->unreadSoft
 	);
+	if (!window->scroll || !num) return;
+	for (size_t i = 0; i < BufferCap; ++i) {
+		line = bufferHard(window->buffer, i);
+		if (!line || line->num != num) continue;
+		scrollTo(window, BufferCap - i);
+		break;
+	}
 }
 
 static void resize(void) {
@@ -762,11 +777,6 @@ static void scrollPage(struct Window *window, int n) {
 	windowScroll(window, n * (MAIN_LINES - SplitLines - MarkerLines - 1));
 }
 
-static void scrollTo(struct Window *window, int top) {
-	window->scroll = 0;
-	windowScroll(window, top - MAIN_LINES + MarkerLines);
-}
-
 static void scrollHot(struct Window *window, int dir) {
 	for (size_t i = windowTop(window) + dir; i < BufferCap; i += dir) {
 		const struct Line *line = bufferHard(window->buffer, i);