emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 b2eb691: Fix scrolling under scroll-preserve-scre


From: Eli Zaretskii
Subject: [Emacs-diffs] emacs-25 b2eb691: Fix scrolling under scroll-preserve-screen-position and margins
Date: Mon, 18 Jan 2016 16:21:09 +0000

branch: emacs-25
commit b2eb6911dc8af51a5a9f8b7a011cf63c724d533b
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Fix scrolling under scroll-preserve-screen-position and margins
    
    * src/window.c (window_scroll_pixel_based): When setting point to
    preserve screen coordinates, don't let cursor enter either of the
    two scroll margins.  Fix incorrect usage of
    WINDOW_WANTS_HEADER_LINE_P and use WINDOW_HEADER_LINE_HEIGHT
    instead of CURRENT_HEADER_LINE_HEIGHT.  (Bug#22395)
---
 src/window.c |   43 ++++++++++++++++++++++++++++---------------
 1 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/src/window.c b/src/window.c
index bbe47c7..1a75342 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4981,27 +4981,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, 
bool whole, bool noerror)
 
   if (n > 0)
     {
+      int last_y = it.last_visible_y - this_scroll_margin - 1;
+
       /* We moved the window start towards ZV, so PT may be now
         in the scroll margin at the top.  */
       move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
-      if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin
+      if (IT_CHARPOS (it) == PT
+         && it.current_y >= this_scroll_margin
+         && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w)
           && (NILP (Vscroll_preserve_screen_position)
              || EQ (Vscroll_preserve_screen_position, Qt)))
        /* We found PT at a legitimate height.  Leave it alone.  */
        ;
-      else if (window_scroll_pixel_based_preserve_y >= 0)
-       {
-         /* If we have a header line, take account of it.
-            This is necessary because we set it.current_y to 0, above.  */
-         move_it_to (&it, -1,
-                     window_scroll_pixel_based_preserve_x,
-                     (window_scroll_pixel_based_preserve_y
-                      - WINDOW_WANTS_HEADER_LINE_P (w)),
-                     -1, MOVE_TO_Y | MOVE_TO_X);
-         SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
-       }
       else
        {
+         if (window_scroll_pixel_based_preserve_y >= 0)
+           {
+             /* Don't enter the scroll margin at the end of the window.  */
+             int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
+
+             /* If we have a header line, take account of it.  This
+                is necessary because we set it.current_y to 0, above.  */
+             move_it_to (&it, -1,
+                         window_scroll_pixel_based_preserve_x,
+                         goal_y - WINDOW_HEADER_LINE_HEIGHT (w),
+                         -1, MOVE_TO_Y | MOVE_TO_X);
+           }
+
+         /* Get out of the scroll margin at the top of the window.  */
          while (it.current_y < this_scroll_margin)
            {
              int prev = it.current_y;
@@ -5025,7 +5032,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, 
bool whole, bool noerror)
       /* We moved the window start towards BEGV, so PT may be now
         in the scroll margin at the bottom.  */
       move_it_to (&it, PT, -1,
-                 (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w)
+                 (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w)
                   - this_scroll_margin - 1),
                  -1,
                  MOVE_TO_POS | MOVE_TO_Y);
@@ -5076,14 +5083,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, 
bool whole, bool noerror)
        ;
       else if (window_scroll_pixel_based_preserve_y >= 0)
        {
+         int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
+                           window_scroll_pixel_based_preserve_y);
+
+         /* Don't let the preserved screen Y coordinate put us inside
+            any of the two margins.  */
+         if (goal_y < this_scroll_margin)
+           goal_y = this_scroll_margin;
          SET_TEXT_POS_FROM_MARKER (start, w->start);
          start_display (&it, w, start);
          /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
             here because we called start_display again and did not
             alter it.current_y this time.  */
          move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
-                     window_scroll_pixel_based_preserve_y, -1,
-                     MOVE_TO_Y | MOVE_TO_X);
+                     goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
          SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
        }
       else



reply via email to

[Prev in Thread] Current Thread [Next in Thread]