GNU bug report logs - #65214
29.1; Tall images in 'image-mode' can't be scrolled with 'pixel-scroll-precision-mode' on

Previous Next

Package: emacs;

Reported by: Rahguzar <rahguzar <at> zohomail.eu>

Date: Thu, 10 Aug 2023 17:20:02 UTC

Severity: normal

Found in version 29.1

To reply to this bug, email your comments to 65214 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Thu, 10 Aug 2023 17:20:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Rahguzar <rahguzar <at> zohomail.eu>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 10 Aug 2023 17:20:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: bug-gnu-emacs <at> gnu.org
Subject: 29.1; Tall images in 'image-mode' can't be scrolled with
 'pixel-scroll-precision-mode' on
Date: Thu, 10 Aug 2023 19:05:03 +0200
Dear Emacs developers,

To reproduce starting from 'emacs -Q' visit an image file. Then
repeatedly use 'i +' till the image is taller than the window. The
image can be scrolled using mouse wheel. Now do

M-x pixel-scroll-precision-mode

After this attempting to scroll the image will set the vscroll to 0
and then image can't be scrolled at all.

From some investigation it seems like this behavior is not specific
to image-mode. Another way to reproduce the behavior is to evaluate
the following lisp code,

(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)

This image thus displayed can not be scrolled. However if the code
above is slightly modified to insert a new line after the image,
scrolling can be done normally, i.e.

(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))
  (insert "\n")
  (goto-char 1)
  (pixel-scroll-precision-mode)
  nil)

produces an image that can be scrolled. Inserting a newline after the
text covered by the text property holding the image also fixes the
problem in 'image-mode' but that doesn't seem like the right fix to me.

Rahguzar


In GNU Emacs 29.1 (build 1, x86_64-suse-linux-gnu, GTK+ Version 3.24.38,
 cairo version 1.17.8) of 2023-08-07 built on lamb11
System Description: openSUSE Tumbleweed

Configured using:
 'configure --host=x86_64-suse-linux-gnu --build=x86_64-suse-linux-gnu
 --program-prefix= --disable-dependency-tracking --prefix=/usr
 --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin
 --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include
 --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var
 --sharedstatedir=/var/lib --mandir=/usr/share/man
 --infodir=/usr/share/info --with-pgtk --with-native-compilation=aot
 --with-cairo --with-libotf --with-jpeg --with-tiff --with-gif
 --with-png --with-rsvg --with-xft --with-xml2 --with-dbus --with-sound
 --with-json --with-mailutils --with-gnutls --with-tree-sitter
 --enable-locallisppath=/usr/share/emacs/29.1/site-lisp:/usr/share/emacs/site-lisp
 'CFLAGS=-O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3
 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables
 -fstack-clash-protection -Werror=return-type -flto=auto'
 LDFLAGS=-Wl,-O2'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY
PDUMPER PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER XIM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: mu4e:main

Minor modes in effect:
  recentf-mode: t
  save-place-mode: t
  global-so-long-mode: t
  projectile-mode: t
  which-key-mode: t
  savehist-mode: t
  better-jumper-mode: t
  better-jumper-local-mode: t
  global-company-mode: t
  company-mode: t
  vertico-mode: t
  all-the-icons-completion-mode: t
  marginalia-mode: t
  evil-goggles-mode: t
  evil-escape-mode: t
  evil-snipe-override-mode: t
  evil-snipe-mode: t
  gcmh-mode: t
  winner-mode: t
  smartparens-global-mode: t
  ws-butler-global-mode: t
  undo-fu-session-global-mode: t
  undo-fu-mode: t
  satchel-mode: t
  mu4e-search-minor-mode: t
  global-hl-line-mode: t
  hl-line-mode: t
  mu4e-update-minor-mode: t
  mu4e-context-minor-mode: t
  dirvish-override-dired-mode: t
  server-mode: t
  pixel-scroll-precision-mode: t
  repeat-mode: t
  evil-mode: t
  evil-local-mode: t
  windmove-mode: t
  +popup-mode: t
  +modeline-global-mode: t
  +modeline-mode: t
  override-global-mode: t
  general-override-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  window-divider-mode: t
  buffer-read-only: t
  size-indication-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  abbrev-mode: t

Load-path shadows:
/home/azeem/.emacs.d/.local/straight/build-29.1/emacsql/emacsql-sqlite-builtin hides /home/azeem/.emacs.d/.local/straight/build-29.1/emacsql-sqlite-builtin/emacsql-sqlite-builtin
/home/azeem/.emacs.d/.local/straight/build-29.1/citar-embark/citar-embark hides /home/azeem/.emacs.d/.local/straight/build-29.1/citar/citar-embark
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-view hides /usr/share/emacs/site-lisp/mu4e/mu4e-view
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-search hides /usr/share/emacs/site-lisp/mu4e/mu4e-search
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-org hides /usr/share/emacs/site-lisp/mu4e/mu4e-org
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-config hides /usr/share/emacs/site-lisp/mu4e/mu4e-config
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-message hides /usr/share/emacs/site-lisp/mu4e/mu4e-message
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-icalendar hides /usr/share/emacs/site-lisp/mu4e/mu4e-icalendar
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-query-items hides /usr/share/emacs/site-lisp/mu4e/mu4e-query-items
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-notification hides /usr/share/emacs/site-lisp/mu4e/mu4e-notification
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-window hides /usr/share/emacs/site-lisp/mu4e/mu4e-window
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-modeline hides /usr/share/emacs/site-lisp/mu4e/mu4e-modeline
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e hides /usr/share/emacs/site-lisp/mu4e/mu4e
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-vars hides /usr/share/emacs/site-lisp/mu4e/mu4e-vars
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-update hides /usr/share/emacs/site-lisp/mu4e/mu4e-update
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-server hides /usr/share/emacs/site-lisp/mu4e/mu4e-server
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-obsolete hides /usr/share/emacs/site-lisp/mu4e/mu4e-obsolete
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-mark hides /usr/share/emacs/site-lisp/mu4e/mu4e-mark
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-main hides /usr/share/emacs/site-lisp/mu4e/mu4e-main
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-helpers hides /usr/share/emacs/site-lisp/mu4e/mu4e-helpers
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-headers hides /usr/share/emacs/site-lisp/mu4e/mu4e-headers
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-folders hides /usr/share/emacs/site-lisp/mu4e/mu4e-folders
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-draft hides /usr/share/emacs/site-lisp/mu4e/mu4e-draft
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-contrib hides /usr/share/emacs/site-lisp/mu4e/mu4e-contrib
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-context hides /usr/share/emacs/site-lisp/mu4e/mu4e-context
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-compose hides /usr/share/emacs/site-lisp/mu4e/mu4e-compose
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-bookmarks hides /usr/share/emacs/site-lisp/mu4e/mu4e-bookmarks
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-actions hides /usr/share/emacs/site-lisp/mu4e/mu4e-actions
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-speedbar hides /usr/share/emacs/site-lisp/mu4e/mu4e-speedbar
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-lists hides /usr/share/emacs/site-lisp/mu4e/mu4e-lists
/home/azeem/.emacs.d/.local/straight/build-29.1/mu4e/mu4e-contacts hides /usr/share/emacs/site-lisp/mu4e/mu4e-contacts

Features:
(shadow whitespace display-line-numbers adaptive-wrap jit-spell ispell
face-remap recentf tree-widget saveplace evil-collection-so-long so-long
emacsbug cursor-sensor vertico-repeat link-hint ffap goto-addr avy
shr-color jka-compr auto-minor-mode mm-archive sort smiley gnus-cite
mail-extr qp textsec uni-scripts idna-mapping ucs-normalize
uni-confusable textsec-check gnus-async gnus-bcklg gnus-ml disp-table
nndraft nnmh nnfolder epa-file network-stream nsm gnus-agent gnus-srvr
gnus-score score-mode nnvirtual gnus-msg nntp gnus-cache projectile
lisp-mnt evil-collection-grep grep hide-mode-line
evil-collection-which-key which-key savehist better-jumper company-capf
company evil-collection-vertico vertico orderless
all-the-icons-completion marginalia compat evil-goggles pulse color
evil-easymotion evil-escape evil-snipe gcmh winner smartparens-config
smartparens-text smartparens dash ws-butler undo-fu-session undo-fu
satchel ibuf-ext evil-collection-ibuffer ibuffer ibuffer-loaddefs
desktop frameset mu4e mu4e-org evil-collection-org smartparens-org org
ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-src ob-comint
org-pcomplete pcomplete org-list org-footnote org-faces org-entities
noutline outline ob-emacs-lisp ob-core ob-eval org-cycle org-table ol
org-fold org-fold-core org-keys oc-natbib oc-csl bibtex oc-biblatex oc
org-loaddefs find-func org-version org-compat org-macs mu4e-notification
notifications mu4e-main mu4e-view gnus-art mm-uu mml2015 mm-view
mml-smime smime gnutls dig gnus-sum gnus-group gnus-undo gnus-start
gnus-dbus dbus autorevert filenotify gnus-cloud nnimap nnmail
mail-source utf7 nnoo parse-time iso8601 gnus-spec gnus-int gnus-range
gnus-win evil-collection-gnus gnus nnheader range
evil-collection-calendar cal-menu calendar cal-loaddefs mu4e-headers
mu4e-compose mu4e-draft mu4e-actions smtpmail mu4e-search mu4e-lists
mu4e-bookmarks mu4e-mark mu4e-message shr pixel-fill kinsoku url-file
svg xml dom browse-url url url-proxy url-privacy url-expand url-methods
url-history url-cookie generate-lisp-file url-domsuf url-util url-parse
auth-source json map url-vars flow-fill mule-util hl-line mu4e-contacts
mu4e-update mu4e-folders mu4e-context mu4e-query-items mu4e-server
mu4e-modeline mu4e-vars mu4e-helpers mu4e-config mu4e-window
evil-collection-bookmark bookmark ido message sendmail mailcap
yank-media puny dirvish transient format-spec eieio eieio-core
evil-collection-dired dired dired-loaddefs rfc822 mml mml-sec
password-cache evil-collection-epa epa epg rfc6068 epg-config gnus-util
time-date mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047
rfc2045 mm-util ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils
mailheader mu4e-obsolete server dtrt-indent ef-spring-theme ef-themes
pixel-scroll cua-base repeat midnight html2text let-alist
evil-collection-flymake flymake-proc flymake project
evil-collection-compile evil-collection-custom cus-edit cus-load
wid-edit evil-collection-comint evil-collection annalist compile
text-property-search comint ansi-osc ansi-color ibuf-macs evil
evil-integration evil-maps evil-commands reveal evil-jumps
evil-command-window evil-search evil-types evil-macros evil-repeat
evil-states evil-core byte-opt advice evil-common windmove calc
calc-loaddefs calc-macs thingatpt rect evil-digraphs evil-vars ring
all-the-icons all-the-icons-faces data-material data-weathericons
data-octicons data-fileicons data-faicons data-alltheicons derived
edmacro kmacro use-package-bind-key bind-key comp comp-cstr warnings
icons rx doom-editor doom-projects doom-ui easy-mmode doom-keybinds pp
cl-extra help-mode use-package-core bytecomp byte-compile general
tex-site doom-start doom-modules cl-seq doom doom-lib cl-macs
cl-loaddefs cl-lib pcase gv harfbuzz jansson dynamic-modules subr-x rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type mwheel term/pgtk-win pgtk-win term/common-win
pgtk-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list
replace newcomment text-mode lisp-mode prog-mode register page tab-bar
menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse
jit-lock font-lock syntax font-core term/tty-colors frame minibuffer
nadvice seq simple cl-generic indonesian philippine cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop
case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify dynamic-setting system-font-setting
font-render-setting cairo gtk pgtk multi-tty make-network-process
native-compile emacs)

Memory information:
((conses 16 838555 316547)
 (symbols 48 42792 15)
 (strings 32 169060 12011)
 (string-bytes 1 5569967)
 (vectors 16 93707)
 (vector-slots 8 1658949 153955)
 (floats 8 1309 1539)
 (intervals 56 17242 89)
 (buffers 984 18))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Fri, 11 Aug 2023 03:39:02 GMT) Full text and rfc822 format available.

Message #8 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Rahguzar <rahguzar <at> zohomail.eu>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Fri, 11 Aug 2023 11:38:28 +0800
Rahguzar <rahguzar <at> zohomail.eu> writes:

> Dear Emacs developers,
>
> To reproduce starting from 'emacs -Q' visit an image file. Then
> repeatedly use 'i +' till the image is taller than the window. The
> image can be scrolled using mouse wheel. Now do
>
> M-x pixel-scroll-precision-mode
>
> After this attempting to scroll the image will set the vscroll to 0
> and then image can't be scrolled at all.
>
>>From some investigation it seems like this behavior is not specific
> to image-mode. Another way to reproduce the behavior is to evaluate
> the following lisp code,
>
> (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)
>
> This image thus displayed can not be scrolled. However if the code
> above is slightly modified to insert a new line after the image,
> scrolling can be done normally, i.e.
>
> (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))
>   (insert "\n")
>   (goto-char 1)
>   (pixel-scroll-precision-mode)
>   nil)
>
> produces an image that can be scrolled. Inserting a newline after the
> text covered by the text property holding the image also fixes the
> problem in 'image-mode' but that doesn't seem like the right fix to me.
>
> Rahguzar

This is a known limitation of pixel-scroll-precision-mode: redisplay's
automatic recentering impededs adjustment of the vscroll as the image
moves outside of the window's text area.  Unfortunately, it's not slated
to be fixed any time soon.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Fri, 11 Aug 2023 14:30:02 GMT) Full text and rfc822 format available.

Message #11 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Fri, 11 Aug 2023 15:19:53 +0200
Hi Po,
In this case it is not the recentering which is causing this problem,
it is rather the binding for next-pos in
pixel-scroll-precision-scroll-down-page which is the issue. The
binding signals an error when downward vertical motion is not
possible. However in this scenario scrolling can still be done.
Replacing that binding with desired-start allow me to scroll the
images.

This change for example allows for scrolling tall images,
@@ -524,10 +524,12 @@ pixel-scroll-precision-scroll-down-page
          (next-pos (save-excursion
                      (goto-char desired-start)
                      (when (zerop (vertical-motion (1+ scroll-margin)))
-                       (set-window-start nil desired-start)
-                       (signal 'end-of-buffer nil))
+                       (unless (let ((remaining-bottom (nth 3 (pos-visible-in-window-p desired-start nil t))))
+                                 (and remaining-bottom (not (zerop remaining-bottom))))
+                         (signal 'end-of-buffer nil)))
                      (while (when-let ((posn (posn-at-point)))
-                              (< (cdr (posn-x-y posn)) delta))
+                              (and (< (point) (point-min))
+                                   (< (cdr (posn-x-y posn)) delta)))
                        (when (zerop (vertical-motion 1))
                          (set-window-start nil desired-start)
                          (signal 'end-of-buffer nil)))

I am not sure it is the correct change since I don't understand the
while loop but comparing 'point' and 'point-min' doesn't seem the write
thing there. On the others hand if there is 'point-min' is 1 and
'point-max' 2, (cdr (posn-x-y posn))

Po Lu <luangruo <at> yahoo.com> writes:

> This is a known limitation of pixel-scroll-precision-mode: redisplay's
> automatic recentering impededs adjustment of the vscroll as the image
> moves outside of the window's text area.  Unfortunately, it's not slated
> to be fixed any time soon.

In this case it is not the recentering which is causing this problem,
it is rather the binding for next-pos in
pixel-scroll-precision-scroll-down-page which is the issue. The
binding signals an error when downward vertical motion is not
possible. However in this scenario scrolling can still be done.
Replacing that binding with desired-start allow me to scroll the
images.

This change for example allows for scrolling tall images,
@@ -524,10 +524,12 @@ pixel-scroll-precision-scroll-down-page
          (next-pos (save-excursion
                      (goto-char desired-start)
                      (when (zerop (vertical-motion (1+ scroll-margin)))
-                       (set-window-start nil desired-start)
-                       (signal 'end-of-buffer nil))
+                       (unless (let ((remaining-bottom (nth 3 (pos-visible-in-window-p desired-start nil t))))
+                                 (and remaining-bottom (not (zerop remaining-bottom))))
+                         (signal 'end-of-buffer nil)))
                      (while (when-let ((posn (posn-at-point)))
-                              (< (cdr (posn-x-y posn)) delta))
+                              (and (< (point) (point-min))
+                                   (< (cdr (posn-x-y posn)) delta)))
                        (when (zerop (vertical-motion 1))
                          (set-window-start nil desired-start)
                          (signal 'end-of-buffer nil)))

I am not sure it is the correct change since I don't understand the
while loop but comparing 'point' and 'point-min' doesn't seem the write
thing there. On the others hand if there is 'point-min' is 1 and
'point-max' 2, (cdr (posn-x-y posn)) is always zero, so that check makes
the loop terminate without signaling an error.

The behavior is also sub optimal in that it allows for scrolling past
the lower edge of the image but how much depends on the speed of the
scrolling, but that can be fixed easily.

Rahguzar




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Fri, 11 Aug 2023 14:41:01 GMT) Full text and rfc822 format available.

Message #14 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Rahguzar <rahguzar <at> zohomail.eu>
Cc: Po Lu <luangruo <at> yahoo.com>, 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Fri, 11 Aug 2023 16:39:22 +0200
The diff in my last message was not correct, sorry about that. It should
be

@@ -524,12 +524,15 @@ pixel-scroll-precision-scroll-down-page
          (next-pos (save-excursion
                      (goto-char desired-start)
                      (when (zerop (vertical-motion (1+ scroll-margin)))
-                       (set-window-start nil desired-start)
-                       (signal 'end-of-buffer nil))
+                       (unless (let ((remaining-bottom (nth 3 (pos-visible-in-window-p desired-start nil t))))
+                                 (and remaining-bottom (not (zerop remaining-bottom))))
+                         (set-window-start nil desired-start t)
+                         (signal 'end-of-buffer nil)))
                      (while (when-let ((posn (posn-at-point)))
-                              (< (cdr (posn-x-y posn)) delta))
+                              (and (< (point) (point-min))
+                                   (< (cdr (posn-x-y posn)) delta)))
                        (when (zerop (vertical-motion 1))
-                         (set-window-start nil desired-start)
+                         (set-window-start nil desired-start t)
                          (signal 'end-of-buffer nil)))
                      (point)))
          (scroll-preserve-screen-position nil)

Rahguzar <rahguzar <at> zohomail.eu> writes:

> Hi Po,
> In this case it is not the recentering which is causing this problem,
> it is rather the binding for next-pos in
> pixel-scroll-precision-scroll-down-page which is the issue. The
> binding signals an error when downward vertical motion is not
> possible. However in this scenario scrolling can still be done.
> Replacing that binding with desired-start allow me to scroll the
> images.
>
> This change for example allows for scrolling tall images,
> @@ -524,10 +524,12 @@ pixel-scroll-precision-scroll-down-page
>           (next-pos (save-excursion
>                       (goto-char desired-start)
>                       (when (zerop (vertical-motion (1+ scroll-margin)))
> -                       (set-window-start nil desired-start)
> -                       (signal 'end-of-buffer nil))
> +                       (unless (let ((remaining-bottom (nth 3 (pos-visible-in-window-p desired-start nil t))))
> +                                 (and remaining-bottom (not (zerop remaining-bottom))))
> +                         (signal 'end-of-buffer nil)))
>                       (while (when-let ((posn (posn-at-point)))
> -                              (< (cdr (posn-x-y posn)) delta))
> +                              (and (< (point) (point-min))
> +                                   (< (cdr (posn-x-y posn)) delta)))
>                         (when (zerop (vertical-motion 1))
>                           (set-window-start nil desired-start)
>                           (signal 'end-of-buffer nil)))
>
> I am not sure it is the correct change since I don't understand the
> while loop but comparing 'point' and 'point-min' doesn't seem the write
> thing there. On the others hand if there is 'point-min' is 1 and
> 'point-max' 2, (cdr (posn-x-y posn))
>
> Po Lu <luangruo <at> yahoo.com> writes:
>
>> This is a known limitation of pixel-scroll-precision-mode: redisplay's
>> automatic recentering impededs adjustment of the vscroll as the image
>> moves outside of the window's text area.  Unfortunately, it's not slated
>> to be fixed any time soon.
>
> In this case it is not the recentering which is causing this problem,
> it is rather the binding for next-pos in
> pixel-scroll-precision-scroll-down-page which is the issue. The
> binding signals an error when downward vertical motion is not
> possible. However in this scenario scrolling can still be done.
> Replacing that binding with desired-start allow me to scroll the
> images.
>
> This change for example allows for scrolling tall images,
> @@ -524,10 +524,12 @@ pixel-scroll-precision-scroll-down-page
>           (next-pos (save-excursion
>                       (goto-char desired-start)
>                       (when (zerop (vertical-motion (1+ scroll-margin)))
> -                       (set-window-start nil desired-start)
> -                       (signal 'end-of-buffer nil))
> +                       (unless (let ((remaining-bottom (nth 3 (pos-visible-in-window-p desired-start nil t))))
> +                                 (and remaining-bottom (not (zerop remaining-bottom))))
> +                         (signal 'end-of-buffer nil)))
>                       (while (when-let ((posn (posn-at-point)))
> -                              (< (cdr (posn-x-y posn)) delta))
> +                              (and (< (point) (point-min))
> +                                   (< (cdr (posn-x-y posn)) delta)))
>                         (when (zerop (vertical-motion 1))
>                           (set-window-start nil desired-start)
>                           (signal 'end-of-buffer nil)))
>
> I am not sure it is the correct change since I don't understand the
> while loop but comparing 'point' and 'point-min' doesn't seem the write
> thing there. On the others hand if there is 'point-min' is 1 and
> 'point-max' 2, (cdr (posn-x-y posn)) is always zero, so that check makes
> the loop terminate without signaling an error.
>
> The behavior is also sub optimal in that it allows for scrolling past
> the lower edge of the image but how much depends on the speed of the
> scrolling, but that can be fixed easily.
>
> Rahguzar




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sat, 12 Aug 2023 02:23:02 GMT) Full text and rfc822 format available.

Message #17 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Rahguzar <rahguzar <at> zohomail.eu>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sat, 12 Aug 2023 10:22:39 +0800
Rahguzar <rahguzar <at> zohomail.eu> writes:

>    (set-window-start nil desired-start)
> -                     

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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sat, 12 Aug 2023 06:57:02 GMT) Full text and rfc822 format available.

Message #20 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sat, 12 Aug 2023 08:50:12 +0200
Hi Po,

Po Lu <luangruo <at> yahoo.com> 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.

Rahguzar




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sat, 12 Aug 2023 07:26:02 GMT) Full text and rfc822 format available.

Message #23 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Rahguzar <rahguzar <at> zohomail.eu>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sat, 12 Aug 2023 15:25:00 +0800
Rahguzar <rahguzar <at> zohomail.eu> writes:

> Hi Po,
>
> Po Lu <luangruo <at> yahoo.com> 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))))))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sat, 12 Aug 2023 10:50:02 GMT) Full text and rfc822 format available.

Message #26 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sat, 12 Aug 2023 12:43:58 +0200
Hi Po,

Po Lu <luangruo <at> yahoo.com> writes:

> Rahguzar <rahguzar <at> zohomail.eu> writes:
>
>> Hi Po,
>>
>> Po Lu <luangruo <at> yahoo.com> 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))))))))


That is much better. Thank you!

I think even better would be to replace the

(set-window-vscroll nil 0)

with

(set-window-vscroll nil current-vs t t)

but that doesn't seem to work and the entire line scrolls out of view
which I agree is undesirable. I don't understand why it doesn't work.
Can you please explain why if possible?

Rahguzar




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sun, 27 Aug 2023 07:56:02 GMT) Full text and rfc822 format available.

Message #29 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sun, 27 Aug 2023 09:53:16 +0200
Hi Po,

Po Lu <luangruo <at> yahoo.com> writes:

> Rahguzar <rahguzar <at> zohomail.eu> writes:
>
>> Hi Po,
>>
>> Po Lu <luangruo <at> yahoo.com> 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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sun, 27 Aug 2023 08:17:02 GMT) Full text and rfc822 format available.

Message #32 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Rahguzar <rahguzar <at> zohomail.eu>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sun, 27 Aug 2023 16:16:06 +0800
Rahguzar <rahguzar <at> zohomail.eu> writes:

> 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.

Alas no, by reason of our policy against risky behavioral changes to the
release branch.

I have asked several other users of p-s-p-m to comment on this offline,
but am still waiting for responses from some of them.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#65214; Package emacs. (Sun, 27 Aug 2023 09:08:01 GMT) Full text and rfc822 format available.

Message #35 received at 65214 <at> debbugs.gnu.org (full text, mbox):

From: Rahguzar <rahguzar <at> zohomail.eu>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 65214 <at> debbugs.gnu.org
Subject: Re: bug#65214: 29.1; Tall images in 'image-mode' can't be scrolled
 with 'pixel-scroll-precision-mode' on
Date: Sun, 27 Aug 2023 10:53:20 +0200
Hi Po,

Po Lu <luangruo <at> yahoo.com> writes:

> Rahguzar <rahguzar <at> zohomail.eu> writes:
>
>> 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.
>
> Alas no, by reason of our policy against risky behavioral changes to the
> release branch.
>
> I have asked several other users of p-s-p-m to comment on this offline,
> but am still waiting for responses from some of them.

Makes sense, since the problem is in an edge case. Since it affects,
'image-mode' which is built in and also some modes which rely on the
functionality provided 'image-mode' is it possible to go with one of the
following workarounds:

1) Special case the handling of buffers with only one line. I don't know
if this can be made safe enough.

2) Modify the 'image-mode' to have a newline after the image. It seems
like a good enough solutions to me: as far as I can tell 'image-mode'
commands just care about the fact that point-min has the display
property holding the image. But most likely there are unintended
consequences I am not thinking of.

3) Have an easy way of disable 'pixel-scroll-precision-mode' buffer
locally. This can then be used by 'image-mode' and others modes. This
might be the best solution since 'image-mode' has sets its own
'mwheel-scroll-up/down-function' to keep track of 'vscroll' and
reapplies it when needed. As far as I can tell this bookkeeping can't be
done with 'pixel-scroll-precision-mode'. I think a non-default value for
'mwheel-scroll-up/down-function' is a good heuristic for when not to
enable 'pixel-scroll-precision-mode' in a buffer but that might also be
too broad a measure.

Or maybe some other way I am not thinking of.

Best,
Rahguzar




This bug report was last modified 251 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.