The problem is that there’s a call, gtk_window_present(), which is very vaguely specified:
Presents a window to the user. This may mean raising the window in the stacking order, deiconifying it, moving it to the current desktop, and/or giving it the keyboard focus, possibly dependent on the user’s platform, window manager, and preferences.
There are at least four ways of dealing with this request. I hope I can establish a consistent terminology for them here. Suppose we are looking at workspace 1, and an application attempts to gtk_window_present() an existing window on workspace 2. We can:
- Summon: the window is moved to workspace 1, so now we’re looking at it.
- Visit: the window stays still, but we move to workspace 2, so we’re looking at it.
- Pulse: the window stays still, we stay on workspace 1, but we set “needs attention” so it pulses on the taskbar.
- Nothing: we do nothing. This is allowable, but I think we can discount it.
gtk_window_present() is implemented using _NET_ACTIVE_WINDOW, which according to its specification allows the WM to make the requested window active (which could mean either Summon or Visit), or Pulse, or Nothing.
Many applications use gtk_window_present(), and because of the vagueness of the spec, there’s no agreement on what they mean by it. Three instances which have been identified are:
- Firefox. If you click a link in your email program, it will summon your current browser. If this is Firefox, and it’s appearing in a new tab, it will gtk_window_present().
- Pidgin. If someone talks to you, it will gtk_window_present() the chat window.
- Nautilus. If you use one window per directory, and you request a directory that is already open in another workspace, it will gtk_window_present() the window for that directory.
The disagreement extends even to what Metacity should do when asked to present windows in each of the cases above. Here are some opinions; feel free to add your own in comments, or tell me where other people have asked for something, and I’ll update this:
- Firefox: Kevin Downey says we want Pulse.
- Pidgin: technicull says we want Summon. The devs themselves say they don’t care as long as it’s not Nothing.
- Nautilus: I think we want Summon here. David agrees.
Some things which Metacity should not do:
- Decide which to do based on the application. This is window matching, and thus a recipe for pain.
- Add a switch somewhere. As Havoc said, this boils down to asking “Do you want to break Firefox, or Pidgin?” And many people (including me) run both.
When people complain about Metacity’s behaviour in this matter, it’s hard to tell whether they’re complaining about upstream or downstream Metacity. Upstream Metacity does Summon in all cases. Ubuntu has patched to do Pulse (except for dialogues, which do Summon), as has Fedora, and I believe SuSE has too. As policy, we usually reconsider policy when several major distributions make the same change, and this means we should probably stop to consider what to do here.
It might be possible for the app itself to hint in the EWMH message which behaviour it wants, if it doesn’t want the default. Patryk Zawadzki says that the behaviour should depend on the user’s action; if the user carried out some positive action to cause the gtk_window_present() (as in the Firefox case), it should result in Visit, but if it happened through some external event (as in the Pidgin case), it should always result in Pulse. Mathias Hasselmann concurs. I think this seems a reasonable plan, but the distinction between events generated by the user and not is one which the app is best placed to make, and so we probably also need a hint here. I’m happy to add hinting as a test; however, the default option will necessarily be “don’t care”, and therefore we will still have to choose a best option as default.
I think most applications may be happy with a default of Summon, and that a default of Pulse is at least better than Visit in most cases, but I’m entirely willing to be convinced otherwise.
What do you think?
Photo © jan glas, cc-by-nc-nd.