aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKim F. Storm2005-02-19 23:30:51 +0000
committerKim F. Storm2005-02-19 23:30:51 +0000
commite10ee30cc54d1cf4ec1d5bf3104df8aba6615e37 (patch)
treeda981ace93e6952df6423363c72a3fcb48e69c2e /src
parented02c1db47526136acacefde75ac09e525f20337 (diff)
downloademacs-e10ee30cc54d1cf4ec1d5bf3104df8aba6615e37.tar.gz
emacs-e10ee30cc54d1cf4ec1d5bf3104df8aba6615e37.zip
(pos_visible_p): Be sure to move to the specified
position. Always get the full ascent / descent of the corresponding row, to return reliable rtop and rbot values. (back_to_previous_visible_line_start): Fix 2005-01-18 change. Must look one character back, as back_to_previous_line_start returns position after the newline. (move_it_vertically_backward): Fix heuristic for when to move further back in case line_height * 2/3 is larger than window height. (cursor_row_fully_visible_p): Rename make_cursor_line_fully_visible_p as it does not do anything anymore. Add arg current_matrix_p to use current matrix rather than desired matrix when set. (try_cursor_movement): Don't scroll to make cursor row fully visible if cursor didn't move. This avoids unexpected recentering in case of blinking cursor or accepting process output. Use current matrix to check cursor row visibility. (redisplay_window): Fix whether to recenter or move to top in case cursor line is taller than window height. (find_first_unchanged_at_end_row): Stop search if we reach a row which not enabled (instead of abort).
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index f7a3b6dc914..85044a3713d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -863,7 +863,7 @@ static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
863 Lisp_Object)); 863 Lisp_Object));
864static void extend_face_to_end_of_line P_ ((struct it *)); 864static void extend_face_to_end_of_line P_ ((struct it *));
865static int append_space_for_newline P_ ((struct it *, int)); 865static int append_space_for_newline P_ ((struct it *, int));
866static int make_cursor_line_fully_visible P_ ((struct window *, int)); 866static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
867static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); 867static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
868static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); 868static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
869static int trailing_whitespace_p P_ ((int)); 869static int trailing_whitespace_p P_ ((int));
@@ -1285,8 +1285,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1285 } 1285 }
1286 1286
1287 start_display (&it, w, top); 1287 start_display (&it, w, top);
1288 move_it_to (&it, charpos, 0, it.last_visible_y, -1, 1288 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1289 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 1289 MOVE_TO_POS | MOVE_TO_Y);
1290 1290
1291 /* Note that we may overshoot because of invisible text. */ 1291 /* Note that we may overshoot because of invisible text. */
1292 if (IT_CHARPOS (it) >= charpos) 1292 if (IT_CHARPOS (it) >= charpos)
@@ -1310,12 +1310,13 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1310 } 1310 }
1311 } 1311 }
1312 } 1312 }
1313 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) 1313 else
1314 { 1314 {
1315 struct it it2; 1315 struct it it2;
1316 1316
1317 it2 = it; 1317 it2 = it;
1318 move_it_by_lines (&it, 1, 0); 1318 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1319 move_it_by_lines (&it, 1, 0);
1319 if (charpos < IT_CHARPOS (it)) 1320 if (charpos < IT_CHARPOS (it))
1320 { 1321 {
1321 visible_p = 1; 1322 visible_p = 1;
@@ -1326,8 +1327,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1326 *y = it2.current_y + it2.max_ascent - it2.ascent; 1327 *y = it2.current_y + it2.max_ascent - it2.ascent;
1327 if (rtop) 1328 if (rtop)
1328 { 1329 {
1329 *rtop = 0; 1330 *rtop = max (0, -it2.current_y);
1330 *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y); 1331 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1332 - it.last_visible_y));
1331 } 1333 }
1332 } 1334 }
1333 } 1335 }
@@ -4697,27 +4699,31 @@ back_to_previous_visible_line_start (it)
4697 /* If newline has a display property that replaces the newline with something 4699 /* If newline has a display property that replaces the newline with something
4698 else (image or text), find start of overlay or interval and continue search 4700 else (image or text), find start of overlay or interval and continue search
4699 from that point. */ 4701 from that point. */
4700 { 4702 if (IT_CHARPOS (*it) > BEGV)
4701 struct it it2 = *it; 4703 {
4702 int pos = IT_CHARPOS (*it); 4704 struct it it2 = *it;
4703 int beg, end; 4705 int pos;
4704 Lisp_Object val, overlay; 4706 int beg, end;
4705 4707 Lisp_Object val, overlay;
4706 it2.sp = 0; 4708
4707 if (handle_display_prop (&it2) == HANDLED_RETURN 4709 pos = --IT_CHARPOS (it2);
4708 && !NILP (val = get_char_property_and_overlay 4710 --IT_BYTEPOS (it2);
4709 (make_number (pos), Qdisplay, Qnil, &overlay)) 4711 it2.sp = 0;
4710 && (OVERLAYP (overlay) 4712 if (handle_display_prop (&it2) == HANDLED_RETURN
4711 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) 4713 && !NILP (val = get_char_property_and_overlay
4712 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) 4714 (make_number (pos), Qdisplay, Qnil, &overlay))
4713 { 4715 && (OVERLAYP (overlay)
4714 if (beg < BEGV) 4716 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4715 beg = BEGV; 4717 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4716 IT_CHARPOS (*it) = beg; 4718 {
4717 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); 4719 if (beg < BEGV)
4718 continue; 4720 beg = BEGV;
4719 } 4721 IT_CHARPOS (*it) = beg;
4720 } 4722 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4723 continue;
4724 }
4725 }
4726
4721 break; 4727 break;
4722 } 4728 }
4723 4729
@@ -6330,7 +6336,8 @@ move_it_vertically_backward (it, dy)
6330 a line height of 13 pixels each, recentering with point 6336 a line height of 13 pixels each, recentering with point
6331 on the bottom line will try to move -39/2 = 19 pixels 6337 on the bottom line will try to move -39/2 = 19 pixels
6332 backward. Try to avoid moving into the first line. */ 6338 backward. Try to avoid moving into the first line. */
6333 && it->current_y - target_y > line_height * 2 / 3 6339 && (it->current_y - target_y
6340 > min (window_box_height (it->w), line_height * 2 / 3))
6334 && IT_CHARPOS (*it) > BEGV) 6341 && IT_CHARPOS (*it) > BEGV)
6335 { 6342 {
6336 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", 6343 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
@@ -11088,7 +11095,7 @@ run_window_scroll_functions (window, startp)
11088 as if point had gone off the screen. */ 11095 as if point had gone off the screen. */
11089 11096
11090static int 11097static int
11091make_cursor_line_fully_visible (w, force_p) 11098cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11092 struct window *w; 11099 struct window *w;
11093 int force_p; 11100 int force_p;
11094{ 11101{
@@ -11104,7 +11111,7 @@ make_cursor_line_fully_visible (w, force_p)
11104 if (w->cursor.vpos < 0) 11111 if (w->cursor.vpos < 0)
11105 return 1; 11112 return 1;
11106 11113
11107 matrix = w->desired_matrix; 11114 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11108 row = MATRIX_ROW (matrix, w->cursor.vpos); 11115 row = MATRIX_ROW (matrix, w->cursor.vpos);
11109 11116
11110 /* If the cursor row is not partially visible, there's nothing to do. */ 11117 /* If the cursor row is not partially visible, there's nothing to do. */
@@ -11409,7 +11416,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11409 11416
11410 /* If cursor ends up on a partially visible line, 11417 /* If cursor ends up on a partially visible line,
11411 treat that as being off the bottom of the screen. */ 11418 treat that as being off the bottom of the screen. */
11412 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1)) 11419 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11413 { 11420 {
11414 clear_glyph_matrix (w->desired_matrix); 11421 clear_glyph_matrix (w->desired_matrix);
11415 ++extra_scroll_margin_lines; 11422 ++extra_scroll_margin_lines;
@@ -11679,6 +11686,12 @@ try_cursor_movement (window, startp, scroll_step)
11679 && CHARPOS (startp) != BEGV) 11686 && CHARPOS (startp) != BEGV)
11680 scroll_p = 1; 11687 scroll_p = 1;
11681 } 11688 }
11689 else
11690 {
11691 /* Cursor did not move. So don't scroll even if cursor line
11692 is partially visible, as it was so before. */
11693 rc = CURSOR_MOVEMENT_SUCCESS;
11694 }
11682 11695
11683 if (PT < MATRIX_ROW_START_CHARPOS (row) 11696 if (PT < MATRIX_ROW_START_CHARPOS (row)
11684 || PT > MATRIX_ROW_END_CHARPOS (row)) 11697 || PT > MATRIX_ROW_END_CHARPOS (row))
@@ -11686,7 +11699,8 @@ try_cursor_movement (window, startp, scroll_step)
11686 /* if PT is not in the glyph row, give up. */ 11699 /* if PT is not in the glyph row, give up. */
11687 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11700 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11688 } 11701 }
11689 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) 11702 else if (rc != CURSOR_MOVEMENT_SUCCESS
11703 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11690 && make_cursor_line_fully_visible_p) 11704 && make_cursor_line_fully_visible_p)
11691 { 11705 {
11692 if (PT == MATRIX_ROW_END_CHARPOS (row) 11706 if (PT == MATRIX_ROW_END_CHARPOS (row)
@@ -11705,7 +11719,7 @@ try_cursor_movement (window, startp, scroll_step)
11705 else 11719 else
11706 { 11720 {
11707 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 11721 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11708 if (!make_cursor_line_fully_visible (w, 0)) 11722 if (!cursor_row_fully_visible_p (w, 0, 1))
11709 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11723 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11710 else 11724 else
11711 rc = CURSOR_MOVEMENT_SUCCESS; 11725 rc = CURSOR_MOVEMENT_SUCCESS;
@@ -11790,7 +11804,7 @@ redisplay_window (window, just_this_one_p)
11790 int temp_scroll_step = 0; 11804 int temp_scroll_step = 0;
11791 int count = SPECPDL_INDEX (); 11805 int count = SPECPDL_INDEX ();
11792 int rc; 11806 int rc;
11793 int centering_position; 11807 int centering_position = -1;
11794 int last_line_misfit = 0; 11808 int last_line_misfit = 0;
11795 11809
11796 SET_TEXT_POS (lpoint, PT, PT_BYTE); 11810 SET_TEXT_POS (lpoint, PT, PT_BYTE);
@@ -12036,7 +12050,7 @@ redisplay_window (window, just_this_one_p)
12036 new_vpos = window_box_height (w) / 2; 12050 new_vpos = window_box_height (w) / 2;
12037 } 12051 }
12038 12052
12039 if (!make_cursor_line_fully_visible (w, 0)) 12053 if (!cursor_row_fully_visible_p (w, 0, 0))
12040 { 12054 {
12041 /* Point does appear, but on a line partly visible at end of window. 12055 /* Point does appear, but on a line partly visible at end of window.
12042 Move it back to a fully-visible line. */ 12056 Move it back to a fully-visible line. */
@@ -12173,7 +12187,7 @@ redisplay_window (window, just_this_one_p)
12173 /* Forget any recorded base line for line number display. */ 12187 /* Forget any recorded base line for line number display. */
12174 w->base_line_number = Qnil; 12188 w->base_line_number = Qnil;
12175 12189
12176 if (!make_cursor_line_fully_visible (w, 1)) 12190 if (!cursor_row_fully_visible_p (w, 1, 0))
12177 { 12191 {
12178 clear_glyph_matrix (w->desired_matrix); 12192 clear_glyph_matrix (w->desired_matrix);
12179 last_line_misfit = 1; 12193 last_line_misfit = 1;
@@ -12233,10 +12247,8 @@ redisplay_window (window, just_this_one_p)
12233 /* Finally, just choose place to start which centers point */ 12247 /* Finally, just choose place to start which centers point */
12234 12248
12235 recenter: 12249 recenter:
12236 centering_position = window_box_height (w) / 2; 12250 if (centering_position < 0)
12237 12251 centering_position = window_box_height (w) / 2;
12238 point_at_top:
12239 /* Jump here with centering_position already set to 0. */
12240 12252
12241#if GLYPH_DEBUG 12253#if GLYPH_DEBUG
12242 debug_method_add (w, "recenter"); 12254 debug_method_add (w, "recenter");
@@ -12333,7 +12345,7 @@ redisplay_window (window, just_this_one_p)
12333 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 12345 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12334 } 12346 }
12335 12347
12336 if (!make_cursor_line_fully_visible (w, centering_position > 0)) 12348 if (!cursor_row_fully_visible_p (w, 0, 0))
12337 { 12349 {
12338 /* If vscroll is enabled, disable it and try again. */ 12350 /* If vscroll is enabled, disable it and try again. */
12339 if (w->vscroll) 12351 if (w->vscroll)
@@ -12348,9 +12360,10 @@ redisplay_window (window, just_this_one_p)
12348 visible, if it can be done. */ 12360 visible, if it can be done. */
12349 if (centering_position == 0) 12361 if (centering_position == 0)
12350 goto done; 12362 goto done;
12363
12351 clear_glyph_matrix (w->desired_matrix); 12364 clear_glyph_matrix (w->desired_matrix);
12352 centering_position = 0; 12365 centering_position = 0;
12353 goto point_at_top; 12366 goto recenter;
12354 } 12367 }
12355 12368
12356 done: 12369 done:
@@ -13135,8 +13148,10 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes)
13135 starts at a minimum position >= last_unchanged_pos_old. */ 13148 starts at a minimum position >= last_unchanged_pos_old. */
13136 for (; row > first_text_row; --row) 13149 for (; row > first_text_row; --row)
13137 { 13150 {
13151 /* This used to abort, but it can happen.
13152 It is ok to just stop the search instead here. KFS. */
13138 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) 13153 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13139 abort (); 13154 break;
13140 13155
13141 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) 13156 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13142 row_found = row; 13157 row_found = row;