Been rebuilding a machine, getting fed up, buying a new computer, setting that up, and generally being ADHD with all my little projects...
Anyway, I've started working on GTK themes, and as it turns out, it's not as difficult as it seems at first. I've released two GTK themes recently on my DeviantArt account...Have a look!
From Screenshots |
From Screenshots |
But anyway, the point of this post was not to toot my own horn ("Too late!" I hear you cry...), it was to explain how I started in GTK theming, and point out some tips to get you started doing it for yourself.
First things first: Step 1 is to grab some GTK themes that you like. Some of my favourites are:
- Elementary GTK (eGTK)
- Espresso
- Human (any of the various versions that come packaged with Ubuntu)
- Dyne Dark (comes pre-installed with Crunchbang Linux)
Now, close your eyes, hold your breath, and jump in.
Start by copying one of your themes into ~/.themes/ and changing the folder to something you can remember. I tend to use ~/.themes/Untitled for new themes I'm working on. The file structure of a GTK theme looks like:
~/ +-- .themes/ +-- Untitled/ +-- gtk-2.0/ +-- gtkrcIf it's a theme like Human, you may also find folders for Metacity, an index.theme (for icons) and others inside the Untitled/ folder.
It's the gtkrc that we want to edit. It's a simple text file with a relatively simple layout.
First, you may define a colour scheme (this is what turns up in the Colors tab of the Customize... dialog in Gnome Appearance Preferences). It will look something like this:
gtk_color_scheme = "base_color:#F7F9FA\nfg_color:#4D4D4D\ntooltip_fg_color:#000000\nselected_bg_color:#a5b26b\nselected_fg_color:#ffffff\ntext_color:#4D4D4D\nbg_color:#D6D6D6\ntooltip_bg_color:#f2f29d"Next, you should have a listing of styles, in the format
style "name" { Various style properties }Start with a "default" style, which will be applied to all widgets, and then on to more specific styles that will apply to only certain widgets. The default style can contain as much as little as you like, but typically you will find:
- Some specific widget style properties, of the format GtkWidget::style-property = value
- Thickness parameters, which define the padding of the objects inside widgets, and look line xthickness = value and ythickness = value
- Colour definitions, of which there should be 20: foreground (fg), background (bg), background of entry fields (base) and text (text), and five states for each (normal, prelight, active, selected and insensitive)
- Default settings for the engine (if any) you choose to use
style "default" { GtkButton ::child-displacement-x = 1 GtkButton ::child-displacement-y = 1 GtkButton ::default-border = { 0, 0, 0, 0 } GtkPaned ::handle-size = 6 GtkRange ::trough-border = 0 GtkRange ::slider-width = 13 GtkRange ::stepper-size = 13 GtkRange ::stepper-spacing = 1 GtkRange ::activate-slider = 1 GtkRange ::arrow-displacement-x = 1 GtkRange ::arrow-displacement-y = 1 GtkRange ::arrow-scaling = 0.7 GtkScale ::slider-width = 13 # Needs to be ODD in order to center evenly GtkScale ::slider-length = 13 GtkScale ::trough-side-details = 1 # 0 = empty slider, 1 = filled GtkScale ::trough-border = 1 GtkScrollbar ::min-slider-length = 42 GtkScrolledWindow ::scrollbar-spacing = 3 GtkNotebook ::tab-curvature = 1 GtkNotebook ::tab-overlap = 1 GtkMenuBar ::internal-padding = 0 GtkExpander ::expander-size = 14 GtkToolbar ::internal-padding = 0 GtkToolButton ::icon-spacing = 3 GtkTreeView ::expander-size = 14 GtkTreeView ::vertical-separator = 0 GtkMenu ::horizontal-padding = 0 GtkMenu ::vertical-padding = 0 xthickness = 1 ythickness = 1 fg[NORMAL] = @fg_color fg[PRELIGHT] = @fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @fg_color fg[INSENSITIVE] = shade (0.7, @bg_color) bg[NORMAL] = @bg_color bg[PRELIGHT] = shade (1.05, @bg_color) bg[SELECTED] = @selected_bg_color bg[INSENSITIVE] = @bg_color bg[ACTIVE] = shade (0.95, @bg_color) base[NORMAL] = @base_color base[PRELIGHT] = shade (0.95, @bg_color) base[ACTIVE] = shade (0.7, @bg_color) # Unfocused selected text background base[SELECTED] = @selected_bg_color base[INSENSITIVE] = @bg_color text[NORMAL] = @text_color text[PRELIGHT] = @text_color text[ACTIVE] = @selected_fg_color text[SELECTED] = @selected_fg_color text[INSENSITIVE] = shade (0.7, @bg_color) engine "murrine" { animation = TRUE # FALSE = disabled, TRUE = enabled colorize_scrollbar = TRUE # FALSE = disabled, TRUE = enabled scrollbar_color = @selected_bg_color contrast = 0.8 # 0.8 for less contrast, more than 1.0 for more contrast on borders glazestyle = 0 # 0 = flat highlight, 1 = curved highlight, 2 = concave style, 3 = top curved highlight, 4 = beryl highlight gradient_shades = {1.05,1.02,1.02,1.0} # default: {1.1,1.0,1.0,1.1} gradients = TRUE # FALSE = disabled, TRUE = enabled highlight_shade = 1.0 # set highlight amount for buttons or widgets lightborder_shade = 1.0 # sets lightborder amount for buttons or widgets lightborderstyle = 0 # 0 = lightborder on top side, 1 = lightborder on all sides listviewheaderstyle = 1 # 0 = flat, 1 = glassy, 2 = raised listviewstyle = 1 # 0 = nothing, 1 = dotted menubaritemstyle = 1 # 0 = menuitem look, 1 = button look menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped menuitemstyle = 1 # 0 = flat, 1 = glassy, 2 = striped menustyle = 0 # 0 = no vertical menu stripe, 1 = display vertical menu stripe reliefstyle = 1 # 0 = flat, 1 = inset, 2 = shadow rgba = FALSE # FALSE = disabled, TRUE = enabled roundness = 3 # 0 = squared, 1 = old default, more will increase roundness scrollbarstyle = 0 # 0 = nothing, 1 = circles, 2 = handles, 3 = diagonal stripes, 4 = diagonal stripes and handles, 5 = horizontal stripes, 6 = horizontal stripes and handles sliderstyle = 0 # 0 = nothing added, 1 = handles stepperstyle = 1 # 0 = standard, 1 = integrated stepper handles, 2 = unknown toolbarstyle = 2 # 0 = flat, 1 = glassy, 2 = gradient } }Since you will apply the default style to all widgets and then pick out individual widgets to change after that, the other styles you define will typically only be a couple of lines long, which will override the corresponding lines from the default style.
After you've defined all your styles, then comes widget matching. It's how the theme applies your styles to all the various widgets that might pop up in GTK-based programs. There are three types of matching:
- Class
- Widget class
- Widget
class "GtkWidget" style "default" widget_class "*GtkCombo*" style "wider" widget "*.gtk-combobox-popup-menu.*" style "combobox-popup"Here, all widgets first have the default theme applied. Then anything whose widget class contains GtkCombo (note the * wild card) has the "wider" style applied. Finally, the very specific case of a widget with .gtk-combobox-popup-menu. will have "combobox-popup" applied. (Please note there is some trickiness here to do with the wild card * -- you can also use $ for a single-character wild card -- and the best place to learn to navigate it is to use trial and error.)
And that's it...For the basics, that is! To get started making your own theme, I would start by tweaking with someone else's, so you get a feel for what changes what. Then if you get really brave, you can start from scratch (which after a few goes, I actually found was easiest!).
The hardest parts of GTK theming are the widget matching, understanding how the widgets are arranged in a hierarchy and understanding how their styles get inherited. I can't say I'm an expert, but that's where step 1 comes in! The best way to learn is a combination of looking at other people's themes and reading the GTK documentation. The latter is particularly useful because the widget hierarchy pages have listings of what style-properties you can specify in your styles.
I hope this gives some of you out there the courage to go ahead and try it...As with all things open-source, the more of us out there doing it, the easier it makes it for all of us!
Very informative, thanks! Everything else I've read on the subject has been cryptic at best. This helps a lot.
ReplyDelete