Skip to content

fix(pdf-roll): forget the displayed pages of every window, not one - #367

Open
alberti42 wants to merge 1 commit into
vedang:masterfrom
alberti42:fix/roll-displayed-pages-all-windows
Open

fix(pdf-roll): forget the displayed pages of every window, not one#367
alberti42 wants to merge 1 commit into
vedang:masterfrom
alberti42:fix/roll-displayed-pages-all-windows

Conversation

@alberti42

Copy link
Copy Markdown

What happens

pdf-roll-initialize and the disable branch of pdf-view-roll-minor-mode both forget which pages a window has displayed like this:

(image-mode-window-put 'displayed-pages nil)

With no window argument that reaches the selected window only. With three windows recorded it leaves two of them untouched:

((t) (window-a 3 4) (window-b 5 6))

Why it matters

The selected window is not necessarily a window showing the buffer. pdf-roll-initialize is an :after advice on revert-buffer-function, and a revert that arrives from a process sentinel or a timer — AUCTeX reverting a recompiled document, auto-revert-mode, a file notification — runs with whatever window happened to be selected at that moment. It is also never the other windows showing the same buffer.

Those windows keep a displayed-pages list naming pages the buffer may no longer hold an overlay for, either because the overlays were replaced or because the new document is shorter than the old one. pdf-roll-pre-redisplay then hands the difference between that list and the pages it just drew to pdf-roll-undisplay-pages, which looks each one up.

The fix

pdf-roll--forget-displayed-pages walks the winprops instead of touching one window. It walks a copy, because image-mode-window-put can add the t entry to image-mode-winprops-alist while the loop is running.

One test in test/pdf-roll-test.el covers it.

Priority

Lower than #361, #362 and #364. It needs the same document in more than one window together with a revert, and #362 guards pdf-roll-undisplay-pages against the consequence, so with that PR applied this is a correctness fix rather than a visible one.

Conflict

Conflicts with #362 in lisp/pdf-roll.el: both change pdf-roll-initialize. Happy to rebase on top of it — the resolution is to call the new helper in place of the single-window image-mode-window-put inside that PR's structure.

`pdf-roll-initialize' and the disable branch of `pdf-view-roll-minor-mode'
clear the `displayed-pages' of a window with

    (image-mode-window-put 'displayed-pages nil)

which reaches the selected window only.  That is not necessarily a window
showing the buffer -- a revert arriving from a process sentinel or a timer
runs with whatever window happened to be selected -- and it is never the
other windows showing it.  Those keep a list naming pages the buffer may
no longer hold an overlay for, either because the overlays were replaced
or because the document is shorter than it was, and
`pdf-roll-undisplay-pages' is then handed a page it cannot find.

With three windows recorded, the old call leaves two of them untouched:

    ((t) (window-a 3 4) (window-b 5 6))

`pdf-roll--forget-displayed-pages' walks the winprops instead.  It walks a
copy, because `image-mode-window-put' can add the `t' entry to the alist.

One test in `test/pdf-roll-test.el'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant