Subject: bug#21333: 25.0.50; window-size-change-functions not called after mini-window resize

From: Eli Zaretskii <[email-masked]>
Date: Mon, 24 Aug 2015 22:03:13 +0300

> Date: Mon, 24 Aug 2015 18:13:29 +0000
> From: Pip Cet <[email-masked]>
> Cc: [email-masked]
> 
> Sorry this is a long email

There's long, and there's long.  I mean, geeez....

>  - Redisplay is so slow that it really doesn't matter that we call an
> extra bit of Lisp code before running it.

I'm not worried by performance aspects of this.  And this hook doesn't
slow down redisplay anyway, because redisplay just sets a flag.

>  - Doing it "my way" is cheap in terms of performance (I benchmarked),
> easy to implement, enables cool but not necessarily useful hacks, but
> requires very slow hook functions to rate-limit themselves in order to
> keep the minibuffer usable.

This is not about performance.  It's about utility and complexity.
Having to program for a system where your hook is called in umpteen
unrelated situations makes your program much more complex and fragile
than it could be if the hook was more accurate.

>  - Doing it your way is even cheaper in terms of performance, not very
> hard to implement, requires those hacks to hook into
> pre-redisplay-functions instead, and has the questionable benefit of
> allowing badly-written non-rate-limiting hook functions to keep the
> minibuffer usable, but still break drag-resizing.

Once again, this is not about performance.

> >> I cannot reproduce the behavior with other windows.
> >
> > See above: at least one other window is resized in this recipe, so the
> > exemption is not about the mini-window itself, it's about any window
> > involved in resizing in this particular scenario.
> 
> I understand what's happening, but wanted to make clear that the
> mini-window involvement is the decisive factor.

No, it's not.  The decisive factor is that the way this is implemented
simply doesn't set the flag in this situation.  IOW, the code to set
it wasn't written.

> > That said, I wonder whether changing the code now to call these
> > functions due to automatic resizing would make sense.  What would be
> > the real-life use cases for using that?
> 
> I am beginning to suspect I'm missing something here. Is there another
> way for windows to find out they're resized?

They are not resized, from my POV.

> For example, I don't see another way to implement dynamic
> fit-image-to-window applications.
> 
> What I would consider a valid use case is to call
> doc-view-fit-page-to-window if the window has been resized (of course,
> a practical implementation would ensure that such automatic resize
> operations would not cause a full re-rendering to happen upon every
> size change, but that's an implementation detail).

How is this different from something else, like a tooltip or a
drop-down menu, temporarily obscuring a portion of the display?

If you want to make the hook scroll the display when the minibuffer is
resized, you will cause annoying jumpy display when some Lisp program
repeatedly displays echo-area messages and clears the echo area -- for
example, consider a Lisp compilation of a large buffer that produces
many warnings.

Moreover, you are worried by the last line of a PDF text, but what
about the first one?  When the window becomes smaller, some part will
have to disappear from display, there's no way around that.  Why
should we care about the last portion more than about the first?

> For something that's less far-fetched, I'm thinking of accessibility
> and automation applications: if you want to point a screen reader to
> the right text to read, you're going to need its X coordinates, which
> might change due to a mini-window resize

But the coordinates of the text that stays on screen don't change in
such a resize.  Some text is obscured, but what's left doesn't move.
So I see no problem here.

> Use cases:
>  1. X hacks. I want to do something with the Emacs X windows and need
> to know their coordinates to do so. EXWM, accessibility, compositing
> WM hacks (transparency, duplicating windows, rendering them
> upside-down, whatever), VNC clipping. Most of those are possible
> without a reliable w-s-c-f hook, but are much easier to implement with
> one.

I'm not sure I understand the use case, but if I do, it's impossible:
you need to have redisplay finish before you can ask Emacs about
coordinates of some point.  So this cannot be done while the
minibuffer is being resized.

>  2. automatic-resize applications. These, strictly speaking, need to
> know only the window size, not its frame-relative position.

Already covered above.  I see no problems here that are specific to
this particular resize.

>  3. things I'm too stupid to think of. I think this is the big one:
> let's leave the feature in and see what smart people come up with.

That's not a use case.

> You appear to be arguing for considering the mini-window a temporary
> overlay that obstructs "real" windows while it exists and goes away
> when it's no longer needed. That's fine, you can have that: create a
> minibuffer-only frame and raise or lower it to your heart's content.
> 
> I'm arguing that the mini-window should be treated like any other
> window.

I'm not special-casing the mini-window here.  I'm special-casing this
particular case of resizing the windows.

> Let's also consider the potential harm done by both options: not
> calling the hook when I think it should be will result in something
> being done to the wrong buffer.

I don't see why it should, not without a more detailed description.

> Calling the hook "too often" will result, well, for most users, in
> twenty lost CPU cycles as a variable is tested and found to be nil.

Once again, this isn't about performance.

> > If you agree, then the current behavior will make sense to you.
> 
> I hope I've made it clear so far that I disagree.

Then I guess we will have to agree to disagree.

> > If anything, IMO we should _reduce_ the number of unrelated events
> > that trigger a call to these functions.  For example, currently any
> > command that reads from the minibuffer will trigger it, because when
> > read-from-minibuffer exits, it restores the window configuration by
> > calling set-window-configuration, which is documented to trigger these
> > functions.  That just doesn't make any sense to me, since most reads
> > from the minibuffer don't resize any windows!
> 
> I believe that's a separate issue.

No, it's not.  It's the same issue: this hook is already called in
situations where it shouldn't have been, and thus imposes on the
programmers who use it complex ways of deciding whether there was or
wasn't a change they should care about.  You suggest to add one more
situation in that class, something that most application that define
this hook shouldn't and don't care.  It's the complexity that worries
me.

> I do not understand why you seem so loath to calling a rarely-used
> hook somewhat more often; I conjecture you might be overestimating the
> cost of checking whether a window's size has actually changed and
> returning if it hasn't. I've attached a test file that uses
> benchmark-run to time a million invocations of the test-and-return
> code, and it takes less than two seconds on this very old machine;
> IOW, to take up 1% of one CPU core, you'd need 5000 resize events per
> second. I can run `redisplay' 20,000 times per second, and that's only
> because those calls return without doing anything. It's cheap.

Once again, this is not about performance.  Never was.  It's about
complexity, IMO gratuitous in this case.  Emacs is already too complex
for this kinds of job due to several hooks that are called
indiscriminately, and leave it to the programmer to figure out whether
some change really happened.

Anyway, it's clear we disagree.  I just wanted to voice my protest
against such creeping featurism.