Subject: bug#67333: pixel-scroll-precision: scroll-up-page gets trapped by invisible characters

From: JD Smith <[email-masked]>
Date: Tue, 21 Nov 2023 11:24:54 -0500

`pixel-scroll-precision-mode' is quite amazing, running 20-50x faster than other comparable pixel scrolling event callbacks.  I’ve found just a few issues with it.

One issue is well-known and mentioned in the pixel-scroll.el commentary:

;; This works well almost all of the time, but is impossible to get right with images larger than
;; the window they're displayed in.  A feature that will allow
;; redisplay to skip recentering is in the works, and will completely
;; resolve this problem.

When attempting to pixel-precise-scroll past an image that overfills the window height, automatic recentering causes “jump back”, and you cannot get past it. Is the mentioned “skip recentering feature” slated for Emacs 30?  Would be glad to test it. 

Here’s the small bug: when scrolling from the bottom up to the top of the buffer, pixel-scroll-precision-scroll-up-page gets trapped if it encounters a wrapped invisible character in the first column.  By this I mean the line and cursor are pinned to the center of the window, only jiggling up and down with further scrolling in either direction.  Note that this only happens when scrolling from the bottom of the buffer up to the top.  Scrolling from top to bottom works fine.  So there’s an asymmetry there. 

A simple reproducer:

Create a new fundamental mode buffer.  
Enable `pixel-scroll-precision-mode’.  
Be sure you have lorem-ipsum installed, and M-100 M-x lorem-ipsum-insert-paragraphs, to insert lots of text. 
M-x visual-line-mode (not required to trigger the bug, but makes it more likely).
From the beginning of buffer, run the following (via M-:) to make the 1st character of every 11th word invisible:

  (cl-loop for cnt from 1 while (forward-word) for p = (point) 
    if (= (% cnt 11) 0) do (set-text-properties (1+ p) (+ 2 p) '(invisible t)))
Now from the bottom of the buffer, start scrolling up to the top.  As point moves, it will eventually encounter an invisible character at column 0, jump immediately to the window’s center, and get stuck there, jiggling around.  Scrolling neither up nor down escapes the trap.