NEWS
Version 0.2, 2008-10-01
Focus on basic CSS support.
Features
- Border radius.
- Background image: -attachment, -position, -repeat, -size.
- External tool
css2gtkrc for extracting gtkrc information form stylesheets.
Theme
- Use actual borders for checks and options, make them use 100% of the
allocated space.
- Gilouche-CSS theme somewhat closer to the original.
Internals
- Have an internal instance of
ccss_style_t with default values, ccss_style_init()
initialises the style to those. Then drawing functions don't have to check
for NULL pointers any more, or, at least not handle them functionally.
- Create
color property and use it for bg- and fg-color (in block, style, ...).
- More robust parsing, handle (some) invalid CSS.
- Better stability, work around a problem in libcroco (b.g.o#553937).
Version 0.1, 2008-08-22
Focus on basic infrastructure.
- Matching (descendant and child).
- Background color.
- Basic border styles, also through the
color property.
- Single background image.
ROADMAP
0.3 "Features"
Features
- Improve gtkrc export.
- Add a fixup stage when the stylesheet is loaded, handle things like
single
background-size: <length>; there.
- Background attachment.
- Store type-name, type-id and selector-group in the GtkStyle and use that
information if no widget is passed.
- Border images, c.f. border-image in Firefox.
- Box-shadow.
- Multiple background images.
- Additional border features, e.g.
collapsed, none.
- Implement `inherit' as per CSS spec. Do we need our own set of attributed
inherited by default?
- Support per-object style attributes in libccss (and maybe also the engine, but how?).
The node-class interface would have to be extended to support a
get_style()
method.
- Application-specific theming, someting like
@import "gimp.css" gimp;,
maybe support wildcards like gimp* to match things like gimp-1.2.
- Match properties against properties, including namespaces:
e.g.
GtkVScrollbar[adjustment:value=attribute(adjustment:lower)].
Can be used to implement custom inactive scrollbars, c.f.
Link.
- Animated images APNG, MNG, animated GIF, whatever gdk-pixbuf supports.
- Support system gtk system colors.
- CSS Transitions
Internals
- Embed the "property" struct in all properties, implement
ccss_selector_apply()
in a generic manner.
- Check all list iterators for const-ness.
- Make all string comparisons case insensitive?
- Get rid of the _match() functions all toghether?
- Check 80 column code width.
- Use
for to iterate over GSList, e.g
for (GSList const *iter = list; iter != NULL; iter = iter->next) { ... }
Theme
- Make theme active (use pseudo-classes).
- Set text color.
- Ready for desktop-wide use.
0.4 "Correctness"
- Unit tests.
- Test using the theme torturer.
- Test using valgrind.
- Investigate splitting out
ccss_css2_style_t from ccss_style_t making it
an opaque unsigned char[x]. Install only a minimal number of of required
headers (ccss, stylesheet, selector-group, style*, node).
- Think about per-stylesheet node-class and functions interface.
- Bugzilla module.
0.5 "Performance"
- Profile using the theme torturer.
- Can selectors and blocks be merged at theme load time?
- Can computed styles be attached to widgets using gobjectset_data()?
- Use a string pool for the lookup tables?
- Can we use binary search in the lookup tables?
- Cache the type name inside the node?
0.6 "Compliance"
- Support widget mimicking by creating Gtk[Rc]Style style information and
feeding it back into gtk, e.g. using
gtk_rc_parse(). Maybe we would end up
with two drawing modes, the normal one and the GtkStyle based one. In any
case gtk_rc_get_style_by_paths() should work. This is very apparent e.g. with
the empty treeview in TWF. Maybe need to fix this earlier, at least partially.
More 0. releases go here if needed ...
1.0 "Rejoicing"
Implement additional CSS pseudo classes like :first-element,
:last-element, maybe custom ones for GtkTable, HippoCanvas.
Those will be queried on the container and can e.g. be used to
make the outer corners of buttons in a button box rounded.
GtkHButtonBox GtkButton:first-element {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
GtkHButtonBox GtkButton:last-element {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
1.2 "Fonts"
2.0 "Canvas"
- Implement a WHATWG canvas and let the theme draw on it using ECMAScript.
Out of band
- Libcroco: fix
#foo and .bar global selectors.
- Investigate libcroco CSS3 compliance: sequences, tuples (see background-image)
- Create a spiffy website, possibly on GNOME Projects.
Any volunteers?
- Evaluate alternative SVG renderers as they become available.
- Investigate a helper app for widget matching, like what's in
GLE.
Inspirations for themes
README
Download
(0) Supported CSS Subset
- Descendant selectors, e.g.
GtkComboBox GtkButton { ... }.
- Child selectors, e.g.
GtkBox > GtkButton { ... }.
- Class selectors, e.g.
hline.handlebox { ... }.
The class-part is mapped to gtk'd detail string.
- ID selectors, e.g.
GtkButton#foo { ... }.
The ID-part is mapped to the widget's name.
- Universal selector, e.g.
* { ... }.
- Sequences of selectors, e.g.
GtkNotebook, GtkFrame { ... }.
(0.1) Supported CSS Properties
The following properties are at least partially supported.
- background
- background-color
- background-image
- background-attachment
- background-position
- background-repeat
- background-size
- border
- border-bottom
- border-left
- border-right
- border-top
- border-radius
- border-top-left-radius
- border-top-right-radius
- border-bottom-right-radius
- border-bottom-left-radius
- color
(1) Primitives
Attributes are canonicalised, i.e. s/_/-/g.
Comments are enclosed in ().
Optionality is expressed through [].
pseudo class "normal" will be default.
arrow
- Classes: arrow | calendar | menu-scroll-arrow-up | menu-scroll-arrow-down |
menuitem | notebook | spinbutton | tearoffmenuitem |
hscrollbar | vscrollbar
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
- arrow: up | down | left | right | none
box
- Classes: buttondefault | button | bar (cellrendererprogress) |
handlebox-bin | hruler | hseparator (in `wide-separators' mode) |
menubar | menu | menu-scroll-arrow-up | menu-scroll-arrow-down |
menuitem | hseparator | notebook | optionmenu |
bar (progress-bar) | trough (progress-bar | range) | hscrollbar |
vscrollbar | trough-upper | trough-lower | trough-fill-level-full |
trough-fill-level | spinbutton | spinbutton-up | spinbutton-down |
toolbar | vseparator | vruler | base (window)
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
boxgap, mapped onto "box".
- Classes: notebook
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
- position: left | right | top | bottom
check
- Classes: cellcheck | checkbutton | check (menuitem)
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
diamond
No predefined classes for this primitive.
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
expander
- Classes: expander | treeview
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- style: collapsed | semi-collapsed | semi-expanded | expanded
extension
- Classes: tab (notebook)
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
- position: left | right | top | bottom
flatbox
- Classes: checkbutton | curve-bg | entry-bg | eventbox | expander | tooltip |
listitem | trough (progress) | checkbutton | text | treeitem |
viewportbin | base (window) |
cell-odd[-start | -end | -middle] |
cell-even[-start | -end | -middle] |
cell-odd-ruled-sorted[-start | -end | -middle] |
cell-even-ruled-sorted[-start | -end | -middle] |
cell-odd-ruled[-start | -end | -middle] |
cell-even-ruled[-start | -end | -middle] |
cell-odd-sorted[-start | -end | -middle] |
cell-even-sorted[-start | -end | -middle]
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
focus
- Classes: button | calendar-day | checkbutton | entry | expander |
colorwheel-light | colorwheel-dark | iconview-drop-indicator |
icon-view | add-mode (listitem) | tab | button (gtkoptionmenu) |
trough (gtkrange) | text | textview | tray-icon | treeitem |
treeview-drop-indicator[-left | -right | -middle] |
treeview[-left | -right | -middle]
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
handle
- Classes: handlebox | paned
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
- orientation: horizontal | vertical
hline
- Classes: handlebox | hseparator | menuitem | tearoffmenuitem | toolbar
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
option
- Classes: cellradio | option (menuitem) | radiobutton
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
resizegrip
- Classes: statusbar
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- edge: north-west | north | north-east | west | east | south-west | south | south-east
shadow
- Classes: calendar | combobox | dnd | entry | frame | handle |
scrolled-window | text | viewport
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
shadowgap, mapped onto "shadow".
- Classes: frame
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
- position: left | right | top | bottom
slider
- Classes: hscale | vscale
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
tab
- Classes: optionmenu | tab
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
- shadow: none | in | out | etched-in | etched-out
vline
- Classes: handlebox | toolbar | vseparator
- Pseudo classes: normal | active | prelight | selected | insensitive
- Selectors:
- Arbitrary widget properties that can be represented as a string.
(1.1) Unsupported primitives
(2) Brainstorming
- Multiple classes per element, can this be emulated somehow?
- CSS Variables. Also named colours could be implemented as built-in variables.
HACKING
General remarks
Code is a maximum of 80 characters wide. This keeps it readable also where
the original screen width limitations do not apply any more.
Use C99, in particular stdint and stdbool, except that variables go at the
beginning of the block. You may use embedded counters in `for' loops though.
Do not initialise variables, pointers in particular, where they are declared.
Initialise immediately before usage and read compiler warnings to find out
whether any variables are being used without initialisation.
Use variable names in sizeof() statements rather than type names. Otherwise
refactorings including changing the datatype can render those broken. Example:
foo_t f;
memset (f, 0, sizeof (f));
Including files
Always include files in the following order:
- C headers, in alphabetical order.
- Dependency libraries' headers, in alphabetical order.
- Project headers, in alphabetical order.
In header files only ever include using pointy brackets and directory prefix.
This makes sure that installed headers work correctly and facilitates
installation of multiple incompatible library versions in the same prefix.
Example foo.h:
#include <bar/bar.h>
In C files plain inclusion of headers from the project is encouraged, just
give the header's file name and leave setting of directories to the build
system. Example foo.c:
#include "foo.h"
Making a release
- NEWS.
- TODO.
- Remove extra version in configure.in.
make distcheck.
- Commit to svn.
- Tag in svn.
- Upload tarball.
- Announce.
- Bump version and add extra version in configure.in.
- Commit to svn.
- Update web-page.