diff options
| author | Noam Postavsky | 2017-02-02 21:35:51 -0500 |
|---|---|---|
| committer | Noam Postavsky | 2017-02-02 21:35:51 -0500 |
| commit | ce88155d83ba84e84321ed69a39c82f40117dd1f (patch) | |
| tree | b56e2f89a597cb407747639c02333dde7e4552ba /src/window.c | |
| parent | 604724e49d7b44dc663ad941998a0a44aa4fc178 (diff) | |
| parent | da515a0d8e97d89a1c7e60faea190174a8c72618 (diff) | |
| download | emacs-ce88155d83ba84e84321ed69a39c82f40117dd1f.tar.gz emacs-ce88155d83ba84e84321ed69a39c82f40117dd1f.zip | |
; Merge: fixes and updates to scroll margin (Bug#5718)
- add new option `maximum-sroll-margin'
- refactor and fix scroll margin calculation
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/window.c b/src/window.c index bc3f488f37f..95690443f8e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -4790,6 +4790,36 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror) | |||
| 4790 | XWINDOW (window)->window_end_valid = false; | 4790 | XWINDOW (window)->window_end_valid = false; |
| 4791 | } | 4791 | } |
| 4792 | 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; | ||
| 4821 | } | ||
| 4822 | |||
| 4793 | 4823 | ||
| 4794 | /* Implementation of window_scroll that works based on pixel line | 4824 | /* Implementation of window_scroll that works based on pixel line |
| 4795 | heights. See the comment of window_scroll for parameter | 4825 | heights. See the comment of window_scroll for parameter |
| @@ -4806,7 +4836,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 4806 | bool vscrolled = false; | 4836 | bool vscrolled = false; |
| 4807 | int x, y, rtop, rbot, rowh, vpos; | 4837 | int x, y, rtop, rbot, rowh, vpos; |
| 4808 | void *itdata = NULL; | 4838 | void *itdata = NULL; |
| 4809 | int window_total_lines; | ||
| 4810 | int frame_line_height = default_line_pixel_height (w); | 4839 | int frame_line_height = default_line_pixel_height (w); |
| 4811 | bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window), | 4840 | bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window), |
| 4812 | Fwindow_old_point (window))); | 4841 | Fwindow_old_point (window))); |
| @@ -5062,12 +5091,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5062 | /* Move PT out of scroll margins. | 5091 | /* Move PT out of scroll margins. |
| 5063 | 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 |
| 5064 | even if there is a header line. */ | 5093 | even if there is a header line. */ |
| 5065 | window_total_lines | 5094 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS); |
| 5066 | = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height; | ||
| 5067 | this_scroll_margin = max (0, scroll_margin); | ||
| 5068 | this_scroll_margin | ||
| 5069 | = min (this_scroll_margin, window_total_lines / 4); | ||
| 5070 | this_scroll_margin *= frame_line_height; | ||
| 5071 | 5095 | ||
| 5072 | if (n > 0) | 5096 | if (n > 0) |
| 5073 | { | 5097 | { |
| @@ -5123,7 +5147,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5123 | in the scroll margin at the bottom. */ | 5147 | in the scroll margin at the bottom. */ |
| 5124 | move_it_to (&it, PT, -1, | 5148 | move_it_to (&it, PT, -1, |
| 5125 | (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) | 5149 | (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) |
| 5126 | - this_scroll_margin - 1), | 5150 | - partial_line_height (&it) - this_scroll_margin - 1), |
| 5127 | -1, | 5151 | -1, |
| 5128 | MOVE_TO_POS | MOVE_TO_Y); | 5152 | MOVE_TO_POS | MOVE_TO_Y); |
| 5129 | 5153 | ||
| @@ -5290,9 +5314,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5290 | 5314 | ||
| 5291 | if (pos < ZV) | 5315 | if (pos < ZV) |
| 5292 | { | 5316 | { |
| 5293 | /* Don't use a scroll margin that is negative or too large. */ | 5317 | int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); |
| 5294 | int this_scroll_margin = | ||
| 5295 | max (0, min (scroll_margin, w->total_lines / 4)); | ||
| 5296 | 5318 | ||
| 5297 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); | 5319 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); |
| 5298 | w->start_at_line_beg = !NILP (bolp); | 5320 | w->start_at_line_beg = !NILP (bolp); |
| @@ -5722,8 +5744,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5722 | 5744 | ||
| 5723 | /* Do this after making BUF current | 5745 | /* Do this after making BUF current |
| 5724 | in case scroll_margin is buffer-local. */ | 5746 | in case scroll_margin is buffer-local. */ |
| 5725 | this_scroll_margin | 5747 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); |
| 5726 | = max (0, min (scroll_margin, w->total_lines / 4)); | ||
| 5727 | 5748 | ||
| 5728 | /* Don't use redisplay code for initial frames, as the necessary | 5749 | /* Don't use redisplay code for initial frames, as the necessary |
| 5729 | data structures might not be set up yet then. */ | 5750 | data structures might not be set up yet then. */ |
| @@ -5962,10 +5983,6 @@ from the top of the window. */) | |||
| 5962 | 5983 | ||
| 5963 | lines = displayed_window_lines (w); | 5984 | lines = displayed_window_lines (w); |
| 5964 | 5985 | ||
| 5965 | #if false | ||
| 5966 | this_scroll_margin = max (0, min (scroll_margin, lines / 4)); | ||
| 5967 | #endif | ||
| 5968 | |||
| 5969 | if (NILP (arg)) | 5986 | if (NILP (arg)) |
| 5970 | XSETFASTINT (arg, lines / 2); | 5987 | XSETFASTINT (arg, lines / 2); |
| 5971 | else | 5988 | else |
| @@ -5981,6 +5998,8 @@ from the top of the window. */) | |||
| 5981 | 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 |
| 5982 | inside #if false so as not to lose it. -- rms. */ | 5999 | inside #if false so as not to lose it. -- rms. */ |
| 5983 | 6000 | ||
| 6001 | this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); | ||
| 6002 | |||
| 5984 | /* 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. */ |
| 5985 | iarg = max (iarg, this_scroll_margin); | 6004 | iarg = max (iarg, this_scroll_margin); |
| 5986 | iarg = min (iarg, lines - this_scroll_margin - 1); | 6005 | iarg = min (iarg, lines - this_scroll_margin - 1); |