diff options
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/src/window.c b/src/window.c index 0a6b94d4d1d..95690443f8e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -521,9 +521,10 @@ select_window (Lisp_Object window, Lisp_Object norecord, | |||
| 521 | bset_last_selected_window (XBUFFER (w->contents), window); | 521 | bset_last_selected_window (XBUFFER (w->contents), window); |
| 522 | 522 | ||
| 523 | record_and_return: | 523 | record_and_return: |
| 524 | /* record_buffer can run QUIT, so make sure it is run only after we have | 524 | /* record_buffer can call maybe_quit, so make sure it is run only |
| 525 | re-established the invariant between selected_window and selected_frame, | 525 | after we have re-established the invariant between |
| 526 | otherwise the temporary broken invariant might "escape" (bug#14161). */ | 526 | selected_window and selected_frame, otherwise the temporary |
| 527 | broken invariant might "escape" (Bug#14161). */ | ||
| 527 | if (NILP (norecord)) | 528 | if (NILP (norecord)) |
| 528 | { | 529 | { |
| 529 | w->use_time = ++window_select_count; | 530 | w->use_time = ++window_select_count; |
| @@ -4769,7 +4770,6 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror) | |||
| 4769 | { | 4770 | { |
| 4770 | ptrdiff_t count = SPECPDL_INDEX (); | 4771 | ptrdiff_t count = SPECPDL_INDEX (); |
| 4771 | 4772 | ||
| 4772 | immediate_quit = true; | ||
| 4773 | n = clip_to_bounds (INT_MIN, n, INT_MAX); | 4773 | n = clip_to_bounds (INT_MIN, n, INT_MAX); |
| 4774 | 4774 | ||
| 4775 | wset_redisplay (XWINDOW (window)); | 4775 | wset_redisplay (XWINDOW (window)); |
| @@ -4788,7 +4788,36 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror) | |||
| 4788 | 4788 | ||
| 4789 | /* Bug#15957. */ | 4789 | /* Bug#15957. */ |
| 4790 | XWINDOW (window)->window_end_valid = false; | 4790 | XWINDOW (window)->window_end_valid = false; |
| 4791 | immediate_quit = false; | 4791 | } |
| 4792 | |||
| 4793 | /* Compute scroll margin for WINDOW. | ||
| 4794 | We scroll when point is within this distance from the top or bottom | ||
| 4795 | of the window. The result is measured in lines or in pixels | ||
| 4796 | depending on the second parameter. */ | ||
| 4797 | int | ||
| 4798 | window_scroll_margin (struct window *window, enum margin_unit unit) | ||
| 4799 | { | ||
| 4800 | if (scroll_margin > 0) | ||
| 4801 | { | ||
| 4802 | int frame_line_height = default_line_pixel_height (window); | ||
| 4803 | int window_lines = window_box_height (window) / frame_line_height; | ||
| 4804 | |||
| 4805 | double ratio = 0.25; | ||
| 4806 | if (FLOATP (Vmaximum_scroll_margin)) | ||
| 4807 | { | ||
| 4808 | ratio = XFLOAT_DATA (Vmaximum_scroll_margin); | ||
| 4809 | ratio = max (0.0, ratio); | ||
| 4810 | ratio = min (ratio, 0.5); | ||
| 4811 | } | ||
| 4812 | int max_margin = min ((window_lines - 1)/2, | ||
| 4813 | (int) (window_lines * ratio)); | ||
| 4814 | int margin = clip_to_bounds (0, scroll_margin, max_margin); | ||
| 4815 | return (unit == MARGIN_IN_PIXELS) | ||
| 4816 | ? margin * frame_line_height | ||
| 4817 | : margin; | ||
| 4818 | } | ||
| 4819 | else | ||
| 4820 | return 0; | ||
| 4792 | } | 4821 | } |
| 4793 | 4822 | ||
| 4794 | 4823 | ||
| @@ -4807,7 +4836,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 4807 | bool vscrolled = false; | 4836 | bool vscrolled = false; |
| 4808 | int x, y, rtop, rbot, rowh, vpos; | 4837 | int x, y, rtop, rbot, rowh, vpos; |
| 4809 | void *itdata = NULL; | 4838 | void *itdata = NULL; |
| 4810 | int window_total_lines; | ||
| 4811 | int frame_line_height = default_line_pixel_height (w); | 4839 | int frame_line_height = default_line_pixel_height (w); |
| 4812 | bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window), | 4840 | bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window), |
| 4813 | Fwindow_old_point (window))); | 4841 | Fwindow_old_point (window))); |
| @@ -5063,12 +5091,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5063 | /* Move PT out of scroll margins. | 5091 | /* Move PT out of scroll margins. |
| 5064 | This code wants current_y to be zero at the window start position | 5092 | This code wants current_y to be zero at the window start position |
| 5065 | even if there is a header line. */ | 5093 | even if there is a header line. */ |
| 5066 | window_total_lines | 5094 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS); |
| 5067 | = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height; | ||
| 5068 | this_scroll_margin = max (0, scroll_margin); | ||
| 5069 | this_scroll_margin | ||
| 5070 | = min (this_scroll_margin, window_total_lines / 4); | ||
| 5071 | this_scroll_margin *= frame_line_height; | ||
| 5072 | 5095 | ||
| 5073 | if (n > 0) | 5096 | if (n > 0) |
| 5074 | { | 5097 | { |
| @@ -5124,7 +5147,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5124 | in the scroll margin at the bottom. */ | 5147 | in the scroll margin at the bottom. */ |
| 5125 | move_it_to (&it, PT, -1, | 5148 | move_it_to (&it, PT, -1, |
| 5126 | (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) | 5149 | (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) |
| 5127 | - this_scroll_margin - 1), | 5150 | - partial_line_height (&it) - this_scroll_margin - 1), |
| 5128 | -1, | 5151 | -1, |
| 5129 | MOVE_TO_POS | MOVE_TO_Y); | 5152 | MOVE_TO_POS | MOVE_TO_Y); |
| 5130 | 5153 | ||
| @@ -5291,9 +5314,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5291 | 5314 | ||
| 5292 | if (pos < ZV) | 5315 | if (pos < ZV) |
| 5293 | { | 5316 | { |
| 5294 | /* Don't use a scroll margin that is negative or too large. */ | 5317 | int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); |
| 5295 | int this_scroll_margin = | ||
| 5296 | max (0, min (scroll_margin, w->total_lines / 4)); | ||
| 5297 | 5318 | ||
| 5298 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); | 5319 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); |
| 5299 | w->start_at_line_beg = !NILP (bolp); | 5320 | w->start_at_line_beg = !NILP (bolp); |
| @@ -5723,8 +5744,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5723 | 5744 | ||
| 5724 | /* Do this after making BUF current | 5745 | /* Do this after making BUF current |
| 5725 | in case scroll_margin is buffer-local. */ | 5746 | in case scroll_margin is buffer-local. */ |
| 5726 | this_scroll_margin | 5747 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); |
| 5727 | = max (0, min (scroll_margin, w->total_lines / 4)); | ||
| 5728 | 5748 | ||
| 5729 | /* Don't use redisplay code for initial frames, as the necessary | 5749 | /* Don't use redisplay code for initial frames, as the necessary |
| 5730 | data structures might not be set up yet then. */ | 5750 | data structures might not be set up yet then. */ |
| @@ -5963,10 +5983,6 @@ from the top of the window. */) | |||
| 5963 | 5983 | ||
| 5964 | lines = displayed_window_lines (w); | 5984 | lines = displayed_window_lines (w); |
| 5965 | 5985 | ||
| 5966 | #if false | ||
| 5967 | this_scroll_margin = max (0, min (scroll_margin, lines / 4)); | ||
| 5968 | #endif | ||
| 5969 | |||
| 5970 | if (NILP (arg)) | 5986 | if (NILP (arg)) |
| 5971 | XSETFASTINT (arg, lines / 2); | 5987 | XSETFASTINT (arg, lines / 2); |
| 5972 | else | 5988 | else |
| @@ -5982,6 +5998,8 @@ from the top of the window. */) | |||
| 5982 | it is probably better not to install it. However, it is here | 5998 | it is probably better not to install it. However, it is here |
| 5983 | inside #if false so as not to lose it. -- rms. */ | 5999 | inside #if false so as not to lose it. -- rms. */ |
| 5984 | 6000 | ||
| 6001 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); | ||
| 6002 | |||
| 5985 | /* Don't let it get into the margin at either top or bottom. */ | 6003 | /* Don't let it get into the margin at either top or bottom. */ |
| 5986 | iarg = max (iarg, this_scroll_margin); | 6004 | iarg = max (iarg, this_scroll_margin); |
| 5987 | iarg = min (iarg, lines - this_scroll_margin - 1); | 6005 | iarg = min (iarg, lines - this_scroll_margin - 1); |