diff options
| author | Eli Zaretskii | 2014-09-09 18:04:35 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-09 18:04:35 +0300 |
| commit | 1acb1beff16b4df3512f0fe59850ed4541d038c3 (patch) | |
| tree | 043517952a10b7f5eaf61f1d038f4a444b87d917 /src | |
| parent | da604136b92764f159442496a9b18cb48204787e (diff) | |
| download | emacs-1acb1beff16b4df3512f0fe59850ed4541d038c3.tar.gz emacs-1acb1beff16b4df3512f0fe59850ed4541d038c3.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 15 |
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 @@ | |||
| 1 | 2014-09-09 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (pos_visible_p): Properly save and restore the iterator | ||
| 4 | state around the call to line_bottom, since it can move the | ||
| 5 | iterator to another screen line. This fixes off-by-one errors in | ||
| 6 | the reported row in some rare cases. | ||
| 7 | |||
| 1 | 2014-09-07 Eli Zaretskii <eliz@gnu.org> | 8 | 2014-09-07 Eli Zaretskii <eliz@gnu.org> |
| 2 | 9 | ||
| 3 | * dispnew.c (prepare_desired_row): When MODE_LINE_P is zero, | 10 | * 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, | |||
| 1452 | glyph. */ | 1452 | glyph. */ |
| 1453 | int top_x = it.current_x; | 1453 | int top_x = it.current_x; |
| 1454 | int top_y = it.current_y; | 1454 | int top_y = it.current_y; |
| 1455 | /* Calling line_bottom_y may change it.method, it.position, etc. */ | ||
| 1456 | enum it_method it_method = it.method; | ||
| 1457 | int bottom_y = (last_height = 0, line_bottom_y (&it)); | ||
| 1458 | int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); | 1455 | int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); |
| 1456 | int bottom_y; | ||
| 1457 | struct it save_it; | ||
| 1458 | void *save_it_data = NULL; | ||
| 1459 | 1459 | ||
| 1460 | /* Calling line_bottom_y may change it.method, it.position, etc. */ | ||
| 1461 | SAVE_IT (save_it, it, save_it_data); | ||
| 1462 | last_height = 0; | ||
| 1463 | bottom_y = line_bottom_y (&it); | ||
| 1460 | if (top_y < window_top_y) | 1464 | if (top_y < window_top_y) |
| 1461 | visible_p = bottom_y > window_top_y; | 1465 | visible_p = bottom_y > window_top_y; |
| 1462 | else if (top_y < it.last_visible_y) | 1466 | 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, | |||
| 1473 | move_it_to again with a slightly larger vertical limit, | 1477 | move_it_to again with a slightly larger vertical limit, |
| 1474 | and see if it actually moved vertically; if it did, we | 1478 | and see if it actually moved vertically; if it did, we |
| 1475 | didn't really reach CHARPOS, which is beyond window end. */ | 1479 | didn't really reach CHARPOS, which is beyond window end. */ |
| 1476 | struct it save_it = it; | ||
| 1477 | /* Why 10? because we don't know how many canonical lines | 1480 | /* Why 10? because we don't know how many canonical lines |
| 1478 | will the height of the next line(s) be. So we guess. */ | 1481 | will the height of the next line(s) be. So we guess. */ |
| 1479 | int ten_more_lines = 10 * default_line_pixel_height (w); | 1482 | 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, | |||
| 1483 | if (it.current_y > top_y) | 1486 | if (it.current_y > top_y) |
| 1484 | visible_p = 0; | 1487 | visible_p = 0; |
| 1485 | 1488 | ||
| 1486 | it = save_it; | ||
| 1487 | } | 1489 | } |
| 1490 | RESTORE_IT (&it, &save_it, save_it_data); | ||
| 1488 | if (visible_p) | 1491 | if (visible_p) |
| 1489 | { | 1492 | { |
| 1490 | if (it_method == GET_FROM_DISPLAY_VECTOR) | 1493 | if (it.method == GET_FROM_DISPLAY_VECTOR) |
| 1491 | { | 1494 | { |
| 1492 | /* We stopped on the last glyph of a display vector. | 1495 | /* We stopped on the last glyph of a display vector. |
| 1493 | Try and recompute. Hack alert! */ | 1496 | Try and recompute. Hack alert! */ |