> We could leave it called on every set-window-configuration > even with an empty window list, as a general post-hook. I've now reworked the patch for the following reasons: - Changing the existing behavior of 'window-state-put' in order to make it behave like 'set-window-configuration' in certain regards is a bad idea IMO. Someone, somewhere might be used to the current behavior. - The entire idea of deleting windows when their buffers are dead might annoy people who prefer a fixed frame layout with a predefined number of windows. The new patch attached renames 'window-kept-windows-functions' to `window-restore-dead-buffer-windows'. That variable is no more a hook but may be - t to never delete a dead buffer window, - 'delete' to do what 'window-state-put' does now - 'dedicated' to do what 'set-window-configuration' does now - nil to keep the current behavior - a function to do what 'window-kept-windows-functions' did. I abandoned the hook idea because having more than one function work on a list of kept windows means asking for troubles. In addition, I now pass a third argument to that function - 'configuration' if called by 'set-window-configuration' and 'state' if called by 'window-state-put'. When looking into this I (re)discovered that 'set-window-configuration' leaves dead buffer windows alone if they do have a buffer in the configuration that function is about to replace. This comment /* Kludge Alert! Mark all windows now on frame as "deleted". Restoring the new configuration "undeletes" any that are in it. Save their current buffers in their height fields, since we may need it later, if a buffer saved in the configuration is now dead. */ tells how this was done in the past and these two snippets /* Since combination limit makes sense for an internal windows only, we use this slot to save the buffer for the sake of possible resurrection in Fset_window_configuration. */ wset_combination_limit (w, w->contents); and /* If we squirreled away the buffer, restore it now. */ if (BUFFERP (w->combination_limit)) wset_buffer (w, w->combination_limit); explain how this is done now. (Calling delete_all_child_windows and running SAFE_NALLOCA in 'set-window-configuration' is a bad idea given the fact that the body of 'save-window-excursion' practically never changes the existing configuration, but I won't discuss that here.) Suffice it to say that 'set-window-configuration' leaves a dead buffer window alone if it shows a buffer in the configuration it is about to replace. 'window-state-put' does not do that because it has no idea of the identity of windows and making it map the current window tree into the window tree it is about to restore does not look like an appealing endeavor to me (besides the fact that it would change existing behavior again). Now what I did was to add two more entries for each window passed to the 'window-restore-dead-buffer-windows' function: - One for the dedicated status of the window in the saved configuration or state. If you restore the old buffer, you should also set that, I suppose. - One that is t if the window was live in the configuration replaced by 'set-window-configuration'. It might help to decide whether the new buffer would be a better alternative than restoring the dead buffer. I don't think the tab bar code would need it. Have a look. > BTW, I didn't test yet what happens when > window-kept-windows-functions is non-nil but does nothing. > Here is what happens: > > Error muted by safe_call: (get-scratch-buffer-create) > signaled (wrong-type-argument window-live-p #) > > But maybe this is ok. I now made it call 'window-restore-dead-buffer-windows' iff it is a function (it may still have the wrong number of arguments though). BTW the "Error muted by safe_call" messages are helpful - once you get used to them. martin