another crazy idea

Tomy Switch Switch controlsAlmost everything we bind keys to could be done with an external application via EWMH, and on my computer there’s no perceptible speed penalty.  (I’m sure there is on slower machines.)  Perhaps there should be a configure switch not to include the code to do everything except the things which pop up switchers (and another switch not to include those, in case you use superswitcher) and then we could supply a separate executable for people who’d turned them off, so that pressing the “move to workspace right” key actually did “metacity-move –right” or something.  Maybe it would reduce the memory footprint on faster machines.  Maybe on the other hand it wouldn’t be worth the trouble.

Photo © Telstar Logistics, cc-by-nc.

Version 3 themes

Mosquito biteSeveral ideas have come up recently about extensions to the theme format.  Here are some rather disjointed notes about the problems we face here.  I apologise for their fragmentary nature.

According to policy, incompatible changes must be made all at once with a new version of the theme format, to preserve backward compatibility.  (This has only happened once so far, so the only versions of the theme format to exist are v1 and v2.)

One feature I’d like in a new theme format is to have everything in the same file.  At present we have almost everything together except the pixmaps.  I’d like to put them in the same file; rather than using base64, we should use xpm for this, which gdk supports out of the box.  That way, you can have just one single file to download.  Also for ease of sharing, it should have the theme name in the filename this time, rather than the directory name.

As to the format of the new files, there’s a strong suggestion around that they should be SVG.  Such a format could either be designed from the ground up or be an evolution of the current system.  However, I believe that what is needed is a clear upgrade path, and so we need an evolutionary approach.  If we can build a conversion utility to convert v1 and v2 themes into v3 themes, then not only will people be able to work with all their existing themes immediately, but we can support only v3 in Metacity itself and call the conversion utility when a theme is encountered which only supports v1 or v2.

One problem with both the evolutionary and revolutionary approaches is that there are ideas in Metacity themes which cannot be expressed in SVG: for example, some themes place a graphic to the left or right of a piece of text of unknown length.  I have spoken informally to a member of the SVG Working Group who has confirmed that this is not possible in current pure SVG designs.  However, it is possible with scripting.  So we can consider a simple refinement of our existing coordinate-expression system as a form of SVG scripting system, where we set the dimensions and positions of elements with respect to other elements.

Something like this could be achieved using librsvg by building a text buffer containing the XML with sufficient whitespace to the left of every decimal.  As our homegrown scripting language was parsed we’d build up a set of pairs of (char*, expression) and every time a frame was drawn we’d simply write the new value into the buffer.  It would obviously be simpler if we could modify the parsed form of the SVG inside librsvg, but I don’t believe it allows that.  More importantly, we need to be able to find the widths and heights of various elements, especially the title, in order to position other elements, and I don’t believe librsvg allows us to read its parsed form either.  (Do you know otherwise?)  If not, where can we go?

Of course we could possibly keep doing it in house as we do now, but use an SVG-like syntax instead.  Effectively we’d be writing our own SVG library.  This is not exactly a cause for rejoicing.

Photo © James Jordan, cc-by-nd.

Sorry for the silence

Banshees on the WindSorry for the silence of the past few days; I’ve been working on a possible fix to the theme rendering code, after the test suite told me that the part which calculates the value of expressions was a bit slow.  Currently it tokenises during theme load but parses every evaluation.  I thought that if I parsed it into some stack-based form on theme load, it might take slightly longer to load a theme, but everything would draw faster by just evaluating the stack-based version.  (I also took the opportunity to do all floating-point arithmetic using scaled integers, because I’m stuck in 1988.)

In practice, though, the results have been disappointing: it only seems to have saved a few microseconds here and there.  So it’s probably not worth the disruption of merging it, though it does also make the code 584 lines shorter, mainly through its use of a GScanner instead of tokenising in house.  I think it also makes the code a bit easier to read.  I’ve put the patch up in case anyone fancies suggesting how it can be sped up a bit further.

(One optimisation that the existing version does that the patch doesn’t do is evaluate constant expressions at theme load time– so if you have Fred+1 where Fred is a constant equal to 2, it will store just 3 and not bother doing the evaluation.  I’m not sure whether that would give much extra speed to the new code.)

Still, experiments are worth doing even if they fail!

Photo © Dead Air, cc-by-nc-sa.

Metacity and D-Bus

Zarko Drincic - The Electric Bus (Awarded by National Geographic Magazine) GNOME bug 531512 suggests that Metacity should have a D-Bus interface.  On the face of it, this is a good idea.  However, the problem lies in the existing EWMH specification, which allows a program to request operations from a window manager– simply put, it’s pretty much exactly what a D-Bus interface would be, but it already exists.  If we also exposed a D-Bus interface, even one called “org.freedesktop.WM” instead of “org.gnome.Metacity”, we wouldn’t be gaining anything we don’t already have, and then people would begin using it and their programs wouldn’t be compatible with other EWMH window managers.  So every WM that implements the EWMH would have to expose the same D-Bus interface, which sounds like a lot of work for not much return.  On the other hand, we could have a separate program which exposed a D-Bus interface which translated the methods into EWMH messages, and which could be used with any EWMH window manager.  Would that do as well?  What do you think, gentle reader?

Photo copyright Zarko Drincic, cc-by-nd.

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?

Take that, Descartes

Die mosquito

Listen to this.

Here are two ideas with which I broadly agree:

  1. A theme format is less useful without a program to edit the theme files.  Having to modify XML by hand is not a prospect which most people relish.
  2. If there’s to be a third version of the Metacity theme format, it would be helpful if it was based around SVG, since theme files describe vector graphics and SVG has become a standard for such files.  It must not however sacrifice the ability of our current format to prevent themes making the computer unusable.

Back in August, I added simple SVG support to a branch of Metacity that I named “Vectacity“.  My project was shelved because of more urgent business elsewhere, but Iain has also done some work in this area.

In order to play around with the Vectacity format, I have since built a very simple version of an editor.  However, I have run into a theoretical problem for which I seek your insight, gentle reader.

There are certain problems which a theme file has to solve which are not faced by ordinary vector graphics.  One of them, which is easily answered, is the question of how to add the buttons which are currently in use to the titlebar, when this is not known in advance.  Another simple question is how to represent colours from the desktop theme.  A more serious problem is that the width and height of the window is not known in advance either, and nor is the width of the window’s title.  Metacity currently solves this problem using a simple expression language in which these variables can appear as terms.

However we solve this problem in Vectacity, it’s not a problem to modify the coordinates of elements according to the size of the window: the SVG in each theme file is going to have to go through a cleaner anyway before it hits the screen.  Some possible solutions include:

  • reuse. Use the existing expression language: <rect x="3" y="10" width="{w-3}" height="{h-3}"/>;.  This is how Vectacity currently works.  But this means we’re using the SVG namespace but including invalid SVG.
  • vectacity:expr. Mark the attributes which need recalculating, but leave precalculated values in the file: <rect x="3" y="10" width="997" height="997" vectacity:expr="width:w-3; height: h-3"/>.
  • stretchyspace. Subvert the concept of Cartesian coordinates by entering stretchyspace.  In stretchyspace there are 1001 coordinates; addresses below 0 and above 1000 are undefined.  Addresses between 0 and 300 are translated with respect to the left or top, addresses between 700 and 1000 with respect to the right or bottom, and addresses between 301 and 699 are as close to the centre as the address is close to 500: <rect x="3" y="10" width="997" height="997"/>.

Stretchyspace neatly keeps us SVG-compliant, but it’s a much less powerful representation than the existing system.  It’s true that the power of the existing system is rarely used to anywhere near its full extent, but there are existing behaviours which stretchyspace cannot represent.  In particular, titlebar decoration often places non-text graphics with respect to the length of the title:

Examples of the same titlebar shown in three themes
Fig. 1: Same titlebar, three themes.

The first line, for Crux, shows a graphic which has been pushed to the right by the length of the titlebar text.  The second, Atlanta, shows the window icon which is centred along with the titlebar text.  The third, Human, involves printing many copies of the titlebar text; this can be simulated in SVG using styling, but the other two are more of a problem, since they involve non-text participating in text flow.   If we’re using an expression language, this can be handled using coordinate substitution, but if we’re using something like stretchyspace, it will need to be handled in the SVG itself.  Non-text elements appearing in text flow may be possible in SVG1.2, but I don’t know how to do it in SVG1.1.  (Is there a way?  Do you know?)  For this reason, stretchyspace is not a useful answer for the representation of relative coordinates.

Another question we need to consider is whether external SVG editors should be usable.  There are many fine SVG editors around, such as Inkscape.  Allowing the use of one of these, with a tool which extracted SVG data and spawned an external editor, would permit people all the power of an existing application and save us the trouble of writing a new one.

If we are to use an external editor, though, we must consider how relative coordinates may be represented whilst within it.  One obvious conclusion is that we could use stretchyspace coordinates, but the same problems with title placement exist in this case as well; they could perhaps be worked around, hackily, since the title field in a saved SVG has a known length.  Other possibilities include using using the vectacity:expr field and copying its value into and then out of the description field of the relevant object, at a severe cost to usability.

If we are not to use an external editor, the value of using SVG at all becomes a little reduced.

Photo by kozzmen, cc-by-nc-nd.