Index: chrome/browser/ui/libgtkui/native_theme_gtk3.cc |
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc |
index 097b80a6b4f17dca3c9aa58a4ef29853fa716bc5..b91c783ba0055ebf0c94e638a7d738664d74a642 100644 |
--- a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc |
+++ b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc |
@@ -6,12 +6,11 @@ |
#include <gtk/gtk.h> |
-#include "base/strings/string_split.h" |
-#include "base/strings/string_util.h" |
#include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" |
#include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" |
#include "chrome/browser/ui/libgtkui/gtk_util.h" |
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" |
+#include "ui/gfx/color_palette.h" |
#include "ui/gfx/color_utils.h" |
#include "ui/gfx/geometry/rect.h" |
#include "ui/native_theme/native_theme_dark_aura.h" |
@@ -20,92 +19,6 @@ namespace libgtkui { |
namespace { |
-enum WidgetState { |
- NORMAL = 0, |
- ACTIVE = 1, |
- PRELIGHT = 2, |
- SELECTED = 3, |
- INSENSITIVE = 4, |
-}; |
- |
-// Same order as enum WidgetState above |
-const GtkStateFlags stateMap[] = { |
- GTK_STATE_FLAG_NORMAL, GTK_STATE_FLAG_ACTIVE, |
- GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_SELECTED, |
- GTK_STATE_FLAG_INSENSITIVE, |
-}; |
- |
-// The caller must g_object_unref the returned context. |
-GtkStyleContext* GetStyleContextFromCss(const char* css_selector) { |
- GtkWidgetPath* path = gtk_widget_path_new(); |
- for (const auto& widget_type : |
- base::SplitString(css_selector, base::kWhitespaceASCII, |
- base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { |
- gtk_widget_path_append_type(path, G_TYPE_NONE); |
- for (const auto& widget_class : |
- base::SplitString(widget_type, ".", base::TRIM_WHITESPACE, |
- base::SPLIT_WANT_NONEMPTY)) { |
- gtk_widget_path_iter_add_class(path, -1, widget_class.c_str()); |
- } |
- } |
- |
- GtkStyleContext* context = gtk_style_context_new(); |
- gtk_style_context_set_path(context, path); |
- gtk_widget_path_unref(path); |
- return context; |
-} |
- |
-SkColor GdkRgbaToSkColor(const GdkRGBA& color) { |
- return SkColorSetARGB(color.alpha * 255, color.red * 255, color.green * 255, |
- color.blue * 255); |
-} |
- |
-SkColor ColorFromContext(GtkStyleContext* context, |
- GtkStateFlags state, |
- const char* color_name) { |
- GdkRGBA* color = nullptr; |
- gtk_style_context_get(context, state, color_name, &color, nullptr); |
- DCHECK(color); |
- SkColor sk_color = GdkRgbaToSkColor(*color); |
- gdk_rgba_free(color); |
- return sk_color; |
-} |
- |
-SkColor GetFGColor(GtkWidget* widget, WidgetState state) { |
- return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state], |
- "color"); |
-} |
- |
-SkColor GetBGColor(GtkWidget* widget, WidgetState state) { |
- return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state], |
- "background-color"); |
-} |
- |
-SkColor GetFGColor(const char* css_selector, GtkStateFlags state) { |
- GtkStyleContext* context = GetStyleContextFromCss(css_selector); |
- SkColor color = ColorFromContext(context, state, "color"); |
- g_object_unref(context); |
- return color; |
-} |
- |
-SkColor GetBGColor(const char* css_selector, GtkStateFlags state) { |
- GtkStyleContext* context = GetStyleContextFromCss(css_selector); |
- SkColor color = ColorFromContext(context, state, "background-color"); |
- g_object_unref(context); |
- return color; |
-} |
- |
-SkColor GetBorderColor(const char* css_selector, GtkStateFlags state) { |
- GtkStyleContext* context = GetStyleContextFromCss(css_selector); |
- GtkBorder border; |
- gtk_style_context_get_border(context, state, &border); |
- bool has_border = border.left || border.right || border.top || border.bottom; |
- SkColor color = ColorFromContext( |
- context, state, has_border ? "border-color" : "background-color"); |
- g_object_unref(context); |
- return color; |
-} |
- |
void PaintWidget(SkCanvas* canvas, |
const gfx::Rect& rect, |
const char* css_selector, |
@@ -120,7 +33,7 @@ void PaintWidget(SkCanvas* canvas, |
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rect.width())); |
cairo_t* cr = cairo_create(surface); |
- GtkStyleContext* context = GetStyleContextFromCss(css_selector); |
+ auto context = GetStyleContextFromCss(css_selector); |
gtk_style_context_set_state(context, state); |
gtk_render_background(context, cr, 0, 0, rect.width(), rect.height()); |
@@ -128,8 +41,6 @@ void PaintWidget(SkCanvas* canvas, |
cairo_destroy(cr); |
cairo_surface_destroy(surface); |
canvas->drawBitmap(bitmap, rect.x(), rect.y()); |
- |
- g_object_unref(context); |
} |
GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { |
@@ -149,251 +60,285 @@ GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { |
} |
} |
-} // namespace |
- |
-// static |
-NativeThemeGtk3* NativeThemeGtk3::instance() { |
- CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); |
- return &s_native_theme; |
-} |
- |
-// Constructors automatically called |
-NativeThemeGtk3::NativeThemeGtk3() {} |
-// This doesn't actually get called |
-NativeThemeGtk3::~NativeThemeGtk3() {} |
- |
-SkColor NativeThemeGtk3::LookupGtkThemeColor(ColorId color_id) const { |
+SkColor SkColorFromColorId(ui::NativeTheme::ColorId color_id) { |
const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43); |
const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29); |
switch (color_id) { |
// Windows |
- case kColorId_WindowBackground: |
- return GetBGColor(GetWindow(), SELECTED); |
- |
+ case ui::NativeTheme::kColorId_WindowBackground: |
// Dialogs |
- case kColorId_DialogBackground: |
- case kColorId_BubbleBackground: |
- return GetBGColor(GetWindow(), NORMAL); |
+ case ui::NativeTheme::kColorId_DialogBackground: |
+ case ui::NativeTheme::kColorId_BubbleBackground: |
+ return GetBGColor(""); |
// FocusableBorder |
- case kColorId_FocusedBorderColor: |
- return GetBGColor(GetEntry(), SELECTED); |
- case kColorId_UnfocusedBorderColor: |
- return GetFGColor(GetEntry(), NORMAL); |
+ case ui::NativeTheme::kColorId_FocusedBorderColor: |
+ return GetBorderColor("GtkEntry.entry:focus"); |
+ case ui::NativeTheme::kColorId_UnfocusedBorderColor: |
+ return GetBorderColor("GtkEntry.entry"); |
// Menu |
- case kColorId_MenuBackgroundColor: |
- return GetBGColor("menu", GTK_STATE_FLAG_NORMAL); |
- case kColorId_MenuBorderColor: |
- return GetBorderColor("menu", GTK_STATE_FLAG_NORMAL); |
- case kColorId_FocusedMenuItemBackgroundColor: |
- return GetBGColor("menu menuitem", GTK_STATE_FLAG_FOCUSED); |
- case kColorId_EnabledMenuItemForegroundColor: |
- return GetFGColor("menu menuitem label", GTK_STATE_FLAG_NORMAL); |
- case kColorId_SelectedMenuItemForegroundColor: |
- return GetFGColor("menu menuitem label", GTK_STATE_FLAG_SELECTED); |
- case kColorId_DisabledMenuItemForegroundColor: |
- return GetFGColor("menu menuitem label", GTK_STATE_FLAG_INSENSITIVE); |
- case kColorId_MenuItemSubtitleColor: |
- return GetFGColor("menu menuitem accelerator", GTK_STATE_FLAG_NORMAL); |
- case kColorId_MenuSeparatorColor: |
- // MenuButton borders are used the same way as menu separtors in Chrome. |
- case kColorId_EnabledMenuButtonBorderColor: |
- case kColorId_FocusedMenuButtonBorderColor: |
- case kColorId_HoverMenuButtonBorderColor: |
- return GetFGColor("menu menuitem.separator", GTK_STATE_FLAG_INSENSITIVE); |
+ case ui::NativeTheme::kColorId_MenuBackgroundColor: |
+ return GetBGColor("GtkMenu.menu"); |
+ case ui::NativeTheme::kColorId_MenuBorderColor: |
+ return GetBorderColor("GtkMenu.menu"); |
+ case ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor: |
+ return GetBGColor("GtkMenu.menu GtkMenuItem.menuitem:focus"); |
+ case ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor: |
+ return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: |
+ return GetFGColor( |
+ "GtkMenu.menu GtkMenuItem.menuitem:selected GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor: |
+ return GetFGColor( |
+ "GtkMenu.menu GtkMenuItem.menuitem:disabled GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_MenuItemSubtitleColor: |
+ return GetFGColor( |
+ "GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label.accelerator"); |
+ case ui::NativeTheme::kColorId_MenuSeparatorColor: |
+ // MenuButton borders are used the same way as menu separators in Chrome. |
+ case ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor: |
+ case ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor: |
+ case ui::NativeTheme::kColorId_HoverMenuButtonBorderColor: |
+ return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem.separator:disabled"); |
// Label |
- case kColorId_LabelEnabledColor: |
- return GetFGColor(GetEntry(), NORMAL); |
- case kColorId_LabelDisabledColor: |
- return GetFGColor(GetLabel(), INSENSITIVE); |
- case kColorId_LabelTextSelectionColor: |
- return GetFGColor(GetLabel(), SELECTED); |
- case kColorId_LabelTextSelectionBackgroundFocused: |
- return GetBGColor(GetLabel(), SELECTED); |
+ case ui::NativeTheme::kColorId_LabelEnabledColor: |
+ return GetFGColor("GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_LabelDisabledColor: |
+ return GetFGColor("GtkLabel.label:disabled"); |
+ case ui::NativeTheme::kColorId_LabelTextSelectionColor: |
+ return GetFGColor("GtkLabel.label .selection:selected"); |
+ case ui::NativeTheme::kColorId_LabelTextSelectionBackgroundFocused: |
+ return GetBGColor("GtkLabel.label .selection:selected"); |
// Link |
- case kColorId_LinkDisabled: |
- return SkColorSetA(GetSystemColor(kColorId_LinkEnabled), 0xBB); |
- case kColorId_LinkEnabled: { |
- SkColor link_color = SK_ColorTRANSPARENT; |
- GdkColor* style_color = nullptr; |
- gtk_widget_style_get(GetWindow(), "link-color", &style_color, nullptr); |
- if (style_color) { |
- link_color = GdkColorToSkColor(*style_color); |
- gdk_color_free(style_color); |
+ case ui::NativeTheme::kColorId_LinkDisabled: |
+ return SkColorSetA( |
+ SkColorFromColorId(ui::NativeTheme::kColorId_LinkEnabled), 0xBB); |
+ case ui::NativeTheme::kColorId_LinkPressed: |
+ case ui::NativeTheme::kColorId_LinkEnabled: { |
+ // TODO(thomasanderson): Gtk changed the way links are colored in 3.12. |
+ // Add code for later versions. |
+ auto link_context = GetStyleContextFromCss("GtkLabel.label.view"); |
+ GdkColor* color; |
+ gtk_style_context_get_style(link_context, "link-color", &color, nullptr); |
+ if (color) { |
+ SkColor ret_color = SkColorSetRGB(color->red / 255, color->green / 255, |
+ color->blue / 255); |
+ gdk_color_free(color); |
+ return ret_color; |
+ } else { |
+ // Default color comes from gtklinkbutton.c. |
+ return SkColorSetRGB(0x00, 0x00, 0xEE); |
} |
- if (link_color != SK_ColorTRANSPARENT) |
- return link_color; |
- // Default color comes from gtklinkbutton.c. |
- return SkColorSetRGB(0x00, 0x00, 0xEE); |
} |
- case kColorId_LinkPressed: |
- return SK_ColorRED; |
// Button |
- case kColorId_ButtonEnabledColor: |
- return GetFGColor(GetButton(), NORMAL); |
- case kColorId_BlueButtonEnabledColor: |
- return GetFGColor(GetBlueButton(), NORMAL); |
- case kColorId_ButtonDisabledColor: |
- return GetFGColor(GetButton(), INSENSITIVE); |
- case kColorId_BlueButtonDisabledColor: |
- return GetFGColor(GetBlueButton(), INSENSITIVE); |
- case kColorId_ButtonHoverColor: |
- return GetFGColor(GetButton(), PRELIGHT); |
- case kColorId_BlueButtonHoverColor: |
- return GetFGColor(GetBlueButton(), PRELIGHT); |
- case kColorId_BlueButtonPressedColor: |
- return GetFGColor(GetBlueButton(), ACTIVE); |
- case kColorId_BlueButtonShadowColor: |
+ case ui::NativeTheme::kColorId_ButtonEnabledColor: |
+ return GetFGColor("GtkButton.button.text-button GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_ButtonDisabledColor: |
+ return GetFGColor("GtkButton.button.text-button:disabled GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_ButtonHoverColor: |
+ return GetFGColor("GtkButton.button.text-button:hover GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_ButtonPressedShade: |
return SK_ColorTRANSPARENT; |
- case kColorId_ProminentButtonColor: |
- return GetSystemColor(kColorId_LinkEnabled); |
- case kColorId_TextOnProminentButtonColor: |
- return GetFGColor(GetLabel(), SELECTED); |
- case kColorId_ButtonPressedShade: |
+ |
+ case ui::NativeTheme::kColorId_BlueButtonEnabledColor: |
+ return GetFGColor( |
+ "GtkButton.button.text-button.suggested-action GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_BlueButtonDisabledColor: |
+ return GetFGColor( |
+ "GtkButton.button.text-button.suggested-action:disabled " |
+ "GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_BlueButtonHoverColor: |
+ return GetFGColor( |
+ "GtkButton.button.text-button.suggested-action:hover GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_BlueButtonPressedColor: |
+ return GetFGColor( |
+ "GtkButton.button.text-button.suggested-action:hover:active " |
+ "GtkLabel.label"); |
+ case ui::NativeTheme::kColorId_BlueButtonShadowColor: |
return SK_ColorTRANSPARENT; |
+ case ui::NativeTheme::kColorId_ProminentButtonColor: |
+ return GetBGColor("GtkButton.button.text-button.destructive-action"); |
+ case ui::NativeTheme::kColorId_TextOnProminentButtonColor: |
+ return GetFGColor( |
+ "GtkButton.button.text-button.destructive-action GtkLabel.label"); |
+ |
// Textfield |
- case kColorId_TextfieldDefaultColor: |
- return GetFGColor(GetEntry(), NORMAL); |
- case kColorId_TextfieldDefaultBackground: |
- return GetBGColor(GetEntry(), NORMAL); |
- |
- case kColorId_TextfieldReadOnlyColor: |
- return GetFGColor(GetEntry(), SELECTED); |
- case kColorId_TextfieldReadOnlyBackground: |
- return GetBGColor(GetEntry(), SELECTED); |
- case kColorId_TextfieldSelectionColor: |
- return GetFGColor(GetLabel(), SELECTED); |
- case kColorId_TextfieldSelectionBackgroundFocused: |
- return GetBGColor(GetLabel(), SELECTED); |
+ case ui::NativeTheme::kColorId_TextfieldDefaultColor: |
+ return GetFGColor("GtkEntry.entry"); |
+ case ui::NativeTheme::kColorId_TextfieldDefaultBackground: |
+ return GetBGColor("GtkEntry.entry"); |
+ case ui::NativeTheme::kColorId_TextfieldReadOnlyColor: |
+ return GetFGColor("GtkEntry.entry:disabled"); |
+ case ui::NativeTheme::kColorId_TextfieldReadOnlyBackground: |
+ return GetBGColor("GtkEntry.entry:disabled"); |
+ case ui::NativeTheme::kColorId_TextfieldSelectionColor: |
+ return GetFGColor("GtkEntry.entry .selection:selected"); |
+ case ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused: |
+ return GetBGColor("GtkEntry.entry .selection:selected"); |
// Tooltips |
- case kColorId_TooltipBackground: |
- return GetBGColor(GetTooltip(), NORMAL); |
- case kColorId_TooltipText: |
- return GetFGColor(GetTooltip(), NORMAL); |
+ case ui::NativeTheme::kColorId_TooltipBackground: |
+ return GetBGColor("GtkTooltip.tooltip"); |
+ case ui::NativeTheme::kColorId_TooltipText: |
+ return color_utils::GetReadableColor(GetFGColor("GtkTooltip.tooltip"), |
+ GetBGColor("GtkTooltip.tooltip")); |
// Trees and Tables (implemented on GTK using the same class) |
- case kColorId_TableBackground: |
- case kColorId_TreeBackground: |
- return GetBGColor(GetTree(), NORMAL); |
- case kColorId_TableText: |
- case kColorId_TreeText: |
- return GetFGColor(GetTree(), NORMAL); |
- case kColorId_TableSelectedText: |
- case kColorId_TableSelectedTextUnfocused: |
- case kColorId_TreeSelectedText: |
- case kColorId_TreeSelectedTextUnfocused: |
- return GetFGColor(GetTree(), SELECTED); |
- case kColorId_TableSelectionBackgroundFocused: |
- case kColorId_TableSelectionBackgroundUnfocused: |
- case kColorId_TreeSelectionBackgroundFocused: |
- case kColorId_TreeSelectionBackgroundUnfocused: |
- return GetBGColor(GetTree(), SELECTED); |
- case kColorId_TreeArrow: |
- return GetFGColor(GetTree(), NORMAL); |
- case kColorId_TableGroupingIndicatorColor: |
- return GetFGColor(GetTree(), NORMAL); |
+ case ui::NativeTheme::kColorId_TableBackground: |
+ case ui::NativeTheme::kColorId_TreeBackground: |
+ return GetBGColor("GtkTreeView.view"); |
+ case ui::NativeTheme::kColorId_TableText: |
+ case ui::NativeTheme::kColorId_TreeText: |
+ case ui::NativeTheme::kColorId_TreeArrow: |
+ case ui::NativeTheme::kColorId_TableGroupingIndicatorColor: |
+ return GetFGColor("GtkTreeView.view .cell"); |
+ case ui::NativeTheme::kColorId_TableSelectedText: |
+ case ui::NativeTheme::kColorId_TableSelectedTextUnfocused: |
+ case ui::NativeTheme::kColorId_TreeSelectedText: |
+ case ui::NativeTheme::kColorId_TreeSelectedTextUnfocused: |
+ return GetFGColor("GtkTreeView.view .cell:selected"); |
+ case ui::NativeTheme::kColorId_TableSelectionBackgroundFocused: |
+ case ui::NativeTheme::kColorId_TableSelectionBackgroundUnfocused: |
+ case ui::NativeTheme::kColorId_TreeSelectionBackgroundFocused: |
+ case ui::NativeTheme::kColorId_TreeSelectionBackgroundUnfocused: |
+ return GetBGColor("GtkTreeView.view .cell:selected"); |
// Results Table |
- case kColorId_ResultsTableNormalBackground: |
- return GetSystemColor(kColorId_TextfieldDefaultBackground); |
- case kColorId_ResultsTableHoveredBackground: |
+ // TODO(thomasanderson): The GtkEntry selectors was how the gtk2 theme got |
+ // these colors. Update this code to use a different widget. |
+ case ui::NativeTheme::kColorId_ResultsTableNormalBackground: |
+ return GetBGColor("GtkEntry.entry"); |
+ case ui::NativeTheme::kColorId_ResultsTableHoveredBackground: |
return color_utils::AlphaBlend( |
- GetSystemColor(kColorId_TextfieldDefaultBackground), |
- GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), 0x80); |
- case kColorId_ResultsTableSelectedBackground: |
- return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused); |
- case kColorId_ResultsTableNormalText: |
- case kColorId_ResultsTableHoveredText: |
- return GetSystemColor(kColorId_TextfieldDefaultColor); |
- case kColorId_ResultsTableSelectedText: |
- return GetSystemColor(kColorId_TextfieldSelectionColor); |
- case kColorId_ResultsTableNormalDimmedText: |
- case kColorId_ResultsTableHoveredDimmedText: |
+ GetBGColor("GtkEntry.entry"), |
+ GetBGColor("GtkEntry.entry .selection:selected"), 0x80); |
+ case ui::NativeTheme::kColorId_ResultsTableSelectedBackground: |
+ return GetBGColor("GtkEntry.entry .selection:selected"); |
+ case ui::NativeTheme::kColorId_ResultsTableNormalText: |
+ case ui::NativeTheme::kColorId_ResultsTableHoveredText: |
+ return GetFGColor("GtkEntry.entry"); |
+ case ui::NativeTheme::kColorId_ResultsTableSelectedText: |
+ return GetFGColor("GtkEntry.entry .selection:selected"); |
+ case ui::NativeTheme::kColorId_ResultsTableNormalDimmedText: |
+ case ui::NativeTheme::kColorId_ResultsTableHoveredDimmedText: |
+ return color_utils::AlphaBlend(GetFGColor("GtkEntry.entry"), |
+ GetBGColor("GtkEntry.entry"), 0x80); |
+ case ui::NativeTheme::kColorId_ResultsTableSelectedDimmedText: |
return color_utils::AlphaBlend( |
- GetSystemColor(kColorId_TextfieldDefaultColor), |
- GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80); |
- case kColorId_ResultsTableSelectedDimmedText: |
- return color_utils::AlphaBlend( |
- GetSystemColor(kColorId_TextfieldSelectionColor), |
- GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80); |
- case kColorId_ResultsTableNormalUrl: |
- case kColorId_ResultsTableHoveredUrl: |
- return NormalURLColor(GetSystemColor(kColorId_TextfieldDefaultColor)); |
- |
- case kColorId_ResultsTableSelectedUrl: |
- return SelectedURLColor( |
- GetSystemColor(kColorId_TextfieldSelectionColor), |
- GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused)); |
+ GetFGColor("GtkEntry.entry .selection:selected"), |
+ GetBGColor("GtkEntry.entry"), 0x80); |
+ case ui::NativeTheme::kColorId_ResultsTableNormalUrl: |
+ case ui::NativeTheme::kColorId_ResultsTableHoveredUrl: |
+ return NormalURLColor(GetFGColor("GtkEntry.entry")); |
+ case ui::NativeTheme::kColorId_ResultsTableSelectedUrl: |
+ return SelectedURLColor(GetFGColor("GtkEntry.entry .selection:selected"), |
+ GetBGColor("GtkEntry.entry .selection:selected")); |
- case kColorId_ResultsTablePositiveText: |
+ case ui::NativeTheme::kColorId_ResultsTablePositiveText: |
return color_utils::GetReadableColor(kPositiveTextColor, |
- GetBGColor(GetEntry(), NORMAL)); |
- case kColorId_ResultsTablePositiveHoveredText: |
+ GetBGColor("GtkEntry.entry")); |
+ case ui::NativeTheme::kColorId_ResultsTablePositiveHoveredText: |
return color_utils::GetReadableColor(kPositiveTextColor, |
- GetBGColor(GetEntry(), PRELIGHT)); |
- case kColorId_ResultsTablePositiveSelectedText: |
- return color_utils::GetReadableColor(kPositiveTextColor, |
- GetBGColor(GetEntry(), SELECTED)); |
- case kColorId_ResultsTableNegativeText: |
- return color_utils::GetReadableColor(kNegativeTextColor, |
- GetBGColor(GetEntry(), NORMAL)); |
- case kColorId_ResultsTableNegativeHoveredText: |
+ GetBGColor("GtkEntry.entry:hover")); |
+ case ui::NativeTheme::kColorId_ResultsTablePositiveSelectedText: |
+ return color_utils::GetReadableColor( |
+ kPositiveTextColor, GetBGColor("GtkEntry.entry:selected")); |
+ case ui::NativeTheme::kColorId_ResultsTableNegativeText: |
return color_utils::GetReadableColor(kNegativeTextColor, |
- GetBGColor(GetEntry(), PRELIGHT)); |
- case kColorId_ResultsTableNegativeSelectedText: |
+ GetBGColor("GtkEntry.entry")); |
+ case ui::NativeTheme::kColorId_ResultsTableNegativeHoveredText: |
return color_utils::GetReadableColor(kNegativeTextColor, |
- GetBGColor(GetEntry(), SELECTED)); |
+ GetBGColor("GtkEntry.entry:hover")); |
+ case ui::NativeTheme::kColorId_ResultsTableNegativeSelectedText: |
+ return color_utils::GetReadableColor( |
+ kNegativeTextColor, GetBGColor("GtkEntry.entry:selected")); |
// Throbber |
- case kColorId_ThrobberSpinningColor: |
- case kColorId_ThrobberLightColor: |
- return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused); |
- |
- case kColorId_ThrobberWaitingColor: |
- return color_utils::AlphaBlend( |
- GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), |
- GetBGColor(GetWindow(), NORMAL), 0x80); |
+ // TODO(thomasanderson): Render GtkSpinner directly. |
+ case ui::NativeTheme::kColorId_ThrobberSpinningColor: |
+ case ui::NativeTheme::kColorId_ThrobberWaitingColor: |
+ return GetFGColor("GtkMenu.menu GtkSpinner.spinner"); |
+ case ui::NativeTheme::kColorId_ThrobberLightColor: |
+ return GetFGColor("GtkMenu.menu GtkSpinner.spinner:disabled"); |
// Alert icons |
- // Just fall back to the same colors as Aura. |
- case kColorId_AlertSeverityLow: |
- case kColorId_AlertSeverityMedium: |
- case kColorId_AlertSeverityHigh: |
- return SK_ColorTRANSPARENT; |
+ case ui::NativeTheme::kColorId_AlertSeverityLow: |
+ return GetBGColor("GtkInfoBar.infobar.info"); |
+ case ui::NativeTheme::kColorId_AlertSeverityMedium: |
+ return GetBGColor("GtkInfoBar.infobar.warning"); |
+ case ui::NativeTheme::kColorId_AlertSeverityHigh: |
+ return GetBGColor("GtkInfoBar.infobar.error"); |
- case kColorId_NumColors: |
+ case ui::NativeTheme::kColorId_NumColors: |
NOTREACHED(); |
break; |
} |
- |
return kInvalidColorIdColor; |
} |
+void OnThemeChanged(GObject* obj, GParamSpec* param, NativeThemeGtk3* theme) { |
+ theme->ResetColorCache(); |
+} |
+ |
+} // namespace |
+ |
+// static |
+NativeThemeGtk3* NativeThemeGtk3::instance() { |
+ CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); |
+ return &s_native_theme; |
+} |
+ |
+// Constructors automatically called |
+NativeThemeGtk3::NativeThemeGtk3() { |
+ // These types are needed by g_type_from_name(), but may not be registered at |
+ // this point. We need the g_type_class magic to make sure the compiler |
+ // doesn't optimize away this code. |
+ g_type_class_unref(g_type_class_ref(gtk_button_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_label_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_window_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_link_button_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_spinner_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_menu_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_menu_item_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_entry_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_info_bar_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_tooltip_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_scrollbar_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_toolbar_get_type())); |
+ g_type_class_unref(g_type_class_ref(gtk_text_view_get_type())); |
+ |
+ g_signal_connect_after(gtk_settings_get_default(), "notify::gtk-theme-name", |
+ G_CALLBACK(OnThemeChanged), this); |
+} |
+ |
+// This doesn't actually get called |
+NativeThemeGtk3::~NativeThemeGtk3() {} |
+ |
+void NativeThemeGtk3::ResetColorCache() { |
+ for (auto& color : color_cache_) |
+ color = base::nullopt; |
+} |
+ |
SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { |
- SkColor color = LookupGtkThemeColor(color_id); |
- if (SkColorGetA(color)) |
- return color; |
- gboolean prefer_dark_theme = FALSE; |
- g_object_get(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", |
- &prefer_dark_theme, nullptr); |
- ui::NativeTheme* fallback_theme = |
- prefer_dark_theme ? ui::NativeThemeDarkAura::instance() |
- : ui::NativeTheme::GetInstanceForNativeUi(); |
- return fallback_theme->GetSystemColor(color_id); |
+ if (color_cache_[color_id]) |
+ return color_cache_[color_id].value(); |
+ |
+ SkColor color = SkColorFromColorId(color_id); |
+ color_cache_[color_id] = color; |
+ return color; |
} |
void NativeThemeGtk3::PaintMenuPopupBackground( |
SkCanvas* canvas, |
const gfx::Size& size, |
const MenuBackgroundExtraParams& menu_background) const { |
- PaintWidget(canvas, gfx::Rect(size), "menu", GTK_STATE_FLAG_NORMAL); |
+ PaintWidget(canvas, gfx::Rect(size), "GtkMenu.menu", GTK_STATE_FLAG_NORMAL); |
} |
void NativeThemeGtk3::PaintMenuItemBackground( |
@@ -401,103 +346,8 @@ void NativeThemeGtk3::PaintMenuItemBackground( |
State state, |
const gfx::Rect& rect, |
const MenuItemExtraParams& menu_item) const { |
- PaintWidget(canvas, rect, "menu menuitem", StateToStateFlags(state)); |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetWindow() const { |
- static GtkWidget* fake_window = NULL; |
- |
- if (!fake_window) { |
- fake_window = chrome_gtk_frame_new(); |
- gtk_widget_realize(fake_window); |
- } |
- |
- return fake_window; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetEntry() const { |
- static GtkWidget* fake_entry = NULL; |
- |
- if (!fake_entry) { |
- fake_entry = gtk_entry_new(); |
- |
- // The fake entry needs to be in the window so it can be realized so we can |
- // use the computed parts of the style. |
- gtk_container_add(GTK_CONTAINER(GetWindow()), fake_entry); |
- gtk_widget_realize(fake_entry); |
- } |
- |
- return fake_entry; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetLabel() const { |
- static GtkWidget* fake_label = NULL; |
- |
- if (!fake_label) |
- fake_label = gtk_label_new(""); |
- |
- return fake_label; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetButton() const { |
- static GtkWidget* fake_button = NULL; |
- |
- if (!fake_button) |
- fake_button = gtk_button_new(); |
- |
- return fake_button; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetBlueButton() const { |
- static GtkWidget* fake_bluebutton = NULL; |
- |
- if (!fake_bluebutton) { |
- fake_bluebutton = gtk_button_new(); |
- TurnButtonBlue(fake_bluebutton); |
- } |
- |
- return fake_bluebutton; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetTree() const { |
- static GtkWidget* fake_tree = NULL; |
- |
- if (!fake_tree) |
- fake_tree = gtk_tree_view_new(); |
- |
- return fake_tree; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetTooltip() const { |
- static GtkWidget* fake_tooltip = NULL; |
- |
- if (!fake_tooltip) { |
- fake_tooltip = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
- gtk_widget_set_name(fake_tooltip, "gtk-tooltip"); |
- gtk_widget_realize(fake_tooltip); |
- } |
- |
- return fake_tooltip; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetMenu() const { |
- static GtkWidget* fake_menu = NULL; |
- |
- if (!fake_menu) |
- fake_menu = gtk_custom_menu_new(); |
- |
- return fake_menu; |
-} |
- |
-GtkWidget* NativeThemeGtk3::GetMenuItem() const { |
- static GtkWidget* fake_menu_item = NULL; |
- |
- if (!fake_menu_item) { |
- fake_menu_item = gtk_custom_menu_item_new(); |
- gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item); |
- } |
- |
- return fake_menu_item; |
+ PaintWidget(canvas, rect, "GtkMenu.menu GtkMenuItem.menuitem", |
+ StateToStateFlags(state)); |
} |
} // namespace libgtkui |