diff options
| author | Eli Zaretskii | 2015-12-06 19:27:12 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2015-12-06 19:27:12 +0200 |
| commit | cca5629f7856d88de940da942acbf5ca7f95a944 (patch) | |
| tree | 66e7d4b5a918a553a8944bbe9013ff693b4ecc87 /src | |
| parent | 302bbe00b31852942827dab42154f33411b99171 (diff) | |
| download | emacs-cca5629f7856d88de940da942acbf5ca7f95a944.tar.gz emacs-cca5629f7856d88de940da942acbf5ca7f95a944.zip | |
Fix cursor display when invisible text is at line beginning
* src/xdisp.c (redisplay_window): When scrolling fails to show
point, prefer using the desired matrix if possible for finding the
fallback glyph row for displaying the cursor. (Bug#22098)
(row_containing_pos): Exit the loop as soon as we hit the first
disabled glyph row. Otherwise we risk accessing garbled data and
departing to the no-no land.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index d1a10ca3c31..3930cbf8fe8 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -16720,6 +16720,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16720 | startp = run_window_scroll_functions (window, it.current.pos); | 16720 | startp = run_window_scroll_functions (window, it.current.pos); |
| 16721 | 16721 | ||
| 16722 | /* Redisplay the window. */ | 16722 | /* Redisplay the window. */ |
| 16723 | bool use_desired_matrix = false; | ||
| 16723 | if (!current_matrix_up_to_date_p | 16724 | if (!current_matrix_up_to_date_p |
| 16724 | || windows_or_buffers_changed | 16725 | || windows_or_buffers_changed |
| 16725 | || f->cursor_type_changed | 16726 | || f->cursor_type_changed |
| @@ -16730,7 +16731,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16730 | || MINI_WINDOW_P (w) | 16731 | || MINI_WINDOW_P (w) |
| 16731 | || !(used_current_matrix_p | 16732 | || !(used_current_matrix_p |
| 16732 | = try_window_reusing_current_matrix (w))) | 16733 | = try_window_reusing_current_matrix (w))) |
| 16733 | try_window (window, startp, 0); | 16734 | use_desired_matrix = (try_window (window, startp, 0) == 1); |
| 16734 | 16735 | ||
| 16735 | /* If new fonts have been loaded (due to fontsets), give up. We | 16736 | /* If new fonts have been loaded (due to fontsets), give up. We |
| 16736 | have to start a new redisplay since we need to re-adjust glyph | 16737 | have to start a new redisplay since we need to re-adjust glyph |
| @@ -16770,9 +16771,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16770 | and similar ones. */ | 16771 | and similar ones. */ |
| 16771 | if (w->cursor.vpos < 0) | 16772 | if (w->cursor.vpos < 0) |
| 16772 | { | 16773 | { |
| 16774 | /* Prefer the desired matrix to the current matrix, if possible, | ||
| 16775 | in the fallback calculations below. This is because using | ||
| 16776 | the current matrix might completely goof, e.g. if its first | ||
| 16777 | row is after point. */ | ||
| 16778 | struct glyph_matrix *matrix = | ||
| 16779 | use_desired_matrix ? w->desired_matrix : w->current_matrix; | ||
| 16773 | /* First, try locating the proper glyph row for PT. */ | 16780 | /* First, try locating the proper glyph row for PT. */ |
| 16774 | struct glyph_row *row = | 16781 | struct glyph_row *row = |
| 16775 | row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0); | 16782 | row_containing_pos (w, PT, matrix->rows, NULL, 0); |
| 16776 | 16783 | ||
| 16777 | /* Sometimes point is at the beginning of invisible text that is | 16784 | /* Sometimes point is at the beginning of invisible text that is |
| 16778 | before the 1st character displayed in the row. In that case, | 16785 | before the 1st character displayed in the row. In that case, |
| @@ -16797,8 +16804,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16797 | alt_pos = XFASTINT (invis_end); | 16804 | alt_pos = XFASTINT (invis_end); |
| 16798 | else | 16805 | else |
| 16799 | alt_pos = ZV; | 16806 | alt_pos = ZV; |
| 16800 | row = row_containing_pos (w, alt_pos, w->current_matrix->rows, | 16807 | row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0); |
| 16801 | NULL, 0); | ||
| 16802 | } | 16808 | } |
| 16803 | } | 16809 | } |
| 16804 | /* Finally, fall back on the first row of the window after the | 16810 | /* Finally, fall back on the first row of the window after the |
| @@ -16806,11 +16812,11 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16806 | displaying the cursor at all. */ | 16812 | displaying the cursor at all. */ |
| 16807 | if (!row) | 16813 | if (!row) |
| 16808 | { | 16814 | { |
| 16809 | row = w->current_matrix->rows; | 16815 | row = matrix->rows; |
| 16810 | if (row->mode_line_p) | 16816 | if (row->mode_line_p) |
| 16811 | ++row; | 16817 | ++row; |
| 16812 | } | 16818 | } |
| 16813 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 16819 | set_cursor_from_row (w, row, matrix, 0, 0, 0, 0); |
| 16814 | } | 16820 | } |
| 16815 | 16821 | ||
| 16816 | if (!cursor_row_fully_visible_p (w, false, false)) | 16822 | if (!cursor_row_fully_visible_p (w, false, false)) |
| @@ -17795,7 +17801,7 @@ row_containing_pos (struct window *w, ptrdiff_t charpos, | |||
| 17795 | while (true) | 17801 | while (true) |
| 17796 | { | 17802 | { |
| 17797 | /* Give up if we have gone too far. */ | 17803 | /* Give up if we have gone too far. */ |
| 17798 | if (end && row >= end) | 17804 | if (end && row >= end || !row->enabled_p) |
| 17799 | return NULL; | 17805 | return NULL; |
| 17800 | /* This formerly returned if they were equal. | 17806 | /* This formerly returned if they were equal. |
| 17801 | I think that both quantities are of a "last plus one" type; | 17807 | I think that both quantities are of a "last plus one" type; |