diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.c | 92 |
1 files changed, 65 insertions, 27 deletions
diff --git a/src/window.c b/src/window.c index a0a8b351a02..ee2faf09ca6 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -336,10 +336,12 @@ If POS is only out of view because of horizontal scrolling, return non-nil. | |||
| 336 | POS defaults to point in WINDOW; WINDOW defaults to the selected window. | 336 | POS defaults to point in WINDOW; WINDOW defaults to the selected window. |
| 337 | 337 | ||
| 338 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, | 338 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, |
| 339 | return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates | 339 | return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), |
| 340 | relative to the top left corner of the window. PARTIAL is nil if the character | 340 | where X and Y are the pixel coordinates relative to the top left corner |
| 341 | after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP | 341 | of the window. The remaining elements are omitted if the character after |
| 342 | and RBOT are the number of pixels invisible at the top and bottom of the row. */) | 342 | POS is fully visible; otherwise, RTOP and RBOT are the number of pixels |
| 343 | invisible at the top and bottom of the row, ROWH is the height of the display | ||
| 344 | row, and VPOS is the row number (0-based) containing POS. */) | ||
| 343 | (pos, window, partially) | 345 | (pos, window, partially) |
| 344 | Lisp_Object pos, window, partially; | 346 | Lisp_Object pos, window, partially; |
| 345 | { | 347 | { |
| @@ -348,7 +350,7 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. * | |||
| 348 | register struct buffer *buf; | 350 | register struct buffer *buf; |
| 349 | struct text_pos top; | 351 | struct text_pos top; |
| 350 | Lisp_Object in_window = Qnil; | 352 | Lisp_Object in_window = Qnil; |
| 351 | int rtop, rbot, fully_p = 1; | 353 | int rtop, rbot, rowh, vpos, fully_p = 1; |
| 352 | int x, y; | 354 | int x, y; |
| 353 | 355 | ||
| 354 | w = decode_window (window); | 356 | w = decode_window (window); |
| @@ -371,17 +373,20 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. * | |||
| 371 | && posint <= BUF_ZV (buf) | 373 | && posint <= BUF_ZV (buf) |
| 372 | && CHARPOS (top) >= BUF_BEGV (buf) | 374 | && CHARPOS (top) >= BUF_BEGV (buf) |
| 373 | && CHARPOS (top) <= BUF_ZV (buf) | 375 | && CHARPOS (top) <= BUF_ZV (buf) |
| 374 | && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, NILP (partially)) | 376 | && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos) |
| 375 | && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p))) | 377 | && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p))) |
| 376 | in_window = Qt; | 378 | in_window = Qt; |
| 377 | 379 | ||
| 378 | if (!NILP (in_window) && !NILP (partially)) | 380 | if (!NILP (in_window) && !NILP (partially)) |
| 379 | in_window = Fcons (make_number (x), | 381 | { |
| 380 | Fcons (make_number (y), | 382 | Lisp_Object part = Qnil; |
| 381 | Fcons ((fully_p ? Qnil | 383 | if (!fully_p) |
| 382 | : Fcons (make_number (rtop), | 384 | part = list4 (make_number (rtop), make_number (rbot), |
| 383 | make_number (rbot))), | 385 | make_number (rowh), make_number (vpos)); |
| 384 | Qnil))); | 386 | in_window = Fcons (make_number (x), |
| 387 | Fcons (make_number (y), part)); | ||
| 388 | } | ||
| 389 | |||
| 385 | return in_window; | 390 | return in_window; |
| 386 | } | 391 | } |
| 387 | 392 | ||
| @@ -4818,10 +4823,10 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4818 | struct it it; | 4823 | struct it it; |
| 4819 | struct window *w = XWINDOW (window); | 4824 | struct window *w = XWINDOW (window); |
| 4820 | struct text_pos start; | 4825 | struct text_pos start; |
| 4821 | Lisp_Object tem; | ||
| 4822 | int this_scroll_margin; | 4826 | int this_scroll_margin; |
| 4823 | /* True if we fiddled the window vscroll field without really scrolling. */ | 4827 | /* True if we fiddled the window vscroll field without really scrolling. */ |
| 4824 | int vscrolled = 0; | 4828 | int vscrolled = 0; |
| 4829 | int x, y, rtop, rbot, rowh, vpos; | ||
| 4825 | 4830 | ||
| 4826 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 4831 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| 4827 | 4832 | ||
| @@ -4829,8 +4834,8 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4829 | the screen. Allow PT to be partially visible, otherwise | 4834 | the screen. Allow PT to be partially visible, otherwise |
| 4830 | something like (scroll-down 1) with PT in the line before | 4835 | something like (scroll-down 1) with PT in the line before |
| 4831 | the partially visible one would recenter. */ | 4836 | the partially visible one would recenter. */ |
| 4832 | tem = Fpos_visible_in_window_p (make_number (PT), window, Qt); | 4837 | |
| 4833 | if (NILP (tem)) | 4838 | if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos)) |
| 4834 | { | 4839 | { |
| 4835 | /* Move backward half the height of the window. Performance note: | 4840 | /* Move backward half the height of the window. Performance note: |
| 4836 | vmotion used here is about 10% faster, but would give wrong | 4841 | vmotion used here is about 10% faster, but would give wrong |
| @@ -4855,7 +4860,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4855 | } | 4860 | } |
| 4856 | else if (auto_window_vscroll_p) | 4861 | else if (auto_window_vscroll_p) |
| 4857 | { | 4862 | { |
| 4858 | if (tem = XCAR (XCDR (XCDR (tem))), CONSP (tem)) | 4863 | if (rtop || rbot) /* partially visible */ |
| 4859 | { | 4864 | { |
| 4860 | int px; | 4865 | int px; |
| 4861 | int dy = WINDOW_FRAME_LINE_HEIGHT (w); | 4866 | int dy = WINDOW_FRAME_LINE_HEIGHT (w); |
| @@ -4865,19 +4870,52 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4865 | dy); | 4870 | dy); |
| 4866 | dy *= n; | 4871 | dy *= n; |
| 4867 | 4872 | ||
| 4868 | if (n < 0 && (px = XINT (XCAR (tem))) > 0) | 4873 | if (n < 0) |
| 4869 | { | 4874 | { |
| 4870 | px = max (0, -w->vscroll - min (px, -dy)); | 4875 | /* Only vscroll backwards if already vscrolled forwards. */ |
| 4871 | Fset_window_vscroll (window, make_number (px), Qt); | 4876 | if (w->vscroll < 0 && rtop > 0) |
| 4872 | return; | 4877 | { |
| 4878 | px = max (0, -w->vscroll - min (rtop, -dy)); | ||
| 4879 | Fset_window_vscroll (window, make_number (px), Qt); | ||
| 4880 | return; | ||
| 4881 | } | ||
| 4873 | } | 4882 | } |
| 4874 | if (n > 0 && (px = XINT (XCDR (tem))) > 0) | 4883 | if (n > 0) |
| 4875 | { | 4884 | { |
| 4876 | px = max (0, -w->vscroll + min (px, dy)); | 4885 | /* Do vscroll if already vscrolled or only display line. */ |
| 4877 | Fset_window_vscroll (window, make_number (px), Qt); | 4886 | if (rbot > 0 && (w->vscroll < 0 || vpos == 0)) |
| 4878 | return; | 4887 | { |
| 4888 | px = max (0, -w->vscroll + min (rbot, dy)); | ||
| 4889 | Fset_window_vscroll (window, make_number (px), Qt); | ||
| 4890 | return; | ||
| 4891 | } | ||
| 4892 | |||
| 4893 | /* Maybe modify window start instead of scrolling. */ | ||
| 4894 | if (rbot > 0 || w->vscroll < 0) | ||
| 4895 | { | ||
| 4896 | int spos; | ||
| 4897 | |||
| 4898 | Fset_window_vscroll (window, make_number (0), Qt); | ||
| 4899 | /* If there are other text lines above the current row, | ||
| 4900 | move window start to current row. Else to next row. */ | ||
| 4901 | if (rbot > 0) | ||
| 4902 | spos = XINT (Fline_beginning_position (Qnil)); | ||
| 4903 | else | ||
| 4904 | spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV); | ||
| 4905 | set_marker_restricted (w->start, make_number (spos), | ||
| 4906 | w->buffer); | ||
| 4907 | w->start_at_line_beg = Qt; | ||
| 4908 | w->update_mode_line = Qt; | ||
| 4909 | XSETFASTINT (w->last_modified, 0); | ||
| 4910 | XSETFASTINT (w->last_overlay_modified, 0); | ||
| 4911 | /* Set force_start so that redisplay_window will run the | ||
| 4912 | window-scroll-functions. */ | ||
| 4913 | w->force_start = Qt; | ||
| 4914 | return; | ||
| 4915 | } | ||
| 4879 | } | 4916 | } |
| 4880 | } | 4917 | } |
| 4918 | /* Cancel previous vscroll. */ | ||
| 4881 | Fset_window_vscroll (window, make_number (0), Qt); | 4919 | Fset_window_vscroll (window, make_number (0), Qt); |
| 4882 | } | 4920 | } |
| 4883 | 4921 | ||
| @@ -4918,7 +4956,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4918 | if (dy <= 0) | 4956 | if (dy <= 0) |
| 4919 | { | 4957 | { |
| 4920 | move_it_vertically_backward (&it, -dy); | 4958 | move_it_vertically_backward (&it, -dy); |
| 4921 | /* Ensure we actually does move, e.g. in case we are currently | 4959 | /* Ensure we actually do move, e.g. in case we are currently |
| 4922 | looking at an image that is taller that the window height. */ | 4960 | looking at an image that is taller that the window height. */ |
| 4923 | while (start_pos == IT_CHARPOS (it) | 4961 | while (start_pos == IT_CHARPOS (it) |
| 4924 | && start_pos > BEGV) | 4962 | && start_pos > BEGV) |
| @@ -4928,7 +4966,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4928 | { | 4966 | { |
| 4929 | move_it_to (&it, ZV, -1, it.current_y + dy, -1, | 4967 | move_it_to (&it, ZV, -1, it.current_y + dy, -1, |
| 4930 | MOVE_TO_POS | MOVE_TO_Y); | 4968 | MOVE_TO_POS | MOVE_TO_Y); |
| 4931 | /* Ensure we actually does move, e.g. in case we are currently | 4969 | /* Ensure we actually do move, e.g. in case we are currently |
| 4932 | looking at an image that is taller that the window height. */ | 4970 | looking at an image that is taller that the window height. */ |
| 4933 | while (start_pos == IT_CHARPOS (it) | 4971 | while (start_pos == IT_CHARPOS (it) |
| 4934 | && start_pos < ZV) | 4972 | && start_pos < ZV) |
| @@ -6656,7 +6694,7 @@ display marginal areas and the text area. */) | |||
| 6656 | CHECK_NATNUM (left_width); | 6694 | CHECK_NATNUM (left_width); |
| 6657 | if (!NILP (right_width)) | 6695 | if (!NILP (right_width)) |
| 6658 | CHECK_NATNUM (right_width); | 6696 | CHECK_NATNUM (right_width); |
| 6659 | 6697 | ||
| 6660 | /* Do nothing on a tty. */ | 6698 | /* Do nothing on a tty. */ |
| 6661 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) | 6699 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) |
| 6662 | && (!EQ (w->left_fringe_width, left_width) | 6700 | && (!EQ (w->left_fringe_width, left_width) |