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?

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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.