aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c64
1 files changed, 47 insertions, 17 deletions
diff --git a/src/window.c b/src/window.c
index bb414e7d311..4aeb8b39a70 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4979,27 +4979,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
4979 4979
4980 if (n > 0) 4980 if (n > 0)
4981 { 4981 {
4982 int last_y = it.last_visible_y - this_scroll_margin - 1;
4983
4982 /* We moved the window start towards ZV, so PT may be now 4984 /* We moved the window start towards ZV, so PT may be now
4983 in the scroll margin at the top. */ 4985 in the scroll margin at the top. */
4984 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 4986 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
4985 if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin 4987 if (IT_CHARPOS (it) == PT
4988 && it.current_y >= this_scroll_margin
4989 && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w)
4986 && (NILP (Vscroll_preserve_screen_position) 4990 && (NILP (Vscroll_preserve_screen_position)
4987 || EQ (Vscroll_preserve_screen_position, Qt))) 4991 || EQ (Vscroll_preserve_screen_position, Qt)))
4988 /* We found PT at a legitimate height. Leave it alone. */ 4992 /* We found PT at a legitimate height. Leave it alone. */
4989 ; 4993 ;
4990 else if (window_scroll_pixel_based_preserve_y >= 0)
4991 {
4992 /* If we have a header line, take account of it.
4993 This is necessary because we set it.current_y to 0, above. */
4994 move_it_to (&it, -1,
4995 window_scroll_pixel_based_preserve_x,
4996 (window_scroll_pixel_based_preserve_y
4997 - WINDOW_WANTS_HEADER_LINE_P (w)),
4998 -1, MOVE_TO_Y | MOVE_TO_X);
4999 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
5000 }
5001 else 4994 else
5002 { 4995 {
4996 if (window_scroll_pixel_based_preserve_y >= 0)
4997 {
4998 /* Don't enter the scroll margin at the end of the window. */
4999 int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
5000
5001 /* If we have a header line, take account of it. This
5002 is necessary because we set it.current_y to 0, above. */
5003 move_it_to (&it, -1,
5004 window_scroll_pixel_based_preserve_x,
5005 goal_y - WINDOW_HEADER_LINE_HEIGHT (w),
5006 -1, MOVE_TO_Y | MOVE_TO_X);
5007 }
5008
5009 /* Get out of the scroll margin at the top of the window. */
5003 while (it.current_y < this_scroll_margin) 5010 while (it.current_y < this_scroll_margin)
5004 { 5011 {
5005 int prev = it.current_y; 5012 int prev = it.current_y;
@@ -5023,7 +5030,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5023 /* We moved the window start towards BEGV, so PT may be now 5030 /* We moved the window start towards BEGV, so PT may be now
5024 in the scroll margin at the bottom. */ 5031 in the scroll margin at the bottom. */
5025 move_it_to (&it, PT, -1, 5032 move_it_to (&it, PT, -1,
5026 (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w) 5033 (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w)
5027 - this_scroll_margin - 1), 5034 - this_scroll_margin - 1),
5028 -1, 5035 -1,
5029 MOVE_TO_POS | MOVE_TO_Y); 5036 MOVE_TO_POS | MOVE_TO_Y);
@@ -5074,14 +5081,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5074 ; 5081 ;
5075 else if (window_scroll_pixel_based_preserve_y >= 0) 5082 else if (window_scroll_pixel_based_preserve_y >= 0)
5076 { 5083 {
5084 int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
5085 window_scroll_pixel_based_preserve_y);
5086
5087 /* Don't let the preserved screen Y coordinate put us inside
5088 any of the two margins. */
5089 if (goal_y < this_scroll_margin)
5090 goal_y = this_scroll_margin;
5077 SET_TEXT_POS_FROM_MARKER (start, w->start); 5091 SET_TEXT_POS_FROM_MARKER (start, w->start);
5078 start_display (&it, w, start); 5092 start_display (&it, w, start);
5079 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT 5093 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
5080 here because we called start_display again and did not 5094 here because we called start_display again and did not
5081 alter it.current_y this time. */ 5095 alter it.current_y this time. */
5082 move_it_to (&it, -1, window_scroll_pixel_based_preserve_x, 5096 move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
5083 window_scroll_pixel_based_preserve_y, -1, 5097 goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
5084 MOVE_TO_Y | MOVE_TO_X);
5085 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 5098 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
5086 } 5099 }
5087 else 5100 else
@@ -5197,6 +5210,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
5197 w->force_start = true; 5210 w->force_start = true;
5198 5211
5199 if (!NILP (Vscroll_preserve_screen_position) 5212 if (!NILP (Vscroll_preserve_screen_position)
5213 && this_scroll_margin == 0
5200 && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) 5214 && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
5201 { 5215 {
5202 SET_PT_BOTH (pos, pos_byte); 5216 SET_PT_BOTH (pos, pos_byte);
@@ -5222,8 +5236,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
5222 marker_byte_position (opoint_marker)); 5236 marker_byte_position (opoint_marker));
5223 else if (!NILP (Vscroll_preserve_screen_position)) 5237 else if (!NILP (Vscroll_preserve_screen_position))
5224 { 5238 {
5239 int nlines = window_scroll_preserve_vpos;
5240
5225 SET_PT_BOTH (pos, pos_byte); 5241 SET_PT_BOTH (pos, pos_byte);
5226 Fvertical_motion (original_pos, window, Qnil); 5242 if (window_scroll_preserve_vpos < this_scroll_margin)
5243 nlines = this_scroll_margin;
5244 else if (window_scroll_preserve_vpos
5245 >= w->total_lines - this_scroll_margin)
5246 nlines = w->total_lines - this_scroll_margin - 1;
5247 Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
5248 make_number (nlines)), window, Qnil);
5227 } 5249 }
5228 else 5250 else
5229 SET_PT (top_margin); 5251 SET_PT (top_margin);
@@ -5249,8 +5271,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
5249 { 5271 {
5250 if (!NILP (Vscroll_preserve_screen_position)) 5272 if (!NILP (Vscroll_preserve_screen_position))
5251 { 5273 {
5274 int nlines = window_scroll_preserve_vpos;
5275
5252 SET_PT_BOTH (pos, pos_byte); 5276 SET_PT_BOTH (pos, pos_byte);
5253 Fvertical_motion (original_pos, window, Qnil); 5277 if (window_scroll_preserve_vpos < this_scroll_margin)
5278 nlines = this_scroll_margin;
5279 else if (window_scroll_preserve_vpos
5280 >= ht - this_scroll_margin)
5281 nlines = ht - this_scroll_margin - 1;
5282 Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
5283 make_number (nlines)), window, Qnil);
5254 } 5284 }
5255 else 5285 else
5256 Fvertical_motion (make_number (-1), window, Qnil); 5286 Fvertical_motion (make_number (-1), window, Qnil);