aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2021-11-30 20:35:11 +0800
committerPo Lu2021-11-30 20:36:43 +0800
commitb79d779ae839d0484b24967b4753df9e9b85f614 (patch)
tree001ea2497f58d2b49cd6f032f6e11a48c6a0786d
parent68c09c6b741be5005b90152c59e781cb0f80704d (diff)
downloademacs-b79d779ae839d0484b24967b4753df9e9b85f614.tar.gz
emacs-b79d779ae839d0484b24967b4753df9e9b85f614.zip
Improve upwards pixel scrolling for large images
This fixes most of the problem, but with a large image the vscroll can sometimes jump about, which has to be fixed. * lisp/pixel-scroll.el (pixel-scroll-precision-up): Handle vscrolling large images in the first unseen line.
-rw-r--r--lisp/pixel-scroll.el85
1 files changed, 45 insertions, 40 deletions
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index 2fd7cace0b0..097e4e53ddc 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -423,50 +423,55 @@ the height of the current window."
423 423
424(defun pixel-scroll-precision-scroll-up (delta) 424(defun pixel-scroll-precision-scroll-up (delta)
425 "Scroll the current window up by DELTA pixels." 425 "Scroll the current window up by DELTA pixels."
426 (when-let* ((max-y (- (window-text-height nil t) 426 (let* ((edges (window-edges nil t nil t))
427 (frame-char-height) 427 (max-y (- (nth 3 edges)
428 (window-tab-line-height) 428 (window-tab-line-height)
429 (window-header-line-height))) 429 (window-header-line-height)))
430 (posn (posn-at-point)) 430 (usable-height (- max-y (nth 1 edges))))
431 (current-y (+ (cdr (posn-x-y posn)) 431 (when-let* ((posn (posn-at-point))
432 (line-pixel-height)))) 432 (current-y (+ (cdr (posn-x-y posn))
433 (while (< (- max-y current-y) delta) 433 (line-pixel-height))))
434 (vertical-motion -1) 434 (while (and (< (- max-y current-y) delta)
435 (setq current-y (- current-y (line-pixel-height))))) 435 (< (cdr (posn-object-width-height posn))
436 (let ((current-vscroll (window-vscroll nil t))) 436 usable-height))
437 (if (<= delta current-vscroll) 437 (vertical-motion -1)
438 (set-window-vscroll nil (- current-vscroll delta) t) 438 (setq current-y (- current-y (line-pixel-height))))
439 (setq delta (- delta current-vscroll)) 439 (when (and (>= (cdr (posn-object-width-height posn))
440 (set-window-vscroll nil 0 t) 440 usable-height)
441 (while (> delta 0) 441 (let ((prev-line-height (save-excursion
442 (let ((position (pixel-point-and-height-at-unseen-line))) 442 (vertical-motion -1)
443 (unless (cdr position) 443 (line-pixel-height))))
444 (signal 'beginning-of-buffer nil)) 444 (<= 0 (- (cdr (posn-x-y posn)) prev-line-height))))
445 (set-window-start nil (car position) t) 445 (vertical-motion -1)))
446 ;; If the line above is taller than the window height (i.e. there's 446 (let ((current-vscroll (window-vscroll nil t)))
447 ;; a very tall image), keep point on it. 447 (if (<= delta current-vscroll)
448 (when (> (cdr position) (window-text-height nil t)) 448 (set-window-vscroll nil (- current-vscroll delta) t)
449 (let ((vs (window-vscroll nil t))) 449 (setq delta (- delta current-vscroll))
450 (goto-char (car position)) 450 (set-window-vscroll nil 0 t)
451 (set-window-vscroll nil vs t))) 451 (while (> delta 0)
452 (setq delta (- delta (cdr position))))) 452 (let ((position (pixel-point-and-height-at-unseen-line)))
453 (when (< delta 0) 453 (unless (cdr position)
454 (when-let* ((desired-pos (posn-at-x-y 0 (+ (- delta) 454 (signal 'beginning-of-buffer nil))
455 (set-window-start nil (car position) t)
456 ;; If the line above is taller than the window height (i.e. there's
457 ;; a very tall image), keep point on it.
458 (when (> (cdr position) usable-height)
459 (goto-char (car position)))
460 (setq delta (- delta (cdr position)))))
461 (when (< delta 0)
462 (if-let* ((desired-pos (posn-at-x-y 0 (+ (- delta)
455 (window-tab-line-height) 463 (window-tab-line-height)
456 (window-header-line-height)))) 464 (window-header-line-height))))
457 (desired-start (posn-point desired-pos)) 465 (desired-start (posn-point desired-pos))
458 (desired-vscroll (cdr (posn-object-x-y desired-pos)))) 466 (desired-vscroll (cdr (posn-object-x-y desired-pos))))
459 (let ((object (posn-object desired-pos))) 467 (progn
460 (if (or (consp object) (stringp object)) 468 (set-window-start nil desired-start t)
461 (set-window-vscroll nil (+ (window-vscroll nil t) 469 (set-window-vscroll nil desired-vscroll t))
462 (- delta)) 470 (set-window-vscroll nil (abs delta) t)))))))
463 t) 471
464 (unless (eq (window-start) desired-start) 472;; FIXME: This doesn't _always_ work when there's an image above the
465 (set-window-start nil desired-start t)) 473;; current line that is taller than the window, and scrolling can
466 (set-window-vscroll nil desired-vscroll t)))))))) 474;; sometimes be jumpy in that case.
467
468;; FIXME: This doesn't work when there's an image above the current
469;; line that is taller than the window.
470(defun pixel-scroll-precision (event) 475(defun pixel-scroll-precision (event)
471 "Scroll the display vertically by pixels according to EVENT. 476 "Scroll the display vertically by pixels according to EVENT.
472Move the display up or down by the pixel deltas in EVENT to 477Move the display up or down by the pixel deltas in EVENT to