Translate

Archives

Unico Theming Engine on Fedora 16

GNOME 3.2 on Fedora 16 ships with only one GTK+ 3.x theming engine, i.e. Adwaita, which is used to theme the bland GNOME 3 default theme (also called Adwaita.) This post shows to how to add the Unico theming engine to Fedora 16 so that you can make use of the many excellent themes that use or can use the Unico engine.

For example, here are two themes which are currently unavailable for GNOME 3 on Fedora 16 but which are nicely rendered by the Unico theme engine. This is the Zubitwo theme:
Unico screenshot
and this is the Adwance theme:
Unico screenshot

What I hear you ask is a theme engine and why do I need more than one theme engine? There is no precise formal definition of a theme engine that I can point to. However a theme engine can be thought of as a thin layer of code that translates the look and feel (the style) of a GTK+ 2.x or GTK+ 3.x widget according to a set of written directives. Or, to put it another way, a theme engine renders widgets in accordance with directives contained in themes. Theme engines work because the GTK+ widget library supports the customization of widget look and feel by means of a shared library (.so) which is loaded to render a particular style. Styling options are mostly engine specific so what works with one engine may or may not work with another engine.

Theme engines are not something new and wonderful; they have been around for a number of years. Support for theme engines was first provided in GTK+ 2.x via the GtkStyle interface using a configuration file called gtkrc. Since 2005 (GNOME 2.2), the default GNOME 2 theme engine has been Clearlooks which was created by Richard Stellingwerff and Daniel Borgmann. Clearlooks has undergone extensive modification since it was first introduced and now uses the Cairo 2D graphics library to render widgets. Prior to Clearlooks, there was no default theme engine. If no theme engine is provided, GTK+ provides a very basic theme called Raleigh. By the way, GTK+ 2.2 and later includes support for a dark variation of an existing theme. Just set the GtkSettings gtk-application-prefer-dark-theme to true.

GTK+ 2.x themes generally live in either a global public directory (/usr/share/themes/THEMENAME/gtk-2.0) or in $HOME/.themes/THEMENAME/gtk-2.0/. If themes of the same name are installed in both the global and the $HOME/.themes directories, GNOME will use the one in $HOME/.themes. If you want to learn more about GTK+ 2.x theming, a good starting point is here and here.

At the 2008 Istanbul GUADEC, developers discussed ways to improve GTK+ theming support and a plan was hatched to move to CSS (Cascading Style Sheets) for specifying the appearance of GTK+ widgets instead of using gtkrc. Meanwhile GNOME developer Robert Staudinger had already been working on an experimental GTK+ CSS theme engine which he announced in July 2008.

Roll forward to early 2011 and the release of GTK+ 3.x and GNOME 3. With this release, theme engines are required to implement the GtkThemingEngine object, theme engines must be installed in $LIBDIR/gtk+-3.0/$GTK_VERSION/theming-engines, and theme files containing style information must be written in the CSS-like format that is understood by GtkCssProvider with the default styling file being /usr/share/themes/THEMENAME/gtk-3.0/gtk.css. In addition, variants of a theme are supposed and placed in the same directory. For example the dark variant of a theme should be named gtk-dark.css and be placed in the same directory as gtk.css. Personal themes are placed in $HOME/.themes/THEMENAME/gtk-3.0/. If you want to learn more about styling GTK+ using CSS, Carlos Garnacho wrote a good article about this topic earlier this year for the GNOME Journal.

The current default GNOME 3 theming engine, Adwaita, was written by the previously mentioned Carlos Garnacho and as he put it in a commit email in January 2011:

This is a blatant ripoff of some clearlooks drawing methods, used as a support by the Adwaita theme to help out with the things that can’t be themed through GtkStyleContext.

If we look at the files under /usr/share/themes/Adwaita, the various files and subdirectories should make more sense to you in light of the quick history of theming engines that I have just provided.

./gtk-2.0
./gtk-2.0/gtkrc
./gtk-3.0
./gtk-3.0/gtk-dark.css
./gtk-3.0/gnome-applications.css
./gtk-3.0/gtk-widgets-dark-overrides.css
./gtk-3.0/gtk-widgets-assets.css
./gtk-3.0/gtk-widgets.css
./gtk-3.0/assets
./gtk-3.0/assets/sidebar-radio-checked-dark.svg
./gtk-3.0/assets/scale-slider-marks-above-horizontal.svg
./gtk-3.0/assets/scale-slider-marks-below-horizontal-dark.svg
./gtk-3.0/assets/radio-unselected-insensitive.svg
./gtk-3.0/assets/checkbox-mixed-insensitive.svg
./gtk-3.0/assets/sidebar-radio-selected-prelight.svg
./gtk-3.0/assets/scale-slider-horizontal-insensitive-dark.svg
./gtk-3.0/assets/radio-unselected.svg
./gtk-3.0/assets/primary-toolbar-button-active-border.svg
./gtk-3.0/assets/trough-active-border-horizontal-dark.svg
./gtk-3.0/assets/trough-active-border-vertical.svg
./gtk-3.0/assets/trough-border-vertical.svg
./gtk-3.0/assets/radio-selected-insensitive-dark.svg
./gtk-3.0/assets/radio-unselected-insensitive-dark.svg
./gtk-3.0/assets/checkbox-unchecked.svg
./gtk-3.0/assets/progressbar-border-dark.svg
./gtk-3.0/assets/scale-slider-vertical-dark.svg
./gtk-3.0/assets/checkbox-checked-insensitive.svg
./gtk-3.0/assets/entry-border-normal-dark.svg
./gtk-3.0/assets/radio-mixed-dark.svg
./gtk-3.0/assets/radio-menuitem-checked-selected.svg
./gtk-3.0/assets/sidebar-radio-selected-dark.svg
./gtk-3.0/assets/entry-border-focused-dark.svg
./gtk-3.0/assets/progressbar-border-vertical-dark.svg
./gtk-3.0/assets/scale-slider-vertical-insensitive.svg
./gtk-3.0/assets/trough-border-horizontal-dark.svg
./gtk-3.0/assets/scale-slider-horizontal.svg
./gtk-3.0/assets/scale-slider-marks-below-vertical-dark.svg
./gtk-3.0/assets/scale-slider-vertical.svg
./gtk-3.0/assets/radio-selected-insensitive.svg
./gtk-3.0/assets/checkbox-unchecked-dark.svg
./gtk-3.0/assets/button-border-dark.svg
./gtk-3.0/assets/button-border.svg
./gtk-3.0/assets/trough-active-border-vertical-dark.svg
./gtk-3.0/assets/checkbox-mixed-insensitive-dark.svg
./gtk-3.0/assets/scale-slider-marks-below-vertical-insensitive.svg
./gtk-3.0/assets/checkbox-checked.svg
./gtk-3.0/assets/radio-menuitem-checked.svg
./gtk-3.0/assets/scale-slider-marks-above-vertical-insensitive-dark.svg
./gtk-3.0/assets/scale-slider-marks-below-vertical-insensitive-dark.svg
./gtk-3.0/assets/checkbox-mixed.svg
./gtk-3.0/assets/sidebar-radio-checked.svg
./gtk-3.0/assets/scale-slider-horizontal-insensitive.svg
./gtk-3.0/assets/progressbar-border.svg
./gtk-3.0/assets/primary-toolbar-raised-button-border-dark.svg
./gtk-3.0/assets/primary-toolbar-button-active-border-dark.svg
./gtk-3.0/assets/primary-toolbar-raised-button-border.svg
./gtk-3.0/assets/scale-slider-horizontal-dark.svg
./gtk-3.0/assets/combobox-entry-border-active.svg
./gtk-3.0/assets/checkbox-menuitem-checked-insensitive.svg
./gtk-3.0/assets/radio-mixed-insensitive.svg
./gtk-3.0/assets/switch-slider-border.svg
./gtk-3.0/assets/checkbox-menuitem-checked-selected.svg
./gtk-3.0/assets/button-default-border.svg
./gtk-3.0/assets/button-active-border-dark.svg
./gtk-3.0/assets/sidebar-radio-selected.svg
./gtk-3.0/assets/scale-slider-marks-above-horizontal-insensitive-dark.svg
./gtk-3.0/assets/checkbox-menuitem-mixed-insensitive.svg
./gtk-3.0/assets/radio-mixed-insensitive-dark.svg
./gtk-3.0/assets/checkbox-unchecked-insensitive.svg
./gtk-3.0/assets/checkbox-checked-insensitive-dark.svg
./gtk-3.0/assets/trough-border-horizontal.svg
./gtk-3.0/assets/sidebar-radio-prelight.svg
./gtk-3.0/assets/checkbox-unchecked-insensitive-dark.svg
./gtk-3.0/assets/scale-slider-marks-below-horizontal.svg
./gtk-3.0/assets/checkbox-menuitem-mixed.svg
./gtk-3.0/assets/entry-border-normal.svg
./gtk-3.0/assets/scale-slider-marks-below-vertical.svg
./gtk-3.0/assets/radio-selected-dark.svg
./gtk-3.0/assets/scale-slider-marks-above-horizontal-insensitive.svg
./gtk-3.0/assets/radio-menuitem-checked-insensitive.svg
./gtk-3.0/assets/checkbox-mixed-dark.svg
./gtk-3.0/assets/switch-slider-active-border.svg
./gtk-3.0/assets/button-active-border.svg
./gtk-3.0/assets/scale-slider-marks-below-horizontal-insensitive-dark.svg
./gtk-3.0/assets/radio-unselected-dark.svg
./gtk-3.0/assets/trough-border-vertical-dark.svg
./gtk-3.0/assets/radio-menuitem-mixed-insensitive.svg
./gtk-3.0/assets/progressbar-border-vertical.svg
./gtk-3.0/assets/radio-mixed.svg
./gtk-3.0/assets/entry-border-focused.svg
./gtk-3.0/assets/scale-slider-marks-above-horizontal-dark.svg
./gtk-3.0/assets/scale-slider-marks-above-vertical-insensitive.svg
./gtk-3.0/assets/radio-selected.svg
./gtk-3.0/assets/trough-active-border-horizontal.svg
./gtk-3.0/assets/scale-slider-vertical-insensitive-dark.svg
./gtk-3.0/assets/button-default-border-dark.svg
./gtk-3.0/assets/checkbox-menuitem-checked.svg
./gtk-3.0/assets/scale-slider-marks-below-horizontal-insensitive.svg
./gtk-3.0/assets/scale-slider-marks-above-vertical-dark.svg
./gtk-3.0/assets/radio-menuitem-mixed.svg
./gtk-3.0/assets/scale-slider-marks-above-vertical.svg
./gtk-3.0/assets/checkbox-checked-dark.svg
./gtk-3.0/settings.ini
./gtk-3.0/gtk.css
./gtk-3.0/gtk-widgets-assets-dark.css
./backgrounds
./backgrounds/stripes.jpg
./index.theme
./metacity-1
./metacity-1/metacity-theme-3.xml
./metacity-1/metacity-theme-2.xml


The files under …/gtk-3.0/assets/ are image files for the GTK+ 3.x theming engine. How and where they are actually used is specified in one or more of the seven CSS files used to specify this particular theme. The file gtk-dark.css indicates that a dark variation of the Adwaita theme is also available.

Notice the metacity files? I have yet not talked about what are sometimes called metacity themes. Metacity is a window manager that was introduced in GNOME 2.2 as a replacement for an older and less flexible window manager. Metacity supports customization (styling) of its window frames using XML files. Remember, a window frame and what is inside of a window are independent and unrelated. A Metacity theme is a set of instructions about how to render the frame decorations around a window. A good starting point to learn more about Metacity is here.

With background information out of the way, let us now turn to how to build, install and use the Unico theming engine with GNOME 3.2 on Fedora 16. The current version of Unico is 1.0.1. You can download it at the Ubuntu launchpad website. The engine was developed by Canonical employee Andrea Cinitan. It builds on Fedora 16 without any problems if you have the following development libraries installed:

cairo-devel-1.10.2-4
gtk3-devel-3.2.0-1


Once you have the requisite development libraries installed, you can configure and build the Unico theming engine using:

$ ./configure --prefix=/
$ make


You can test the new theme engine by invoking test-widgets from the tests sub-directory.

Unico screenshot

Use make install to install the library. For 32-bit platforms, the appropriate place is /lib/gtk-3.0/3.0.0/theming-engines/.

# ls -l /lib/gtk-3.0/3.0.0/theming-engines/libunico*
-rw-r--r--. 1 root root 382502 Oct  8 17:17 libunico.a
-rwxr-xr-x. 1 root root   1166 Oct  8 17:17 libunico.la
-rwxr-xr-x. 1 root root 228069 Oct  8 17:17 libunico.so


For 64-bit platforms, /lib64/gtk-3.0/3.0.0/theming-engines is the appropriate place. You can delete the .a and .la files; they are not required.

If you want to create an RPM package for Unico, here is a suitable .spec file.

Name: gtk3-unico-engine
Version: 1.0.1
Release: 1%{?dist}
Summary: Unico GTK3+ theme engine

Group: System Environment/Libraries
License: LGPLv2+
URL: https://launchpad.net/unico

Packager: fpmurphy

Source: http://launchpad.net/ubuntu/+archive/primary/+files/gtk3-engines-unico_1.0.1.orig.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

BuildRequires: glib2-devel >= 2.26.0
BuildRequires: gtk3-devel  >= 3.1.10
BuildRequires: cairo-devel >= 1.10

%description
Unico is a GTK3+ theme engine that uses CSS for styling directives.
It is the default GTK3+ theme engine on Ubuntu 11.10 (Oneiric).

%prep
%setup -q -n unico-%{version}

%build
%configure
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

%clean
rm -rf $RPM_BUILD_ROOT

%define _unpackaged_files_terminate_build 0
# only package the .so and any doc

%files
%defattr(-,root,root,-)
%doc
%{_libdir}/gtk-3.0/3.0.0/theming-engines/libunico.so

%changelog
* Sat Oct 8 2011 F.P.Murphy  1.0.1
- Initial RPM release 


If you are unsure of how to build an RPM package, here is a good resource. If you want to use the Unico engine RPM that I created, you can download the RPM or SRPM from here.

Looking at the source code that implements to the GtkThemingEngine object provides us with an easy way to compare the styling directives supported by the Adwaita and Unico engines.

Here is the Unico implementation:

static void
unico_engine_class_init (UnicoEngineClass *klass)
{
  GtkThemingEngineClass *engine_class = GTK_THEMING_ENGINE_CLASS (klass);

  engine_class->render_activity    = unico_engine_render_activity;
  engine_class->render_arrow       = unico_engine_render_arrow;
  engine_class->render_background  = unico_engine_render_background;
  engine_class->render_check       = unico_engine_render_check;
  engine_class->render_expander    = unico_engine_render_expander;
  engine_class->render_extension   = unico_engine_render_extension;
  engine_class->render_focus       = unico_engine_render_focus;
  engine_class->render_frame       = unico_engine_render_frame;
  engine_class->render_frame_gap   = unico_engine_render_frame_gap;
  engine_class->render_handle      = unico_engine_render_handle;
  engine_class->render_line        = unico_engine_render_line;
  engine_class->render_option      = unico_engine_render_option;
  engine_class->render_slider      = unico_engine_render_slider;

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("background-texture",
                                                            "Background texture",
                                                            "Background texture",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-border-color",
                                                            "Focus border color",
                                                            "Focus border color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_int ("focus-border-radius",
                                                          "Focus border radius",
                                                          "Focus border radius",
                                                          0, G_MAXINT, 0, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-fill-color",
                                                            "Focus fill color",
                                                            "Focus fill color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-outer-stroke-color",
                                                            "Focus outer stroke color",
                                                            "Focus outer stroke color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_int ("glow-radius",
                                                          "Glow radius",
                                                          "Glow radius",
                                                          0, G_MAXINT, 0, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("glow-color",
                                                            "Glow color",
                                                            "Glow color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-color",
                                                            "Inner stroke color",
                                                            "Inner stroke color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-top-color",
                                                            "Inner stroke top color",
                                                            "Inner stroke top color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-right-color",
                                                            "Inner stroke right color",
                                                            "Inner stroke right color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-bottom-color",
                                                            "Inner stroke bottom color",
                                                            "Inner stroke bottom color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("glow-color",
                                                            "Glow color",
                                                            "Glow color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-color",
                                                            "Inner stroke color",
                                                            "Inner stroke color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-top-color",
                                                            "Inner stroke top color",
                                                            "Inner stroke top color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-right-color",
                                                            "Inner stroke right color",
                                                            "Inner stroke right color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-bottom-color",
                                                            "Inner stroke bottom color",
                                                            "Inner stroke bottom color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-left-color",
                                                            "Inner stroke left color",
                                                            "Inner stroke left color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-gradient",
                                                            "Inner stroke gradient",
                                                            "Inner stroke gradient",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("inner-stroke-width",
                                                            "Inner stroke width",
                                                            "Inner stroke width",
                                                            GTK_TYPE_BORDER, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-color",
                                                            "Outer stroke color",
                                                            "Outer stroke color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-top-color",
                                                            "Outer stroke top color",
                                                            "Outer stroke top color",
                                                            GDK_TYPE_RGBA, 0));

 gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-right-color",
                                                            "Outer stroke right color",
                                                            "Outer stroke right color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-bottom-color",
                                                            "Outer stroke bottom color",
                                                            "Outer stroke bottom color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-left-color",
                                                            "Outer stroke left color",
                                                            "Outer stroke left color",
                                                            GDK_TYPE_RGBA, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-gradient",
                                                            "Outer stroke gradient",
                                                            "Outer stroke gradient",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("outer-stroke-width",
                                                            "Outer stroke width",
                                                            "Outer stroke width",
                                                            GTK_TYPE_BORDER, 0));

  gtk_theming_engine_register_property (UNICO_NAMESPACE, NULL,
                                        g_param_spec_boxed ("text-shadow-color",
                                                            "Text shadow color",
                                                            "Text shadow color",
                                                            GDK_TYPE_RGBA, 0));
}

and here is what is implemented by the Adwaita engine:

static void
adwaita_engine_class_init (AdwaitaEngineClass *klass)
{
  GtkThemingEngineClass *engine_class = GTK_THEMING_ENGINE_CLASS (klass);

  engine_class->render_arrow = adwaita_engine_render_arrow;
  engine_class->render_focus = adwaita_engine_render_focus;
  engine_class->render_check = adwaita_engine_render_check;
  engine_class->render_option = adwaita_engine_render_option;
  engine_class->render_extension = adwaita_engine_render_extension;
  engine_class->render_frame = adwaita_engine_render_frame;
  engine_class->render_background = adwaita_engine_render_background;
  engine_class->render_expander = adwaita_engine_render_expander;
  engine_class->render_activity = adwaita_engine_render_activity;
  engine_class->render_slider = adwaita_engine_render_slider;
  engine_class->render_handle = adwaita_engine_render_handle;

  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-border-color",
                                                            "Focus border color",
                                                            "Focus border color",
                                                            GDK_TYPE_RGBA, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_int ("focus-border-radius",
                                                          "Focus border radius",
                                                          "Focus border radius",
                                                          0, G_MAXINT, 0,
                                                          0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-border-gradient",
                                                            "Focus border gradient",
                                                            "Focus border gradient",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("focus-fill-color",
                                                            "Focus fill color",
                                                            "Focus fill color",
                                                            GDK_TYPE_RGBA, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("selected-tab-color",
                                                            "Selected tab color",
                                                            "Selected tab color",
                                                            GDK_TYPE_RGBA, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("border-gradient",
                                                            "Border gradient",
                                                            "Border gradient",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boolean ("focus-border-dashes",
                                                              "Focus border uses dashes",
                                                              "Focus border uses dashes",
                                                              FALSE, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("menuitem-arrow-color",
                                                            "Menuitem arrow color",
                                                            "Menuitem arrow color",
                                                            GDK_TYPE_RGBA, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("switch-grip-color",
                                                            "Switch grip color",
                                                            "Switch grip color",
                                                            GDK_TYPE_RGBA, 0));
  gtk_theming_engine_register_property (ADWAITA_NAMESPACE, NULL,
                                        g_param_spec_boxed ("progressbar-pattern",
                                                            "Progressbar pattern",
                                                            "Progressbar pattern",
                                                            CAIRO_GOBJECT_TYPE_PATTERN, 0));
}


The Unico engine appears to support a richer set of styling options. Go here if you want to browse the source code for the Unico engine. Go here if you want to browse source code for the Adwaita engine.

Once you have the Unico theming engine installed, you need to find a suitable GNOME theme that uses this engine, install that theme and tell GNOME to use the theme. For the purposes of this post, I installed the excellent GNOME Zukitwo theme pack which was created by a young Swedish digital artist. This theme pack includes three variations of a minimalistic theme as three separate themes as well as a theme for the GNOME Shell.

Here are the files for one of the three themes:

./metacity-1
./metacity-1/maximize_unfocused_prelight.png
./metacity-1/menu_prelight.png
./metacity-1/maximize_focused_normal.png
./metacity-1/maximize_focused_prelight.png
./metacity-1/close_unfocused_prelight.png
./metacity-1/minimize_unfocused_prelight.png
./metacity-1/unmaximize_focused_pressed.png
./metacity-1/close_unfocused.png
./metacity-1/maximize_unfocused.png
./metacity-1/metacity-theme-3.xml
./metacity-1/menu.png
./metacity-1/minimize_focused_prelight.png
./metacity-1/trough_right.png
./metacity-1/close_focused_normal.png
./metacity-1/close_focused_prelight.png
./metacity-1/trough_middle.png
./metacity-1/close_focused_pressed.png
./metacity-1/minimize_focused_pressed.png
./metacity-1/minimize_focused_normal.png
./metacity-1/unmaximize_focused_normal.png
./metacity-1/unmaximize_focused_prelight.png
./metacity-1/metacity-theme-1.xml
./metacity-1/minimize_unfocused.png
./metacity-1/unmaximize_unfocused_prelight.png
./metacity-1/maximize_focused_pressed.png
./metacity-1/trough_left.png
./metacity-1/unmaximize_unfocused.png
./gtk-3.0
./gtk-3.0/unity
./gtk-3.0/unity/close_unfocused_over.png
./gtk-3.0/unity/maximize_unfocused_prelight.png
./gtk-3.0/unity/menu_prelight.png
./gtk-3.0/unity/maximize_focused_normal.png
./gtk-3.0/unity/maximize_focused_prelight.png
./gtk-3.0/unity/close_unfocused_prelight.png
./gtk-3.0/unity/minimize_unfocused_prelight.png
./gtk-3.0/unity/unmaximize_focused_pressed.png
./gtk-3.0/unity/close_unfocused.png
./gtk-3.0/unity/maximize_unfocused.png
./gtk-3.0/unity/minimize_unfocused_over.png
./gtk-3.0/unity/menu.png
./gtk-3.0/unity/minimize_focused_prelight.png
./gtk-3.0/unity/trough_right.png
./gtk-3.0/unity/close_focused_normal.png
./gtk-3.0/unity/minimize.png
./gtk-3.0/unity/close_focused_prelight.png
./gtk-3.0/unity/trough_middle.png
./gtk-3.0/unity/close_focused_pressed.png
./gtk-3.0/unity/minimize_focused_pressed.png
./gtk-3.0/unity/minimize_focused_normal.png
./gtk-3.0/unity/unmaximize_focused_normal.png
./gtk-3.0/unity/unmaximize_focused_prelight.png
./gtk-3.0/unity/unmaximize_unfocused_pressed.png
./gtk-3.0/unity/close.png
./gtk-3.0/unity/minimize_unfocused.png
./gtk-3.0/unity/close_unfocused_pressed.png
./gtk-3.0/unity/maximize_unfocused_over.png
./gtk-3.0/unity/unmaximize_unfocused_prelight.png
./gtk-3.0/unity/unmaximize.png
./gtk-3.0/unity/maximize.png
./gtk-3.0/unity/maximize_focused_pressed.png
./gtk-3.0/unity/minimize_unfocused_pressed.png
./gtk-3.0/unity/maximize_unfocused_pressed.png
./gtk-3.0/unity/unmaximize_unfocused_over.png
./gtk-3.0/unity/trough_left.png
./gtk-3.0/unity/unmaximize_unfocused.png
./gtk-3.0/gtk-widgets.css
./gtk-3.0/apps
./gtk-3.0/apps/gnome-panel.css
./gtk-3.0/apps/nautilus.css
./gtk-3.0/apps/unity.css
./gtk-3.0/settings.ini
./gtk-3.0/gtk.css
./gtk-2.0
./gtk-2.0/widgets
./gtk-2.0/widgets/Null
./gtk-2.0/widgets/Null/null.png
./gtk-2.0/widgets/Null/Thumbs.db
./gtk-2.0/widgets/Panel
./gtk-2.0/widgets/Panel/panel-button-inactive.png
./gtk-2.0/widgets/Panel/panel-button-active.png
./gtk-2.0/widgets/Panel/arrow-blank.png
./gtk-2.0/widgets/Panel/Thumbs.db
./gtk-2.0/widgets/Panel/handle-h.png
./gtk-2.0/widgets/Panel/arrow-down.png
./gtk-2.0/widgets/Panel/handle-v.png
./gtk-2.0/widgets/Panel/panel-bg.png
./gtk-2.0/widgets/Panel/panel-button-hover.png
./gtk-2.0/widgets/toolbar.rc
./gtk-2.0/widgets/panel.rc
./gtk-2.0/widgets/Others
./gtk-2.0/widgets/Others/null.png
./gtk-2.0/widgets/Others/handle.png
./gtk-2.0/widgets/Others/toolbar.png
./gtk-2.0/widgets/Others/close.png
./gtk-2.0/apps
./gtk-2.0/apps/Nautilus
./gtk-2.0/apps/Nautilus/breadcrumb_active.png
./gtk-2.0/apps/Nautilus/mode_normal.png
./gtk-2.0/apps/Nautilus/resize_grip.png
./gtk-2.0/apps/Nautilus/breadcrumb_prelight.png
./gtk-2.0/apps/Nautilus/slider.png
./gtk-2.0/apps/Nautilus/left_slider_normal.png
./gtk-2.0/apps/Nautilus/breadcrumb_normal.png
./gtk-2.0/apps/Nautilus/trough.png
./gtk-2.0/apps/Nautilus/extra-widget.png
./gtk-2.0/apps/Nautilus/slider-prelight.png
./gtk-2.0/apps/Nautilus/mode_pressed.png
./gtk-2.0/apps/Nautilus/nautilus-toolbar.png
./gtk-2.0/apps/Nautilus/mode_prelight.png
./gtk-2.0/apps/Nautilus/right_slider_normal.png
./gtk-2.0/apps/nautilus-e.rc
./gtk-2.0/apps/stock_forward.png
./gtk-2.0/apps/Null
./gtk-2.0/apps/Null/null.png
./gtk-2.0/apps/Null/Thumbs.db
./gtk-2.0/apps/nautilus.rc
./gtk-2.0/apps/stock_back.png
./gtk-2.0/apps/stock_home.png
./gtk-2.0/apps/stock_stop.png
./gtk-2.0/apps/stock_find.png
./gtk-2.0/apps/stock_refresh.png
./gtk-2.0/apps/combo_down.png
./gtk-2.0/apps/pcmanfm.rc
./gtk-2.0/apps/Others
./gtk-2.0/apps/Others/null.png
./gtk-2.0/apps/Others/Thumbs.db
./gtk-2.0/apps/dummy.png
./gtk-2.0/apps/gedit.rc
./gtk-2.0/apps/Handles
./gtk-2.0/apps/Handles/Thumbs.db
./gtk-2.0/apps/Handles/handle-nautilus.png
./gtk-2.0/apps/Handles/resize_grip.png
./gtk-2.0/gtkrc
./panelbg.png


As you can see there are lots more files than for the Adwaita theme.

GTK+ 3.x widgets are styled using the Unico engine. GTK+ 2.x widgets are styled using the well-respected GTK+ 2.x Murrine theme engine, which was upgraded by Andrea Cimitan to render GTK+ 2.x widgets. Murrine is the Italian word for colored glass patterns made by Venetian glass makers. The engine is written in C, uses the Cairo graphics library and is highly configurable. This theming engine is available in the Fedora 16 repositories as gtk-murrine-engine-0.98.1. You need to install this package if you wish to use the Zukitwo themes.

The easiest way to enable other themes on GNOME 3 on Fedora 16 at present is to install the following RPM packages

gnome-shell-extension-common
gnome-shell-extension-user-theme
gnome-tweak-tool


and use gnome-tweak-tool to select and enable the new theme. Note that you need to first enable the user-theme GNOME Shell extension using gnome-tweak-tool before trying to change any of the themes.

This is a screenshot of the Zukitwo-Dark theme:

Unico screenshot

and this is a screenshot of the Zukitwo-Resonance theme:

Unico screenshot

Another Ubuntu theme which I quite like is Ambiance. You can download a GTK3 port of Ambiance called adwanta from Deviant Art. By default it uses the Adwaita engine and does not look particularly good. However, if you change the engine directive in gtk-widgets.css, you end up with a much tighter and nicer looking theme. The second screenshot in this post (see above) shows the Ambiance theme used with the Zukitwo shell theme.

Another example of a theme that uses the Unico engine is Ambiance Blue:
Unico screenshot

Well that is about all I have time to write about theming engines for today. If you are feeling adventurous and want to experiment with another GTK3+ theme engine, why not port the Solidity theme engine to Fedora and play with it. It is the only other publicly available GTK3+ theme engine that I am aware of at present. Be forewarned however – it is still under development.

As always, enjoy experimenting.

9 comments to Unico Theming Engine on Fedora 16

  • vister

    thx for the post..
    by the way,gnome-shell 3.2 is relesed,can we have some updates for gnome-shell Extensions in this page to work with shell 3.2:

    http://www.fpmurphy.com/gnome-shell-extensions/
    ??

    thank you :)

  • james

    Please! Looking for a good way to hide the topbar. Evidentally, you’re the only one who has this working.

    • I will be updating my GNOME Shell extensions in a few weeks time. Just waiting for the initial set of GS 3.2 bugs to be fixed first,

  • James Hunt

    Nice themes….pity about the rest of the UI….

    ….and “Yes” I have installed and used Fedora 15 and the recent Fedora 16 Beta with Gnome 3.

    XFCE is quite nice thank you, and a huge usability improvement over Gnome 3. I’ll keep trying, but I have absolutely no doubt that it will take till Gnome 4 for the thing to be anything other than pretty.

    James

  • Pikachu_2014

    Unico is available on Fedora 16… Since 10 Oct (package gtk-unico-engine).

  • Eduardo

    I thought it was only me and the mess I always do (now on Ubuntu), but I’ve noticed that you have the same bug with themes: take a look at the Ambiance-blue screenshot and you’ll realize that clicking on the panel results on a (so to speak) misplaced selection. Also, the «Activities» text is just too close to the edge. Orta and many other themes behave so under GS 3.2. Any idea how to fix it?

  • Kim-Alec Connors

    As a Fedora and long time Linux advocate, I really appreciate the work you’ve done and continue to do ( time permitting.. of course ).– Your extensions have allowed me to introduce Gnome Shell to those that would of otherwise shy’d away from using it on their production systems.– The majority of my current Linux user contacts were utterly frustrated with Unity desktop, and others have eagerly switched over from the Windows world.
    Thanks much!