summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2013-06-15 12:34:20 +0300
committerEli Zaretskii <eliz@gnu.org>2013-06-15 12:34:20 +0300
commit9583ec36c459ecf14237b08ee2e29fe301a63c4e (patch)
tree9f3f8b2b6a9901cdbe7f430ab109b333ca630311 /lisp
parentd1ad37b23f4e0f6e9403355e1844d33a23e84544 (diff)
downloademacs-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/ChangeLog8
-rw-r--r--lisp/simple.el61
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.