android_webview
apps
ash
base
blink
build
build_overrides
cc
chrome
chrome_elf
chromecast
chromeos
cloud_print
components
content
courgette
crypto
dbus
device
docs
accessibility
design
images
ios
media
memory
memory-infra
process
security
speed
sync
testing
ui
OWNERS
README.md
accessibility.md
adding_to_third_party.md
android_accessing_cpp_enums_in_java.md
android_build_instructions.md
android_cast_build_instructions.md
android_debugging_instructions.md
android_logging.md
android_studio.md
android_test_instructions.md
angle_in_chromium.md
atom.md
bitmap_pipeline.md
browser_view_resizer.md
callback.md
ccache_mac.md
chrome_os_logging.md
chrome_settings.md
chromedriver_status.md
chromeos_build_instructions.md
chromium_browser_vs_google_chrome.md
chromoting_android_hacking.md
cl_respect.md
clang.md
clang_format.md
clang_static_analyzer.md
clang_tidy.md
clang_tool_refactoring.md
closure_compilation.md
cocoa_tips_and_tricks.md
code_reviews.md
component_build.md
cr_respect.md
cr_user_manual.md
cygwin_dll_remapping_failure.md
debugging_with_crash_keys.md
documentation_best_practices.md
documentation_guidelines.md
eclipse.md
emacs.md
erc_irc.md
es6_chromium.md
fuchsia_build_instructions.md
fuchsia_sdk_updates.md
get_the_code.md
git_cookbook.md
git_tips.md
google_play_services.md
graphical_debugging_aid_chromium_views.md
gtk_vs_views_gtk.md
how_to_add_your_feature_flag.md
how_to_extend_layout_test_framework.md
installation_at_vmware.md
ios_build_instructions.md
ios_infra.md
ios_voiceover.md
ipc_fuzzer.md
jumbo.md
kiosk_mode.md
layout_tests_linux.md
linux_build_instructions.md
linux_build_instructions_prerequisites.md
linux_building_debug_gtk.md
linux_cast_build_instructions.md
linux_cert_management.md
linux_chromium_arm.md
linux_chromium_packages.md
linux_crash_dumping.md
linux_debugging.md
linux_debugging_gtk.md
linux_debugging_ssl.md
linux_dev_build_as_default_browser.md
linux_development.md
linux_eclipse_dev.md
linux_graphics_pipeline.md
linux_gtk_theme_integration.md
linux_hw_video_decode.md
linux_minidump_to_core.md
linux_password_storage.md
linux_pid_namespace_support.md
linux_plugins.md
linux_profiling.md
linux_proxy_config.md
linux_sandbox_ipc.md
linux_sandboxing.md
linux_suid_sandbox.md
linux_suid_sandbox_development.md
linux_sysroot.md
linux_zygote.md
luci_migration_faq.md
mac_build_instructions.md
network_traffic_annotations.md
new_port_policy.md
old_chromoting_build_instructions.md
optimizing_web_uis.md
optional.md
origin_trials_integration.md
ozone_overview.md
piranha_plant.md
profiling_content_shell_on_android.md
proxy_auto_config.md
qtcreator.md
release_branch_guidance.md
retrieving_code_analysis_warnings.md
seccomp_sandbox_crash_dumping.md
servicification.md
static_initializers.md
sublime_ide.md
subtle_threading_bugs.md
system_hardening_features.md
tab_helpers.md
task_scheduler_migration.md
test_descriptions.md
threading_and_tasks.md
tour_of_luci_ui.md
tpm_quick_ref.md
updating_clang.md
updating_clang_format_binaries.md
useful_urls.md
user_data_dir.md
user_handle_mapping.md
using_a_linux_chroot.md
using_build_runner.md
vanilla_msysgit_workflow.md
vscode.md
webui_explainer.md
webui_in_components.md
webview_policies.md
win_cross.md
win_order_files.md
windows_build_instructions.md
windows_split_dll.md
working_remotely_with_android.md
writing_clang_plugins.md
extensions
gin
google_apis
google_update
gpu
headless
infra
ios
ipc
jingle
mash
media
mojo
native_client_sdk
net
pdf
ppapi
printing
remoting
rlz
sandbox
services
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
.clang-format
.eslintrc.js
.git-blame-ignore-revs
.gitattributes
.gitignore
.gn
.vpython
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
DEPS
ENG_REVIEW_OWNERS
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings

This CL * Uses entry colors instead of window colors for the NTP * Fixes a leak involving ScopedGObject * Simplifies how background and border colors are calculated * Adds the ".label" class only on versions of Gtk before 3.20 * Fixes text selection colors on one theme * Updates the doc to reflect the new way colors are calculated BUG=132847 Review-Url: https://codereview.chromium.org/2683953005 Cr-Commit-Position: refs/heads/master@{#449709}
188 lines
8.3 KiB
Markdown
188 lines
8.3 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 Settings -> Appearance -> Use GTK+ theme).
|
|
|
|
# GTK3
|
|
|
|
At some point after version 57, Chromium will switch to using the GTK3 theme by
|
|
default.
|
|
|
|
## How Chromium determines which colors to use
|
|
|
|
GTK3 added a new CSS theming engine which gives fine-tuned control over how
|
|
widgets are styled. Chromium's themes, by contrast, are much simpler: it is
|
|
mostly a list of about 80 colors (see //src/ui/native_theme/native_theme.h)
|
|
overridden by the theme. Chromium usually doesn't use GTK to render entire
|
|
widgets, but instead tries to determine colors from them.
|
|
|
|
Chromium needs foreground, background and border colors from widgets. The
|
|
foreground color is simply taken from the CSS "color" property. Backgrounds and
|
|
borders are complicated because in general they might have multiple gradients or
|
|
images. To get the color, Chromium uses GTK to render the background or border
|
|
into a 24x24 bitmap and uses the average color for theming. This mostly gives
|
|
reasonable results, but in case theme authors do not like the resulting color,
|
|
they have the option to theme Chromium widgets specially.
|
|
|
|
## Note to GTK theme authors: How to theme Chromium widgets
|
|
|
|
Every widget Chromium uses will have a "chromium" style class added to it. For
|
|
example, a textfield selector might look like:
|
|
|
|
```
|
|
.window.background.chromium .entry.chromium
|
|
```
|
|
|
|
If themes want to handle Chromium textfields specially, for GTK3.0 - GTK3.19,
|
|
they might use:
|
|
|
|
```
|
|
/* Normal case */
|
|
.entry {
|
|
color: #ffffff;
|
|
background-color: #000000;
|
|
}
|
|
|
|
/* Chromium-specific case */
|
|
.entry.chromium {
|
|
color: #ff0000;
|
|
background-color: #00ff00;
|
|
}
|
|
```
|
|
|
|
For GTK3.20 or later, themes will as usual have to replace ".entry" with
|
|
"entry".
|
|
|
|
The list of CSS selectors that Chromium uses to determine its colors is in
|
|
//src/chrome/browser/ui/libgtkui/native_theme_gtk3.cc.
|
|
|
|
# GTK2
|
|
|
|
Chromium's GTK2 theme will soon be deprecated, and this section will be removed.
|
|
|
|
## Describing the previous heuristics
|
|
|
|
The heuristics often don't pick good colors due to a lack of information in the
|
|
GTK themes. 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.
|