Subject: bug#1754: 23.0.60; tool-bar is shown with tool-bar-mode off

From: "Drew Adams" <[email-masked]>
Date: Mon, 12 Jan 2009 13:59:18 -0800

> >> I'm not sure I understand the question.  It doesn't add 
> >> the setting to window-system-default-frame-alist, does it?
> >> So all it does is remove any overriding setting from it,
> >> just like it does with initial-frame-alist, which is
> >> necessary for the default-frame-alist
> >> setting to be effective.
> 
> > I'm not sure whether toggling tool-/menu-bar-mode should override
> > window-system specific settings.  When we set tool-bar-lines in
> > default-frame-alist we don't override window-system 
> > specific settings. Is toggling tool-/menu-bar-mode conceptually 
> > "stronger" than setting default-frame-alist WRT to future frames?  
> > What's the purpose of setting `window-system-default-frame-alist'
> > in .emacs when a simple click on a menu entry will annihilate
> > its effect for the rest of the session?  Such
> > clicks are not window-system specific.
> 
> That's a more general problem: I usually don't have a menu-bar in my
> frames, except for a few exception where I give them a menu-bar via
> special-display-buffer-names. Whenever I use M-x menu-bar-mode,
> these details are lost.
> 
> The problem is that tool-bar-mode, and menu-bar-mode and too coarse:
> they offer no way for the user to say whether he wants it to apply to
> every single frame, or only to those currently displayed, or only the
> current one, or only those on the current terminal, ...
> 
> Also, making them work right would probably require keeping track for
> each and ever frame of where its parameters came from.  So 
> tool-bar-mode could just set default-frame-alist and then
> "refresh" every frame's parameters.

Not sure I want to jump in here again, but here goes nothing. I am no expert on
this, so feel free to set me straight. ;-)

I don't think that the problem is that `tool-bar-mode' and `menu-bar-mode' are
too coarse. The problem is that it is not simple to decide how to juggle the
various ways of changing frame parameters and, in particular, the possible
intentions of users. Which also means that it is not always simple for users or
code to achieve a desired behavior.

I think that a straightforward rule should govern this - chronological order.
The latest change to a frame parameter should win - always. And nothing should
affect future frames in a way that overrides later parameter settings - ever.  

In particular, no default definition for frames - whether `default-frame-alist'
or `pop-up-frame-alist' or special-display frame functions (or default values) -
should override explicitly setting a frame parameter.

Second, `tool-bar-mode' and `menu-bar-mode' should not be special in any way.
They should change all existing frames (yes, all), and they should use only
`after-make-frame-functions' to affect future frames.

[If it's _really_ important to prevent those two modes from interfering with
settings that might be made in other ways, we could special-case them by having
two additional frame parameters that stop those modes from changing a given
frame's parameter: `inhibit-tool-bar-mode' and `inhibit-menu-bar-mode'.]

If this principle is accepted, the question then becomes what the order should
be, in particular for actions that are intended to affect future frames (or
future frames of some type). Suggested order:

1. The frame alists that are applicable (init, default, popup, special-display,
whatever). And, in the case of special-display frames, that would include
whatever any pertinent special-display functions do. IOW, all such things would
provide only _default_ values for frame parameters.

2. Any frame-parameter modification done by `after-make-frame-functions'.

3. Explicit later calls that modify parameters of existing frames (e.g.
`modify-frame-paramters').

Because of chronological order, #3 overrides #2, which overrides #1. Always.
There is no need to save any special state or history to record intentions.

All functions or modes that intend to affect future frames would use a hook such
as `after-make-frame-functions' to do so. There would be no built-in treatment
for future frames (other than the default definitions). In this way,
`tool-bar-mode' and `menu-bar-mode' would not be treated specially.

Calls to `tool-bar-mode' and `menu-bar-mode' are covered in #3. But those modes
would also add (or remove) a function to `after-make-frame-functions' that would
add a tool bar or menu bar.

[If it's really important that `tool-bar-mode' and `menu-bar-mode' be
special-cased, then their role of affecting future frames could take effect
systematically between steps #1 and #2. That would still let you override their
effect using `after-make-frame-functions'. But I don't think special-casing them
is necessary or TRT.]

The advantage of such a scheme is simplicity: chronological order rules. That is
already the rule we use within a hook such as `after-make-frame-functions', and
it makes sense more generally also.

Someone (or some code) that wants, say, most frames to have a tool bar but not
certain frames (e.g. pop-up frames or those with a name that contains `foobar'),
would:

1. Turn on `tool-bar-mode' (which would in turn put a function on
`after-make-frame-functions' that creates a tool bar).

2. Append a function to `after-make-frame-functions' that tests the frame type
(checking any characteristics it wants) and, if appropriate, removes the tool
bar.

This approach might sound overly simplistic, but the alternative is, I think, a
nightmare (aka un merdier).