From 5b5953c070455773f3bdfb9ebcc7ecc15dde0611 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 4 Jul 2014 16:22:04 +0300 Subject: [PATCH] Fix bug #17905 with display of point in partially visible line at end of window. src/xdisp.c (redisplay_window): If redisplay of a window ends up with point in a partially visible line at end of the window, make sure the amended position of point actually has smaller Y coordinate; if not, give up and scroll the display. src/window.c (window_scroll_pixel_based): When point ends up at the last fully visible line, don't let move_it_to stop at the left edge of the line and dupe us into thinking point is inside the scroll margin. --- src/ChangeLog | 10 ++++++++++ src/window.c | 26 ++++++++++++++++++++++++++ src/xdisp.c | 12 ++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 24343faa407..a88c6caacfd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,15 @@ 2014-07-04 Eli Zaretskii + * xdisp.c (redisplay_window): If redisplay of a window ends up + with point in a partially visible line at end of the window, make + sure the amended position of point actually has smaller Y + coordinate; if not, give up and scroll the display. (Bug#17905) + + * window.c (window_scroll_pixel_based): When point ends up at the + last fully visible line, don't let move_it_to stop at the left + edge of the line and dupe us into thinking point is inside the + scroll margin. + * w32.c (network_interface_info): Make sure the argument is a Lisp string. diff --git a/src/window.c b/src/window.c index 8e8252d3b76..5e9dd0ec718 100644 --- a/src/window.c +++ b/src/window.c @@ -5167,6 +5167,32 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) charpos = IT_CHARPOS (it); bytepos = IT_BYTEPOS (it); + /* If PT is in the screen line at the last fully visible line, + move_it_to will stop at X = 0 in that line, because the + required Y coordinate is reached there. See if we can get to + PT without descending lower in Y, and if we can, it means we + reached PT before the scroll margin. */ + if (charpos != PT) + { + struct it it2; + void *it_data; + + it2 = it; + it_data = bidi_shelve_cache (); + move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); + if (IT_CHARPOS (it) == PT && it.current_y == it2.current_y) + { + charpos = IT_CHARPOS (it); + bytepos = IT_BYTEPOS (it); + bidi_unshelve_cache (it_data, 1); + } + else + { + it = it2; + bidi_unshelve_cache (it_data, 0); + } + } + /* See if point is on a partially visible line at the end. */ if (it.what == IT_EOB) partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y; diff --git a/src/xdisp.c b/src/xdisp.c index 459edf4367f..fe5d0f579d8 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16106,6 +16106,18 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) /* Point does appear, but on a line partly visible at end of window. Move it back to a fully-visible line. */ new_vpos = window_box_height (w); + /* But if window_box_height suggests a Y coordinate that is + not less than we already have, that line will clearly not + be fully visible, so give up and scroll the display. + This can happen when the default face uses a font whose + dimensions are different from the frame's default + font. */ + if (new_vpos >= w->cursor.y) + { + w->cursor.vpos = -1; + clear_glyph_matrix (w->desired_matrix); + goto try_to_scroll; + } } else if (w->cursor.vpos >= 0) { -- 2.39.5