# HG changeset patch # User Chong Yidong # Date 1218047207 0 # Node ID be8555b348377f1099922ce3d416f269be60e6ec # Parent eb328facb6f60dc6d61c40cda451d07d5798d852 (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. diff -r eb328facb6f6 -r be8555b34837 src/xdisp.c --- a/src/xdisp.c Wed Aug 06 18:26:02 2008 +0000 +++ b/src/xdisp.c Wed Aug 06 18:26:47 2008 +0000 @@ -12655,19 +12655,12 @@ { 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; + 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; - int height; - int extra_scroll_margin_lines = last_line_misfit ? 1 : 0; #if GLYPH_DEBUG debug_method_add (w, "try_scrolling"); @@ -12706,48 +12699,44 @@ 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) - { - 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; - } - - if (PT >= CHARPOS (scroll_margin_pos)) - { - int y0; - - /* Point is in the scroll margin at the bottom of the window, or - below. Compute a new window start that makes point visible. */ - - /* 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 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; - + /* Decide whether we have to scroll down. */ + if (PT > CHARPOS (startp)) + { + int scroll_margin_y; + + /* 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)); + + 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); + + /* 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; + + 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 @@ } 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 @@ /* 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 @@ 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