Subject: Re: bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update)

From: martin rudalics <[email-masked]>
Date: Sun, 16 Jul 2023 10:26:04 +0200

> These global variables come from the time when the Emacs redisplay was
 > much less selective.  It basically has only two modes: either
 > redisplay only the selected window, or redisplay all the windows on
 > all the frames.  (Here "redisplay" means "examine for redisplay and
 > decide whether and which parts need that", not necessarily "actually
 > redraw".)  When the various 'redisplay' flags were added, the intent
 > was to make redisplay more selective, so that it could completely
 > refrain from examining windows on a certain frame, for example.  The
 > right way to keep advancing in that direction is to extend these flags
 > and maybe introduce more flags that will describe the need to
 > redisplay in more detail.  Global variables such as update_mode_lines
 > can do that only if they provide specific values to describe each
 > required aspect of redisplay.  But in any case, the code which sets
 > the variable cannot make decisions for redisplay, it can only describe
 > the changes for redisplay to consider.

 From the POV of window management the situation is simple: When the size
of a window or a decoration changes, it would like to tell redisplay
about it.  But redisplay would have to tell it first which kind of
changes it's able to accept.  For example, I don't even know whether,
when running without window matrices, redisplay is capable of doing
something reasonable with the fact that the border between two adjacent
windows shifted and a third window not affected by that shift can be
spared by redisplay.  So from the POV of window management, redisplay
would have to offer a list of such flags it is able to handle and do
something reasonable about.

As an example: one of the worst things the window code does is saving a
window configuration, reading something from the minibuffer and
restoring the window configuration when done.  In nine out of ten cases
the restored configuration will not have changed and redisplay wouldn't
have to do anything.  Now Fset_window_configuration is awful in the
regard that it deletes all windows on the frame regardless of whether
the configuration changed only to "restore" them later (including that
n_leaf_windows allocation hack to find out which glyph matrices can be
safely freed).  While it is fairly easy to fix that, it's by no means
clear what and how to tell redisplay that some window did change in one
of those rare cases where it did.

Try the following simple scenario which currently breaks redisplay:

(let (config)
   (set-frame-parameter nil 'left-fringe 50)
   (y-or-n-p "?")
   (setq config (current-window-configuration))
   (setq left-fringe-width 0)
   (set-window-buffer nil (window-buffer))
   (y-or-n-p "?")
   (set-window-configuration config))

Here 'set-window-configuration' should be able to tell redisplay that it
should redisplay the window but it should be able to tell that iff the
fringe really changed which is fairly easy to find out.  Once it found
out, which kind of flag would it set?

martin