Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled with 'pixel-scroll-precision-mode' on

From: Rahguzar <[email-masked]>
Date: Sun, 27 Aug 2023 09:53:16 +0200

Hi Po,

Po Lu <[email-masked]> writes:

> Rahguzar <[email-masked]> writes:
>
>> Hi Po,
>>
>> Po Lu <[email-masked]> writes:
>>
>>> I tried to fix this differently on master.  Please see if it resolves
>>> your problem (and other issues with scrolling past large images.)
>>>
>>> As always, keep an eye out for performance regressions.  Thanks.
>>
>>
>> The issue is still there and can be reproduced by evaluating
>>
>> (let* ((win (display-buffer (get-buffer-create "image-pixel-precision-test")))
>>        (height (* (window-text-height win t) 2))
>>        (file "path/to/image"))
>>   (select-window win)
>>   (erase-buffer)
>>   (insert-image (create-image file nil nil))
>>   (goto-char 1)
>>   (pixel-scroll-precision-mode)
>>   nil)
>>
>> The resulting image cannot be scrolled.
>>
>> In the new code this is because vscroll is reset to 0 inside the binding
>> for `line-after`. Commenting out that line allows me to scroll the
>> image.
>
> But as a repercussion, scrolling past the image will result in the
> window being vscrolled indefinitely.  That is unacceptable, because
> redisplay grows exponentially slower as vscroll increases.
>
> Is this compromise acceptable?  It will enable scrolling within the last
> line of the window, but will reset vscroll entirely once the window
> start becomes invisible, resulting in a visually disconnected ``jump''
> back to the top of that line.
>
> diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
> index 488f6781254..8961f196ec7 100644
> --- a/lisp/pixel-scroll.el
> +++ b/lisp/pixel-scroll.el
> @@ -543,14 +543,18 @@ pixel-scroll-precision-scroll-down-page
>          (let ((line-after (save-excursion
>                              (goto-char new-start-position)
>                              (if (zerop (vertical-motion 1))
> -                                (progn
> -                                  (set-window-vscroll nil 0 t t)
> -                                  nil) ; nil means move to new-start-position.
> +                                nil ; nil means move to new-start-position.
>                                (point)))))
>            (if (not line-after)
>                (progn
>                  (goto-char new-start-position)
> -                (signal 'end-of-buffer nil))
> +                ;; If vscroll has resulted in the entire line being
> +                ;; scrolled outside the window's text area, set it to
> +                ;; the height of the last line.
> +                (let ((visibility (pos-visible-in-window-p new-start-position nil t)))
> +                  (unless visibility
> +                    (set-window-vscroll nil 0)
> +                    (signal 'end-of-buffer nil))))
>              (if (pos-visible-in-window-p line-after nil t)
>                  (goto-char line-after)
>                (goto-char new-start-position))))))))

This is just a ping. Any chance these changes will be part of Emacs
29.2? I think they are a big improvement over large images not scrolling
at all.

Thanks,
Rahguzar