From e10ee30cc54d1cf4ec1d5bf3104df8aba6615e37 Mon Sep 17 00:00:00 2001 From: "Kim F. Storm" Date: Sat, 19 Feb 2005 23:30:51 +0000 Subject: [PATCH] (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). --- src/xdisp.c | 103 ++++++++++++++++++++++++++++++---------------------- 1 file 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 *, Lisp_Object)); static void extend_face_to_end_of_line P_ ((struct it *)); static int append_space_for_newline P_ ((struct it *, int)); -static int make_cursor_line_fully_visible P_ ((struct window *, int)); +static int cursor_row_fully_visible_p P_ ((struct window *, int, int)); static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); static int trailing_whitespace_p P_ ((int)); @@ -1285,8 +1285,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) } start_display (&it, w, top); - move_it_to (&it, charpos, 0, it.last_visible_y, -1, - MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + move_it_to (&it, charpos, -1, it.last_visible_y, -1, + MOVE_TO_POS | MOVE_TO_Y); /* Note that we may overshoot because of invisible text. */ if (IT_CHARPOS (it) >= charpos) @@ -1310,12 +1310,13 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) } } } - else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y) + else { struct it it2; it2 = it; - move_it_by_lines (&it, 1, 0); + if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') + move_it_by_lines (&it, 1, 0); if (charpos < IT_CHARPOS (it)) { visible_p = 1; @@ -1326,8 +1327,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p) *y = it2.current_y + it2.max_ascent - it2.ascent; if (rtop) { - *rtop = 0; - *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y); + *rtop = max (0, -it2.current_y); + *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent) + - it.last_visible_y)); } } } @@ -4697,27 +4699,31 @@ back_to_previous_visible_line_start (it) /* If newline has a display property that replaces the newline with something else (image or text), find start of overlay or interval and continue search from that point. */ - { - struct it it2 = *it; - int pos = IT_CHARPOS (*it); - int beg, end; - Lisp_Object val, overlay; - - it2.sp = 0; - if (handle_display_prop (&it2) == HANDLED_RETURN - && !NILP (val = get_char_property_and_overlay - (make_number (pos), Qdisplay, Qnil, &overlay)) - && (OVERLAYP (overlay) - ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) - : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) - { - if (beg < BEGV) - beg = BEGV; - IT_CHARPOS (*it) = beg; - IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); - continue; - } - } + if (IT_CHARPOS (*it) > BEGV) + { + struct it it2 = *it; + int pos; + int beg, end; + Lisp_Object val, overlay; + + pos = --IT_CHARPOS (it2); + --IT_BYTEPOS (it2); + it2.sp = 0; + if (handle_display_prop (&it2) == HANDLED_RETURN + && !NILP (val = get_char_property_and_overlay + (make_number (pos), Qdisplay, Qnil, &overlay)) + && (OVERLAYP (overlay) + ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) + : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) + { + if (beg < BEGV) + beg = BEGV; + IT_CHARPOS (*it) = beg; + IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); + continue; + } + } + break; } @@ -6330,7 +6336,8 @@ move_it_vertically_backward (it, dy) a line height of 13 pixels each, recentering with point on the bottom line will try to move -39/2 = 19 pixels backward. Try to avoid moving into the first line. */ - && it->current_y - target_y > line_height * 2 / 3 + && (it->current_y - target_y + > min (window_box_height (it->w), line_height * 2 / 3)) && IT_CHARPOS (*it) > BEGV) { TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", @@ -11088,7 +11095,7 @@ run_window_scroll_functions (window, startp) as if point had gone off the screen. */ static int -make_cursor_line_fully_visible (w, force_p) +cursor_row_fully_visible_p (w, force_p, current_matrix_p) struct window *w; int force_p; { @@ -11104,7 +11111,7 @@ make_cursor_line_fully_visible (w, force_p) if (w->cursor.vpos < 0) return 1; - matrix = w->desired_matrix; + matrix = current_matrix_p ? w->current_matrix : w->desired_matrix; row = MATRIX_ROW (matrix, w->cursor.vpos); /* 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, /* If cursor ends up on a partially visible line, treat that as being off the bottom of the screen. */ - if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1)) + if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)) { clear_glyph_matrix (w->desired_matrix); ++extra_scroll_margin_lines; @@ -11679,6 +11686,12 @@ try_cursor_movement (window, startp, scroll_step) && CHARPOS (startp) != BEGV) scroll_p = 1; } + else + { + /* Cursor did not move. So don't scroll even if cursor line + is partially visible, as it was so before. */ + rc = CURSOR_MOVEMENT_SUCCESS; + } if (PT < MATRIX_ROW_START_CHARPOS (row) || PT > MATRIX_ROW_END_CHARPOS (row)) @@ -11686,7 +11699,8 @@ try_cursor_movement (window, startp, scroll_step) /* if PT is not in the glyph row, give up. */ rc = CURSOR_MOVEMENT_MUST_SCROLL; } - else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) + else if (rc != CURSOR_MOVEMENT_SUCCESS + && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) && make_cursor_line_fully_visible_p) { if (PT == MATRIX_ROW_END_CHARPOS (row) @@ -11705,7 +11719,7 @@ try_cursor_movement (window, startp, scroll_step) else { set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); - if (!make_cursor_line_fully_visible (w, 0)) + if (!cursor_row_fully_visible_p (w, 0, 1)) rc = CURSOR_MOVEMENT_MUST_SCROLL; else rc = CURSOR_MOVEMENT_SUCCESS; @@ -11790,7 +11804,7 @@ redisplay_window (window, just_this_one_p) int temp_scroll_step = 0; int count = SPECPDL_INDEX (); int rc; - int centering_position; + int centering_position = -1; int last_line_misfit = 0; SET_TEXT_POS (lpoint, PT, PT_BYTE); @@ -12036,7 +12050,7 @@ redisplay_window (window, just_this_one_p) new_vpos = window_box_height (w) / 2; } - if (!make_cursor_line_fully_visible (w, 0)) + if (!cursor_row_fully_visible_p (w, 0, 0)) { /* Point does appear, but on a line partly visible at end of window. Move it back to a fully-visible line. */ @@ -12173,7 +12187,7 @@ redisplay_window (window, just_this_one_p) /* Forget any recorded base line for line number display. */ w->base_line_number = Qnil; - if (!make_cursor_line_fully_visible (w, 1)) + if (!cursor_row_fully_visible_p (w, 1, 0)) { clear_glyph_matrix (w->desired_matrix); last_line_misfit = 1; @@ -12233,10 +12247,8 @@ redisplay_window (window, just_this_one_p) /* Finally, just choose place to start which centers point */ recenter: - centering_position = window_box_height (w) / 2; - - point_at_top: - /* Jump here with centering_position already set to 0. */ + if (centering_position < 0) + centering_position = window_box_height (w) / 2; #if GLYPH_DEBUG debug_method_add (w, "recenter"); @@ -12333,7 +12345,7 @@ redisplay_window (window, just_this_one_p) set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); } - if (!make_cursor_line_fully_visible (w, centering_position > 0)) + if (!cursor_row_fully_visible_p (w, 0, 0)) { /* If vscroll is enabled, disable it and try again. */ if (w->vscroll) @@ -12348,9 +12360,10 @@ redisplay_window (window, just_this_one_p) visible, if it can be done. */ if (centering_position == 0) goto done; + clear_glyph_matrix (w->desired_matrix); centering_position = 0; - goto point_at_top; + goto recenter; } done: @@ -13135,8 +13148,10 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes) starts at a minimum position >= last_unchanged_pos_old. */ for (; row > first_text_row; --row) { + /* This used to abort, but it can happen. + It is ok to just stop the search instead here. KFS. */ if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) - abort (); + break; if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) row_found = row; -- 2.39.2