]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix ommissions in window scrolling commands that ought to clear vscroll
authorPo Lu <luangruo@yahoo.com>
Sat, 27 Apr 2024 11:48:45 +0000 (19:48 +0800)
committerEshel Yaron <me@eshelyaron.com>
Mon, 29 Apr 2024 15:05:05 +0000 (17:05 +0200)
* 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

index 7e7a33ed69ee39d44e7fad74e58132329c9f0a3a..2ef26e57681a807b57a0016f6f197a72c9dc08ce 100644 (file)
@@ -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);