diff options
| author | Po Lu | 2021-11-30 20:35:11 +0800 |
|---|---|---|
| committer | Po Lu | 2021-11-30 20:36:43 +0800 |
| commit | b79d779ae839d0484b24967b4753df9e9b85f614 (patch) | |
| tree | 001ea2497f58d2b49cd6f032f6e11a48c6a0786d | |
| parent | 68c09c6b741be5005b90152c59e781cb0f80704d (diff) | |
| download | emacs-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.el | 85 |
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. |
| 472 | Move the display up or down by the pixel deltas in EVENT to | 477 | Move the display up or down by the pixel deltas in EVENT to |