
Stylistic and other fixes R=andybons@chromium.org BUG=524256 Review URL: https://codereview.chromium.org/1318153003 Cr-Commit-Position: refs/heads/master@{#346569}
136 lines
6.7 KiB
Markdown
136 lines
6.7 KiB
Markdown
# Linux GTK Theme Integration
|
|
|
|
The GTK+ port of Chromium has a mode where we try to match the user's GTK theme
|
|
(which can be enabled under Wrench -> Options -> Personal Stuff -> Set to GTK+
|
|
theme). The heuristics often don't pick good colors due to a lack of information
|
|
in the GTK themes.
|
|
|
|
Starting in Chrome 9, we're providing a new way for theme authors to control our
|
|
GTK+ theming mode. I am not sure of the earliest build these showed up in, but I
|
|
know 9.0.597 works.
|
|
|
|
## Describing the previous heuristics
|
|
|
|
The frame heuristics were simple. Query the `bg[SELECTED]` and `bg[INSENSITIVE]`
|
|
colors on the `MetaFrames` class and darken them slightly. This usually worked
|
|
OK until the rise of themes that try to make a unified titlebar/menubar look. At
|
|
roughly that time, it seems that people stopped specifying color information for
|
|
the `MetaFrames` class and this has lead to the very orange chrome frame on
|
|
Maverick.
|
|
|
|
`MetaFrames` is (was?) a class that was used to communicate frame color data to
|
|
the window manager around the Hardy days. (It's still defined in most of
|
|
[XFCE's themes](http://packages.ubuntu.com/maverick/gtk2-engines-xfce)). In
|
|
chrome's implementation, `MetaFrames` derives from `GtkWindow`.
|
|
|
|
If you are happy with the defaults that chrome has picked, no action is
|
|
necessary on the part of the theme author.
|
|
|
|
## Introducing `ChromeGtkFrame`
|
|
|
|
For cases where you want control of the colors chrome uses, Chrome gives you a
|
|
number of style properties for injecting colors and other information about how
|
|
to draw the frame. For example, here's the proposed modifications to Ubuntu's
|
|
Ambiance:
|
|
|
|
```
|
|
style "chrome-gtk-frame"
|
|
{
|
|
ChromeGtkFrame::frame-color = @fg_color
|
|
ChromeGtkFrame::inactive-frame-color = lighter(@fg_color)
|
|
|
|
ChromeGtkFrame::frame-gradient-size = 16
|
|
ChromeGtkFrame::frame-gradient-color = "#5c5b56"
|
|
|
|
ChromeGtkFrame::scrollbar-trough-color = @bg_color
|
|
ChromeGtkFrame::scrollbar-slider-prelight-color = "#F8F6F2"
|
|
ChromeGtkFrame::scrollbar-slider-normal-color = "#E7E0D3"
|
|
}
|
|
|
|
class "ChromeGtkFrame" style "chrome-gtk-frame"
|
|
```
|
|
|
|
### Frame color properties
|
|
|
|
These are the frame's main solid color.
|
|
|
|
| **Property** | **Type** | **Description** | **If unspecified** |
|
|
|:-------------|:---------|:----------------|:-------------------|
|
|
| `frame-color` | `GdkColor` | The main color of active chrome windows. | Darkens `MetaFrame::bg[SELECTED]` |
|
|
| `inactive-frame-color` | `GdkColor` | The main color of inactive chrome windows. | Darkens `MetaFrame::bg[INSENSITIVE]` |
|
|
| `incognito-frame-color` | `GdkColor` | The main color of active incognito windows. | Tints `frame-color` by the default incognito tint |
|
|
| `incognito-inactive-frame-color` | `GdkColor` | The main color of inactive incognito windows. | Tints `inactive-frame-color` by the default incognito tint |
|
|
|
|
### Frame gradient properties
|
|
|
|
Chrome's frame (along with many normal window manager themes) have a slight
|
|
gradient at the top, before filling the rest of the frame background image with
|
|
a solid color. For example, the top `frame-gradient-size` pixels would be a
|
|
gradient starting from `frame-gradient-color` at the top to `frame-color` at the
|
|
bottom, with the rest of the frame being filled with `frame-color`.
|
|
|
|
| **Property** | **Type** | **Description** | **If unspecified** |
|
|
|:-------------|:---------|:----------------|:-------------------|
|
|
| `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 |
|
|
| `frame-gradient-color` | `GdkColor` | Top color of the gradient | Lightens `frame-color` |
|
|
| `inactive-frame-gradient-color` | `GdkColor` | Top color of the inactive gradient | Lightents `inactive-frame-color` |
|
|
| `incognito-frame-gradient-color` | `GdkColor` | Top color of the incognito gradient | Lightens `incognito-frame-color` |
|
|
| `incognito-inactive-frame-gradient-color` | `GdkColor` | Top color of the incognito inactive gradient. | Lightens `incognito-inactive-frame-color` |
|
|
|
|
### Scrollbar control
|
|
|
|
Because widget rendering is done in a separate, sandboxed process that doesn't
|
|
have access to the X server or the filesystem, there's no current way to do
|
|
GTK+ widget rendering. We instead pass WebKit a few colors and let it draw a
|
|
default scrollbar. We have a very
|
|
[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)
|
|
where we render the widget and then average colors if this information isn't
|
|
provided.
|
|
|
|
| **Property** | **Type** | **Description** |
|
|
|:-------------|:---------|:----------------|
|
|
| `scrollbar-slider-prelight-color` | `GdkColor` | Color of the slider on mouse hover. |
|
|
| `scrollbar-slider-normal-color` | `GdkColor` | Color of the slider otherwise |
|
|
| `scrollbar-trough-color` | `GdkColor` | Color of the scrollbar trough |
|
|
|
|
## Anticipated Q&A
|
|
|
|
### Will you patch themes upstream?
|
|
|
|
I am at the very least hoping we can get Radiance and Ambiance patches since we
|
|
make very poor frame decisions on those themes, and hopefully a few others.
|
|
|
|
### How about control over the min/max/close buttons?
|
|
|
|
I actually tried this locally. There's a sort of uncanny valley effect going on;
|
|
as the frame looks more native, it's more obvious that it isn't behaving like a
|
|
native frame. (Also my implementation added a startup time hit.)
|
|
|
|
### Why use style properties instead of (i.e.) bg[STATE]?
|
|
|
|
There's no way to distinguish between colors set on different classes. Using
|
|
style properties allows us to be backwards compatible and maintain the
|
|
heuristics since not everyone is going to modify their themes for chromium (and
|
|
the heuristics do a reasonable job).
|
|
|
|
### Why now?
|
|
|
|
* I (erg@) was putting off major changes to the window frame stuff in
|
|
anticipation of finally being able to use GTK+'s theme rendering for the
|
|
window border with client side decorations, but client side decorations
|
|
either isn't happening or isn't happening anytime soon, so there's no
|
|
justification for pushing this task off into the future.
|
|
* Chrome looks pretty bad under Ambiance on Maverick.
|
|
|
|
### Details about `MetaFrames` and `ChromeGtkFrame` relationship and history?
|
|
|
|
`MetaFrames` is a class that was used in metacity to communicate color
|
|
information to the window manager. During the Hardy Heron days, we slurped up
|
|
the data and used it as a key part of our heuristics. At least on my Lucid Lynx
|
|
machine, none of the GNOME GTK+ themes have `MetaFrames` styling. (As mentioned
|
|
above, several of the XFCE themes do, though.)
|
|
|
|
Internally to chrome, our `ChromeGtkFrame` class inherits from `MetaFrames`
|
|
(again, which inherits from `GtkWindow`) so any old themes that style the
|
|
`MetaFrames` class are backwards compatible.
|