summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2014-09-09 18:04:35 +0300
committerEli Zaretskii <eliz@gnu.org>2014-09-09 18:04:35 +0300
commit1acb1beff16b4df3512f0fe59850ed4541d038c3 (patch)
tree043517952a10b7f5eaf61f1d038f4a444b87d917
parentda604136b92764f159442496a9b18cb48204787e (diff)
downloademacs-1acb1beff16b4df3512f0fe59850ed4541d038c3.tar.gz
Fix the row number mistakenly reported by pos_visible_p in rare cases.
src/xdisp.c (pos_visible_p): Properly save and restore the iterator state around the call to line_bottom, since it can move the iterator to another screen line. This fixes off-by-one errors in the reported row in some rare cases.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/xdisp.c15
2 files changed, 16 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e834a2cc161..274817d8262 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2014-09-09 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (pos_visible_p): Properly save and restore the iterator
+ state around the call to line_bottom, since it can move the
+ iterator to another screen line. This fixes off-by-one errors in
+ the reported row in some rare cases.
+
2014-09-07 Eli Zaretskii <eliz@gnu.org>
* dispnew.c (prepare_desired_row): When MODE_LINE_P is zero,
diff --git a/src/xdisp.c b/src/xdisp.c
index d435bf148a0..6991e44b931 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1452,11 +1452,15 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
glyph. */
int top_x = it.current_x;
int top_y = it.current_y;
- /* Calling line_bottom_y may change it.method, it.position, etc. */
- enum it_method it_method = it.method;
- int bottom_y = (last_height = 0, line_bottom_y (&it));
int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
+ int bottom_y;
+ struct it save_it;
+ void *save_it_data = NULL;
+ /* Calling line_bottom_y may change it.method, it.position, etc. */
+ SAVE_IT (save_it, it, save_it_data);
+ last_height = 0;
+ bottom_y = line_bottom_y (&it);
if (top_y < window_top_y)
visible_p = bottom_y > window_top_y;
else if (top_y < it.last_visible_y)
@@ -1473,7 +1477,6 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
move_it_to again with a slightly larger vertical limit,
and see if it actually moved vertically; if it did, we
didn't really reach CHARPOS, which is beyond window end. */
- struct it save_it = it;
/* Why 10? because we don't know how many canonical lines
will the height of the next line(s) be. So we guess. */
int ten_more_lines = 10 * default_line_pixel_height (w);
@@ -1483,11 +1486,11 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
if (it.current_y > top_y)
visible_p = 0;
- it = save_it;
}
+ RESTORE_IT (&it, &save_it, save_it_data);
if (visible_p)
{
- if (it_method == GET_FROM_DISPLAY_VECTOR)
+ if (it.method == GET_FROM_DISPLAY_VECTOR)
{
/* We stopped on the last glyph of a display vector.
Try and recompute. Hack alert! */