Because the posts about Cowbell are threatening to choke the rest of this blog, and because it’s only of interest to a particular subset of readers, I’ve created a Cowbell blog. See you over there. Normal service will be resumed here.
The height of a button in a CSS theme is determined by the height of the titlebar, which in turn is determined in most cases by the height of the titlebar font, but occasionally explicitly. The height of buttons cannot be set explicitly.
For the width of the button, however, there are two common cases:
- The artist wants it to be a specified number of pixels, millimetres, ems, etc.
- Much more often, the artist wants it to be a specified multiple of the button’s height, often 1:1.
There has been some controversy about how we should represent this in CSS:
- In the first draft of the themes specification, the width and height properties could be set on a button, but were only used to calculate the ratio. Explicit widths could be set using max-width and min-width. Screwtape called this abuse of the semantics “a bit cruel”.
- We could honour width directly for absolute values, but then there comes the question of how to handle ratios. If you set the width to a percentage, we could use that, but traditionally that has meant a percentage of the width of the enclosing element, not of the height. We could make an exception in this case, of course.
- The universal solution of width: -cowbell-button-ratio(0.25), or whatever, which is ugly.
- Or alternatively allow width to be set directly for absolute widths, and as an alternative have -cowbell-width-ratio: 0.25.
- Invent a new unit! width: 0.25ht. This idea should probably be avoided.
Your chronicler is stumped as to the solution which would be clearest to theme artists. Gentle reader, do you have a suggestion?
- Human may be replaced. We don’t usually cover news about specific themes here (although perhaps we should) but it’s worth noting that Ubuntu’s default theme, Human, although very beautiful, is a little long in the tooth. There has been a proposal to replace it in 10.4 Lucid Lynx with a new, similar theme called Homosapien. (Your chronicler notes that the human species is homo sapiens sapiens, not *homo sapien, and wonders whether it is too late to change the name.)
- Universal theme format. At present, there are scores of different formats for theming user interfaces, some of which are often packaged together to be complementary or alternatives. There are also various metatheme formats for packaging several disparate types of theme together, but they are specific to a particular desktop. David D Lowe has proposed a “universal theme format”, which is a container for various types of themes, to be considered as a freedesktop.org standard. Time will tell whether it’s adopted, but for the moment, gentle reader, you can find out the details in this PDF (there is no HTML version, unfortunately).
- The state of Cowbell. Speaking of universal theme formats, Cowbell is an attempt to allow theming using CSS rather than Metacity’s own rather recondite theme format, which may hopefully one day be picked up by other window managers. More work has been done on the cowbell branch than has seen the light of day, but it has proved difficult to merge the existing content with the master branch; furthermore, we should probably be looking at keeping the CSS theme code separate in a library so that other window managers can use it as well. So the branch has been quiet recently. There are plans to forge ahead with what we have, however, and to integrate the results of the detailed discussion on the subject at the end of last year.
- Cowbell and its dependencies. There are several ways in which the current libccss-based implementation falls short of what we need, at least last time we checked. Any or all of these apparent problems may be mistaken, but:
- Several of the CSS3 selectors which would be really useful weren’t implemented, even things like sibling selectors.
- There’s also a lot of flexibility we don’t need, since our “documents” are of a fixed form.
- There’s apparently no way to refer to a window’s icon other than by saving it as a bitmap and reloading it.
- Some of the extensions we’d need to have equivalent power to the v2 theme system, such as -cowbell-replace-color, look like they’d be a nightmare to implement for similar reasons.
- We can’t easily implement the requirement that it should be possible to load images from a tarball, for similar reasons.
- We can’t easily add new colours, which we’d need to to implement system colours (which may be deprecated but suit our purpose very well), or any similar way of getting at the GTK colours.
We could work around these, but it’s far better to make the theme format usable by humans than to tie ourselves in knots to get around infelicities in the software. And we always have the option of adapting libccss to our needs. But a lot of what we need to do is specific to our own case, and if this results in tying the library in knots it may become better to write a stripped-down in-house CSS parser that does what we want and is, as they used to say in Cambridge in the old days, BALGE: by and large good enough.
Gentle reader, we love your letters. Let us know your news, whether or not it’s about themes.
Photo © camera_obscura, cc-by-nc.
- The existing functionality is going to be moved into a library called libcowbell. Very little will be changed at this point from what we already have. (But there will be some extra tests.)
- A release of the metacity-cowbell branch will be made that can use libcowbell.
- A release of real Metacity will be made that can use either libcowbell or conventional themes.
- Development of libcowbell can continue. (I expect pseudoclasses to be among the first things added.)
More more cowbell. Iain has pointed out an existing GNOME-based project called cowbell. I hope the fact that this project will be libcowbell will be enough to avoid confusion.
- §3: I did start out by showing the structure as pseudo-XML, but people commented as if the window borders were the result of rendering that XML (as if it were XUL, or something similar), so I think it may be misleading.
- §3: I dithered over using the ID or a class for this sort of thing for quite a while. In the end I went with a class because we use classes for buttons (since they may repeat) and it seemed as well to use the same design for areas, and because you may have more than one content area visible at once, even if they are on separate windows. But I may have been wrong, and I invite opposing opinions.
- §3: buttongroup: I really like this idea. But AFAIK libccss doesn’t yet support last-child etc (see next…)
- §3.1: I want our CSS support to be up to level 3 wherever possible. However, we are constrained partly by what libccss is currently capable of. Of course we can patch libccss too! Backgrounds and Borders is largely supported by libccss, though.
- §3.2: Unpainted areas are transparent (though if the frame is opaque, you’ll just see the frame through them).
- §3.3: font-size is important; what should the interaction be between the font size set in Metacity gconf and the font size in the theme? Just use the theme font size for scaling as in v2?
- §3.3: button heights: I think I didn’t explain myself properly here. You can (should) set height and width on buttons. But these only serve to establish an aspect ratio. The height is always calculated from the titlebar height at present. Perhaps this is overly confusing.
- §3.5: :focus pseudoclass: perhaps this should be set on all elements in a focused window. Or perhaps just the frame and we can use the descendant selector.
- §3.5: :disabled — hadn’t thought of this, good idea. TMTOWTDI.
- §3.5: I’m not sure libccss supports :not() (but maybe it does!) If so, yes, we should use it. It’s far better to work the way people expect us to work.
- §3.7: I hope we support SVG too. It would be extra nice if it could be styled with the same CSS somehow.
- §3.8: I really want mm and em as well as px. I’m not certain libccss knows how to do this, but I will check.
- §4: Nobody’s really tried to put Dublin Core data in CSS before, and I’m probably not doing it the best way. I worry that including a required custom XML file will be slipping back into using custom formats, though. Maybe we should use an @rule. Or specially-formatted comments. Or maybe we should give up on the whole required metadata idea.
- §4: I like the idea of specifying alternative stylesheets, though metadata in the stylesheets themselves could also do this.
- §6.1: yes, we really need a default stylesheet. I’m not sure what should go into it. I will think about this and include it in the first libcowbell release.
- §6.2: okay, we’ll avoid data: URLs.
- §6.2: let’s implement the single file doctrine by allowing any file in ~/.themes/ThemeName/cowbell/ThemeName.tar to be treated as if it was in ~/.themes/ThemeName/cowbell/. I think we can get that in the first libcowbell release too.
- §6.5: I really like Firebug. Are you thinking we could use Firebug itself, or just copy its UI?
- §6.11: Maybe we could also modify hue/saturation/value directly in the URL thus: url(‘file:fred.png?hue=#f00’)?
- §6.13: I was thinking of themes which, say, repeat a pattern an integral number of times on the otherwise empty part of the titlebar, scaled to fit; this wouldn’t be possible using border-images, but would work fine with filler. On the other hand, perhaps this is overkill.
Feedback from everyone reading this, on the above and on the original document, is very welcome.
Maybe we need to take over a little piece of live.gnome.org to hash all this out. Or maybe we need a mailing list. I’ll wikify all this tonight and then post about it here.
- Fix the :hover and :active pseudoclasses.
- Add support for v2 themes back in.
- Provide a patch for Mutter.
- Port some more themes, such as Crux.
Anyone wishing to advocate for anything else on the future directions list to come sooner is welcome to make their point, however.
Please let me know if you’re testing Cowbell, or if you’re interested in it. whether or not you’re working on new themes. I’d like to keep the Cowbell community cohesive.
Photo © Eva the Weaver, cc-by-nc-sa.
I’m happy to announce the first experimental version of Metacity with support for CSS window borders (“Cowbell”). This work was largely supported by Collabora Ltd.
- download the tarball;
- read the documentation (it’s not as boring as you might imagine);
- review the source history.
This diagram should explain everything, perhaps.
I would especially like to hear from:
- theme artists, to let me know whether it’s adequately powerful;
- anyone else interested in hacking on this with me;
- the GTK client-side decoration people, so that we can harmonise the way we represent things;
- people who know a lot about CSS and can offer insights into the suitability of the way we represent things;
- people who know a lot about the Dublin Core and can offer insights into whether our metadata system uses it appropriately;
- maintainers of other window managers (especially Mutter), so we can talk about including CSS support in other window managers;
- everyone else, to suggest which of the directions for future development are most interesting.
I think it may perhaps be helpful to set up a Cowbell mailing list, so that we can compare notes on implementations. For example, I haven’t written down anywhere how to place an image to the right of the title, which is commonly needed (you use border-image).
Photo © Craft*ology, cc-by-nc.
I posted a while ago about a system to represent window border styles in CSS. Well, once we had a workable system sorted out, it was time to add the support to a window manager. So I’ve recently been working on adding CSS support to Metacity. The most fiddly part so far has been getting the window geometry calculations right, rather than actually rendering anything.
On the right you can see the Human theme rendered using CSS, and below it the result of adding a blue border to the CSS.
Clearly I still need to fix:
- text rendering
- getting the rounded corners on the physical window and the corners rendered in CSS the same
but I believe it won’t take more than a few days to get this to a state where other people can happily play with it.
Special thanks go to Collabora, who supported this project and let me do some of it on work time.
This blog is not about to become devoted to the single topic of experimental CSS theming, but some interesting points were raised in the discussion yesterday, which spilled over to Slashdot. We should have emphasised the experimental nature of the CSS subsystem in its name: perhaps “CSS On Window Borders Experimental Layout Language”.
Why? Some people have asked why anyone should be interested in CSS theming, given the existence of a stable and mature theme description format. The answer is that there are perhaps a couple of hundred people in the world who understand the Metacity theme format, and its complexity presents a significant barrier to entry for anyone else attempting to learn it. By contrast, millions upon millions of people have a basic understanding of CSS.
Efficiency. Some have pointed out that using CSS may cause great increase in memory footprint or execution time. Both of these are of primary importance to us. Furthermore, we know just how fast every theme renders using the standard engine. We are not prepared to introduce a new theme engine unless it is at least as efficient as the old one.
Mismatch. Some complain that the lists we gave of things we would need to ignore and things which would need to be added proved that there was a mismatch between CSS and what was needed. This is based on a misunderstanding of CSS as a language to style HTML. In fact CSS is a general-purpose styling language, and there are only a few places where it does not quite meet our needs. Even in those places the design is flexible enough to accommodate us.
The balance of power. Ray asked whether the structure of the window should be under theme control, as well as the styling. Some ask how we decide what is under the control of the CSS. We always need to find a balance between giving power to themes and giving power to users. Some things should be under theme control and some under user control, but it’s not trivial to decide which. Here are some examples:
- Justification of the text on the titlebar. Currently this is entirely under theme control; the user can’t change it. Some people would like this to change.
- The arrangement of buttons on the titlebar: which are on the left, which are on the right, and which aren’t shown at all. This is currently entirely under user control; the theme can’t change it. (This means that themes which attempt to look like OS X have to ask you to reorder your buttons so that close is on the left, since they can’t do it themselves.)
- The font on the titlebar. Currently this is entirely under user control; the theme can’t change it. This among other things is something we’d need to reexamine with a CSS theming engine.
(“Under user control” means set in GConf and, generally, modifiable in the control panel. Some of these options cannot be set in the control panel at present, but that’s a separate problem.)
It may be true that windows should have a more flexible structure, and the ability to have the titlebar elsewhere is certainly something that’s been asked for from time to time. But assuming we should add such abilities, should the decision to use them be made by the theme, or should it be something selectable by the user in the control panel? These are deep questions.
Co-operation with GTK CSS theming. Yes: a good idea. Whatever they’re doing, we should probably try to share in it.
Complexity. Some have said that CSS is a complex system, and that anything implementing it will therefore also be complex and difficult to implement. This is an unwarranted assumption. Take a look at the table of contents of the CSS specification and see how little of it actually applies to a fully-functional system for description of window borders:
- Syntax and basic data types; Selectors; Assigning property values, Cascading, and Inheritance; Media types: all handled for us already by libcroco.
- Box model: we would need to implement this. Not terribly complex because we have a simple and unchangeable layout model.
- Visual formatting model; Visual effects: these are complex, and we can ignore them entirely, since our layout needs are simple and unchangeable.
- Generated content, automatic numbering, and lists: we would need to implement basic generated content (the easy part); we have no content to be numbered, and no lists.
- Paged media: does not apply to us.
- Colors and Backgrounds: the most complex part which we would need to implement.
- Fonts; Text: partially applies to us (since some of it isn’t theme-controlled); mostly involves passing things into Pango.
- Tables: doesn’t apply to us; we have no tables.
- User interface: this is about setting cursors and things, and doesn’t apply to us.
Finally, we should probably reiterate that:
- this is still an experiment, and not an official direction which Metacity is taking;
- even if it ever happens, there’s certainly no decision to use WebKit.
Photo © johninbkk, cc-by.
The recent discussion about CSS themes looks as though it may become one of the most interesting new ideas in theming in recent years. Here are some further thoughts on what may evolve from this.
An alternative. There is no general way, and few special ways, to convert expression-based v1 and v2 themes to the hypothetical box-based CSS themes. Therefore this would need to be an alternative theming system, without any upgrade path leading to it.
Document structure. CSS exists to style documents. In our case the document is purely notional rather than existing somewhere as a file, so we have great leeway in its representation. As I mentioned earlier, there are multiple ways in which we can use the ideas of element name, ID, and class to represent what we want to do. The guiding principle is not what would be easiest to implement but what would cause least astonishment to new theme authors. After some thought, I think such a layout might look like this:
<button class=”menu”/> <!– possibly others –>
<button class=”close”/> <!– possibly others –>
- Feel free to disagree and to come up with alternatives.
- There are no attributes on any element. Attempts to select on attributes will fail. The class is written as an attribute only for notational convenience: hence the italics.
- Class is used instead of identifier because it’s not impossible that some implementation of this scheme will wish to have multiple buttons with the same function on a frame.
CSS3. Almost everything we already have can be represented in CSS level 2, and there is no immediate need for level 3. The sticking point mentioned earlier was the window icon being part of the title in Atlanta. However, this can be implemented in CSS2 as follows:
where metacity:icon is a magic URL which returns the current application icon. (But it might be wise not to use the name “Metacity” in this format, in case other window managers might like to use it; that goes for vendor-specific extensions, too. Maybe we should use -wm-.) That said, I am salivating over the possibilities of the new round attribute to background-repeat.
However, there is one piece of level 3 we absolutely need: we will need to allow border-radius at least on the frame, if not on the subsidiary elements.
Implementation. A format is independent of implementations, of course, but we need at least one implementation in order to test things. There have been a few possible implementations suggested:
- webkit. This would work and reuse a lot of code, but I’m a little wary of embedding a web browser into the window manager.
- nbtk. This seems to be missing a lot of what we need at present.
- libccss. This has more of what we need, but still there’s a lot left open to us to implement, and a lot of what it implements we don’t need. It also doesn’t allow us to define new colours, which we need, and appears not to implement sibling selectors, which we will probably also need.
- Using libcroco for parsing and cascading and building the rest ourselves. This is slightly more work than using nbtk or libccss, but may be necessary because of the particularly specialised nature of what we are doing here.
Justification. One of the things people seem very keen on is how the window title is justified. In the box model, the correct way to do this is with the auto keyword on the padding or margins of the title, and not using a text-justify declaration (since the title only has one line of text which fits snugly in its own content box). However, since people are bound to try to use text-justify anyway, perhaps we should allow them to do so, and merely interpret it as another way of setting the padding.
Things we need to implement: The whole box model; several kinds of border pattern; basic generated content for the title; various kinds of text styling for the title; ability to use pseudoclasses to prelight and press buttons.
Things we should ignore: Padding on the frame. Height and width set on the frame, or the content box. Perhaps: Any theme without proper metadata. If we’re doing things the same way as in v2, the font-family, font-weight, and font-style set for the title. (Or should we allow themes to specify a font?) Should we give a warning if a theme attempts to use anything we don’t support?
Photo © Jonathan W, cc-by-nc-nd.
Further to our previous discussion of CSS, Thomas spent a few hours on sketching out a possible design for a CSS-based theme format, and on representing Daniel Borgmann‘s Human theme using it. This is an experiment, all very blue-sky and unofficial, and is quite likely never to lead anywhere.
The first question to resolve is how the interplay of element names, classes, and identifiers applies to us. For example, when styling the close button, is it:
- a button with id=”close”, or
- a box with class=”button” and id=”close”, or
- a close with no class or id attributes?
For simplicity, we went with the last option. We represent the decorations of a window frame using a set of unique element names arranged into a particular hierarchy. Almost every element is a simple box; the exception is title which is textual.
We use libccss to parse the theme and also to apply certain of the box styles; this means that this experiment is drawn using Cairo. (It would have been possible but more complicated to use nbtk for styling, which would have meant this experiment used Clutter. This is more probably what a final working result would be like. An attempt was made to use nbtk but some of the more complicated styling options appeared to be currently unsupported.)
libccss supported background images and reasonably complex border drawing. There were two things we needed which it did not (yet) support, so we had to kludge those in:
- text styling, for the title; we only bothered to implement justification. Our approach here is to use a simple text label for the title and to style it, rather than using explicit vector graphics as in v2. Effects like Human‘s shadowing would be implemented by something like CSS3’s text-shadow. More complicated arrangements like Atlanta‘s centred icons would be impossible.
- the complete CSS box model; only borders were supported. We made a half-hearted attempt to support margin, and did not even touch padding. However, in so doing, we made…
A useful discovery: In doing this it became clear that there are two possible ways for a file format to describe vector graphics. Either the position of everything can be represented using arithmetic expressions, which is how the current Metacity theme format works, or it can use a hierarchical box model, as HTML and CSS do. One of our stated aims for v3 is ease of editing, and the box model appears to be a better fit for humans to understand in a drag-and-drop editor (as seen, for example, in Inkscape). Therefore, if we do not adopt SVG or CSS for v3, it may be worthwhile to look into box-based layout models even in a custom format.
Problems and challenges:
- New properties. We are certainly going to need to invent properties which are unheard of in real CSS. (For example, corners will need to indicate the degree of rounding.) These properties should probably be marked in some way. Mozilla marks its new properties with a leading -moz; perhaps we should do something similar.
- Dublin Core metadata. This could be implemented using custom properties on the toplevel “theme” element, representing the author, licence, and so on.
- Named colours (especially those which refer to the GTK theme). libccss does not allow new colour names to be defined; perhaps we should ask for this. On the other hand, it does allow new callback functions to be created, so that you can write color: gtk("bg-selected") or something. This allows us to get the same effect at least within the CSS. However…
- Pixmaps. This system is well-suited to defining pixmap themes, which are at least fast, easy to understand, and simple to manipulate. However, they are generally discouraged because they scale badly and don’t recolour well when the GTK colours change. There are two possible workarounds:
- Introduce custom properties to scale and colourise the pixmaps as appropriate. v2 is already capable of pixmap colourisation (it’s used quite heavily in Crux, since that is a pixmap theme, but rarely elsewhere).
- Use SVG images instead. This immediately brings up the problem of how to style these images: we could of course use this very CSS to style them, but then our custom callback functions to get GTK colours would still need to be honoured somehow.
- CSS has possibilities as a window border format: it is a standard and well-understood format and there are plenty of tools around to edit and parse it. However, it is certainly not as powerful as v2 and probably cannot be. That may not be a problem, as we said before.
- As somebody mentioned earlier, research is needed to discover which features of v2 are commonly used, and therefore necessary in any possible v3. We need to make a big collection of themes and score each feature with how heavily it is used.
- Box-based layout is simpler for humans to edit (and perhaps to understand in general) than expression-based layout.
Photo © rogdorf, cc-by-nc-sa.