Subject: Re: bug#64252: 29.0.91; pixel-scroll-precision-mode scrolling jumps with large images

From: Po Lu <[email-masked]>
Date: Sat, 24 Jun 2023 09:29:06 +0800

Rahguzar <[email-masked]> writes:

> Dear Emacs developers,
>
> Starting with `emacs -Q`, paste the following code in scratch buffer
>
> (let* ((win (display-buffer (get-buffer-create "image-pixel-precision-test")))
>        (height (/ (window-text-height win t) 3))
>        (file "path-to-some-image-file"))
>   (select-window win)
>   (erase-buffer)
>   (insert-image (create-image file nil nil :height height))
>   (insert "\n")
>   (insert-image (create-image file nil nil :height (* 2 height)))
>   (insert "\n")
>   (insert-image (create-image file nil nil :height (* 3 height)))
>   (insert "\n")
>   (goto-char 1)
>   (pixel-scroll-precision-mode)
>   nil)
>
> after replacing the binding of variable 'file' with the path to some
> existing image. This should selected a window with three images. The
> first one take up 1/3 of the window and the second one 2/3 of the
> window. The third image is off screen has height equal to the window.
> The point is on the first image. Now try to scroll the image using mouse
> wheel or track pad. When scrolling starts the point moves to 2nd image
> but scrolling works as expected as long some part of the second image is
> in view. However as soon as the first image is out of view, any
> scrolling results in the second image disappearing and window being
> filled with the 3rd image.
>
> As far as I can tell this is not limited to pixel-scroll-precision mode
> and is part of Emacs scrolling behavior, but in
>
> https://lists.gnu.org/archive/html/help-gnu-emacs/2023-06/msg00199.html
>
> Eli said that pixel-scroll-precision-mode can handle this scenario but
> in my testing it cannot. As far as I can tell in Emacs partial scrolling
> works well if there is either 1) a line that is completely visible in
> the window or 2) a line that is bigger than the window. However when
> both of the these conditions are not satisfied it is only possible to
> scroll in line sized jumps. This happens for example when there are two
> images which are individually less tall than the window but their
> combined height is more than the window. My suspicion is that this is
> related to how 'set-window-start' operates and in the scenario outlined
> above it moves the window content to make a whole line visible.
>
> I tried setting 'global-disable-point-adjustment' to see if it helps but
> it doesn't.
>
>
> In GNU Emacs 29.0.91 (build 1, x86_64-suse-linux-gnu, GTK+ Version
>  3.24.38, cairo version 1.17.8) of 2023-06-20 built on lamb78
> 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.0.91/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
>   global-evil-surround-mode: t
>   evil-surround-mode: t
>   eros-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
>   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.0.91/emacsql/emacsql-sqlite-builtin hides /home/azeem/.emacs.d/.local/straight/build-29.0.91/emacsql-sqlite-builtin/emacsql-sqlite-builtin
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/citar-embark/citar-embark hides /home/azeem/.emacs.d/.local/straight/build-29.0.91/citar/citar-embark
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-view hides /usr/share/emacs/site-lisp/mu4e/mu4e-view
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-search hides /usr/share/emacs/site-lisp/mu4e/mu4e-search
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-query-items hides /usr/share/emacs/site-lisp/mu4e/mu4e-query-items
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-org hides /usr/share/emacs/site-lisp/mu4e/mu4e-org
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-notification hides /usr/share/emacs/site-lisp/mu4e/mu4e-notification
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-icalendar hides /usr/share/emacs/site-lisp/mu4e/mu4e-icalendar
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-config hides /usr/share/emacs/site-lisp/mu4e/mu4e-config
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-window hides /usr/share/emacs/site-lisp/mu4e/mu4e-window
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-modeline hides /usr/share/emacs/site-lisp/mu4e/mu4e-modeline
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e hides /usr/share/emacs/site-lisp/mu4e/mu4e
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-vars hides /usr/share/emacs/site-lisp/mu4e/mu4e-vars
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-update hides /usr/share/emacs/site-lisp/mu4e/mu4e-update
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-server hides /usr/share/emacs/site-lisp/mu4e/mu4e-server
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-obsolete hides /usr/share/emacs/site-lisp/mu4e/mu4e-obsolete
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-message hides /usr/share/emacs/site-lisp/mu4e/mu4e-message
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-mark hides /usr/share/emacs/site-lisp/mu4e/mu4e-mark
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-main hides /usr/share/emacs/site-lisp/mu4e/mu4e-main
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-helpers hides /usr/share/emacs/site-lisp/mu4e/mu4e-helpers
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-headers hides /usr/share/emacs/site-lisp/mu4e/mu4e-headers
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-folders hides /usr/share/emacs/site-lisp/mu4e/mu4e-folders
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-draft hides /usr/share/emacs/site-lisp/mu4e/mu4e-draft
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-contrib hides /usr/share/emacs/site-lisp/mu4e/mu4e-contrib
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-context hides /usr/share/emacs/site-lisp/mu4e/mu4e-context
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-compose hides /usr/share/emacs/site-lisp/mu4e/mu4e-compose
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-bookmarks hides /usr/share/emacs/site-lisp/mu4e/mu4e-bookmarks
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-actions hides /usr/share/emacs/site-lisp/mu4e/mu4e-actions
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-speedbar hides /usr/share/emacs/site-lisp/mu4e/mu4e-speedbar
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-lists hides /usr/share/emacs/site-lisp/mu4e/mu4e-lists
> /home/azeem/.emacs.d/.local/straight/build-29.0.91/mu4e/mu4e-contacts hides /usr/share/emacs/site-lisp/mu4e/mu4e-contacts
>
> Features:
> (shadow emacsbug evil-collection-xref xref company-ispell
> company-yasnippet company-dabbrev delsel jka-compr whitespace
> adaptive-wrap face-remap recentf tree-widget saveplace
> evil-collection-so-long so-long evil-collection-helpful helpful cc-langs
> cc-vars cc-defs evil-collection-imenu imenu trace evil-collection-edebug
> edebug evil-collection-debug debug backtrace info-look
> evil-collection-info info f f-shortdoc help-fns radix-tree
> evil-collection-elisp-refs elisp-refs s vertico-directory hide-mode-line
> org-crypt evil-embrace evil-surround eros highlight-quoted
> rainbow-delimiters highlight-numbers parent-mode hl-todo
> evil-collection-elisp-mode elisp-mode org-eldoc embrace expand-region
> text-mode-expansions the-org-mode-expansions er-basic-expansions
> expand-region-core expand-region-custom cdlatex texmathp toc-org
> evil-org display-line-numbers jit-spell ispell org-indent org-element
> org-persist xdg org-id org-refile avl-tree generator ol-bibtex
> gnus-async gnus-bcklg gnus-ml disp-table auto-minor-mode link-hint ffap
> goto-addr avy sort gnus-cite smiley shr-color mm-archive mail-extr
> textsec uni-scripts idna-mapping ucs-normalize uni-confusable
> textsec-check qp projectile lisp-mnt evil-collection-grep grep nndraft
> nnmh nnfolder cursor-sensor vertico-repeat epa-file network-stream nsm
> gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg nntp
> gnus-cache 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 autorevert filenotify 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 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 repeat midnight 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 html2text let-alist 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 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 1112649 163180)
>  (symbols 48 47706 27)
>  (strings 32 197743 25767)
>  (string-bytes 1 7031793)
>  (vectors 16 120738)
>  (vector-slots 8 2076120 174082)
>  (floats 8 1459 2514)
>  (intervals 56 75919 1751)
>  (buffers 984 23))

If an image is larger than the window, pixel-scroll-precision-mode is
unable to determine a position of point that will not cause redisplay to
recenter the window after scrolling takes place.

There is definitely a solution to this problem, but I haven't found it
yet.  Patches welcome.

Thanks.