From f699c8c3b3e8cdc336bbb7ca4d205ed691f30ae5 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 27 Apr 2024 19:48:45 +0800 Subject: [PATCH] Fix ommissions in window scrolling commands that ought to clear vscroll * src/window.c (Fdelete_other_windows_internal) (window_scroll_for_long_lines, Frecenter, Fmove_to_window_line): Reset window vscroll, or, if force_start be set, just preserve_vscroll_p, after moving window start to a position computed from iterators for the window in question, so that vscroll may be reliably reset again after the conditions for redisplay's doing the same were corrected. (bug#70386) (cherry picked from commit 01e0b783bcd1b48ec856c8960e9da571a289a1b2) --- src/window.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/window.c b/src/window.c index 7e7a33ed69e..2ef26e57681 100644 --- a/src/window.c +++ b/src/window.c @@ -3518,6 +3518,10 @@ window-start value is reasonable when this function is called. */) get called. */ w->optional_new_start = true; + /* Reset the vscroll, as redisplay will not. */ + w->vscroll = 0; + w->preserve_vscroll_p = false; + set_buffer_internal (obuf); } } @@ -5755,6 +5759,11 @@ window_scroll_for_long_lines (struct window *w, int n, bool noerror) else if (n < 0) pos = *vmotion (PT, PT_BYTE, - (ht / 2), w); SET_PT_BOTH (pos.bufpos, pos.bytepos); + + /* Since `vmotion' computes coordinates after vscroll is applied, + it is taken into account in POS, and vscroll must be reset by + `force_start' in `redisplay_internal'. */ + w->preserve_vscroll_p = false; } else { @@ -6898,8 +6907,14 @@ and redisplay normally--don't erase and redraw the frame. */) /* Set the new window start. */ set_marker_both (w->start, w->contents, charpos, bytepos); - w->window_end_valid = false; + /* The window start was calculated with an iterator already adjusted + by the existing vscroll, so w->start must not be combined with + retaining the existing vscroll, which redisplay will not reset if + w->preserve_vscroll_p is enabled. (bug#70386) */ + w->vscroll = 0; + w->preserve_vscroll_p = false; + w->window_end_valid = false; w->optional_new_start = true; w->start_at_line_beg = (bytepos == BEGV_BYTE @@ -6987,6 +7002,11 @@ from the top of the window. */) set_marker_both (w->start, w->contents, PT, PT_BYTE); w->start_at_line_beg = !NILP (Fbolp ()); w->force_start = true; + + /* Since `Fvertical_motion' computes coordinates after vscroll is + applied, it is taken into account in POS, and vscroll must be + reset by `force_start' in `redisplay_internal'. */ + w->preserve_vscroll_p = false; } else Fgoto_char (w->start); -- 2.39.5