Commit 442ac471 authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

GTK: Supply correct frame colors when using the system frame

The GTK theme draws a different top area depending on if Chrome or the window
manager draws the frame [1].  On themes like KDE's Breeze, these colors can be
very different.  This can cause colors calculated from the frame color (like the
inactive tab text color) to be calculated incorrectly.

This CL caches the system and Chrome frame colors in GtkUi and gets the
appropriate one depending on the user's preferences.

Also fix the GTK2 build.

[1] https://cs.chromium.org/chromium/src/chrome/browser/ui/libgtkui/native_theme_gtk3.cc?rcl=ae5bd514aea0486e53a743ddc2870ac3029eb9b3&l=654

BUG=875844
R=pkasting

Change-Id: Ia3e8065de1f843618277b6c562bb9fb54671691d
Reviewed-on: https://chromium-review.googlesource.com/1182508
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584646}
parent c633990f
......@@ -61,7 +61,7 @@ bool SystemThemeX11::GetTint(int id, color_utils::HSL* hsl) const {
}
bool SystemThemeX11::GetColor(int id, SkColor* color) const {
return linux_ui_ && linux_ui_->GetColor(id, color);
return linux_ui_ && linux_ui_->GetColor(id, color, pref_service_);
}
gfx::Image SystemThemeX11::GetImageNamed(int id) {
......
......@@ -86,6 +86,7 @@ template("libgtkui") {
deps = invoker.deps + [
"//chrome/browser/ui/views",
"//chrome/common:constants",
"//base",
"//base:i18n",
"//base/third_party/dynamic_annotations",
......@@ -96,6 +97,7 @@ template("libgtkui") {
"//chrome:strings",
"//chrome/app:command_ids",
"//chrome/app/theme:theme_resources",
"//components/prefs",
"//components/resources",
"//content/public/browser",
"//printing",
......
......@@ -41,6 +41,8 @@
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
#include "chrome/browser/ui/libgtkui/unity_service.h"
#include "chrome/browser/ui/libgtkui/x11_input_method_context_impl_gtk.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "printing/buildflags/buildflags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
......@@ -362,6 +364,12 @@ views::LinuxUI::NonClientWindowFrameAction GetDefaultMiddleClickAction() {
}
#if GTK_MAJOR_VERSION > 2
using GdkSetAllowedBackendsFn = void (*)(const gchar*);
// Place this function pointer in read-only memory after being resolved to
// prevent it being tampered with. See https://crbug.com/771365 for details.
PROTECTED_MEMORY_SECTION base::ProtectedMemory<GdkSetAllowedBackendsFn>
g_gdk_set_allowed_backends;
// COLOR_TOOLBAR_TOP_SEPARATOR represents the border between tabs and the
// frame, as well as the border between tabs and the toolbar. For this
// reason, it is difficult to calculate the One True Color that works well on
......@@ -414,14 +422,6 @@ SkColor GetToolbarTopSeparatorColor(SkColor header_fg,
}
#endif
#if GTK_MAJOR_VERSION > 2
using GdkSetAllowedBackendsFn = void (*)(const gchar*);
// Place this function pointers in read-only memory after being resolved to
// prevent it being tampered with. See crbug.com/771365 for details.
PROTECTED_MEMORY_SECTION base::ProtectedMemory<GdkSetAllowedBackendsFn>
g_gdk_set_allowed_backends;
#endif
} // namespace
GtkUi::GtkUi() {
......@@ -526,11 +526,16 @@ bool GtkUi::GetTint(int id, color_utils::HSL* tint) const {
return false;
}
bool GtkUi::GetColor(int id, SkColor* color) const {
ColorMap::const_iterator it = colors_.find(id);
if (it != colors_.end()) {
*color = it->second;
return true;
bool GtkUi::GetColor(int id, SkColor* color, PrefService* pref_service) const {
for (const ColorMap& color_map :
{colors_, pref_service->GetBoolean(prefs::kUseCustomChromeFrame)
? custom_frame_colors_
: native_frame_colors_}) {
ColorMap::const_iterator it = color_map.find(id);
if (it != color_map.end()) {
*color = it->second;
return true;
}
}
return false;
......@@ -994,18 +999,6 @@ void GtkUi::LoadGtkValues() {
colors_[ThemeProperties::COLOR_NTP_HEADER] =
colors_[ThemeProperties::COLOR_FRAME];
#else
std::string header_selector = GtkVersionCheck(3, 10)
? "#headerbar.header-bar.titlebar"
: "GtkMenuBar#menubar";
SkColor frame_color = GetBgColor(header_selector);
SkColor frame_color_inactive = GetBgColor(header_selector + ":backdrop");
colors_[ThemeProperties::COLOR_FRAME] = frame_color;
colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = frame_color_inactive;
colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] =
color_utils::HSLShift(frame_color, kDefaultTintFrameIncognito);
colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] =
color_utils::HSLShift(frame_color_inactive, kDefaultTintFrameIncognito);
SkColor tab_color = GetBgColor("");
SkColor tab_text_color = GetFgColor("GtkLabel");
......@@ -1013,10 +1006,6 @@ void GtkUi::LoadGtkValues() {
colors_[ThemeProperties::COLOR_TAB_TEXT] = tab_text_color;
colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = tab_text_color;
colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
ui::MaterialDesignController::IsRefreshUi()
? GetFgColor(header_selector + " GtkLabel")
: color_utils::BlendTowardOppositeLuma(tab_text_color, 50);
SkColor location_bar_border = GetBorderColor("GtkEntry#entry");
if (SkColorGetA(location_bar_border))
......@@ -1042,30 +1031,6 @@ void GtkUi::LoadGtkValues() {
// Separates the detached bookmark bar from the NTP.
colors_[ThemeProperties::COLOR_DETACHED_BOOKMARK_BAR_SEPARATOR] = tab_border;
// These colors represent the border drawn around tabs and between
// the tabstrip and toolbar.
SkColor toolbar_top_separator =
GetBorderColor(header_selector + " GtkButton#button");
SkColor toolbar_top_separator_inactive =
GetBorderColor(header_selector + ":backdrop GtkButton#button");
if (!ui::MaterialDesignController::IsRefreshUi()) {
toolbar_top_separator = GetToolbarTopSeparatorColor(
toolbar_top_separator, frame_color, tab_border, tab_color);
toolbar_top_separator_inactive = GetToolbarTopSeparatorColor(
toolbar_top_separator_inactive, frame_color_inactive, tab_border,
tab_color);
}
// Unlike with toolbars, we always want a border around tabs, so let
// ThemeService choose the border color if the theme doesn't provide one.
if (SkColorGetA(toolbar_top_separator) &&
SkColorGetA(toolbar_top_separator_inactive)) {
colors_[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR] =
toolbar_top_separator;
colors_[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_INACTIVE] =
toolbar_top_separator_inactive;
}
colors_[ThemeProperties::COLOR_NTP_BACKGROUND] =
native_theme_->GetSystemColor(
ui::NativeTheme::kColorId_TextfieldDefaultBackground);
......@@ -1073,6 +1038,52 @@ void GtkUi::LoadGtkValues() {
ui::NativeTheme::kColorId_TextfieldDefaultColor);
colors_[ThemeProperties::COLOR_NTP_HEADER] =
GetBorderColor("GtkButton#button");
for (bool custom_frame : {false, true}) {
ColorMap& color_map =
custom_frame ? custom_frame_colors_ : native_frame_colors_;
const std::string header_selector = custom_frame && GtkVersionCheck(3, 10)
? "#headerbar.header-bar.titlebar"
: "GtkMenuBar#menubar";
const SkColor frame_color = GetBgColor(header_selector);
const SkColor frame_color_inactive =
GetBgColor(header_selector + ":backdrop");
color_map[ThemeProperties::COLOR_FRAME] = frame_color;
color_map[ThemeProperties::COLOR_FRAME_INACTIVE] = frame_color_inactive;
color_map[ThemeProperties::COLOR_FRAME_INCOGNITO] =
color_utils::HSLShift(frame_color, kDefaultTintFrameIncognito);
color_map[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] =
color_utils::HSLShift(frame_color_inactive, kDefaultTintFrameIncognito);
color_map[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
ui::MaterialDesignController::IsRefreshUi()
? GetFgColor(header_selector + " GtkLabel")
: color_utils::BlendTowardOppositeLuma(tab_text_color, 50);
// These colors represent the border drawn around tabs and between
// the tabstrip and toolbar.
SkColor toolbar_top_separator =
GetBorderColor(header_selector + " GtkButton#button");
SkColor toolbar_top_separator_inactive =
GetBorderColor(header_selector + ":backdrop GtkButton#button");
if (!ui::MaterialDesignController::IsRefreshUi()) {
toolbar_top_separator = GetToolbarTopSeparatorColor(
toolbar_top_separator, frame_color, tab_border, tab_color);
toolbar_top_separator_inactive = GetToolbarTopSeparatorColor(
toolbar_top_separator_inactive, frame_color_inactive, tab_border,
tab_color);
}
// Unlike with toolbars, we always want a border around tabs, so let
// ThemeService choose the border color if the theme doesn't provide one.
if (SkColorGetA(toolbar_top_separator) &&
SkColorGetA(toolbar_top_separator_inactive)) {
color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR] =
toolbar_top_separator;
color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_INACTIVE] =
toolbar_top_separator_inactive;
}
}
#endif
colors_[ThemeProperties::COLOR_TOOLBAR] = tab_color;
......
......@@ -24,12 +24,13 @@ typedef struct _GtkStyle GtkStyle;
typedef struct _GtkWidget GtkWidget;
namespace libgtkui {
using ColorMap = std::map<int, SkColor>;
class Gtk2KeyBindingsHandler;
class DeviceScaleFactorObserver;
class SettingsProvider;
// Interface to GTK2 desktop features.
//
// Interface to GTK desktop features.
class GtkUi : public views::LinuxUI {
public:
GtkUi();
......@@ -71,7 +72,9 @@ class GtkUi : public views::LinuxUI {
// views::LinuxUI:
void Initialize() override;
bool GetTint(int id, color_utils::HSL* tint) const override;
bool GetColor(int id, SkColor* color) const override;
bool GetColor(int id,
SkColor* color,
PrefService* pref_service) const override;
SkColor GetFocusRingColor() const override;
SkColor GetThumbActiveColor() const override;
SkColor GetThumbInactiveColor() const override;
......@@ -119,8 +122,7 @@ class GtkUi : public views::LinuxUI {
std::vector<ui::TextEditCommandAuraLinux>* commands) override;
private:
typedef std::map<int, SkColor> ColorMap;
typedef std::map<int, color_utils::HSL> TintMap;
using TintMap = std::map<int, color_utils::HSL>;
CHROMEG_CALLBACK_1(GtkUi,
void,
......@@ -159,6 +161,14 @@ class GtkUi : public views::LinuxUI {
// caller while |use_gtk_| is true.
ColorMap colors_;
// Frame colors (and colors that depend on frame colors) when using
// Chrome-rendered borders and titlebar.
ColorMap custom_frame_colors_;
// Frame colors (and colors that depend on frame colors) when using
// system-rendered borders and titlebar.
ColorMap native_frame_colors_;
// Colors that we pass to WebKit. These are generated each time the theme
// changes.
SkColor focus_ring_color_;
......
......@@ -161,6 +161,9 @@ SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
return GetTextColor(GetMenuItem(), INSENSITIVE);
case kColorId_MenuBackgroundColor:
return GetBgColor(GetMenu(), NORMAL);
case kColorId_TouchableMenuItemLabelColor:
case kColorId_ActionableSubmenuVerticalSeparatorColor:
return kInvalidColorIdColor;
// Label
case kColorId_LabelEnabledColor:
......
......@@ -22,6 +22,8 @@
// The main entrypoint into Linux toolkit specific code. GTK code should only
// be executed behind this interface.
class PrefService;
namespace aura {
class Window;
}
......@@ -101,7 +103,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
virtual void Initialize() = 0;
virtual bool GetTint(int id, color_utils::HSL* tint) const = 0;
virtual bool GetColor(int id, SkColor* color) const = 0;
virtual bool GetColor(int id,
SkColor* color,
PrefService* pref_service) const = 0;
// Returns the preferences that we pass to WebKit.
virtual SkColor GetFocusRingColor() const = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment