From 523a9735371f2045a9fb3ff290b3790386d40d22 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 6 Aug 2008 18:26:47 +0000 Subject: [PATCH] (try_scrolling): Use iterator to find the scroll margin, instead of window-end which does the wrong thing at eob. (try_cursor_movement): Minor optimization. (redisplay_window): If scroll margin is defined, don't assume window doesn't need scrolling. --- src/xdisp.c | 95 ++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 78f2dd6478c..4c099653a6d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12655,19 +12655,12 @@ try_scrolling (window, just_this_one_p, scroll_conservatively, { struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - struct text_pos scroll_margin_pos; - struct text_pos pos; - struct text_pos startp; + struct text_pos pos, startp; struct it it; - Lisp_Object window_end; - int this_scroll_margin; - int dy = 0; - int scroll_max; - int rc; - int amount_to_scroll = 0; - Lisp_Object aggressive; - int height; + int this_scroll_margin, scroll_max, rc, height; + int dy = 0, amount_to_scroll = 0, scroll_down_p = 0; int extra_scroll_margin_lines = last_line_misfit ? 1 : 0; + Lisp_Object aggressive; #if GLYPH_DEBUG debug_method_add (w, "try_scrolling"); @@ -12706,48 +12699,44 @@ try_scrolling (window, just_this_one_p, scroll_conservatively, scroll_max = 0; scroll_max *= FRAME_LINE_HEIGHT (f); - /* Decide whether we have to scroll down. Start at the window end - and move this_scroll_margin up to find the position of the scroll - margin. */ - window_end = Fwindow_end (window, Qt); - too_near_end: - CHARPOS (scroll_margin_pos) = XINT (window_end); - BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos)); - - if (this_scroll_margin || extra_scroll_margin_lines) + /* Decide whether we have to scroll down. */ + if (PT > CHARPOS (startp)) { - start_display (&it, w, scroll_margin_pos); - if (this_scroll_margin) - move_it_vertically_backward (&it, this_scroll_margin); - if (extra_scroll_margin_lines) - move_it_by_lines (&it, - extra_scroll_margin_lines, 0); - scroll_margin_pos = it.current.pos; - } + int scroll_margin_y; - if (PT >= CHARPOS (scroll_margin_pos)) - { - int y0; + /* Compute the pixel ypos of the scroll margin, then move it to + either that ypos or PT, whichever comes first. */ + start_display (&it, w, startp); + scroll_margin_y = it.last_visible_y - this_scroll_margin + - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines; + move_it_to (&it, PT, -1, scroll_margin_y - 1, -1, + (MOVE_TO_POS | MOVE_TO_Y)); - /* Point is in the scroll margin at the bottom of the window, or - below. Compute a new window start that makes point visible. */ + if (PT > CHARPOS (it.current.pos)) + { + /* Point is in the scroll margin at the bottom of the + window, or below. Compute the distance from the scroll + margin to PT, and give up if the distance is greater than + scroll_max. */ + move_it_to (&it, PT, -1, it.last_visible_y - 1, -1, + MOVE_TO_POS | MOVE_TO_Y); - /* Compute the distance from the scroll margin to PT. - Give up if the distance is greater than scroll_max. */ - start_display (&it, w, scroll_margin_pos); - y0 = it.current_y; - move_it_to (&it, PT, 0, it.last_visible_y, -1, - MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + /* To make point visible, we must move the window start down + so that the cursor line is visible, which means we have + to add in the height of the cursor line. */ + dy = line_bottom_y (&it) - scroll_margin_y; - /* To make point visible, we have to move the window start - down so that the line the cursor is in is visible, which - means we have to add in the height of the cursor line. */ - dy = line_bottom_y (&it) - y0; + if (dy > scroll_max) + return SCROLLING_FAILED; - if (dy > scroll_max) - return SCROLLING_FAILED; + scroll_down_p = 1; + } + } + if (scroll_down_p) + { /* Move the window start down. If scrolling conservatively, move it just enough down to make point visible. If scroll_step is set, move it down by scroll_step. */ @@ -12787,9 +12776,10 @@ try_scrolling (window, just_this_one_p, scroll_conservatively, } else { + struct text_pos scroll_margin_pos = startp; + /* See if point is inside the scroll margin at the top of the window. */ - scroll_margin_pos = startp; if (this_scroll_margin) { start_display (&it, w, startp); @@ -13038,9 +13028,13 @@ try_cursor_movement (window, startp, scroll_step) /* Scroll if point within this distance from the top or bottom of the window. This is a pixel value. */ - this_scroll_margin = max (0, scroll_margin); - this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); - this_scroll_margin *= FRAME_LINE_HEIGHT (f); + if (scroll_margin > 0) + { + this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); + this_scroll_margin *= FRAME_LINE_HEIGHT (f); + } + else + this_scroll_margin = 0; top_scroll_margin = this_scroll_margin; if (WINDOW_WANTS_HEADER_LINE_P (w)) @@ -13674,6 +13668,11 @@ redisplay_window (window, just_this_one_p) debug_method_add (w, "same window start"); #endif + /* If there's a scroll margin, we must try to scroll, in case + point is now in the scroll margin. */ + if (scroll_margin > 0) + goto try_to_scroll; + /* Try to redisplay starting at same place as before. If point has not moved off frame, accept the results. */ if (!current_matrix_up_to_date_p -- 2.39.2