[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Window change functions

From: Stefan Monnier
Subject: Re: Window change functions
Date: Wed, 26 Dec 2018 14:55:54 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

> The attached patch should radically change the way we run functions
> when window changes occur.  The only hook it does not affect is
> 'window-scroll-functions'.  For the remainder we now would have the
> following four hooks:
> (1) 'window-state-change-functions' runs when a window got a new
>     buffer or was created or deleted since last redisplay.

I'd call it `window-buffer-change-functions` because the notion of
"window-state" includes much more than just whether it's alive and which
buffer it displays.

> (2) 'window-size-change-functions' runs when a window was created or
>     got a new buffer, body or total size since last redisplay.
> (3) 'window-configuration-change-hook' runs as (1) and (2) together.
> (4) 'window-selection-change-functions' run when a window got
>     (de-)selected since last redisplay.

These sound good, thanks.

One question is where they're consulted and run.
E.g. for (4) one window got deselected and another got selected, so
I guess it's run twice and is looked up each time in the corresponding
window's buffer?

For (1) in response to set-window-buffer, will the hook be run in the
buffer before the change or after the change (and in which buffer will
the hook's value be consulted)?

> This means that, for example, running 'save-window-excursion' will
> call such hooks only if a redisplay is embedded within that form.  It
> also means that any code that changes windows internally won't have to
> care about calling `run-window-configuration-change-hook' any more.

That generally sounds like a very good idea for

For 'window-size-change-functions and 'window-state-change-functions
(and hence window-configuration-change-hook), it's sufficiently rare to
change the size (or the window's buffer) of a window and revert it
before the next redisplay that I'm not sure it's beneficial.

Tho, it is clearly normal for a window to change size
several times within a given command (e.g. balance-windows-area does
just that to incrementally settle on a balanced result).

Is this delaying done on-purpose for all hooks individually, or is there
some underlying reason why it's helpful to delay them all?

> - Some functions on 'window-configuration-change-hook' (notably in
>   erc-track.el and rcirc.el) put further code on 'post-command-hook'.
>   This concept will be broken since 'post-command-hook' now runs
>   before 'window-configuration-change-hook'.

This does sound potentially problematic, indeed.  Looking at those two,
I don't see why they postpone the work to post-command-hook, tho.
They use the exact same code, with the exact same comment (erc-track
copied it from rcirc), but neither clearly explains why they do that.
The comment just says:

  (unless (minibuffer-window-active-p (minibuffer-window))
    ;; delay this until command has finished to make sure window is
    ;; actually visible before clearing activity
    (add-hook 'post-command-hook #'erc-modified-channels-update)))

I'm wondering which scenario caused problem.

>   xterm.el has a bit more convoluted code whose purpose I haven't been
>   able to figure out yet.  The solution should be similar though.

I don't see anything there that would suffer from being postponed.

> address@hidden window-state-change-functions
> +This variable specifies functions called at the end of redisplay when
> +window states have changed.  The value should be a list of functions
> +that take one argument

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.

> +Functions specified buffer-locally are called for any window showing
> +the corresponding buffer if that window has been created or assigned
> +that buffer since the last time window change functions were run.  In
> +this case the window is passed as argument.

Hmm... so to detect when a specific buffer stops being displayed you
need to use the global part of the hook and you're not told which was
the previously displayed buffer, so you need to keep track of
that yourself.

>  @defvar window-size-change-functions
> -Each function receives the frame as its sole argument.  To find out
> -whether a specific window has changed size, compare the return values of
> address@hidden and
> address@hidden respectively
> address@hidden and
> address@hidden for that window (@pxref{Window Sizes}).
> +Functions specified buffer-locally are called for any window showing
> +the corresponding buffer if that window has been added or assigned
> +another buffer, total or body size since the last time window change
> +functions were run.  In this case the window is passed as argument.

The new text doesn't mention the window-pixel-height-before-size-change
functions any more.  Is it just an oversight or is there a reason
for that?

> +Functions specified buffer-locally are called for any window showing
> +the corresponding buffer if that window has been selected or
> +deselected (among all windows or among all windows on its frame) since
> +the last time window change functions were run.  In this case the
> +window is passed as argument.

IIUC this hook is hence also run for changes to frame-selected-window,
even when that frame is not selected?  I wonder if it's a good idea.
frame-selected-window is a fairly obscure detail, in my experience.

        Stefan "who hasn't looked at the code"

reply via email to

[Prev in Thread] Current Thread [Next in Thread]