diff options
| author | Eli Zaretskii | 2013-06-15 12:34:20 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-06-15 12:34:20 +0300 |
| commit | 9583ec36c459ecf14237b08ee2e29fe301a63c4e (patch) | |
| tree | 9f3f8b2b6a9901cdbe7f430ab109b333ca630311 | |
| parent | d1ad37b23f4e0f6e9403355e1844d33a23e84544 (diff) | |
| download | emacs-9583ec36c459ecf14237b08ee2e29fe301a63c4e.tar.gz emacs-9583ec36c459ecf14237b08ee2e29fe301a63c4e.zip | |
Fix bug #14567 with jumpy scrolling of tall images.
src/xdisp.c (Fline_pixel_height): New function, required for solving
bug #14567.
lisp/simple.el (line-move-partial): Don't jump to the next screen
line as soon as it becomes visible. Instead, continue enlarging
the vscroll until the portion of a tall screen line that's left on
display is about the height of the frame's default font.
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/simple.el | 61 | ||||
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/xdisp.c | 19 |
4 files changed, 76 insertions, 17 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index cced6eb0043..fadbabf808e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-06-15 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * simple.el (line-move-partial): Don't jump to the next screen | ||
| 4 | line as soon as it becomes visible. Instead, continue enlarging | ||
| 5 | the vscroll until the portion of a tall screen line that's left on | ||
| 6 | display is about the height of the frame's default font. | ||
| 7 | (Bug#14567) | ||
| 8 | |||
| 1 | 2013-06-15 Glenn Morris <rgm@gnu.org> | 9 | 2013-06-15 Glenn Morris <rgm@gnu.org> |
| 2 | 10 | ||
| 3 | * vc/vc-dispatcher.el (vc-compilation-mode): Avoid making | 11 | * vc/vc-dispatcher.el (vc-compilation-mode): Avoid making |
diff --git a/lisp/simple.el b/lisp/simple.el index 3fd94e96d33..34ebc8f122f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -4738,42 +4738,62 @@ lines." | |||
| 4738 | (vpos (nth 1 lh)) | 4738 | (vpos (nth 1 lh)) |
| 4739 | (ypos (nth 2 lh)) | 4739 | (ypos (nth 2 lh)) |
| 4740 | (rbot (nth 3 lh)) | 4740 | (rbot (nth 3 lh)) |
| 4741 | (this-lh (window-line-height)) | ||
| 4742 | (this-height (nth 0 this-lh)) | ||
| 4743 | (this-ypos (nth 2 this-lh)) | ||
| 4744 | (fch (frame-char-height)) | ||
| 4741 | py vs) | 4745 | py vs) |
| 4742 | (when (or (null lh) | 4746 | (when (or (null lh) |
| 4743 | (>= rbot (frame-char-height)) | 4747 | (>= rbot fch) |
| 4744 | (<= ypos (- (frame-char-height)))) | 4748 | (<= ypos (- fch)) |
| 4749 | (null this-lh) | ||
| 4750 | (<= this-ypos (- fch))) | ||
| 4745 | (unless lh | 4751 | (unless lh |
| 4746 | (let ((wend (pos-visible-in-window-p t nil t))) | 4752 | (let ((wend (pos-visible-in-window-p t nil t))) |
| 4747 | (setq rbot (nth 3 wend) | 4753 | (setq rbot (nth 3 wend) |
| 4748 | vpos (nth 5 wend)))) | 4754 | vpos (nth 5 wend)))) |
| 4755 | (unless this-lh | ||
| 4756 | (let ((wstart (pos-visible-in-window-p nil nil t))) | ||
| 4757 | (setq this-ypos (nth 2 wstart) | ||
| 4758 | this-height (nth 4 wstart)))) | ||
| 4759 | (setq py | ||
| 4760 | (or (nth 1 this-lh) | ||
| 4761 | (let ((ppos (posn-at-point))) | ||
| 4762 | (cdr (or (posn-actual-col-row ppos) | ||
| 4763 | (posn-col-row ppos)))))) | ||
| 4749 | (cond | 4764 | (cond |
| 4750 | ;; If last line of window is fully visible, move forward. | 4765 | ;; If last line of window is fully visible, and vscrolling |
| 4751 | ((or (null rbot) (= rbot 0)) | 4766 | ;; more would make this line invisible, move forward. |
| 4767 | ((and (or (< (setq vs (window-vscroll nil t)) fch) | ||
| 4768 | (null this-height) | ||
| 4769 | (<= this-height fch)) | ||
| 4770 | (or (null rbot) (= rbot 0))) | ||
| 4752 | nil) | 4771 | nil) |
| 4753 | ;; If cursor is not in the bottom scroll margin, move forward. | 4772 | ;; If cursor is not in the bottom scroll margin, and the |
| 4754 | ((and (> vpos 0) | 4773 | ;; current line is is not too tall, move forward. |
| 4755 | (< (setq py | 4774 | ((and (or (null this-height) (<= this-height fch)) |
| 4756 | (or (nth 1 (window-line-height)) | 4775 | vpos |
| 4757 | (let ((ppos (posn-at-point))) | 4776 | (> vpos 0) |
| 4758 | (cdr (or (posn-actual-col-row ppos) | 4777 | (< py |
| 4759 | (posn-col-row ppos)))))) | ||
| 4760 | (min (- (window-text-height) scroll-margin 1) (1- vpos)))) | 4778 | (min (- (window-text-height) scroll-margin 1) (1- vpos)))) |
| 4761 | nil) | 4779 | nil) |
| 4762 | ;; When already vscrolled, we vscroll some more if we can, | 4780 | ;; When already vscrolled, we vscroll some more if we can, |
| 4763 | ;; or clear vscroll and move forward at end of tall image. | 4781 | ;; or clear vscroll and move forward at end of tall image. |
| 4764 | ((> (setq vs (window-vscroll nil t)) 0) | 4782 | ((> vs 0) |
| 4765 | (when (> rbot 0) | 4783 | (when (or (and rbot (> rbot 0)) |
| 4766 | (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t))) | 4784 | (and this-height (> this-height fch))) |
| 4785 | (set-window-vscroll nil (+ vs fch) t))) | ||
| 4767 | ;; If cursor just entered the bottom scroll margin, move forward, | 4786 | ;; If cursor just entered the bottom scroll margin, move forward, |
| 4768 | ;; but also vscroll one line so redisplay won't recenter. | 4787 | ;; but also vscroll one line so redisplay won't recenter. |
| 4769 | ((and (> vpos 0) | 4788 | ((and vpos |
| 4789 | (> vpos 0) | ||
| 4770 | (= py (min (- (window-text-height) scroll-margin 1) | 4790 | (= py (min (- (window-text-height) scroll-margin 1) |
| 4771 | (1- vpos)))) | 4791 | (1- vpos)))) |
| 4772 | (set-window-vscroll nil (frame-char-height) t) | 4792 | (set-window-vscroll nil (frame-char-height) t) |
| 4773 | (line-move-1 arg noerror to-end) | 4793 | (line-move-1 arg noerror to-end) |
| 4774 | t) | 4794 | t) |
| 4775 | ;; If there are lines above the last line, scroll-up one line. | 4795 | ;; If there are lines above the last line, scroll-up one line. |
| 4776 | ((> vpos 0) | 4796 | ((and vpos (> vpos 0)) |
| 4777 | (scroll-up 1) | 4797 | (scroll-up 1) |
| 4778 | t) | 4798 | t) |
| 4779 | ;; Finally, start vscroll. | 4799 | ;; Finally, start vscroll. |
| @@ -4808,7 +4828,14 @@ lines." | |||
| 4808 | ;; display-based motion doesn't make sense (because each | 4828 | ;; display-based motion doesn't make sense (because each |
| 4809 | ;; logical line occupies exactly one screen line). | 4829 | ;; logical line occupies exactly one screen line). |
| 4810 | (not (> (window-hscroll) 0))) | 4830 | (not (> (window-hscroll) 0))) |
| 4811 | (line-move-visual arg noerror) | 4831 | (prog1 (line-move-visual arg noerror) |
| 4832 | ;; If we moved into a tall line, set vscroll to make | ||
| 4833 | ;; scrolling through tall images more smooth. | ||
| 4834 | (let ((lh (line-pixel-height))) | ||
| 4835 | (if (and (< arg 0) | ||
| 4836 | (< (point) (window-start)) | ||
| 4837 | (> lh (frame-char-height))) | ||
| 4838 | (set-window-vscroll nil (- lh (frame-char-height)) t)))) | ||
| 4812 | (line-move-1 arg noerror to-end))))) | 4839 | (line-move-1 arg noerror to-end))))) |
| 4813 | 4840 | ||
| 4814 | ;; Display-based alternative to line-move-1. | 4841 | ;; Display-based alternative to line-move-1. |
diff --git a/src/ChangeLog b/src/ChangeLog index ec0fbc493cb..a26577c20a3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-06-15 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (Fline_pixel_height): New function, required for solving | ||
| 4 | bug #14567. | ||
| 5 | |||
| 1 | 2013-06-15 Paul Eggert <eggert@cs.ucla.edu> | 6 | 2013-06-15 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 7 | ||
| 3 | * fns.c (Fcopy_sequence): Simplify XTYPE calculation. | 8 | * fns.c (Fcopy_sequence): Simplify XTYPE calculation. |
diff --git a/src/xdisp.c b/src/xdisp.c index e1d6b0c9a27..54ea325f642 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1217,6 +1217,24 @@ line_bottom_y (struct it *it) | |||
| 1217 | return line_top_y + line_height; | 1217 | return line_top_y + line_height; |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | DEFUN ("line-pixel-height", Fline_pixel_height, | ||
| 1221 | Sline_pixel_height, 0, 0, 0, | ||
| 1222 | doc: /* Return height in pixels of text line in the selected window. | ||
| 1223 | |||
| 1224 | Value is the height in pixels of the line at point. */) | ||
| 1225 | (void) | ||
| 1226 | { | ||
| 1227 | struct it it; | ||
| 1228 | struct text_pos pt; | ||
| 1229 | struct window *w = XWINDOW (selected_window); | ||
| 1230 | |||
| 1231 | SET_TEXT_POS (pt, PT, PT_BYTE); | ||
| 1232 | start_display (&it, w, pt); | ||
| 1233 | it.vpos = it.current_y = 0; | ||
| 1234 | last_height = 0; | ||
| 1235 | return make_number (line_bottom_y (&it)); | ||
| 1236 | } | ||
| 1237 | |||
| 1220 | /* Subroutine of pos_visible_p below. Extracts a display string, if | 1238 | /* Subroutine of pos_visible_p below. Extracts a display string, if |
| 1221 | any, from the display spec given as its argument. */ | 1239 | any, from the display spec given as its argument. */ |
| 1222 | static Lisp_Object | 1240 | static Lisp_Object |
| @@ -28691,6 +28709,7 @@ syms_of_xdisp (void) | |||
| 28691 | defsubr (&Stool_bar_lines_needed); | 28709 | defsubr (&Stool_bar_lines_needed); |
| 28692 | defsubr (&Slookup_image_map); | 28710 | defsubr (&Slookup_image_map); |
| 28693 | #endif | 28711 | #endif |
| 28712 | defsubr (&Sline_pixel_height); | ||
| 28694 | defsubr (&Sformat_mode_line); | 28713 | defsubr (&Sformat_mode_line); |
| 28695 | defsubr (&Sinvisible_p); | 28714 | defsubr (&Sinvisible_p); |
| 28696 | defsubr (&Scurrent_bidi_paragraph_direction); | 28715 | defsubr (&Scurrent_bidi_paragraph_direction); |