From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: martin rudalics Newsgroups: gmane.emacs.devel Subject: Re: Window change functions Date: Thu, 27 Dec 2018 10:36:33 +0100 Message-ID: <5C249D21.7070508@gmx.at> References: <5C21FB4B.7030005@gmx.at> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: blaine.gmane.org 1545903325 9066 195.159.176.226 (27 Dec 2018 09:35:25 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 27 Dec 2018 09:35:25 +0000 (UTC) To: Stefan Monnier , emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 27 10:35:21 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gcS4X-0002DX-BD for ged-emacs-devel@m.gmane.org; Thu, 27 Dec 2018 10:35:21 +0100 Original-Received: from localhost ([127.0.0.1]:50527 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gcS6d-000505-H1 for ged-emacs-devel@m.gmane.org; Thu, 27 Dec 2018 04:37:31 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:41805) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gcS62-000500-Hm for emacs-devel@gnu.org; Thu, 27 Dec 2018 04:36:55 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gcS5z-0002H0-As for emacs-devel@gnu.org; Thu, 27 Dec 2018 04:36:54 -0500 Original-Received: from mout.gmx.net ([212.227.15.18]:49883) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gcS5z-0002AA-16 for emacs-devel@gnu.org; Thu, 27 Dec 2018 04:36:51 -0500 Original-Received: from [192.168.1.101] ([46.125.250.89]) by mail.gmx.com (mrgmx002 [212.227.17.190]) with ESMTPSA (Nemesis) id 0LhfZR-1h7P7j0wS1-00moka; Thu, 27 Dec 2018 10:36:42 +0100 In-Reply-To: X-Provags-ID: V03:K1:0960TvTLiW3ZIX8J2SxDBNccRYEilp89mxWfn+I8OOn4fNJEe8w nf2RG9aUMF9Ff/h0Wfi6XzdYyJ9EZI1yEQau82qJx2fmHVsMIl0nx7bOoBlT5jyI1zedd+L PPTdnReVD11MhERuUWU/vCl4RD84G28Bttig+KBK0njamBwM9ugeCdqyJl74oFtu8MVJvGJ 2F/1MNqV7P5hOMErCwqCg== X-UI-Out-Filterresults: notjunk:1;V03:K0:bju3CaLpQUY=:s/qP1UMKSkg8MuXL5mny+3 4HjVyuBzVSrtfJX+wYSlTSukqNNSl7D7ooNn9KbExNoPDS9Qn4wJGJ8sMrvWjBgnSVeUnURH4 v12d2k87Y4DjcdHku7UMiV54Lo2rNj0f/q0KVX6onhpq6vVtMZGvIACDP2TxUYB2gOZK/f9Ek YATOu/OdUC9zwLrSmXh1ImEtfZP/C8VrG6sA8dVL8b606pnxh7gkC6hlsm+tvczYRwGOE38Wx yEr+t45y1mRvsFKEoALDp4Aku/1wjnuUK5JyUUbMlFB2bQ8fKc2Fbt3+g0jQFH6pHQYU8XmjB EHwLtTJF8tWSP64yE7qXpYyuWOyTrJKZd5ANOJcK/ZDkLMMwEGklHu0jdsi4whMTeDszT4FyT w7mtJ7/rsAz4WxI7I+6F0vLd2aWzzh2Mwkx6XbhHBImYzG+P4KXKu7mHHwU79cAWpCrYNFXnj OkK+rdlNFwBAbQDRukb3iP2rg129JtuGYwKHvoE8UOHpeCaUC/uWMvbpA+WO26I2El38X0V0P o7uCE8gpVvUocZm2dwayI8h9gUXpxsroKjoR/LV2rHYLSykQh+cYGzwHkp7Hu2HUvS6dWF51T vf+8nvXwPzThBIbdeUF8/2B1tzNVVfmXYwCdyQeLfAlN9rkbjwP4j0X7RRD4gWVTSq+gjI1xc Q8d/zWWu3E+lv2NnrsGiDDfV66rgdp8M7YTg54iWArvkW3qHrxcov7/1aL1FonH2KKvOdW/HN ZZ5H47SL+X7ahva7UVDppwRYGoTYq7ZKJIubXHis357KutZKSALXnZmytSTDEHlZZcBbdjVi X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.15.18 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:231997 Archived-At: >> (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. OK. While deleting a window doesn't really change its buffer, a state change could be admittedly considered as something more substantial. >> (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? Yes. The buffer local hooks are run for every window the buffer is in that gets selected or deselected with the respective window passed as argument. This means that if a buffer B is shown in two windows W1 and W2 and W1 gets deselected and W2 gets selected, the buffer-local hook is run twice for the same buffer - once with W1 and once with W2 as argument. The global hooks are run once for each frame where a selection or deselection occurred with the frame as argument. So if a new frame gets selected there will be two calls of the global hook - once for the old and once for the now selected frame. > 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? There are several reasons that favor delaying: (1) When finishing a window excursion by restoring the previous configuration we should run 'window-configuration-change-hook' if and only if something really changed. Telling whether something really changed is hard and I doubt current Emacs does it right. (2) 'balance-windows-area' is a good example for why we should delay calling size change functions IMO: Its intermediate steps are not really interesting for any client of that hook. (3) Delaying hooks and running them all in one bunch allows to reliably look at possibly related changes by consulting the 'window-old-...' functions. (4) Some clients do the delaying themselves by putting an according function on 'post-command-hook'. This won't be needed any more with delayed execution. >> - 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. I don't use them and cannot tell. But since change functions would now run after 'post-command-hook' running 'erc-modified-channels-update' from 'window-configuration-change-hook' right away should satisfy the author's intentions. >> 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. Neither do I. >> +@defvar 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. Note that 'window-size-change-functions' are currently already run right in the middle of redisplay. Often, window sizes are correct only *after* redisplay. Think of minibuffer window resizing or changes in the fringes, margins or modeline sub-structures. But a final word on the location of the call will have to be told by Eli. > 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. Correct. The right position to detect when a "specific buffer stops being displayed" is (1) 'kill-buffer-hook' and *would be* (2) a 'before-delete-window-hook' because right after its deletion a window might get GCed immediately and (2) would not have anything else but the buffer itself to work upon. So if someone sees a need for (2) please tell me and I'll add such a hook (it won't cost much but some lines in the manual). > 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? It's been renamed to 'window-old-pixel-height' so the 'window-old-' prefix matches that of its new colleagues. >> +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. If someone changes it separately (that is, sets it for a non-selected frame), there is now a hook to trace that. Otherwise, any change of 'frame-selected-window' is just a side-effect of changing the selected window and will not be noticed by clients. > Stefan "who hasn't looked at the code" He could try it though. martin