diff options
author | C. McEnroe | 2021-01-26 22:33:16 -0500 |
---|---|---|
committer | C. McEnroe | 2021-01-26 22:33:16 -0500 |
commit | d7d4572220b234e6774d53b8e893c20e4ff55591 (patch) | |
tree | d9fb8e7aad05ba240d74e2628a7d552d5ae4667b | |
parent | 52c58128c83a4e6207afd75318446793fd0110ff (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.
-rw-r--r-- | ui.c | 20 |
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); |