Subject: bug#34138: 27.0.50; Delayed display of PDF file images

From: martin rudalics <[email-masked]>
Date: Wed, 23 Jan 2019 19:27:24 +0100

> Now, image-mode works by changing an overlay.  Changes in overlays are
 > examined by the display engine, and windows displaying buffers where
 > overlays have been changed have the corresponding portions redrawn.
 > Windows that don't have any overlay changes and whose buffer text
 > didn't change are skipped by redisplay, on the assumption that nothing
 > has changed in them that requires displaying some of its part anew.
 > And since run_window_configuration_change_hook is called only _after_
 > the display engine already examined the windows, it cannot trigger
 > redisplay of the window where we show the image of the PDF document.
 > Thus, the image is shown only upon next more or less thorough
 > redisplay, which redraws the window in question.

So emacs 26 has

- make a new window
- in the ensuing configuration change hook make the overlay
- redisplay picks up the overlay immediately.

While emacs 27 has

- make a new window
- redisplay sees no overlay
- in the ensuing configuration change hook make the overlay
- a next through redisplay will pick up the overlay.

Now doc-view-mode has

     (add-hook 'image-mode-new-window-functions
	      'doc-view-new-window-function nil t)
     (image-mode-setup-winprops)

and pdf-view.el has

   ;; Keep track of display info
   (add-hook 'image-mode-new-window-functions
             'pdf-view-new-window-function nil t)
   (image-mode-setup-winprops)

where 'image-mode-setup-winprops' does

   (add-hook 'window-configuration-change-hook
	    #'image-mode-reapply-winprops nil t))

Strictly spoken, all of these abuse the concept of hooks.  Making a
new window, putting an overlay there, setting some properties are
deterministic actions.  Why do we have to do them from the hook?
Basically, hooks are needed when some other agent does a change in a
non-deterministic (from the POV of the person that puts the function
on the hook) way.

 > Therefore, a question to Martin: why was the call to
 > run_window_change_functions put at the very end of redisplay_internal?
 > Is this intentional, and if so, what were the reasons for that?

We early discussed this (with the initial text by Stefan) as

 > >  > If it's run "at the end of redisplay", then I think it's too late: those
 > >  > hooks will often want to change something visual, and they will want it
 > >  > to appear right away, so it should be run just *before* redisplay.
 > >
 > > Note that 'window-size-change-functions' are currently already run
 > > right in the middle of redisplay.  Often, window sizes are correct
 > > only *after* redisplay.  Think of minibuffer window resizing or
 > > changes in the fringes, margins or modeline sub-structures.  But a
 > > final word on the location of the call will have to be told by Eli.
 >
 > I don't think I can utter that final word, primarily because I don't
 > understand Stefan's concerns.

Running the hooks at late as possible will catch most size changes
(calculating the mode line height or minibuffer heights) done by
redisplay so you have the final layout of a frame available when
running the hooks.  But maybe that's just needless perfectionism.

Also, I'm still not sure whether running hooks earlier will handle
'pdf-view-new-window-function' and 'image-mode-reapply-winprops'
running the deterministic emacs 26 way.  After all, the idea seems to
be

(1) Make the window.

(2) Run 'image-mode-reapply-winprops'.

(3) Run 'pdf-view-new-window-function'.

(4) Continue with overlays and properties set up.

(5) Redisplay, eventually.

If anything in (4) needs anything done in (2) and (3), running the
hooks earlier in redisplay won't help.

Note: We can always restore the emacs 26 (better emacs 25) way
'window-configuration-change-hook' is run.  That won't affect the
remaining hooks and prevent scenarios as the one found here.

martin