Subject: bug#38181: Actual height of mode-line not taken into account

From: martin rudalics <[email-masked]>
Date: Sat, 16 Oct 2021 18:48:41 +0200

> Now, let's define test-popup-no-redisplay as the version of test-popup
 > with the call to redisplay removed, and test-popup-redisplay as the
 > version that calls redisplay before fitting the window to its buffer:
 >
 > (test-popup-no-redisplay) -> cropped content
 > close popup
 > (test-popup-no-redisplay) -> cropped content
 > close popup
 > (test-popup-redisplay) -> ok
 > close popup
 > (test-popup-redisplay) -> ok
 > close popup
 > (test-popup-no-redisplay) -> cropped content
 > close popup
 >
 > As you can see, the redisplay only "fixes" the next fit, after that the
 > problem reappears.

Right.  The "close popup" removes anything redisplay cached for the
window's mode line in the last call of 'test-popup-redisplay'.

 > This may be of interest:
 >
 > (test-popup-no-redisplay) -> cropped content
 > (test-popup-no-redisplay) -> ok
 > (test-popup-no-redisplay) -> ok
 > (test-popup-no-redisplay) -> ok
 >
 > (N.B. I'm not closing the popup) It seems like the window was reused
 > and the second time it got things right.

Right.  It always uses the cached mode line height in this case.

 > My interpretation is that the early redisplay "prepares" the current
 > window for the fit. Now, the workaround that I linked above does a
 > redisplay once per buffer, not once per window.

What is the "workaround"?  IIUC there is no "redisplay" one can call on
a "per buffer" base.

 > The issue I observe,
 > which I believe is the same one that motivated this report in the
 > first place, is an org-set-tags-command menu clipped at the bottom
 > (it's not the only case, though). Since the popup windows that
 > org-mode opens for this and other menus are transient but their
 > buffers likely remain hidden, that may be the reason why the
 > workaround is not, well, working around. What I'm failing to grasp is
 > how could it ever work... maybe there was some change in the
 > implementation of org-mode popups.
 >
 > I would be happy with a sound statement like "if you change the
 > modeline height so it is different to the default char size, you need
 > to call redisplay for each window that sports the modified modeline
 > before executing any operation that requires knowledge of the geometry
 > of that modeline, including fit-window-to-buffer". If that's true then the
 > current trick could be reasonably modified to cope with every possible
 > case instead of hooking to particular functions (fit-window-to-buffer) in
 > maybe the wrong scope (buffer), by just triggering an early redisplay
 > each time a new window is created.

Even the 'redisplay' trick will not be sufficient: Consider Eli's
scenario in this thread but with _different_ heights for active and
inactive mode lines.  It will break things when after doing the
'fit-window-to-buffer' call you (de-)select the window you've just fit.

 > Rereading (some of) the above thread, I noticed you said:
 >
 >> If we don't want 'fit-window-to-buffer' to do that always we'd need
 >> some variable, either buffer local or even a window parameter, that
 >> 'fit-window-to-buffer' would inspect once and reset immediately in
 >> order to perform only the redisplay call that's really needed.
 >
 > I believe this is similar to what I've just suggested. Then a long
 > discussion full of technicalities that I won't be able to follow in
 > depth anytime soon took place. I understand that maybe forcing an
 > early display is not ideal because, in principle, we only want to
 > update the size of the modeline, not prematurely redisplay the window.
 > Moreover, modelines could change after creating a window,
 > but this is not an interesting use case in real life.
 > But since creating a window is not a frequent operation, and
 > changing a modeline on the fly is not a likely event, would it be
 > so bad to trigger that early redisplay on window creation?

I think you mean with every set_window_buffer?  And probably with every
set_window_configuration too.  Did you try it?

 > I'm not saying that emacs should do it, I'm confident that your
 > decision in this regard will be far better than anything I could
 > come up with, I'm just looking for a workaround that gets the job
 > done or, alternatively, the certainty that it's a bad idea and that we
 > should refrain from pretiffing modelines.

Here I have no problems with the scenarios I've seen in this thread
because I update the mode line caches with every change of a window
height (which includes the case where a window is created) and with any
change of a buffer local variable like 'mode-line-format'.  So basically
no redisplay is ever needed in the first place, just a recalculation of
the mode line heights of all windows whose heights have changed.

martin