Towards a third version of the theme format: some design goals

Eggistentialism 1.5 or Three of a Perfect PairWhen we add features to the theme format, they must be added all in one go for reasons which were explained earlier. We are currently on version 2 of the theme format. In case there is ever a version 3, here are some of our design goals.  Not all of these may necessarily be met when and if it happens.  These are not in order of importance.

  1. Standard format. If possible, it should use standard file formats rather than custom ones.  This helps build tools, it helps code reuse, and it helps users learn the format.
  2. Editable. It should be designed such that it’s possible to write a theme editor which is easy to understand and use.
  3. Delegation. It would be useful if at least some of the code to parse and render the theme files was in a pre-existing library rather than being part of Metacity itself.
  4. Shareability. It should be at least possible to use the same theme format with various other window managers, which could perhaps be helped by keeping the code in an LGPL library.
  5. Single file. There should be a standard format for keeping all files associated with a theme in a single file, at least for both distribution and installation.  This will save the end user from ever having to deal with tar or zip.
  6. Subthemes. It should be possible to write a theme which inherits some of its attributes from an existing parent theme.
  7. Named colours. It should be possible to give identifiers and descriptions to a subset of colour constants so that the theme artist can override them on the fly.  (This is perhaps already solved given that we can use colours out of GTK themes.)
  8. Well-defined metadata. There should be visible metadata, including licence identifiers, which can contain a list of all authors as a theme gets remixed.  Theme editors should make it easy to keep this up to date.  In keeping with our use of standard formats, we should probably use Dublin Core for the fields and perhaps the same identifiers that DOAP uses for licences.  The casual theme artist should never see any of this, of course.
  9. Upgrade path. It should be possible to convert themes in version 1 or version 2 format to version 3 format automatically.  Conversion from other WM’s formats would be a nice touch.
  10. Minimum power. We don’t need to be able to do everything that v2 can do.  We do need to be able to do everything that is commonly done in v2.  (For example, v2 allows you to have a title “centred” ⅔ of the way across the titlebar.  This has probably never been used, and it’s no big problem if v3 can’t do it.  If it can’t centre the title in the middle, that’s more of a problem.)
  11. Maximum power. It should not be possible for the theme to get in the user’s way.  For example, it should not be possible to write a theme which obscures the contents of windows; otherwise it would not be possible to switch away from it.  Neither should it be possible to solve the Towers of Hanoi in the theme engine.  People have better things to do with their time.

Your thoughts on these and your suggestions for other goals are welcome, gentle reader.

Photo copyright © bitzcelt, cc-by-nc-nd.

Window matching experiment

Saint Patrick's Day MatchesAt the Collabora party, Robert Ancell asked me how difficult it would be to implement window matching in Metacity. I decided this was an interesting question and spent an hour and a half today working on it. The results are now in the matching branch in GNOME git. If you’d like to download it and give it a try, please feel free.

It currently saves configuration data in a keyfile which contains one group per window, in this format:

[xlogo]
x=287
y=178
w=250
h=231

This isn’t necessarily how it will end up: we could use GConf or perhaps some database-like format. It uses a modified version of the system suggested by Hongli Lai: if WM_WINDOW_ROLE is set, we use that to recognise the window, otherwise we use the window title– otherwise programs like xclock wouldn’t be matchable. The role or title is currently represented by the group name in the keyfile.  The keyfile is saved at ~/.cache/metacity/matching.conf.

The system stores the position and size of every window at the moment it was closed.  There is no need to edit configuration files by hand.

There are inevitably some caveats:

  • There is a bug such that when windows are restored they are offset by the size of the top-left hand corner of the frame.  (In other words, the coordinates are misinterpreted as the client window’s position, not the frame’s.)
  • I haven’t tested this for scalability at all.  Keyfiles might be very inefficient when you have hundreds of records for all I know.
  • It doesn’t know about workspaces, and it should; this will probably be the next thing I add.
  • If your window was minimised or maximised, this will not be restored, and it should be.  This will probably be the next thing after that.
  • It might not be the best idea to write out the keyfile on every window close.  Probably better to keep it in memory until the WM exits.
  • It might be useful to have a switch on the window menu to lock the position and size so it restores the same way when you reload it, in case you move it.  On the other hand, this sounds like crack.

Should this branch be merged when the bugs are ironed out? Should it replace WM-based session files? These are good and interesting questions and ones we should discuss.  Tune in next time, gentle reader!  Or better, comment below.

Photo © Bob Fornal, cc-by-nc-sa.

Vectacity as CSS

Coloured boxesDavyd Madeley made an interesting suggestion for redesigning the theme format.  Assuming, as seems likely, we end up using Clutter, there’s no need to specify the structure of a window, which would need SVG.  After all, all windows have a basically similar structure.  Instead, we could style any item on the window usinga CSS file, parsed by libccss.

Don’t want a titlebar?
#titlebar {
height: 0;
}

Want a red background on the close button?
button#close {
background-color: red;
}

And so on.  I think this is an interesting idea because it seems comprehensive enough to capture all the problems we face in theme design.  I’m wondering whether it’s perhaps more powerful than necessary and whether it could cause themes to be able to be disruptive, though.

Photo © Sarah G, cc-by.

Squib of the day: SVG theme support

Brutality against mosquitoes.GNOME bug 107012 brings up the perennial question of SVG support in themes, otherwise known as Vectacity. We’ve already covered this in a few places, but I think it may be worth mentioning here the two main reasons SVG-based themes is a good thing (there may be any number of other reasons they’re a bad thing, as well):

  • SVG is now a clear standard for vector graphics.  So theme artists will be able to reuse their existing knowledge about SVG when coming to design Metacity themes.
  • It means we can remove large amounts of code from Metacity and use whatever SVG library we end up depending on instead.  (There is a heavy presumption that this library will be GNOME’s own librsvg.)  Having less code around is generally a positive thing.

However, stretching SVG to meet our needs, or indeed stretching librsvg to meet our needs, rather negates the second benefit: it’s possible that including CSS will let us do what we need, but it’s also possible that librsvg is not clever enough to let this happen without so much coaxing on our side that we may as well have written an entire SVG library of our own, which is something we’d like to avoid.

If Vectacity ever becomes a reality, it certainly needs to be possible to convert a v1 or v2 theme to Vectacity automatically.  This is partly for the theme artists’ benefit, but also because it means if a Vectacity-enabled Metacity finds itself having to load a v1 or v2 theme, it can do the conversion by spawning a separate program rather than having to keep the legacy code for reading v1 and v2 themes lying around, which again negates the second benefit.

Forthcoming versions of SVG are specifically considering use by window managers, but we may have to wait a while for them to get into a usable format. It may be best to WONTFIX this one, at least until v4.  On the other hand, the two benefits given are indeed important benefits, and I’d like to see it happen sooner.

Photo © freebird (bobinson|ബോബിന്‍സണ്), cc-by-nc-sa.

Squib of the day: line weight

Empty Victoria Line Tube TrainAt present all lines are drawn at the same thickness.  However, some people such as partially-sighted users require particularly thick lines.  GNOME bug 86040 suggests that the line format be extended to give the width as a fraction of the current icon height.

Since this is a change to the format, it must appear first on a branch. This bug actually predates v2, but wasn’t included in that version because it wasn’t marked as blocking the v2 tracker bug.

If this would still be useful to anyone, it could certainly still go into v3 of the theme format.

This bug is perhaps the first place where the use of SVG was suggested as a workaround for having to add new features.  Elsewhere, someone also suggests a novel idea of allowing themes to ship TrueType fonts which contain unusual glyphs, in order to have access to another well-defined vector graphics language.  Of course, this would be subsumed if we decided to use SVG.

Photo © Callistobreeze, cc-by-nc-sa.

Policy about theme versions

a day's workMetacity has a policy about enhancements which require changes to the theme format.  Metacity has to be both backwards and forward compatible.  In other words, it’s not enough that a later version of Metacity can run with themes intended for an earlier version.  Earlier versions must also be able to run with themes intended for a later version.

In order to accomplish this goal, themes are kept in a file named metacity-theme-n.xml, where n is the number of the version of the theme format.  A theme which supports a version should also have files for all the preceding versions, and Metacity will read only the highest version found which it can understand and leave the rest alone.

This works.  However, if there were hundreds of theme versions, it would become unwieldy.  So we save up enhancements and commit a bunch of them all together.  The only time this has happened so far was in October 2006, when v2 was introduced.  (Not many people are using v2, even over three years later, and even though users evidently want the features it brings.  This may be because theme artists aren’t sure how to create them.  One of the advantages of a theme editor would be that it would be able to take care of creating valid intermediate versions for you.)

Some enhancements still being suggested will involve changes to the theme format.  For example, Screwtape has suggested a special window state representing windows which are running as root, so that they can be drawn using a different colour or something.  Enhancements such as these will all have to be made on a branch and merged all together at some time in the medium future, perhaps next year.  I have made a category to group posts about such enhancement requests into.

One of the big questions about v3 is whether it should be SVG-based– the so-called Vectacity format.  This will quite possibly win us very little for the extra effort that will be required to mould SVG into a format which can adequately represent window decorations, so Vectacity may not happen in version 3, or at all.

Photo © Tim McFarlane, cc-by-nc-nd.

Squib of the day: “(as root)”

GNOME bug 549389, which has a couple of duplicates, says that if a window is owned by an app which is running as a user other than the user who’s running Metacity, then it should have “(as fred)” on the titlebars, just as it would have “(on chiark)” or whatever if you were running the app remotely.  The obvious very useful case here is to have “(as root)” when you’re running a program as root, to remind you to be careful.

The code to do this exists in Bugzilla now, so we can check it into trunk at any point.

Other suggestions, some better than others, have included:

  • Use an alternative theme for root windows
  • Draw a red border around the window
  • Use a label (a space as big as the titlebar immediately below it) saying “Root process”
  • Say “(as superuser)” instead of “(as root)” in case users don’t know what “root” means
  • Have a hint not to write the username in the titlebar so that apps which generally run as root, like the package manager, don’t have baffling information all over their titlebar.

meta_warning() and dialogue boxes

meta_warning exampleI didn’t expect to get useful suggestions from the Linux Haters’ blogs, but here’s something that might fly: they point out that warnings from the window manager end up in .xsession-errors where nobody ever sees them. But now that we’re using Zenity for dialogues throughout, there’s no reason why we can’t adapt meta_warning() to put up a dialogue every time a warning is issued, which might alert users to useful things, such as why they can’t bind the keystroke they want.  Having a way to turn this off might also be helpful.

Zenity, sessions, and window matching

Apples & Oranges - They Don't CompareIt has been pointed out that session management in Metacity is currently a bit broken. Firstly, it leaves a lot of useless files around. I assume that the only session file which is really necessary is the most recent one. Secondly, I recently found and fixed a bug where Metacity actually crashed when attempting to save a session. I wonder nobody had found it before, but maybe this shows that session management doesn’t get used, or at least looked at, very much. Thirdly, there’s still a bug in the session management that I found the other day while fixing Zenity support, wherein it tries to put up a dialogue before closing the session… and then always quits, so you can’t see what you were told.

It seems to me that session management is three-quarters of window matching, but isn’t half as useful.  It further seems to me that if window positions were remembered properly during day-to-day use, they would be remembered properly across sessions.  This seems to be a rather compelling argument for dropping session handling entirely and adding some kind of window matching in its place.  After all, it wouldn’t affect our claim to be a lightweight window manager to drop one broken feature and add a more useful one instead.

Photo © TheBusyBrain, cc-by.

Squib of the day: keep the menu in one place

At present the system menu, which you see when you right-click anywhere on the titlebar, left-click the menu button, or right-click an entry on the pager, is hard-coded separately into Metacity and libwnck, and required to be the same in both places.

I’ve been considering the idea of making it a property on the root window called, say, _METACITY_SYSTEM_MENU. Let’s think about how this could look. It would need multiple lines, and multiple fields for each line; so let’s say the lines are delimited by newlines and the fields by tabs, for easier processing. The first field in a line would dictate the function of the line. If it began with a star it would be something special, and we only need to define two of these, “*workspacemove” for “move up, down, left, right a workspace” and “*workspacemenu” for the submenu of workspaces.

Let’s say, though, that if it began with a colon it would represent an EWMH message.  A naive approach would be to send these messages when they were chosen; a more efficient approach would be to fake one up and pretend it had been received, to avoid the round trip to the X server. NARGERY: Let’s say that it consists of a number of subfields separated by colons; the first is the atom for the message_type; the second is “W” if the window field is to be filled in with the ID of the current window, and empty otherwise; the third and following are the contents of data.l[n], with any decimal integer standing for itself, a blank standing for zero, a dot followed by any characters representing an atom, S standing for a source indication and T for the current server time.  Trailing blanks can be omitted.  (For these purposes we pretend that toggling _NET_WM_STATE_HIDDEN minimises and un-minimises.)

Alternatively we could simplify matters by using a percentage sign followed by one of the names of the keybinding actions, such as %close.  This would be simpler but less portable to other window managers, if this ever became some kind of a standard.

The remainingfields for an action would be the string which represented it in the current locale and possibly a string representing the keybinding, in case we didn’t want to work it out for ourselves.

Given all this, we’d avoid duplicating the menu in both programs, and more importantly we’d make it possible to add entries to the menu, as requested in GNOME bug 345233 and elsewhere.  It has been suggested, for example, that if you have a program installed that allows you to share windows across the network, every window should give you the option of doing so in the system menu.  That could quite easily be done using “%run_command_n” here.

(Written during a long compile, so apologies if it rambles.  Also bear in mind that squibs of the day are supposed to be blue-sky ideas!)

Photo © appaloosa, cc-by-nc-nd.

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