Here are two ideas with which I broadly agree:
- 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.
- 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:
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.
Another option for you, which vaguely resembles your option number two: Put the theme in a file which is valid SVG, then use a theme-provided XSLT, with appropriate parameters for the real window and theme information, to transform the SVG into what gets displayed.
You could probably standardise appropriate attributes to the SVG to let most themes use a standard XSLT.
@Andrew Aylett:
I like that idea very much. *wanders off to think about it*
I think there’s still the problem of how we represent relative coordinates in an SVG editor which only knows about absolute coordinates, though. Perhaps we could have special ids or id prefixes to indicate which element an element was positioned with respect to.
Or use SVG for the graphics, and CSS to apply them without having to resort to hacks like the ones you describe. Works pretty well for the CSS engine: http://www.gnome.org/~robsta/gtk-css-engine/screenshots/15-single-canvas.png (work in progress)
@Rob:
Are you saying then that we will have to use a custom editor rather than Inkscape or something?
How will using CSS help us position, say, the blocky graphic to the right of the titlebar text in Crux?
Thomas: not quite, but you can preview themes in Firefox or any other (CSS compliant) browser.
For positioning elements so they “stick” to an edge look at the “float” property: http://www.w3.org/TR/CSS21/visuren.html#floats