X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/da7520dea49de723bc5b2871b83f5049c441f2aa..ea21ef78590fc94fcf1c385fe15594b6f5b3124f:/src/window.c diff --git a/src/window.c b/src/window.c index e7040e3c49..c8067f9035 100644 --- a/src/window.c +++ b/src/window.c @@ -50,6 +50,7 @@ Boston, MA 02110-1301, USA. */ Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; +Lisp_Object Qscroll_up, Qscroll_down; Lisp_Object Qwindow_size_fixed; extern Lisp_Object Qleft_margin, Qright_margin; @@ -214,6 +215,10 @@ Lisp_Object Vscroll_preserve_screen_position; int window_deletion_count; +/* Used by the function window_scroll_pixel_based */ + +static int window_scroll_pixel_based_preserve_y; + #if 0 /* This isn't used anywhere. */ /* Nonzero means we can split a frame even if it is "unsplittable". */ static int inhibit_frame_unsplittable; @@ -1861,7 +1866,8 @@ MINIBUF neither nil nor t means never include the minibuffer window. */) Lisp_Object frame, minibuf, window; { if (NILP (window)) - window = selected_window; + window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window; + CHECK_WINDOW (window); if (NILP (frame)) frame = selected_frame; @@ -4720,7 +4726,6 @@ window_scroll_pixel_based (window, n, whole, noerror) struct text_pos start; Lisp_Object tem; int this_scroll_margin; - int preserve_y; /* True if we fiddled the window vscroll field without really scrolling. */ int vscrolled = 0; @@ -4786,12 +4791,21 @@ window_scroll_pixel_based (window, n, whole, noerror) point in the same window line as it is now, so get that line. */ if (!NILP (Vscroll_preserve_screen_position)) { - start_display (&it, w, start); - move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); - preserve_y = it.current_y; + /* We preserve the goal pixel coordinate across consecutive + calls to scroll-up or scroll-down. This avoids the + possibility of point becoming "stuck" on a tall line when + scrolling by one line. */ + if (window_scroll_pixel_based_preserve_y < 0 + || (current_kboard->Vlast_command != Qscroll_up + && current_kboard->Vlast_command != Qscroll_down)) + { + start_display (&it, w, start); + move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); + window_scroll_pixel_based_preserve_y = it.current_y; + } } else - preserve_y = -1; + window_scroll_pixel_based_preserve_y = -1; /* Move iterator it from start the specified distance forward or backward. The result is the new window start. */ @@ -4921,14 +4935,14 @@ window_scroll_pixel_based (window, n, whole, noerror) || EQ (Vscroll_preserve_screen_position, Qt))) /* We found PT at a legitimate height. Leave it alone. */ ; - else if (preserve_y >= 0) + else if (window_scroll_pixel_based_preserve_y >= 0) { /* If we have a header line, take account of it. This is necessary because we set it.current_y to 0, above. */ - if (WINDOW_WANTS_HEADER_LINE_P (w)) - preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w); - - move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y); + move_it_to (&it, -1, -1, + window_scroll_pixel_based_preserve_y + - (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ), + -1, MOVE_TO_Y); SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); } else @@ -4948,7 +4962,8 @@ window_scroll_pixel_based (window, n, whole, noerror) int charpos, bytepos; int partial_p; - /* Save our position, for the preserve_y case. */ + /* Save our position, for the + window_scroll_pixel_based_preserve_y case. */ charpos = IT_CHARPOS (it); bytepos = IT_BYTEPOS (it); @@ -4978,20 +4993,15 @@ window_scroll_pixel_based (window, n, whole, noerror) || EQ (Vscroll_preserve_screen_position, Qt))) /* We found PT before we found the display margin, so PT is ok. */ ; - else if (preserve_y >= 0) + else if (window_scroll_pixel_based_preserve_y >= 0) { SET_TEXT_POS_FROM_MARKER (start, w->start); start_display (&it, w, start); -#if 0 /* It's wrong to subtract this here - because we called start_display again - and did not alter it.current_y this time. */ - - /* If we have a header line, take account of it. */ - if (WINDOW_WANTS_HEADER_LINE_P (w)) - preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w); -#endif - - move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y); + /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT + here because we called start_display again and did not + alter it.current_y this time. */ + move_it_to (&it, -1, -1, window_scroll_pixel_based_preserve_y, -1, + MOVE_TO_Y); SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); } else @@ -6987,6 +6997,12 @@ init_window () void syms_of_window () { + Qscroll_up = intern ("scroll-up"); + staticpro (&Qscroll_up); + + Qscroll_down = intern ("scroll-down"); + staticpro (&Qscroll_down); + Qwindow_size_fixed = intern ("window-size-fixed"); staticpro (&Qwindow_size_fixed); Fset (Qwindow_size_fixed, Qnil); @@ -7012,6 +7028,8 @@ syms_of_window () minibuf_selected_window = Qnil; staticpro (&minibuf_selected_window); + window_scroll_pixel_based_preserve_y = -1; + DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function, doc: /* Non-nil means call as function to display a help buffer. The function is called with one argument, the buffer to be displayed.