From 06b6bbb578cae9ebc00ffd6d4a2c7dc4995588bf Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 26 Mar 2011 20:31:36 +0200 Subject: [PATCH] Fix bug #6671 with point position in the window when scrolling far away. src/xdisp.c (redisplay_window): Don't check buffer's clip_changed flag as a prerequisite for invoking try_scrolling. (try_scrolling): Limit scrolling to 100 screen lines. (SCROLL_LIMIT): New macro. (try_scrolling): Use it when setting scroll_limit. (redisplay_window): Even when falling back on "recentering", position point in the window according to scroll-conservatively, scroll-margin, and scroll-*-aggressively variables. --- src/ChangeLog | 5 ++++ src/xdisp.c | 69 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 83bcca1db65..ef3a1546913 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,11 @@ * xdisp.c (redisplay_window): Don't check buffer's clip_changed flag as a prerequisite for invoking try_scrolling. (Bug#6671) (try_scrolling): Limit scrolling to 100 screen lines. + (SCROLL_LIMIT): New macro. + (try_scrolling): Use it when setting scroll_limit. + (redisplay_window): Even when falling back on "recentering", + position point in the window according to scroll-conservatively, + scroll-margin, and scroll-*-aggressively variables. (Bug#6671) 2011-03-26 Juanma Barranquero diff --git a/src/xdisp.c b/src/xdisp.c index 270d29d0213..263bedec4a2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13003,6 +13003,9 @@ enum SCROLLING_NEED_LARGER_MATRICES }; +/* If scroll-conservatively is more than this, never recenter. */ +#define SCROLL_LIMIT 100 + static int try_scrolling (Lisp_Object window, int just_this_one_p, EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step, @@ -13017,7 +13020,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p, int extra_scroll_margin_lines = last_line_misfit ? 1 : 0; Lisp_Object aggressive; /* We will never try scrolling more than this number of lines. */ - int scroll_limit = 100; + int scroll_limit = SCROLL_LIMIT; #if GLYPH_DEBUG debug_method_add (w, "try_scrolling"); @@ -14202,11 +14205,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p) } } - /* Finally, just choose place to start which centers point */ + /* Finally, just choose a place to start which positions point + according to user preferences. */ recenter: - if (centering_position < 0) - centering_position = window_box_height (w) / 2; #if GLYPH_DEBUG debug_method_add (w, "recenter"); @@ -14218,10 +14220,62 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (!buffer_unchanged_p) w->base_line_number = Qnil; - /* Move backward half the height of the window. */ + /* Determine the window start relative to point. */ init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); it.current_y = it.last_visible_y; + if (centering_position < 0) + { + int margin = + scroll_margin > 0 + ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4) + : 0; + int scrolling_up = PT > CHARPOS (startp) + margin; + Lisp_Object aggressive = + scrolling_up + ? BVAR (current_buffer, scroll_up_aggressively) + : BVAR (current_buffer, scroll_down_aggressively); + + if (!MINI_WINDOW_P (w) + && scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)) + { + int pt_offset = 0; + + /* Setting scroll-conservatively overrides + scroll-*-aggressively. */ + if (!scroll_conservatively && NUMBERP (aggressive)) + { + double float_amount = XFLOATINT (aggressive); + + pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w); + if (pt_offset == 0 && float_amount > 0) + pt_offset = 1; + if (pt_offset) + margin -= 1; + } + /* Compute how much to move the window start backward from + point so that point will be displayed where the user + wants it. */ + if (scrolling_up) + { + centering_position = it.last_visible_y; + if (pt_offset) + centering_position -= pt_offset; + centering_position -= + FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0)); + /* Don't let point enter the scroll margin near top of + the window. */ + if (centering_position < margin * FRAME_LINE_HEIGHT (f)) + centering_position = margin * FRAME_LINE_HEIGHT (f); + } + else + centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset; + } + else + /* Move backward from point half the height of the window. */ + centering_position = window_box_height (w) / 2; + } move_it_vertically_backward (&it, centering_position); + xassert (IT_CHARPOS (it) >= BEGV); /* The function move_it_vertically_backward may move over more @@ -14238,8 +14292,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p) it.current_x = it.hpos = 0; - /* Set startp here explicitly in case that helps avoid an infinite loop - in case the window-scroll-functions functions get errors. */ + /* Set the window start position here explicitly, to avoid an + infinite loop in case the functions in window-scroll-functions + get errors. */ set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it)); /* Run scroll hooks. */ -- 2.39.5