Subject: bug#5616: 23.1.92; `delete-frame' deletes the last frame when emacsclient runs

From: "Drew Adams" <[email-masked]>
Date: Sun, 21 Feb 2010 15:27:42 -0800

> > I wonder if `delete-frame' really should act differently in 
> > this way for emacsclient. What's the rationale for this?
> > Was this exceptional behavior an explicit design decision or
> > just a side effect of some implementation changes for emacsclient?
> 
> The normal reason for refusing to delete the last visible 
> frame is that doing so orphans the Emacs process; this is moot in
> daemon mode.

That in itself is certainly no argument for introducing exceptional behavior -
making the default behavior of `delete-frame' depend on the context (daemon vs
no daemon).

There is nothing wrong with the daemon-mode code deleting the frame even if it
is the only visible one. I already said that that is appropriate, and I
mentioned that previous client/server code (gnuserv.el) did the same thing. But
that is not a reason to change `delete-frame' itself to have an exceptional
behavior when --daemon is used.

Just because one caller of `foo' doesn't need some of the distinctions that
`foo' makes, that doesn't mean that other callers don't need them. Just because
such a distinction is moot for that one caller, that doesn't mean that it is
moot for all callers.

Just because daemon mode doesn't need to prevent deleting the last frame, that
doesn't mean that the right _way_ to have daemon mode obtain that behavior is to
change the behavior of `delete-frame'.

Get the behavior that is appropriate for daemon mode, sure, but don't change
`delete-frame' to do that. That's not necessary, is it? It's just asking for
trouble and complicating things needlessly (Occam's razor).

Simply have the daemon-mode code call `delete-frame' with a FORCE arg - that's
what it's for. Instead of changing `delete-frame' to make it modal, the daemon
code should call (delete-frame FRAME t), not (delete-frame FRAME). Is there some
reason that that cannot be done?

Unless it is unavoidable to do otherwise, `delete-frame' should do what it
always has done, in all contexts. I see no reason to change it. It already
provides an arg to do what is needed.

> > Until now (Emacs 23), `(delete-frame FRAME)' has always raised an
> > error if there is only one visible frame. This means that some
> > existing code will expect this behavior, and it will now be broken.
> 
> This sounds far-fetched.  Unless you can point to a real-life
> misbehavior, let's not worry about this.

It should be obvious. Please read the rest of my mail. It's not just about
breaking existing code. It's also about making future code more complex.

Now, _anyone_ calling `(delete-frame FRAME)' without a FORCE arg will need to
explicitly test whether FRAME is the last visible frame, if they want to raise
the standard error.

That sole-visible-frame test is _already_ made by `delete-frame' itself. But
code can no longer depend on it, because of this change that makes the behavior
now depend on the context (--daemon). When in daemon mode, that test by
`delete-frame' is ignored, but without employing the tool provided for ignoring
it: the FORCE arg.

As to "real-life misbehavior": Yes, this change broke my code, which is why you
got this bug report from Zheng. I have a function that deletes all windows
showing a given buffer. If the window is alone in its frame, and the frame is
not a standalone minibuffer, then the function deletes the frame.

With this change in the behavior of delete-frame', I had to change the code to
also check whether the frame is the only visible one. Not a big deal, obviously,
but yes, this change has broken real code.

More importantly, what for? What is gained in doing things this way? Why not
just call `(delete-frame FRAME t)' when you need that behavior?