Theming

While most of the Unity look tries to adapt to the current user wallpaper, there are some aspects of unity that can be themed.

Decorations

Until 13.10 unity supported the metacity theming engine, through the compiz native gtk-window-decorator, however this system is quite old right now, and has never been ported to gtk3 to get better theming capabilities and support gtk-css theming (hey, no anti-aliased rounded corners!). Also its architecture was really quite complex and caused things such as the normal resizing to be much slower.

So, as part of the cleanup for Ubuntu 14.04, we defined a completely new theming system based on GtkStyleContext, that uses CSS for pretty much everything.

In order to theme the window decorations (examples on ubuntu-themes branch), you basically need to define a style for the UnityDecoration "fake" widget and for the classes top, left, right and bottom in your Gtk3 theme.

Properties

The UnityDecoration widget also supports some custom properties that we use to define some decoration-related parameters; you can see the ones currently supported here:

   1 UnityDecoration {
   2     /* Border properties (top, right, bottom, left) */
   3     -UnityDecoration-extents: 28px 1px 1px 1px; /* the size of the decorations  */
   4     -UnityDecoration-input-extents: 10px; /* the extra size of the input areas */
   5 
   6     /* Shadows settings */
   7     -UnityDecoration-shadow-offset-x: 1px; /* Size property, the shadow x offset */
   8     -UnityDecoration-shadow-offset-y: 1px; /* Size property, the shadow y offset */
   9     -UnityDecoration-active-shadow-color: rgba (0, 0, 0, 0.647); /* Color property, active window shadow color */
  10     -UnityDecoration-active-shadow-radius: 8px; /* Size property, active window shadow radius */
  11     -UnityDecoration-inactive-shadow-color: rgba (0, 0, 0, 0.647); /* Color property, inactive windows shadow color */
  12     -UnityDecoration-inactive-shadow-radius: 5px; /* Size property, inactive windows shadow radius */
  13 
  14     /* Glow applied to the selected scaled window */
  15     -UnityDecoration-glow-size: 10px; /* Size property, size of glow */
  16     -UnityDecoration-glow-color: rgb (221, 72, 20); /* Color property of the glow */
  17 
  18     /* Title settings */
  19     -UnityDecoration-title-indent: 10px; /* Size property, left indent of the title */
  20     -UnityDecoration-title-fade: 35px; /* Size property, space of the title that can be faded */
  21     -UnityDecoration-title-alignment: 0.0; /* Float from 0.0 to 1.0, to align the title */
  22 }
  23 

Examples

Except these "special" per-theme settings, all the rest of the theming can be done with standard GtkCss. You only need to define a theme for each selector, keeping in mind that the normal state covers the active window, while the backdrop state will match the inactive windows.
For example:

   1 /* This will theme the top decoration, so the whole space above the window */
   2 UnityDecoration.top {
   3     border: 1px solid shade (@bg_color, 0.5);
   4     border-bottom-width: 0;
   5     border-radius: 8px 8px 0 0; /* Corner radius, only the top ones should be */
   6     padding: 1px 8px 0 8px; /* This padding will be applied to the content of the top layout */
   7     background-color: shade (@dark_bg_color, 1.5); /* Decoration background */
   8     color: @dark_fg_color; /* The foreground color will be used to paint the text */
   9     text-shadow: 1px 0 #333, -1px 0 #333, 0 1px #333, 0 -1px #333;
  10 }
  11 
  12 /* Top decoration for inactive windows */
  13 UnityDecoration.top:backdrop {
  14     border: 1px solid @dark_bg_color;
  15     border-bottom-width: 0;
  16     background-color: shade (#474642, 0.92);
  17     color: #807d78;
  18 }
  19 
  20 /* Left decoration, it themes only the space at the left of the window */
  21 UnityDecoration.left,
  22 /* Right decoration, it themes only the space at the right of the window */
  23 UnityDecoration.right,
  24 /* Bottom decoration, it themes all the space below the window */
  25 UnityDecoration.bottom {
  26     background-color: shade (@bg_color, 0.5);
  27 }
  28 
  29 /* Left, right and bottom decorations themes for inactive windows */
  30 UnityDecoration.left:backdrop,
  31 UnityDecoration.right:backdrop,
  32 UnityDecoration.bottom:backdrop {
  33     background-color: shade (@bg_color, 0.3);
  34 }
  35 

Window Buttons

Finally, for the window buttons, you should provide these pixmaps in order to cover all the types and possible widget states.
These pixmaps we'll be used by both the Unity decorations and the Unity panel. We have a policy were we try to load SVGs first, then pngs:

$THEME_PATH/unity/close.{svg, png}
$THEME_PATH/unity/close_focused_normal.{svg, png}
$THEME_PATH/unity/close_focused_prelight.{svg, png}
$THEME_PATH/unity/close_focused_pressed.{svg, png}
$THEME_PATH/unity/close_unfocused.{svg, png}
$THEME_PATH/unity/close_unfocused_prelight.{svg, png}
$THEME_PATH/unity/close_unfocused_pressed.{svg, png}
$THEME_PATH/unity/maximize.{svg, png}
$THEME_PATH/unity/maximize_focused_normal.{svg, png}
$THEME_PATH/unity/maximize_focused_prelight.{svg, png}
$THEME_PATH/unity/maximize_focused_pressed.{svg, png}
$THEME_PATH/unity/maximize_unfocused.{svg, png}
$THEME_PATH/unity/maximize_unfocused_prelight.{svg, png}
$THEME_PATH/unity/maximize_unfocused_pressed.{svg, png}
$THEME_PATH/unity/minimize.{svg, png}
$THEME_PATH/unity/minimize_focused_normal.{svg, png}
$THEME_PATH/unity/minimize_focused_prelight.{svg, png}
$THEME_PATH/unity/minimize_focused_pressed.{svg, png}
$THEME_PATH/unity/minimize_unfocused.{svg, png}
$THEME_PATH/unity/minimize_unfocused_prelight.{svg, png}
$THEME_PATH/unity/minimize_unfocused_pressed.{svg, png}
$THEME_PATH/unity/unmaximize.{svg, png}
$THEME_PATH/unity/unmaximize_focused_normal.{svg, png}
$THEME_PATH/unity/unmaximize_focused_prelight.{svg, png}
$THEME_PATH/unity/unmaximize_focused_pressed.{svg, png}
$THEME_PATH/unity/unmaximize_unfocused.{svg, png}
$THEME_PATH/unity/unmaximize_unfocused_prelight.{svg, png}
$THEME_PATH/unity/unmaximize_unfocused_pressed.{svg, png}

The dash buttons are themable as well using these names:

$THEME_PATH/unity/icons/close_dash.{svg, png}
$THEME_PATH/unity/icons/close_dash_disabled.{svg, png}
$THEME_PATH/unity/icons/close_dash_prelight.{svg, png}
$THEME_PATH/unity/icons/close_dash_pressed.{svg, png}
$THEME_PATH/unity/icons/maximize_dash.{svg, png}
$THEME_PATH/unity/icons/maximize_dash_disabled.{svg, png}
$THEME_PATH/unity/icons/maximize_dash_prelight.{svg, png}
$THEME_PATH/unity/icons/maximize_dash_pressed.{svg, png}
$THEME_PATH/unity/icons/minimize_dash.{svg, png}
$THEME_PATH/unity/icons/minimize_dash_disabled.{svg, png}
$THEME_PATH/unity/icons/minimize_dash_prelight.{svg, png}
$THEME_PATH/unity/icons/minimize_dash_pressed.{svg, png}
$THEME_PATH/unity/icons/unmaximize_dash.{svg, png}
$THEME_PATH/unity/icons/unmaximize_dash_disabled.{svg, png}
$THEME_PATH/unity/icons/unmaximize_dash_prelight.{svg, png}
$THEME_PATH/unity/icons/unmaximize_dash_pressed.{svg, png}

In case you don't have specified a theme for UnityDecorations in your theme, we generate window buttons using cairo (using the foreground color for non-close buttons, and red for close one) and we try to fallback to gnome-panel and/or gnome-headerbar themes.
So, although the result won't be as nice as it might be with a native theme, it will be still usable.
Keep in mind, when writing an UnityDecoration theme, that if you've defined a theme for gnome-panel and/or gnome-headerbar, they might clash with this one (that has priority, though), so in case of weird behavior, just make sure you override their values (i.e. using something such as background-image: none;).

Locally Integrated Menus

Of course menu items embedded into the decorations can be themed as well, adding the .menuitem class, such as:

   1 UnityDecoration.menuitem {
   2     color: #dd4814;
   3 }
   4 

Theming tools

To make easier for theme writers to check the results of their CSS, I've written a simple vala program that draws a decoration (using the current theme) into an image. You can grab it here to see the results of your theming work without applying this directly to unity.

Unity Panel

Like the decorations, the panel is decorated with Gtk3 css themes, so all you need is defining a style for the UnityPanelWidget widget and with class .unity-panel

   1 UnityPanelWidget,
   2 .unity-panel {
   3     background-color: shade (@dark_bg_color, 1.5);
   4     color: @dark_fg_color; /* Text color */
   5 }
   6 

If you only want to modify the panel title you can use this selector:

   1 .unity-panel.panel-title {
   2     color: shade (@dark_fg_color, 1.5); /* Text color */
   3 }
   4 

For menu-items (and indicators) you can use instead:

   1 .unity-panel.menuitem {
   2     color: shade (@dark_fg_color, 1.2); /* Labels color */
   3 }
   4 

Panel Menu Items

Also menu items are themed using Gtk3 css:

   1 .unity-panel.menuitem,
   2 .unity-panel .menuitem {
   3     border-width: 1px 1px 0 1px;
   4     icon-shadow: 0 -1px shade (@dark_bg_color, 0.7);
   5 }
   6 
   7 .unity-panel.menubar:backdrop,
   8 .unity-panel .menubar *:backdrop {
   9     color: @backdrop_dark_fg_color;
  10 }
  11 
  12 .unity-panel.menubar.menuitem:hover,
  13 .unity-panel.menubar .menuitem *:hover {
  14     background-color: red;
  15 }
  16 

Launcher/Switcher Icons

The launcher and switcher are automagically coloured using the average background color (unless you don't force a color in ccsm), but still you can theme the icon tiles, providing the proper textures to make them look in the way you prefer.

First of all, we currently support two sizes for each texture (small, used when icons have a tile < 100px, big otherwise); the icons can be both SVGs or PNGs (althought the first are preferred to scale better in HiDPI displays).
Also, they will be painted following the order below:

These textures will be drawn before the actual icon pixbuf:

$THEME_PATH/unity/launcher_icon_shadow_{62, 200}.{svg, png} /* icon shadow, not colorified */
$THEME_PATH/unity/launcher_icon_back_{54, 150}.{svg, png} /* icon background, it can be colorified */
$THEME_PATH/unity/launcher_icon_selected_back_{54, 150}.{svg, png} /* icon background on key navigation */
$THEME_PATH/unity/launcher_icon_edge_{54, 150}.{svg, png} /* edges of the icon, generally not colorified */

While these textures will be drawn after the actual icon pixbuf:

$THEME_PATH/unity/launcher_icon_shine_{54, 150}.{svg, png} /* icon shine, not colorified */
$THEME_PATH/unity/launcher_icon_glow_{62, 200}.{svg, png} /* icon glow, it can be colorified */

These are the icon emblems used to draw the progress bar over an icon:

$THEME_PATH/unity/progress_bar_trough.{svg, png}
$THEME_PATH/unity/progress_bar_fill.{svg, png}

And these are the icon markers that can be drawn on left or right of the icons, depending on their state:

$THEME_PATH/unity/launcher_arrow_ltr_{19, 37}.{svg, png} /* the marker drawn on running apps */
$THEME_PATH/unity/launcher_arrow_outline_ltr_{19, 37}.{svg, png} /* the marker drawn running apps on different WS/monitor */
$THEME_PATH/unity/launcher_pip_ltr_{19, 37}.{svg, png} /* the marker drawn on apps with multiple windows (can be repeated) */
$THEME_PATH/unity/launcher_arrow_rtl_{19, 37}.{svg, png} /* the marker drawn on the focused app */

Make sure you respect these sizes, (and paddings for markers) or the results might not be the ones you expect.

Windows Force Quit dialog

You can select the unity windows force-quit dialogs by using the .unity-force-quit class or just the SheetStyleDialog generic name:

   1 SheetStyleDialog.unity-force-quit {
   2     background-color: #dd4814;
   3 }
   4 

It will instead use these icons for the close button:

$THEME_PATH/unity/sheet_style_close_focused.{svg, png}
$THEME_PATH/unity/sheet_style_close_focused_prelight.{svg, png}
$THEME_PATH/unity/sheet_style_close_focused_pressed.{svg, png}

Unity/Theming (last edited 2014-04-02 14:16:03 by 3v1n0)