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:
<frame class=”maximized”>
<area class=”titlebar”>
<button class=”menu”/> <!– possibly others –>
<title/>
<button class=”minimize”/>
<button class=”maximize”/>
<button class=”close”/> <!– possibly others –>
</area>
<area class=”content“/>
</frame>
- 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:
title:before {
content: url("metacity:icon");
}
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.
There is no data in your example XML, only whitespace. (ok, whitespace *is* data, but still) The data that you want to describe is a window and its parts, not emptiness.
However, if you want to stick with something along the lines of your example, XUL is similar, https://developer.mozilla.org/en/XUL.
Mac OS X describes GUI interfaces using XIB, http://en.wikipedia.org/wiki/Interface_Builder.
@Ryan:
With respect, I think you’re rather missing the point: I used XML because it was a convenient notation and saved me having to draw a diagram. There is no place where the user gets to decide the structure of window manager borders, now or in a system which allowed CSS theming. The structure of the window is not represented in any kind of XML, including XUL or XIB, but is an abstract data structure. As I said in the post, “in our case the document is purely notional”.
Maybe it *should* be possible to provide XML to describe the structure of the window in a theme. That way, theme designers can do crazy new things such as putting the title text of the window on the bottom, or w/e. I mean, that’s not something I’d want personally, but theme writers should be able to do what they want with their design; you don’t want to force theme-writers into the exact same ICON-TITLE-MINIMIZE-MAXIMIZE-CLOSE paradigm that we’ve been using for years…
… or would something like this be possible with CSS? Or would there be some sort of option for users to customize how themes are formatted? The later would be kind of cool. Users could somehow say “Yeah, I want the title on the bottom”, and all themes automatically change to accommodate that.
From a kwin point of view: when you have finished up your thoughts I will have a look at the possibilities to use your CSS to write a compatible engine – if possible. I cannot say anything yet if it is possible. But I think it will be possible and would be a great step if we finally had themes working in both KDE and GNOME :-)
So now to the engine. For KWin it would be clear: we would use webkit. WebKit is part of Qt and unfortunatelly we already pull in WebKit thanks to our Plasma dependency.
So if it is possible for KWin to use your CSS themes and we start to support it, it could be a good idea to use the same rendering engine to have the same rendering results.
I’m currently converting MiG Layout (http://www.miglayout.com/) to Vala/GObject system. It could be potentially used for declarative description of window layout (with constraints placed in CSS or in “Document structure”)…
Introducing MigLayout. The One Layout Manager to Rule Them All: http://www.javalobby.org/articles/miglayout/
While you may be wary of including a “web browser” into your code as a reflex, I’d say you should give it deeper consideration and a real technical run-through.
Consider that webkit is fairly light and fast.
It’s NOT a browser, it’s a rendering engine which many browsers are built around. There are controls for it in several toolkits (ie qt, wxWidgets, gtk?) for brainless embedding into an application.
You get lots of raw power for free, there’s no way it’s going to be abandoned in the near or far future, and it should continue to serve you well into Mutter 2, 3 and beyond, no matter what features you need to add.
“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.”
And now I’m thinking about adding a link to the whole window matching stuff.
Shouldn’t the window role or name be an attribute of the pseudo XML document, so that we may have different styling depending on some window attribute ? In fact, exposing WM and NET_WM properties as frame attributes will allow many customizations…
@Oliver:
I like that idea. I can imagine a user stylesheet, for example, to turn off window decorations entirely for the Gimp:
titlebar[role|=”gimp”] {
display: none;
}
I’m not sure how generally useful this might be, but it’s nifty that the design can support it so well.
@Ray:
We 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 is something we’d need to reexamine with a CSS theming engine.
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.
I think this comment could become a separate post in itself.
@Thomas
This is where CSS could really come into its own. You give the themes *complete* control, yet at the same time if the user wishes to force any particular element to have a certain style, that could still take precedence by using an (implicit?) !important on any of the settings.
Have you thought of applying it to things other than window decoration as well? One thing that comes to mind (don’t mind the ID names etc):
app-switcher.app-title {
display: list-item
}
app-switcher.app-title:before {
content: counter(app-number) ” “;
counter-increment: app-number;
}
@Frans
I think that’s an excellent idea.