Inbox zero

Year of the Ox Lantern - UnlitIt’s been a few weeks since the Western new year (though the Chinese new year is coming up), so it’s a bit late for resolutions, but let’s pretend. There are currently 447 open bugs on the Metacity bug tracker, which I think is an unsupportable situation. So let’s say that by 25 January 2010 all the bugs will have been dealt with.

That’s a bit more than one a day. I’m going to need help.  Will you help me?

Out of these, 19 are tracker bugs and so don’t count towards the total. These would be better done with keywords, anyway.

There are a few crashers which are either reproducible or they aren’t.

Most of the bugs are squibs, ideas that someone raised for us to consider.  Some of them have patches.  We need to decide one way or the other whether these are going in.  For the ones which aren’t, we need to decide a place to keep all the patches which didn’t make it in.  This can be done with a wiki page linking to all of them; when we have a DVCS, we could also have a branch for each.

I think I’m going to introduce a Bug of the Day feature here where we discuss the possible impact of each such bug.

Thoughts?

Half-finished code finishing marathon time

I have several half-finished bits of code lying around.  I think I’ll make an effort to merge them in, at least in test branches, to see what people think.  (When we get a DVCS, this will be easier.)

  1. Veracity, a test suite.  This is about two-thirds done, but will require a bit of autotools magic to link into the main build process.  I may need some help with that.
  2. Window matching: something to remember window positions across sessions.  There’s been a few requests for it recently (most recently, Launchpad bug 311615).  We’ve always said we wouldn’t do this, but maybe there’s no harm done in trying it in a branch as an experiment.
  3. Opacity, a simple WYSIWYG theme editor.  About a quarter to a third of it is written.  Probably would be best to make this a separate project.
  4. Actions.  The idea has often come up (e.g. GNOME bug 345233) that if there’s something you can bind a keystroke to, you should be able to put it into the window menu or make it a titlebar button or whatever.  This may be over-configurable, but there may be advantages of a simplified architecture in making it possible at all. There’s experimental code to do this, but it’s about half done.
  5. “Cringe”: how much can we avoid keeping in memory at once?  This is an answer to what I think is our oldest current bug, GNOME bug 144242.  Saving a few bytes here and there per window can really add up.  I’ve done a small amount of playing around with this, but more is needed.  Having Veracity working will really make this easier because then we’ll just be able to run a stress test inside valgrind.

Gentle reader, which should be moved out of Metacity Labs first?

Notifisation

Fire Notifier

Listen to this.

Launchpad bug 124326 requests a new titlebar button which minimises an application to the notification area rather than ordinary minimisation. Mostly this is currently done with the close button on the apps which support it, but some people feel it would be cleaner if these two functions were distinct. This action has been given the name “iconification” by some, but since this is the name the X specification gives to what we now call minimisation, I propose the ugly word “notifisation”.

There are four problems with this idea.

  1. Adding new titlebar buttons is always problematic for reasons given earlier.
  2. The EWMH specification is going to have to include a way to tell which apps may be notifised, and a way for the WM to tell an app to notifise itself.  This is going to require arguing out on wm-spec-list.  In itself, this is not a major obstacle, but it’s important to be aware of.
  3. It is unclear what the real difference between minimisation and notifisation is in practice.  And if there is one, why shouldn’t all apps be notifisable?
  4. Using the notification area for things other than ephemeral notifications– that is, using it as a cheap way to make panel applets– is contrary to the Human Interface Guidelines.  Perhaps the HIG is wrong, but then we need careful thought before we give the practice a stamp of approval by enshrining it in the EWMH.  Besides, there is talk of enforcing notification ephemerality.

Photo by The Joy of the Mundane, cc-by-nc.

2008-11-11: fullscreen, focus and so on

Listen to this.

Welcome back, gentle reader, to the Metacity Journal, which now talks to you over your cornflakes.  This may not be a long-term feature, but your chronicler thought it worth trying.

It’s been a quiet few days in the world of Metacity, but here’s the latest news.  As ever, feel free to dive in on any of the bugs mentioned.

The recent post about why window matching is currently impossible brings up a chicken-and-egg question.  The window manager doesn’t do window matching because it’s nearly impossible, since windows don’t identify themselves, but windows don’t identify themselves because there’s no need, since the window manager doesn’t support it.  Perhaps adding window matching as an experimental option would help persuade people to add the GTK call to enable window matching in their programs.  Meanwhile, Thomas has suggested making these changes as a new GNOME Goal.

There has been some offlist discussion about reviving Vectacity, the SVG-based branch.  This would make theme editing a fair amount simpler.

Recent bugs

  • GNOME bug 560142: AisleRiot and Metacity arguing over fullscreen mode.
  • GNOME bug 533277: session restoration problems
  • GNOME bug 524468: problem with the screenshot button reported; Thomas cannot reproduce it
  • GNOME bug 487356: there are focus issues if a buried window is fullscreen.  This is quite important to fix and is currently at the top of the hitlist.

Around the blogs

And that’s all until next time.

Window matching

glass pane, shatteredWindow matching is the process of identifying a new window as one we’ve seen before.  Of course every new window is new, and so we’ve never seen it before, but there’s an intuitive understanding that if you open a document in OpenOffice and then come back to it a week later that the window is in some way the same.

Some good properties to use for this are:

  • SM_CLIENT_ID, which is set by the session manager for a particular instance of a running program. XSMP says that “a unique value called a client-ID is provided by the protocol for the purpose of disambiguating multiple instantiations of clients.”
  • WM_WINDOW_ROLE, which is optional.  The ICCCM says that “the combination of SM_CLIENT_ID and WM_WINDOW_ROLE can be used by other clients to uniquely identify a window across sessions.”  If there is no WM_WINDOW_ROLE, the ICCCM tells us to fall back on WM_CLASS and WM_NAME…
  • WM_NAME is the window title.
  • WM_CLASS is a two-part property.  Let’s call these Instance and Class, although these aren’t the real names. Instance is generally the name of the program, although it can sometimes be set on the commandline.
  • Class is “the general class of applications to which the client that owns this window belongs”, i.e. the brand name of the program (rather than “editor”).

Metacity does not currently do window matching for three good reasons.

1. Separation of concerns: in-process or not?

The EWMH allows us to do window matching outside the WM, and in fact this is what Devil’s Pie and gdevilspie are for.  They have all the other problems, but they’re not part of the WM, and if they crash they don’t bring the WM down.  It appears that because this can be done outside the WM it should be.  (Isn’t this fun?  We can pretend we’re the Hurd.)  Feel free to argue the point, of course.

2. Separation of concerns: app or WM?

It is also possible that nobody except the application itself knows where its windows should be placed, and that everything should be left up to the apps (and in practice the toolkits).  This would allow us to do away with session management entirely.  Certainly it would mean that it was none of Metacity’s business.

3. Paucity of distinguishability: who sets what?

Devil’s Pie requires you to set up rules to identify windows.  Doing window matching at the window manager level implies that the rules are written for you automatically.  This wouldn’t be a problem, except that applications set the attributes above very inconsistently.  Although WM_NAME is always set, it isn’t necessarily reliable– for example, gedit adds a star to it when you begin editing a document. I believe therefore that we cannot use it in automated window matching.

As to the others, let’s introduce a notation: Role|Instance|Class.  If Role is missing, we write [NONE]|Instance|Class.  Here is a program called same.c which will print these values for you.  Some common examples:

  • Firefox sets browser|Navigator|Firefox in all cases.  It is therefore not possible to distinguish Firefox windows from one another except by WM_NAME.
  • Thunderbird sets [NONE]|gecko|Thunderbird-bin, but it usually only has one window open.
  • nautilus sets [NONE]|nautilus|Nautilus and it is therefore impossible to tell the difference between Nautilus windows except by WM_NAME.
  • inkscape sets [NONE]|inkscape|Inkscape similarly.
  • gnome-calculator sets [NONE]|gnome-calculator|Gnome-calculator.
  • gnome-terminal sets gnome-terminal-SOME-LONG-STRING-OF-NUMBERS|gnome-terminal|Gnome-terminal with the string of numbers different each time.  This gets an A.
  • epiphany sets epiphany-window-SOME-LONG-STRING-OF-NUMBERS|epiphany-browser|Epiphany-browser with the numbers differing.  Another A.
  • The GIMP sets gimp-XXX|gimp|Gimp where XXX is “toolbox”, “dock”, “tip-of-the-day”, etc.  This gets an A+.

Please feel free to comment with more results and I’ll add them.

Conclusion

  • People often complain that Metacity doesn’t do window matching.
  • There are many reasons why it shouldn’t (but feel free to disagree in comments).
  • Window matching of any kind is needlessly difficult because the important properties are set inconsistently.
  • Therefore for the sake of window matching in general, whether we do it in Metacity or not, it would be a useful exercise to patch all programs which don’t set roles as well as the GIMP does.  (gtk_window_set_role() is the relevant GTK function; it’s not widely used.)  Perhaps this could become a GNOME Goal.

Photo: Glass pane, shattered, © nchenga nchenga, cc-by-nc.

Know all men by these presents…

sheep  &  her lambI tried to discuss the gtk_window_present() problem earlier, but I only managed to confuse myself. So here’s an extra rundown; perhaps we can move towards solving it.

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.

Annotations

Perfection in the MarginsMany people, from various programming communities, have come to the conclusion that if functions are first-class objects they should be allowed properties. For example, if a function in a test suite is checking for regression of the fix to a particular ticket, it could have a property for the ticket number. Then other parts of the code can deal with it in a consistent way through introspection, without keeping related information all over the place.

In Java, these are known as annotations and look like this:

@ticket(177177)
public static void testFrobulation () { ...

Python also calls them annotations (replacing the older system of decorators, which looked similar to the Java syntax but achieved its effect in a way more like Lisp macros). Annotations in Python look like this:

def testFrobulation(ticket: 177177): ...

In the past few months, two infelicities of the Metacity codebase presented themselves. Firstly, some translators complained, rather reasonably, in GNOME bug 469361 that the same information was repeated over and over again in the long descriptions of the keybindings.  Secondly, the same information about keybindings was repeated over and over in several places in the code, and in many of those places it was required to stay in the same order as the other places and would cause subtle breakage if it didn’t.  And of course, when anyone provided a patch to add a new keybinding it needed to modify several more files than would seem really necessary.  What would have been best is to be able to write something like

static void @keybinding ("Activate the window menu", "<Alt>Space")
handle_activate_window_menu (MetaDisplay    *display, ...

But you can’t really do annotations in C (despite a half-arsed attempt by Microsoft). Or can you?

In Dr Dobb’s Journal of May 2001, Randy Meyers introduced an idea called x-macros. This idea is the mildest of preprocessor abuse: you create a file containing lines of grouped data, like these:

item (switch_windows, "Move between windows, using a popup window", "<Alt>Tab")
item (switch_to_workspace_1, "Switch to workspace 1", NULL)
...

Then you #include the file anywhere you want to work with this data, but you #define item() as appropriate each time.  This way, the data only needs to be modified in one place, and it’s guaranteed to stay in order.  It occurs to me that what we have here is pretty close to annotation.  True, it’s in another file, but C also requires that the prototypes of public functions be in a separate file, and nobody minds about that.

So Metacity in trunk is now working fine using this system.  There are a few places it could be neater;  screen and window bindings have always been kept separate, but it would possibly make sense to keep them together and distinguish them (as they already are distinguished) by the cunning use of flags.  Also, the handler functions should probably be given by name and not calculated from root and suffix, because it’s just confusing.

This whole idea also means that the GConf schemas which concern keybindings can be generated during the build process, which solves GNOME bug 469361 rather neatly.  In conversation with Rodney Dawes it also came up that most of the short and long versions of the keybinding descriptions say the same thing in twice in different words, which is an unfair burden on the translators.  I have merged them as appropriate: the number of strings has gone down by about thirty, and the .pot file is now 70% of its former size.

Photo: Perfection in the Margin, © Adam Shaylor, cc-by-nd.

Double-click to close

doble clickWindow decorations on Windows 3.1 had no close button, so they used to let you double-click the menu button to close a window. When Windows 95 came along, they added a close button, but they kept the double-clicking behaviour. The ability to close a window by double-clicking the menu button has lasted right up until Vista; apparently Microsoft tried to take it out in the beta, but so many users complained that they left it in in the end.

Many *nix window managers support double-click to close for the benefit of people moving from Windows who learned how to close a window before 1995 and haven’t broken the habit yet.  Metacity doesn’t, and in GNOME bug 83892 people have been saying it should.  Often, they add that there’d be no harm in adding the behaviour because people who wouldn’t know about it wouldn’t trigger it.  However, other people say that the effect of accidentally double-clicking the close button, and losing anything which happens to be in the window, is too disastrous to add a feature for such a marginal audience.

The HIG also (apparently) says that the top entry in a context menu should be the one triggered by a double click.  “Close” is not currently the top entry in Metacity’s window menu.

A good while ago, Thomas Thurman provided a patch to add this behaviour, which has rotted, and today provided a current one.  The current consensus among the maintainers is that this will not be added.  However, you might be able to change our minds if at least one distro includes the patch.  For example, Debian bug 381509 discusses the matter; if you know corresponding bugs in other distros, please let me know and I’ll add them here.

Photo © saba♫dija, cc-by.

Doxygen

Blowtorch on full powerHere’s a really easy way of getting involved with Metacity which doesn’t even involve being able to compile it, can be carried out even if you only have a basic knowledge of C, and will teach you something about the way the system works and get you credit in the release notes.

A goal of mine for 2.26 is to see all the functions documented. I’d like to see every function begin with a comment saying what it does, what its parameters are, and what its return value is. And you can figure this out by reading the code– or if you can’t, you can read more of the code to find out, or come here and ask. And really, if you can’t figure it out, that’s nothing to be ashamed of– it shows we really needed the comment.

In my opinion, the system used by Doxygen, which is similar to that used by Javadoc, does everything we need in a reasonable way, and for a few months I have been adding documentation comments to functions all over the place– I think bell.c is a good example of the style, though I’ve learned a few new things about the Doxygen system since then that I’d like to modify. You can see some of the results here. However, there’s a lot left to do, and I could probably be spending my Metacity time better by fixing bugs, since I know the system pretty well by now, and this is something that can largely be done by people who are learning it (given that they’re supplying patches which will be checked for quality by someone who knows what they’re doing).

If you want to help work on this, sort out here which module you’d like to help work on, so we don’t have two people working on the same place. If you don’t know, I can suggest something. I’ll make a bug sometime so patches can be attached. It’s far more important that nonstatic functions are documented than static ones. Oh, and don’t forget to start block comments with a slash followed by two stars.

Photo credit: Terence T.S. Tam, cc-by-nc-sa.

Reminding us

cuddle cowTwo of you emailed me out of the blue today to remind me that GNOME bug 504692 has an unreviewed patch on it that you’d like looked at before the next unstable release.  Thank you!  This is a very good way of reminding me of such things, and I think that holds true for most maintainers: we get dozens of pieces of email a day from Bugzilla, and a personal note is a bit of a stronger push.

(That said, don’t overdo it; I’m drowning in email as it is.)

The patch needs me to set up dual screens to test it.  There was a joke earlier that there needed to be a collection to buy me a second screen, since all Metacity development is done on a laptop; I have now been lent a second screen.  However, for the next couple of days I’ll be unusually busy in the world of non-GNOME software, and then I need to figure out how to get Xinerama and so on working on the new setup. I shall, of course, keep you up to date with extreme punctiliousness.

Thanks for being such a friendly and helpful bunch of users.

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.