diff options
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 64 |
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); |