Section 3

3a: abstract data structure

TT: "CSS has traditionally been used to style other documents. However, when you use CSS to style window borders, you should forget the idea of a document which you are styling. Instead, you are styling an abstract data structure."

ST: Actually, CSS has always been used to style abstract data structures, it's just that traditionally those abstract data structures have been defined in HTML you could look at with View Source, while COWBELL uses CSS to style abstract data structures with no easily-visible serialisation.

For people who want an XML-style document to refer to, there's nothing stopping you putting a mock-up in the documentation:

<frame>
    <area class="titlebar">
        <button class="menu"/>
        <title>Happy Birthday!</title>
        <button class="minimize"/>
        <button class="maximize"/>
        <button class="close"/>
    </area>
    <area class="content">Content goes here</area>
</frame>

...perhaps with the caveat that CSS isn't used for the *layout* of these things (there's no good way to specify that a titlebar pushes the buttons to the outer edges of the enclosing frame in raw CSS, for example). In particular, you probably want to define the "display", "float" and "clear" properties as off-limits.

TT: 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.

ST: Since the vast majority of of CSS usage in this modern world involves decorating XML-like documents, I think it would help a lot of people to have even a sketched document covered with caveats - on the other hand, it might mislead even more people into thinking there was an actual XML document underneath. I suppose it won't be difficult to add one if there are requests, so we can leave it out for now.

TT: It's a fair point: I'll put it back in.

3b: id versus class

ST: Since there's exactly one titlebar, and one content area, those elements might well have their roles in the id attribute, rather than the class attribute.

TT: 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.

ST: id vs. class is an internal-documentation issue - by giving certain things IDs, you're promising that there will be exactly one of them in the entire document (which corresponds pretty tightly to 'window' in the analogy we're drawing). Using class, on the other hand, tells people that you might have multiple elements with the same role, in future. You don't want people wasting time trying to design themes that will still work in the presence of multiple titlebars, for example.

I imagine the number of people who want to make Metacity themes and are familiar with the id vs. class distinction will be vastly more than the number of people who want to make Metacity themes and will be confused by having to use slightly different syntax for some of the elements.

The third alternative, of course, is just to have <titlebar/> instead of <area id="titlebar"/> or <area class="titlebar"/> - that makes the CSS syntax even simpler, and I can't immediately imagine any reason somebody would want to have as style that both <area/> elements used (but nothing else).

TT: I like the third alternative best. I can't now remember why I decided against it, so I'll put it back in.

3c: buttongroup

ST: Since themes often want to draw grouped buttons as actually grouped (for example, the Resilience theme in Ubuntu Karmic, it would be helpful to have an extra element around the buttons on each side:

<buttongroup id="left">
    <button class="menu"/>
</buttongroup>
<title>Happy Birthday!</title>
<buttongroup id="right">
    <button class="minimize"/>
    <button class="maximize"/>
    <button class="close"/>
</buttongroup>

That would allow styling of the entire button group by styling the buttongroup element, styling the "end cap" buttons in a group differently by styling button:first-child, button:last-child and button:only-child, and not drawing an empty group if there's no buttons at that end of the title-bar (buttongroup:empty).

TT: buttongroup: I really like this idea. But AFAIK libccss doesn’t yet support last-child etc (see next…)

Section 3.1: CSS level

ST: It would be good to know exactly which parts of which versions of CSS these themes support. Each new version of CSS adds a whole lot of very useful features. For example:

  • CSS's pseudo-classes are terribly useful for styling UIs - things like :disabled, :focus, :hover, :active
  • CSS 3's more sophisticated psuedo-classes are useful for dealing with documents that have arbitrarily-long lists of items (such as buttons in a titlebar) - things like :first-child, :last-child, :only-child.
  • CSS 3's Backgrounds and Borders module directly describes the sort of things theme authors would want to do in themes, and makes lots more things possible than the CSS 2 version.

TT: 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.

ST: Looking at the current CCSS readme, it does indeed look a little grim — but at least there's an obvious roadmap for CCSS to improve and gain new abilities in a backwards-compatible fashion (the W3C's CSS specs).

Section 3.2: unpainted areas

ST: What happens to sections of the frame that are not painted? Are they left transparent, or will they have a default fill?

TT: Unpainted areas are transparent (though if the frame is opaque, you’ll just see the frame through them).

ST: I was thinking of themes like BeOS's tabbed-title-bars, or the classic "Blue Steel" theme for Enlightenment. Being able to have arbitrarily-shaped title-bars would be much more useful than just rounded corners, but then you either have to assume a composited environment (which I guess Mutter/gnome-shell can) or do tricky things with XShape.

Section 3.3

3.3a: theme control of font size

ST: I think setting font-size is important - it's quite common for utility windows to be styled with smaller title-bar fonts than regular windows. You might want to clip values so people don't set the font-size to zero, although you might want to support "visibility: hidden"

TT: 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?

ST: I would expect the font-size set in gconf would be the initial value of the font-size property on the <frame/> element, and the computed value of the 'em' unit. If the theme allows people to set font-size themselves, you might want to clamp the computed value for font-size inherited by the <title/> element to some sane bounds - such as 0.5× to 2× the gconf value. You might also want to explicitly allow a font-size of 0, to allow for effects like your Prelude theme.

3.3b: button heights

ST: If the height of a button is always the height of the title, it seems silly to require people to set the height. Let people set the width of buttons, though. "width: 1em" (assuming the default size of the title-text is defined to be 1em, which seems reasonable) should make buttons exactly square. I'm not sure what should happen if a button is set to "width: auto"; perhaps that should be disallowed. If the width is set to a percentage, I guess that would be a percentage of the area.titlebar width.

TT: 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.

ST: I think that allowing the themer to set values for height and width that are almost totally ignored is a bit cruel, and counter to the behaviour of "width:" and "height:" in other contexts. Rather than setting the aspect-ratio of buttons (which I imagine was inherited from the v2 theme format) I think it would be more logical to prevent themers from setting the height (since that's required to be the height of the titlebar) and allow them to directly set the width (which you can use to calculate an aspect-ratio anyway).

It would make it difficult to have properly-square buttons unless there's some measurement that means "exactly the height of the titlebar", unless the themer made sure to set the font-size and various vertical paddings and margins in the same units (presumably ems or exes, which seems a reasonably sane thing to do).

TT: I need to think about this and play with the various options some more before I have a good answer either way.

3.3c: max/min width of buttons

ST: I imagine min-width and max-width only apply to buttons if their width is set to be a percentage.

3.3d: title positioning

ST: Currently, the cowbell docs suggest that text-align is the way to move the title text around the title-bar; some themers may expect to be able to use CSS tricks like:

title {
    position: absolute;
    left: 30%;
    top: 5px;
}

...to position the title exactly where they want it to be. Is this a thing we want to support, or prohibit?

TT: I'd think we should support it, but perhaps not in the first release.

Section 3.5: pseudoclasses

3.5a: :focus pseudoclass

ST: The "is-focused" attribute on the frame might more naturally be expressed with the CSS :focus pseudo-class. The contents of the "type" attribute might more naturally be expressed as classes (frame.dialog, frame.utility, etc.) Many of the Power attributes might more naturally be expressed as combinations of the :disabled pseudo-class and the corresponding button element (such as button.close:disabled).

TT: :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.

ST: Since the frame is the only thing that can logically be focussed (until such time as we have keyboard access to the title-bar buttons), I'd expect that only frames would ever match the :focus state - and the descendant selector should be more than adequate to do whatever theming is needed.

3.5b: :disabled pseudoclass

ST: Exposing the Power attributes is more generic than using the :disabled state on buttons, but I suspect :disabled buttons is what people will try first (by analogy with :hover and :active). You might as well do both, I guess.

TT: :disabled — hadn’t thought of this, good idea. TMTOWTDI.

3.5c: :not() pseudoclass

ST: Conventional HTML says that boolean attributes are present if the attribute is true, and absent if the attribute is false, like so:

<select name="version">
    <option default>Metacity 1.x
    <option>Metacity 2.x
</select>

It would seem simplest to make the state attributes work likewise, and let people use the :not() pseudo-class instead of testing for attributes equal to "0":

frame:not([is-maximized]) { ... }

TT: 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.

ST: The README claims it doesn't, but now that I think about it we shouldn't need it:

frame {
    /* default rules */
}

frame {
    /* rules for non-maximized windows */
}

frame[is-maximized] {
    /* overrides for maximized windows */
}

Section 3.7: SVG

ST: I hope eventually SVG images are supported, being rasterized at the output resolution rather than the input resolution.

TT: I hope we support SVG too. It would be extra nice if it could be styled with the same CSS somehow.

ST: If it's an SVG file in the same directory as the CSS file, I imagine you could have the SVG import the CSS file using whatever normal CSS import mechanisms SVG has. Of course, that might not be terribly useful until CSS has a way of defining colour keywords that can be re-used in multiple rules.

Section 3.8: units

ST: In CSS 2.1, "px" is defined as a distance that subtends about 0.0213 degrees of the user's visual field from a comfortable viewing distance - usually rounded to device pixels.

I think the most useful unit to have would be "em", so things could be sized relative to the title-bar text.

TT: I really want mm and em as well as px. I’m not certain libccss knows how to do this, but I will check.

Section 4: metadata

4a: separate metadata file

ST: There is a need for metadata in themes, but sticking it into the CSS cascade feels like an abuse. Since a theme will likely need separate image files anyway, you might as well put the metadata in a separate file - RFC-822 style, or JSON or one of the presumably many XML serialisations.

TT: 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.

ST: Well, Dublin Core data is designed for documents, and CSS is normally an add-on to a document rather than a document itself. I think themes should have required metadata, but since a theme is a collection of files I think it's OK if the CSS file isn't the "main" file.

As for custom formats, it seems RDF/XML is a popular way to express DC data. Alternatively, if you wanted to have a metadata file styled after HTML's <head>, the <meta> and <link> syntax is even simpler - and would enable you to use other HTML-like <link> elements for alternate stylesheets, as discussed below.

TT: I wonder whether this file should be mandatory even for simple themes.

ST: If it's simple enough to create, if there's examples to copy from and if there's not too many mandatory fields, I don't see why not. At the very least 'theme name' and 'author' should be available, I'd think.

4b: "alternate stylesheet"

ST: If a theme contains many variations, such a metadata file would also be a good place to describe the alternatives:

<link rel="alternate stylesheet" href="orange.css" title="Orange Highlights"/>
<link rel="alternate stylesheet" href="green.css" title="Green Highlights"/>

TT: I like the idea of specifying alternative stylesheets, though metadata in the stylesheets themselves could also do this.

ST: Metadata in the stylesheets themeselves *could* do this, but anyone familiar with HTML and CSS should already know about this syntax.

Section 6.1: the cascade; default stylesheets

ST: The "cascade" in CSS is the sequence of style sheets that override each other. The "default" appearance of items is just the appearance defined in the user-agent's built-in style sheet. The CSS spec includes a suggested default style sheet for HTML, it's only sensible that the Cowbell spec would include a default style sheet for its own appearance - and hopefully, a style sheet that includes lots of these "hooks" to make theme authorship easy.

TT: 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.

Section 6.2

6.2a: need to read tarballs

ST: Reading files from a zip or tar-ball is greatly useful.

TT: 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.

ST: What about ~/.themes/ThemeName.tar?

TT: it's just a convention that .themes is a set of directories named after themes with directories inside them named after formats; I wouldn't want to break this convention even though Cowbell is supposed to be cross-WM. And besides, that obscures the distinction between border themes and any other kind of themes (like widget themes).

6.2b: data: URLs considered harmful

ST: Storing images as data: URLs makes them a terrible pain to edit, and means having editable source-files and a build-process that creates a theme blob the WM can load. More pain than it's worth, IMHO.

TT: okay, we’ll avoid data: URLs.

Section 6.5: editors, Firebug

ST: Investigating the UI and capabilities of Firebug (a HTML/CSS/JS debugger add-on for Firefox) would be instructive.

TT: I really like Firebug. Are you thinking we could use Firebug itself, or just copy its UI?

ST: Firebug itself is too intimately tied to the Mozilla stack to be reusable, I suspect, but anything that edits CSS would be wise to liberally steal UI ideas from Firebug, as WebKit's Web Inspector and IE's Web Developer tools have.

Section 6.10: theme dependencies

ST: You already have a theme identifier in the -dc-identifier property, it shouldn't be too hard to have a property in the metadata for theme X that says "depends on the contents of theme Y", and if there's no installed theme whose -dc-identifier is set to Y, then you refuse to load theme X.

Section 6.11: specifying per-image HSV filters

ST: The -cowbell-color filter needs to affect individual images, not elements. It's hard to imagine how this might be specified in CSS syntax, except perhaps as an alternative to the url() function in "background-image:" property - something like this:

background-image: -cowbell-replace-color(#000, -cowbell-gtk("active", "text"), "menu.png");

TT: Maybe we could also modify hue/saturation/value directly in the URL thus:

url(’file:fred.png?hue=#f00′)

ST: That worries me, since the file: URL scheme is already defined not to take query strings, and fragment-identifiers are too useful to waste on a little hack like this.

As far as I know, there's no existing parameterisation systems designed to deal with this. Without adding any new file-formats at all, I imagine the best we could do is to depend on SVG graphics that use CSS2 System Colors.

It occurs to me that Mozilla has done some work recently with applying SVG filters to elements to HTML content, and while that work isn't directly applicable here (since I don't think any SVG filters easily allow the kind of palette-remapping we're talking about) we might want to appropriate the syntax with our own filter-definition format:

  • In some file called filters.txt:

    filter "map-to-normal" {
        map "#f00" gtk:text[NORMAL]
        map "#0f0" gtk:base[NORMAL]
    }
    
    filter "map-to-hover" {
        map "#f00" gtk:text[PRELIGHT]
        map "#0f0" gtk:base[PRELIGHT]
    }
  • In the CSS file:

    button.close {
        background-image:
            -cowbell-filter(url('filters.txt#map-to-normal'), url('close.png'));
    }
    
    button.close:hover {
        background-image:
            -cowbell-filter(url('filters.txt#map-to-hover'), url('close.png'));
    }

The -cowbell-filter() function would of course have to guess how to apply a particular filter to a particular image. If anyone ever wants, GLSL pixel-shaders in their themes (to replicate the blur effect that Aero uses) or some other crazy filter format, this would be a handy way of adding support for the feature without having to add new syntax.

* TT: Again, I need to play around with this and see what comes up.

Section 6.13: area.filler and alternatives to area.filler

ST: A simpler alternative might be to make the title markup slightly more complex:

<title>
    <titletext>Happy Birthday!</titletext>
</title>

...where <title> is a display: block element, and <titletext> is a display: inline element.

Then, you can add a background to the title element to draw the background on either side of the text, and add a background to the titletext element to cover it back up, no matter what the text-align property on the title element is.

TT: 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.

ST: My objection to area.filler is that it doesn't really fit into the CSS layout system (the filler areas would be controlled by the text-alignment given to the <title/> element, whereas normally text just flows into whatever container it's given, it can't affect the layout of other things around it). On the other hand, filler areas would make it possible to do things like the title-text-following decoration in Crux, or the the title-bar stripes on the Apple Lisa. I think the flexibility of area.filler is worth the incompatibility with strict CSS layout (which we're not using anyway).

Actions

* Put the XML-based description back in the docs. * Replace area.content and area.titlebar with content and titlebar. * Add a new element buttongroup which surrounds groups of buttons. * Read font-size from CSS; initial value is from gconf. * Set :focus on focused frames. * Look into adding :not() support to CCSS. * Look into adding em/mm support to CCSS if it doesn't already have them. * Maybe have an RDF default document? * Add filler either side (not area.filler this time). * ...more?

Projects/Metacity/CowbellDiscussion (last edited 2013-11-23 01:29:21 by WilliamJonMcCann)