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

From: Eli Zaretskii <[email-masked]>
Date: Thu, 13 Jul 2023 16:34:44 +0300

> From: Ihor Radchenko <[email-masked]>
> Date: Thu, 13 Jul 2023 13:00:26 +0000
> 
> `force-mode-line-update' has the following FIXME:
> 
>   if (!NILP (all))
>     {
>       update_mode_lines = 10;
>       /* FIXME: This can't be right.  */
>       current_buffer->prevent_redisplay_optimizations_p = true;
>     }
>   else if (buffer_window_count (current_buffer))
>     {
>       bset_update_mode_line (current_buffer);
>       current_buffer->prevent_redisplay_optimizations_p = true;
>     }
> 
> This FIXME has been introduced in 655ab9a3800, shortly after
> ecda65d4f7e, which moved this code from `set-buffer-modified-p'.

Yes, it was part of Stefan's effort to make redisplay less expensive
by avoiding too thorough redisplay in as many use cases as possible.

> AFAIU, the purpose of disabling redisplay optimizations is avoiding the
> situation when the modification flag is unset in the buffer, but the
> buffer was actually modified, and has to be redrawn.

No, it's more subtle.  In a nutshell, it is meant to prevent redisplay
from applying certain optimizations (search xdisp.c for the uses of
this flag).  These optimizations are based on various assumptions,
such as that the current glyph matrix of the window is up-to-date.
Setting the prevent_redisplay_optimizations_p flag tells the display
engine that those assumptions are (or might be) false.

Updating the mode line usually requires more thorough redisplay,
especially when the only reason for that is that some Lisp called
force-mode-line-update -- without setting that flag, the display
engine could easily decide that the window doesn't need to be redrawn.

> If my understanding is correct,
> current_buffer->prevent_redisplay_optimizations_p = true does not belong
> to `force-mode-line-update', but rather to `restore-buffer-modified-p'.

The purpose of force-mode-line-update is to do what its name says,
regardless of whether the buffer was modified or not, and how it was
modified.  The idea is that Lisp programs which change something that
they know must affect the mode line call this function to make sure
the mode line is redrawn with up-to-date information.  By contrast,
buffer modifications could be such that don't affect redisplay at all,
or allow redisplay to use some shortcuts and redraw only a very small
portion of the window.

> I also grepped through src/display.c looking at the usage of
> update_mode_lines, and there seems to be no obvious situation where
> update_mode_lines being non-nil is ignored.

Stefan will tell, but I'm quite sure he wrote that FIXME because
removing that line caused regression in some situation.  I see that
this flag is tested without also testing update_mode_lines in
window-lines-pixel-dimensions, window-line-height, window-end,
redisplay_window, try_window_id, and display_line.  So I don't think I
agree with your conclusion.