aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorNoam Postavsky2017-02-02 21:35:51 -0500
committerNoam Postavsky2017-02-02 21:35:51 -0500
commitce88155d83ba84e84321ed69a39c82f40117dd1f (patch)
treeb56e2f89a597cb407747639c02333dde7e4552ba /src/window.c
parent604724e49d7b44dc663ad941998a0a44aa4fc178 (diff)
parentda515a0d8e97d89a1c7e60faea190174a8c72618 (diff)
downloademacs-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.c53
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. */
4797int
4798window_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);