Re: Sharing CSS code between Gtk and the Shell



> (Yes GMane, I'm top-posting)

That discussion has come up quite a bit on IRC, but I guess I never wrote down
what I think about this.

So, here's some principles I've followed in the development of the CSS stuff.
(Disclaimer: These are my own and not official GTK project principles. Other
developers might disagree with them.)

(1) CSS is an implementation detail of GTK
This means that I don't think GTK should expose API that lets you get at the
details of the CSS implementation. The most I'd want to allow people is to have
a string of CSS and throw it at GTK to influence how stuff behaves.
I certainly don't want to give anyone the ability to query CSS values. Because
if app developers have that capability, they will use it and do stuff with it.
And that stuff certainly isn't CSS conformant and then Lapo comes and shouts and
me when widgets behave in unexpected ways.
And that means that if you try to hook into the GTK CSS engine from the shell
you're gonna have a bad time.

(2) Keep the CSS interaction from the GTK core as small as possible
The API used by GTK widget implementations is essentially GtkStyleContext. The
drawing and sizing code is just calling _gtk_style_context_peek_value() (plus
the getters for the different value types) and the matching code needs a
GtkCssMatcher. That's it. So it should be reasonably easy to rip out if one
wanted to.

(3) Keep as close to CSS as possible
I want to follow the upstream development as closely as possible. This makes
some things really hard (like border collapsing). But it gives me a target for
performance considerations. Because when I know that there's an existing
implementation that is fast (read: Firefox or WebKit) I can be confident that I
can get there, too. This breaks down however if we have extra requirements
(color lookup is pretty slow for example).
Of course we are going to have extensions (like @define-color or icon-shadow,
and there's probably going to be quite a few more icon properties coming, like
"icon-style: symbolic" or @define-icon), but those need to be clearly marked and
it needs to be communicated that they can go away at any time, should a W3C
replacement come up for those.

(4) The CSS machinery is meant to be constantly in flux
This is necessary for two reasons: We want to implement new features and we need
memory/performance optimizations. Both of these often require large refactorings
of the CSS machinery. So essentially, the CSS stuff has broken its API every GTK
release. And I don't expect this to stop happening in the near future.
On the plus size, the refactorings have kept the code rather clean. So I think
it is easy to extend.

(5) We're gonna get rid of theme engines
Theme engines (and the ability to add custom style properties) will go away at
some point. That point will roughly be reached when Adwaita and Ubuntu don't
need to ship their own engine anymore. At that point all those deprecated
register_property() functions will be no-ops and GTK will not load plugins for
themes anymore.


So, now if I wanted to unify GNOME's CSS implementations, I would target:
- GTK
- St
- librsvg
- our own debugging tools for CSS
I would explicitly not target:
- everything else
and I would create a private CSS library that is essentially API unstable. I
would either make that library part of GTK (ie have a libgtkcss.so) or put it in
its own tarball. (I think I prefer the "inside GTK" solution, because all the
other targets link against GTK anyway and it makes refactoring easier - if we
assume GTK is the main driver of development.)
I would put into that library: gtkcss*.[ch], gtk*property.[ch],
gtkcssmatcher.[ch], gtkstyleprovider(private).[ch], gtkcssocomputedvalues.[ch],
gtkstylecontext.[ch]. And then I'd bump that library with every GTK release.

Would that work? Does that sound useful?


As a last thing, here's where I think the CSS code needs improvement:
- a tokenizing parser. strpbrk() only gets you so far.
- faster CSS computation. Alex has been working on it, but I think we're still 
WAY too slow.
- better debugging. Having to export GTK_CSS_DEBUG and what you get then is
kinda sad.

Benjamin


Giovanni Campagna <scampa.giovanni@...> writes:

> 
> Hello Gtk and hello Shell developers,
> 
> In https://bugzilla.gnome.org/show_bug.cgi?id=687881 I promised I'd
> try to address one of the big performance problems in the current
> gnome-shell, which is the St theming system.
> Currently St does an awful lot of string matching again and again, as
> neither the style classes and element names, nor the property names
> are interned or preprocessed. We rely on libcroco to do basic
> tokenization, but that's it, everything else happens every time a
> StThemeNode (~ GtkStyleContext) is computed. We introduced some
> caching at the beginning of the 3.7 cycle, but to me that's just
> papering over a bad implementation.
> So I started to rewrite it. I streamlined selector matching, added
> quarking to classes, tried to normalize css values at parsing time and
> finally built a map of known CSS properties to StThemeNode fields. But
> I don't have a selector tree, I don't have GtkBitmask optimizations, I
> had to reimplement GtkCssValue, etc.
> The patch is not complete (it's missing background properties), but
> I'm thinking: why should I write this again? Someone else did this in
> Gtk, can't we just use that?
> 
> And this prompted me to this mail: is there a way for gnome-shell to
> reuse Gtk CSS implementation?
> Ideally, we would just use GtkStyleContext outside GtkWidget, and
> parts of Gtk's docs claim it is supported. But I'm curious on what
> assumptions are made from GtkWidgetPath, and if those assumptions can
> be worked around or lifted. Additionally, there are a number of
> accessors that are not exposed by GtkStyleContext or GtkThemingEngine,
> but are available only to Gtk internals.
> Consider that we can't use gtk_render_*, since we use Cogl for
> painting, not cairo.
> The next issue with that straightforward approach is that St's theming
> is slightly more powerul than Gtk's. Looking at the gtk docs, I see
> Gtk has no support for box-shadow, icon-shadow (st extension),
> background-position, background-size, outline, text-decoration,
> text-align, as well as width, min-width and max-width. If we were to
> use Gtk directly, we would need to move our implementation into Gtk,
> or work around that limitation.
> Also, I saw that Gtk has recently deprecated extension CSS properties.
> We use a number of those in gnome-shell, and it's not always possible
> to replace them with standard CSS2, although I guess it'd be possible
> to use gtk_style_context_save() / add_class() / restore() like Gtk
> themes do.
> 
> The second option is to share just code, in some form, either as a
> private shared library that would be provided by Gtk
> (libgtk-internal?) and developed by both teams, or just as a copy-lib,
> with a massive s/Gtk/St/. I'm not sure what would be the cost of this
> last possibility, but I'm still convinced it would be lower than
> rewriting from scratch, and maintaining two different CSS
> implementations in GNOME.
> 
> Looking forward to your comments,
> 
> Giovanni
> 






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]