]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix cursor position under scroll-conservatively and overlay strings
authorEli Zaretskii <eliz@gnu.org>
Mon, 8 Aug 2016 15:15:55 +0000 (18:15 +0300)
committerEli Zaretskii <eliz@gnu.org>
Mon, 8 Aug 2016 15:15:55 +0000 (18:15 +0300)
* src/xdisp.c (try_scrolling): Handle the case where the last
visible screen line of a window displays a before- or after-string
that takes up the whole screen line, and therefore there's no
place to display the cursor, even though the window does seem to
include the position of point.  (Bug#24179)

src/xdisp.c

index efd5f54fa39f57a6b4c0d9cb32bfa2029c52998f..21fc01f1e692d6dbf12ac444c2421034cd29b93d 100644 (file)
@@ -15307,6 +15307,40 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
                      -1, MOVE_TO_POS | MOVE_TO_Y);
          dy = line_bottom_y (&it) - y0;
 
+         if (dy > scroll_max)
+           return SCROLLING_FAILED;
+
+         if (dy > 0)
+           scroll_down_p = true;
+       }
+      else if (PT == IT_CHARPOS (it)
+              && IT_CHARPOS (it) < ZV
+              && it.method == GET_FROM_STRING
+              && arg_scroll_conservatively > scroll_limit
+              && it.current_x == 0)
+       {
+         enum move_it_result skip;
+         int y1 = it.current_y;
+         int vpos;
+
+         /* A before-string that includes newlines and is displayed
+            on the last visible screen line could fail us under
+            scroll-conservatively > 100, because we will be unable to
+            position the cursor on that last visible line.  Try to
+            recover by finding the first screen line that has some
+            glyphs coming from the buffer text.  */
+         do {
+           skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
+           if (skip != MOVE_NEWLINE_OR_CR
+               || IT_CHARPOS (it) != PT
+               || it.method == GET_FROM_BUFFER)
+             break;
+           vpos = it.vpos;
+           move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
+         } while (it.vpos > vpos);
+
+         dy = it.current_y - y1;
+
          if (dy > scroll_max)
            return SCROLLING_FAILED;