diff options
| author | Yuuki Harano | 2020-12-14 01:52:10 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2020-12-14 01:52:10 +0900 |
| commit | 3e30047ce3a81dd0879973012abbf570d3215dfd (patch) | |
| tree | c7c10e82f2ff37705356a0c25b98d92c603c7983 /src/window.c | |
| parent | aea5dbec2514811fb2e1cc44b2347a976a5b7de8 (diff) | |
| parent | fe50a8b9ba79b4ac14a3a352d8bf84eaee4f2122 (diff) | |
| download | emacs-3e30047ce3a81dd0879973012abbf570d3215dfd.tar.gz emacs-3e30047ce3a81dd0879973012abbf570d3215dfd.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/src/window.c b/src/window.c index 6cd3122b43b..8e75e460b2b 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5669,7 +5669,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5669 | if (whole) | 5669 | if (whole) |
| 5670 | { | 5670 | { |
| 5671 | ptrdiff_t start_pos = IT_CHARPOS (it); | 5671 | ptrdiff_t start_pos = IT_CHARPOS (it); |
| 5672 | int dy = frame_line_height; | 5672 | int flh = frame_line_height; |
| 5673 | int ht = window_box_height (w); | 5673 | int ht = window_box_height (w); |
| 5674 | int nscls = sanitize_next_screen_context_lines (); | 5674 | int nscls = sanitize_next_screen_context_lines (); |
| 5675 | /* In the below we divide the window box height by the frame's | 5675 | /* In the below we divide the window box height by the frame's |
| @@ -5677,14 +5677,37 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5677 | box is not an integral multiple of the line height. This is | 5677 | box is not an integral multiple of the line height. This is |
| 5678 | important to ensure we get back to the same position when | 5678 | important to ensure we get back to the same position when |
| 5679 | scrolling up, then down. */ | 5679 | scrolling up, then down. */ |
| 5680 | dy = n * max (dy, (ht / dy - nscls) * dy); | 5680 | int dy = n * max (flh, (ht / flh - nscls) * flh); |
| 5681 | int goal_y; | ||
| 5682 | void *it_data; | ||
| 5681 | 5683 | ||
| 5682 | /* Note that move_it_vertically always moves the iterator to the | 5684 | /* Note that move_it_vertically always moves the iterator to the |
| 5683 | start of a line. So, if the last line doesn't have a newline, | 5685 | start of a line. So, if the last line doesn't have a newline, |
| 5684 | we would end up at the start of the line ending at ZV. */ | 5686 | we would end up at the start of the line ending at ZV. */ |
| 5685 | if (dy <= 0) | 5687 | if (dy <= 0) |
| 5686 | { | 5688 | { |
| 5689 | goal_y = it.current_y - dy; | ||
| 5687 | move_it_vertically_backward (&it, -dy); | 5690 | move_it_vertically_backward (&it, -dy); |
| 5691 | /* Extra precision for people who want us to preserve the | ||
| 5692 | screen position of the cursor: effectively round DY to the | ||
| 5693 | nearest screen line, instead of rounding to zero; the latter | ||
| 5694 | causes point to move by one line after C-v followed by M-v, | ||
| 5695 | if the buffer has lines of different height. */ | ||
| 5696 | if (!NILP (Vscroll_preserve_screen_position) | ||
| 5697 | && it.current_y - goal_y > 0.5 * flh) | ||
| 5698 | { | ||
| 5699 | it_data = bidi_shelve_cache (); | ||
| 5700 | struct it it2 = it; | ||
| 5701 | |||
| 5702 | move_it_by_lines (&it, -1); | ||
| 5703 | if (it.current_y < goal_y - 0.5 * flh) | ||
| 5704 | { | ||
| 5705 | it = it2; | ||
| 5706 | bidi_unshelve_cache (it_data, false); | ||
| 5707 | } | ||
| 5708 | else | ||
| 5709 | bidi_unshelve_cache (it_data, true); | ||
| 5710 | } | ||
| 5688 | /* Ensure we actually do move, e.g. in case we are currently | 5711 | /* Ensure we actually do move, e.g. in case we are currently |
| 5689 | looking at an image that is taller that the window height. */ | 5712 | looking at an image that is taller that the window height. */ |
| 5690 | while (start_pos == IT_CHARPOS (it) | 5713 | while (start_pos == IT_CHARPOS (it) |
| @@ -5693,8 +5716,25 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5693 | } | 5716 | } |
| 5694 | else if (dy > 0) | 5717 | else if (dy > 0) |
| 5695 | { | 5718 | { |
| 5696 | move_it_to (&it, ZV, -1, it.current_y + dy, -1, | 5719 | goal_y = it.current_y + dy; |
| 5697 | MOVE_TO_POS | MOVE_TO_Y); | 5720 | move_it_to (&it, ZV, -1, goal_y, -1, MOVE_TO_POS | MOVE_TO_Y); |
| 5721 | /* See the comment above, for the reasons of this | ||
| 5722 | extra-precision. */ | ||
| 5723 | if (!NILP (Vscroll_preserve_screen_position) | ||
| 5724 | && goal_y - it.current_y > 0.5 * flh) | ||
| 5725 | { | ||
| 5726 | it_data = bidi_shelve_cache (); | ||
| 5727 | struct it it2 = it; | ||
| 5728 | |||
| 5729 | move_it_by_lines (&it, 1); | ||
| 5730 | if (it.current_y > goal_y + 0.5 * flh) | ||
| 5731 | { | ||
| 5732 | it = it2; | ||
| 5733 | bidi_unshelve_cache (it_data, false); | ||
| 5734 | } | ||
| 5735 | else | ||
| 5736 | bidi_unshelve_cache (it_data, true); | ||
| 5737 | } | ||
| 5698 | /* Ensure we actually do move, e.g. in case we are currently | 5738 | /* Ensure we actually do move, e.g. in case we are currently |
| 5699 | looking at an image that is taller that the window height. */ | 5739 | looking at an image that is taller that the window height. */ |
| 5700 | while (start_pos == IT_CHARPOS (it) | 5740 | while (start_pos == IT_CHARPOS (it) |
| @@ -8206,11 +8246,17 @@ is displayed in the `mode-line' face. */); | |||
| 8206 | DEFVAR_LISP ("scroll-preserve-screen-position", | 8246 | DEFVAR_LISP ("scroll-preserve-screen-position", |
| 8207 | Vscroll_preserve_screen_position, | 8247 | Vscroll_preserve_screen_position, |
| 8208 | doc: /* Controls if scroll commands move point to keep its screen position unchanged. | 8248 | doc: /* Controls if scroll commands move point to keep its screen position unchanged. |
| 8249 | |||
| 8209 | A value of nil means point does not keep its screen position except | 8250 | A value of nil means point does not keep its screen position except |
| 8210 | at the scroll margin or window boundary respectively. | 8251 | at the scroll margin or window boundary respectively. |
| 8252 | |||
| 8211 | A value of t means point keeps its screen position if the scroll | 8253 | A value of t means point keeps its screen position if the scroll |
| 8212 | command moved it vertically out of the window, e.g. when scrolling | 8254 | command moved it vertically out of the window, e.g. when scrolling |
| 8213 | by full screens. | 8255 | by full screens. If point is within `next-screen-context-lines' lines |
| 8256 | from the edges of the window, point will typically not keep its screen | ||
| 8257 | position when doing commands like `scroll-up-command'/`scroll-down-command' | ||
| 8258 | and the like. | ||
| 8259 | |||
| 8214 | Any other value means point always keeps its screen position. | 8260 | Any other value means point always keeps its screen position. |
| 8215 | Scroll commands should have the `scroll-command' property | 8261 | Scroll commands should have the `scroll-command' property |
| 8216 | on their symbols to be controlled by this variable. */); | 8262 | on their symbols to be controlled by this variable. */); |