Conversation
`pdf-roll-scroll-forward' and `pdf-roll-scroll-backward' record where they arrive in `pdf-view-current-page' and leave `window-start' to `pdf-roll-pre-redisplay', which runs once per redisplay. Both then read `window-start' to find where they are starting from, so the second scroll of a command starts from the page the first one started on. A scroll that stays inside one page still lands correctly, because it works from the vscroll, which the previous scroll did set. A scroll that crosses a page boundary does not: the vscroll then measures a position near the bottom of the page the previous scroll moved to, and the next scroll applies that number to the page before it. So holding `pdf-view-previous-line-or-previous-page' moves up to the top of a page, crosses into the previous one, and then moves back down to near the bottom of the page it started on. Page one is never reached. Take the starting position from `pdf-view-current-page', which is what the next redisplay will make `window-start', and take the pixels already scrolled past from `window-vscroll' rather than from `pos-visible-in-window-p', which measures against `window-start' as well. Also stop at the top of page one. The backward walk stored the leftover pixels as a negative vscroll; `set-window-vscroll' clamps that to zero, but `image-mode-window-put' keeps the negative number.
This was referenced Aug 27, 2026
This was referenced Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What happens
With
pdf-view-roll-minor-modeon, a command that scrolls more than once per invocation cannot reach page one.pdf-view-previous-line-or-previous-pagewith an argument is one, since it runspdf-roll-scroll-backwardin adotimes; so is any key bound to several scrolls.The view moves up to the top of a page, crosses into the previous page, and then moves back down to near the bottom of the page it started on. Pressing the key again repeats that, so the document stays on the same two pages.
A trace from a window on page 4 at vscroll 40, running five backward scrolls of one line in a single command (frame char height 23, page height 2144):
The command was asked for 115 pixels upward and produced about 2000 downward.
pdf-view-next-line-or-next-pagehas the same problem in the other direction.Scrolling with a wheel or a trackpad does not show it, because those deliver one scroll per event with a redisplay in between.
Why
pdf-roll-scroll-forwardandpdf-roll-scroll-backwardrecord the page they reach inpdf-view-current-pageand set the vscroll, but they do not setwindow-start.pdf-roll-pre-redisplaydoes that, frompdf-view-current-page, and it runs once per redisplay. Both functions nevertheless start from(window-start window). Within one command there is no redisplay between the scrolls, so every scroll after the first starts from the page the command began on.A scroll that stays inside one page is unaffected: it works from the vscroll, which the previous scroll did set, and
window-startstill names the right page. A scroll that crosses a page boundary leaves a vscroll belonging to the page it moved to — a large number, because it measures from the top of that page down to near its bottom. The next scroll combines that number with the stalewindow-startand reads it as a position near the bottom of the page the command began on.pdf-roll-scroll-backwardpicks the same stale value up a second time throughpos-visible-in-window-p, whose RTOP is measured againstwindow-start.The fix
pdf-roll-window-startreturnspdf-roll-page-to-posofpdf-view-current-page, which is the position the next redisplay will givewindow-start. Both scroll functions start from it. Inpdf-roll-scroll-backward, the pixels already scrolled past come fromwindow-vscrollinstead ofpos-visible-in-window-p, for the same reason.The same trace after the change:
Separately,
pdf-roll-scroll-backwardended with(pdf-roll-set-vscroll (- n) window), and N is still positive when the walk stops at page one, so it stored a negative vscroll.set-window-vscrollclamps that to zero, butimage-mode-window-putkeeps the negative number andpdf-roll-pre-redisplayandpdf-roll-display-pagesthen pass it on. Now(max 0 (- n)).Tests
One test in
test/pdf-roll-test.el, forpdf-roll-window-start: withpdf-view-current-pageon page 3 andwindow-startstill on page 1, it has to report page 3's position. The scroll functions themselves need a live window and a running server, so they are not covered in batch, in keeping with the note at the top of that file.No new byte-compile warnings.
Relation to #361, #362 and #338
Independent of #361 and #362, and branched off
masterlike both of them. The three change different functions;lisp/pdf-roll.elmerges without a conflict. Onlytest/pdf-roll-test.elconflicts with #362, because both append a section at the end of the file.#338 rewrites both scroll functions and does not fix this: its versions still begin with
(goto-char (window-start window)), so the second scroll of a command still starts from the wrong page. Itspdf-roll-scroll-backwardalso combines thatwindow-startwith(pdf-view-image-size t window)and(window-vscroll nil t), and both of those report on the selected window rather than on WINDOW. It does already contain the(max 0 (- n))clamp, so that part of this change is present there.