Closed Zulu-Inuoe closed 3 years ago
The usage of purpose-change-buffer
and window--display-buffer
throughout Purpose is supposed to play correctly with quit-window
. IIRC this happens also without Purpose, so I didn't investigate too closely after my initial research. Didn't evaluate the PR yet, but is the problem really only with popwin extension?
This is a bit of a complicated issue, and I was skeptical with the 'fix' so let me give a full reproduction so maybe you can verify and sanity check me on this:
(purpose-mode)
(require 'window-purpose-x)
(purpose-x-popwin-setup)
*Messages*
to be have popup purpose:
(purpose-set-extension-configuration :testing-popup (purpose-conf :name-purposes '(("*Messages*" . popup))))
*Messages*
buffer. Should get a popup window.C-h k C-n
to open up a help buffer. Should reuse the same window.q
to quit the help window. This takes us back to the *Messages*
buffer in the same window.q
to quit the *Messages*
buffer.Now instead of the popup window having been killed, we have some other random buffer being displayed in that window.
I tracked down this behaviour to the specific rules in which Emacs will actually kill a window in response to quit-window
:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting-Windows.html
Specifically (I formatted it a bit to make it more readable..):
The window is deleted entirely if:
When the popup window is first created, it indeed has the right quit-restore-parameter
. But after that quit-window
call from step 5, it is set to nil
because..:
The function's behavior is determined by the four elements of the list specified by the quit-restore window parameter (see Window Parameters), which is set to nil afterwards.
I couldn't think of a way to play nice with quit-window with this behaviour, so the PR is indeed a bit of a hacky workaround. I'd love to have a cleaner way to go about it, if somebody can come up with it. Maybe I overlooked something.
Sorry for the length post!
When we reuse a popup window to display some other popup buffer, and then we quit from that buffer via
(quit-window t)
or the like, we will be back at our previous popup buffer, and have our quit-restore parameter set to nil.Unfortunately then,
quit-window
once more will cause the window to display a random buffer because whenquit-restore
is nil,quit-window
will not actually kill the window because ????This means that our popup window will now be displaying a random buffer, rather than having been killed as it should have been.