0

I'm running into an odd problem scrolling by pixels, it seems calling scroll-up doesn't properly handle pixel scrolling (set-window-vscroll).

This is a simple test that attempts to scroll up by pixels in a timer.

When the entire line is scrolled, the view flickers.

(setq pixel-counter 0)
(defun scroll-down-by-pixels ()
  (setq pixel-counter (+ pixel-counter 1))
  (if (= pixel-counter (frame-char-height))
    (progn
      (set-window-vscroll nil 0 t)
      (scroll-down 1)
      (setq pixel-counter 0))
    (set-window-vscroll nil (- (frame-char-height) pixel-counter) t)))

(defun test-me ()
  (interactive)
  (end-of-buffer) ;; for testing convenience.
  (run-with-timer 0.0 0.01 'scroll-down-by-pixels))
;; Map to any key
(global-set-key (kbd "<f7>") 'test-me)

Oddly enough the reverse direction doesn't suffer from this problem.

(setq pixel-counter 0)
(defun scroll-up-by-pixels ()
  (setq pixel-counter (+ pixel-counter 1))
  (if (= pixel-counter (frame-char-height))
    (progn
      (set-window-vscroll nil 0 t)
      (scroll-up 1)
      (setq pixel-counter 0))
    (set-window-vscroll nil pixel-counter t)))

(defun test-me ()
  (interactive)
  (beginning-of-buffer) ;; for testing convenience.
  (run-with-timer 0.0 0.01 'scroll-up-by-pixels))
;; Map to any key
(global-set-key (kbd "<f7>") 'test-me)

Is this a known issue or is there some way to avoid it?

ideasman42
  • 8,375
  • 1
  • 28
  • 105

1 Answers1

0
  • You can't use scroll-up as it tags the window to reset the pixel scrolling value.
  • Instead you need to use set-window-start, with the 3rd NOFORCE argument to t.
  • This complicates things because the point then needs to be moved before the window, since, unlike scroll, setting the window-start doesn't move the point to stay in the window bounds.

See: How to scroll immediately by a pixel offset?

ideasman42
  • 8,375
  • 1
  • 28
  • 105