blob: caf0941993c8d475982bb5a20639f221beb8a1ab [file] [log] [blame] [view]
thomasandersonacc42142017-01-10 21:11:451# Linux GTK Theme Integration
andybons3322f762015-08-24 21:37:092
andybonsad92aa32015-08-31 02:27:443The GTK+ port of Chromium has a mode where we try to match the user's GTK theme
thomasandersonacc42142017-01-10 21:11:454(which can be enabled under Settings -> Appearance -> Use GTK+ theme).
andybons3322f762015-08-24 21:37:095
thomasandersonacc42142017-01-10 21:11:456# GTK3
7
8At some point after version 57, Chromium will switch to using the GTK3 theme by
9default.
10
11## How Chromium determines which colors to use
12
13GTK3 added a new CSS theming engine which gives fine-tuned control over how
14widgets are styled. Chromium's themes, by contrast, are much simpler: it is
15mostly a list of about 80 colors (see //src/ui/native_theme/native_theme.h)
16overridden by the theme. Chromium usually doesn't use GTK to render entire
17widgets, but instead tries to determine colors from them.
18
thomasanderson419a91a12017-02-10 20:05:4819Chromium needs foreground, background and border colors from widgets. The
20foreground color is simply taken from the CSS "color" property. Backgrounds and
21borders are complicated because in general they might have multiple gradients or
22images. To get the color, Chromium uses GTK to render the background or border
23into a 24x24 bitmap and uses the average color for theming. This mostly gives
24reasonable results, but in case theme authors do not like the resulting color,
25they have the option to theme Chromium widgets specially.
thomasandersonacc42142017-01-10 21:11:4526
27## Note to GTK theme authors: How to theme Chromium widgets
28
29Every widget Chromium uses will have a "chromium" style class added to it. For
thomasanderson419a91a12017-02-10 20:05:4830example, a textfield selector might look like:
thomasandersonacc42142017-01-10 21:11:4531
32```
33.window.background.chromium .entry.chromium
34```
35
36If themes want to handle Chromium textfields specially, for GTK3.0 - GTK3.19,
37they might use:
38
39```
40/* Normal case */
41.entry {
42 color: #ffffff;
43 background-color: #000000;
44}
45
46/* Chromium-specific case */
47.entry.chromium {
48 color: #ff0000;
49 background-color: #00ff00;
50}
51```
52
53For GTK3.20 or later, themes will as usual have to replace ".entry" with
54"entry".
55
thomasandersonacc42142017-01-10 21:11:4556The list of CSS selectors that Chromium uses to determine its colors is in
57//src/chrome/browser/ui/libgtkui/native_theme_gtk3.cc.
58
59# GTK2
60
61Chromium's GTK2 theme will soon be deprecated, and this section will be removed.
andybons3322f762015-08-24 21:37:0962
andybonsad92aa32015-08-31 02:27:4463## Describing the previous heuristics
andybons3322f762015-08-24 21:37:0964
thomasandersonacc42142017-01-10 21:11:4565The heuristics often don't pick good colors due to a lack of information in the
66GTK themes. The frame heuristics were simple. Query the `bg[SELECTED]` and
67`bg[INSENSITIVE]` colors on the `MetaFrames` class and darken them
68slightly. This usually worked OK until the rise of themes that try to make a
69unified titlebar/menubar look. At roughly that time, it seems that people
70stopped specifying color information for the `MetaFrames` class and this has
71lead to the very orange chrome frame on Maverick.
andybons3322f762015-08-24 21:37:0972
andybonsad92aa32015-08-31 02:27:4473`MetaFrames` is (was?) a class that was used to communicate frame color data to
74the window manager around the Hardy days. (It's still defined in most of
75[XFCE's themes](http://packages.ubuntu.com/maverick/gtk2-engines-xfce)). In
76chrome's implementation, `MetaFrames` derives from `GtkWindow`.
andybons3322f762015-08-24 21:37:0977
andybonsad92aa32015-08-31 02:27:4478If you are happy with the defaults that chrome has picked, no action is
79necessary on the part of the theme author.
andybons3322f762015-08-24 21:37:0980
andybonsad92aa32015-08-31 02:27:4481## Introducing `ChromeGtkFrame`
andybons3322f762015-08-24 21:37:0982
andybonsad92aa32015-08-31 02:27:4483For cases where you want control of the colors chrome uses, Chrome gives you a
84number of style properties for injecting colors and other information about how
85to draw the frame. For example, here's the proposed modifications to Ubuntu's
86Ambiance:
andybons3322f762015-08-24 21:37:0987
88```
89style "chrome-gtk-frame"
90{
91 ChromeGtkFrame::frame-color = @fg_color
92 ChromeGtkFrame::inactive-frame-color = lighter(@fg_color)
93
94 ChromeGtkFrame::frame-gradient-size = 16
95 ChromeGtkFrame::frame-gradient-color = "#5c5b56"
96
97 ChromeGtkFrame::scrollbar-trough-color = @bg_color
98 ChromeGtkFrame::scrollbar-slider-prelight-color = "#F8F6F2"
99 ChromeGtkFrame::scrollbar-slider-normal-color = "#E7E0D3"
100}
101
102class "ChromeGtkFrame" style "chrome-gtk-frame"
103```
104
andybonsad92aa32015-08-31 02:27:44105### Frame color properties
andybons3322f762015-08-24 21:37:09106
107These are the frame's main solid color.
108
109| **Property** | **Type** | **Description** | **If unspecified** |
110|:-------------|:---------|:----------------|:-------------------|
111| `frame-color` | `GdkColor` | The main color of active chrome windows. | Darkens `MetaFrame::bg[SELECTED]` |
112| `inactive-frame-color` | `GdkColor` | The main color of inactive chrome windows. | Darkens `MetaFrame::bg[INSENSITIVE]` |
113| `incognito-frame-color` | `GdkColor` | The main color of active incognito windows. | Tints `frame-color` by the default incognito tint |
114| `incognito-inactive-frame-color` | `GdkColor` | The main color of inactive incognito windows. | Tints `inactive-frame-color` by the default incognito tint |
115
andybonsad92aa32015-08-31 02:27:44116### Frame gradient properties
andybons3322f762015-08-24 21:37:09117
andybonsad92aa32015-08-31 02:27:44118Chrome's frame (along with many normal window manager themes) have a slight
119gradient at the top, before filling the rest of the frame background image with
120a solid color. For example, the top `frame-gradient-size` pixels would be a
121gradient starting from `frame-gradient-color` at the top to `frame-color` at the
122bottom, with the rest of the frame being filled with `frame-color`.
andybons3322f762015-08-24 21:37:09123
124| **Property** | **Type** | **Description** | **If unspecified** |
125|:-------------|:---------|:----------------|:-------------------|
126| `frame-gradient-size` | Integers 0 through 128 | How large the gradient should be. Set to zero to disable drawing a gradient | Defaults to 16 pixels tall |
127| `frame-gradient-color` | `GdkColor` | Top color of the gradient | Lightens `frame-color` |
128| `inactive-frame-gradient-color` | `GdkColor` | Top color of the inactive gradient | Lightents `inactive-frame-color` |
129| `incognito-frame-gradient-color` | `GdkColor` | Top color of the incognito gradient | Lightens `incognito-frame-color` |
130| `incognito-inactive-frame-gradient-color` | `GdkColor` | Top color of the incognito inactive gradient. | Lightens `incognito-inactive-frame-color` |
131
andybonsad92aa32015-08-31 02:27:44132### Scrollbar control
andybons3322f762015-08-24 21:37:09133
andybonsad92aa32015-08-31 02:27:44134Because widget rendering is done in a separate, sandboxed process that doesn't
135have access to the X server or the filesystem, there's no current way to do
136GTK+ widget rendering. We instead pass WebKit a few colors and let it draw a
137default scrollbar. We have a very
138[complex fallback](http://git.chromium.org/gitweb/?p=chromium.git;a=blob;f=chrome/browser/gtk/gtk_theme_provider.cc;h=a57ab6b182b915192c84177f1a574914c44e2e71;hb=3f873177e192f5c6b66ae591b8b7205d8a707918#l424)
139where we render the widget and then average colors if this information isn't
140provided.
andybons3322f762015-08-24 21:37:09141
142| **Property** | **Type** | **Description** |
143|:-------------|:---------|:----------------|
144| `scrollbar-slider-prelight-color` | `GdkColor` | Color of the slider on mouse hover. |
145| `scrollbar-slider-normal-color` | `GdkColor` | Color of the slider otherwise |
146| `scrollbar-trough-color` | `GdkColor` | Color of the scrollbar trough |
147
andybonsad92aa32015-08-31 02:27:44148## Anticipated Q&A
andybons3322f762015-08-24 21:37:09149
andybonsad92aa32015-08-31 02:27:44150### Will you patch themes upstream?
andybons3322f762015-08-24 21:37:09151
andybonsad92aa32015-08-31 02:27:44152I am at the very least hoping we can get Radiance and Ambiance patches since we
153make very poor frame decisions on those themes, and hopefully a few others.
andybons3322f762015-08-24 21:37:09154
andybonsad92aa32015-08-31 02:27:44155### How about control over the min/max/close buttons?
andybons3322f762015-08-24 21:37:09156
andybonsad92aa32015-08-31 02:27:44157I actually tried this locally. There's a sort of uncanny valley effect going on;
158as the frame looks more native, it's more obvious that it isn't behaving like a
159native frame. (Also my implementation added a startup time hit.)
andybons3322f762015-08-24 21:37:09160
nodira6074d4c2015-09-01 04:26:45161### Why use style properties instead of (i.e.) bg[STATE]?
andybons3322f762015-08-24 21:37:09162
andybonsad92aa32015-08-31 02:27:44163There's no way to distinguish between colors set on different classes. Using
164style properties allows us to be backwards compatible and maintain the
165heuristics since not everyone is going to modify their themes for chromium (and
166the heuristics do a reasonable job).
andybons3322f762015-08-24 21:37:09167
andybonsad92aa32015-08-31 02:27:44168### Why now?
andybons3322f762015-08-24 21:37:09169
andybonsad92aa32015-08-31 02:27:44170* I (erg@) was putting off major changes to the window frame stuff in
171 anticipation of finally being able to use GTK+'s theme rendering for the
172 window border with client side decorations, but client side decorations
173 either isn't happening or isn't happening anytime soon, so there's no
174 justification for pushing this task off into the future.
175* Chrome looks pretty bad under Ambiance on Maverick.
andybons3322f762015-08-24 21:37:09176
andybonsad92aa32015-08-31 02:27:44177### Details about `MetaFrames` and `ChromeGtkFrame` relationship and history?
andybons3322f762015-08-24 21:37:09178
andybonsad92aa32015-08-31 02:27:44179`MetaFrames` is a class that was used in metacity to communicate color
180information to the window manager. During the Hardy Heron days, we slurped up
181the data and used it as a key part of our heuristics. At least on my Lucid Lynx
182machine, none of the GNOME GTK+ themes have `MetaFrames` styling. (As mentioned
183above, several of the XFCE themes do, though.)
andybons3322f762015-08-24 21:37:09184
andybonsad92aa32015-08-31 02:27:44185Internally to chrome, our `ChromeGtkFrame` class inherits from `MetaFrames`
186(again, which inherits from `GtkWindow`) so any old themes that style the
187`MetaFrames` class are backwards compatible.