diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-06-15 12:34:20 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-06-15 12:34:20 +0300 |
commit | 9583ec36c459ecf14237b08ee2e29fe301a63c4e (patch) | |
tree | 9f3f8b2b6a9901cdbe7f430ab109b333ca630311 /lisp | |
parent | d1ad37b23f4e0f6e9403355e1844d33a23e84544 (diff) | |
download | emacs-9583ec36c459ecf14237b08ee2e29fe301a63c4e.tar.gz emacs-9583ec36c459ecf14237b08ee2e29fe301a63c4e.tar.bz2 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.
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ChangeLog | 8 | ||||
-rw-r--r-- | lisp/simple.el | 61 |
2 files changed, 52 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 @@ +2013-06-15 Eli Zaretskii <eliz@gnu.org> + + * 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. + (Bug#14567) + 2013-06-15 Glenn Morris <rgm@gnu.org> * 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." (vpos (nth 1 lh)) (ypos (nth 2 lh)) (rbot (nth 3 lh)) + (this-lh (window-line-height)) + (this-height (nth 0 this-lh)) + (this-ypos (nth 2 this-lh)) + (fch (frame-char-height)) py vs) (when (or (null lh) - (>= rbot (frame-char-height)) - (<= ypos (- (frame-char-height)))) + (>= rbot fch) + (<= ypos (- fch)) + (null this-lh) + (<= this-ypos (- fch))) (unless lh (let ((wend (pos-visible-in-window-p t nil t))) (setq rbot (nth 3 wend) vpos (nth 5 wend)))) + (unless this-lh + (let ((wstart (pos-visible-in-window-p nil nil t))) + (setq this-ypos (nth 2 wstart) + this-height (nth 4 wstart)))) + (setq py + (or (nth 1 this-lh) + (let ((ppos (posn-at-point))) + (cdr (or (posn-actual-col-row ppos) + (posn-col-row ppos)))))) (cond - ;; If last line of window is fully visible, move forward. - ((or (null rbot) (= rbot 0)) + ;; If last line of window is fully visible, and vscrolling + ;; more would make this line invisible, move forward. + ((and (or (< (setq vs (window-vscroll nil t)) fch) + (null this-height) + (<= this-height fch)) + (or (null rbot) (= rbot 0))) nil) - ;; If cursor is not in the bottom scroll margin, move forward. - ((and (> vpos 0) - (< (setq py - (or (nth 1 (window-line-height)) - (let ((ppos (posn-at-point))) - (cdr (or (posn-actual-col-row ppos) - (posn-col-row ppos)))))) + ;; If cursor is not in the bottom scroll margin, and the + ;; current line is is not too tall, move forward. + ((and (or (null this-height) (<= this-height fch)) + vpos + (> vpos 0) + (< py (min (- (window-text-height) scroll-margin 1) (1- vpos)))) nil) ;; When already vscrolled, we vscroll some more if we can, ;; or clear vscroll and move forward at end of tall image. - ((> (setq vs (window-vscroll nil t)) 0) - (when (> rbot 0) - (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t))) + ((> vs 0) + (when (or (and rbot (> rbot 0)) + (and this-height (> this-height fch))) + (set-window-vscroll nil (+ vs fch) t))) ;; If cursor just entered the bottom scroll margin, move forward, ;; but also vscroll one line so redisplay won't recenter. - ((and (> vpos 0) + ((and vpos + (> vpos 0) (= py (min (- (window-text-height) scroll-margin 1) (1- vpos)))) (set-window-vscroll nil (frame-char-height) t) (line-move-1 arg noerror to-end) t) ;; If there are lines above the last line, scroll-up one line. - ((> vpos 0) + ((and vpos (> vpos 0)) (scroll-up 1) t) ;; Finally, start vscroll. @@ -4808,7 +4828,14 @@ lines." ;; display-based motion doesn't make sense (because each ;; logical line occupies exactly one screen line). (not (> (window-hscroll) 0))) - (line-move-visual arg noerror) + (prog1 (line-move-visual arg noerror) + ;; If we moved into a tall line, set vscroll to make + ;; scrolling through tall images more smooth. + (let ((lh (line-pixel-height))) + (if (and (< arg 0) + (< (point) (window-start)) + (> lh (frame-char-height))) + (set-window-vscroll nil (- lh (frame-char-height)) t)))) (line-move-1 arg noerror to-end))))) ;; Display-based alternative to line-move-1. |