Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Side by Side Diff: chrome/browser/ui/libgtkui/native_theme_gtk3.cc

Issue 2588993002: Gtk3: Refactor NativeThemeGtk3 to use foreign drawing only (Closed)
Patch Set: Add color cache Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/libgtkui/native_theme_gtk3.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" 5 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" 9 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h"
12 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" 10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h"
13 #include "chrome/browser/ui/libgtkui/gtk_util.h" 11 #include "chrome/browser/ui/libgtkui/gtk_util.h"
14 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" 12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
13 #include "ui/gfx/color_palette.h"
15 #include "ui/gfx/color_utils.h" 14 #include "ui/gfx/color_utils.h"
16 #include "ui/gfx/geometry/rect.h" 15 #include "ui/gfx/geometry/rect.h"
17 #include "ui/native_theme/native_theme_dark_aura.h" 16 #include "ui/native_theme/native_theme_dark_aura.h"
18 17
19 namespace libgtkui { 18 namespace libgtkui {
20 19
21 namespace { 20 namespace {
22 21
23 enum WidgetState {
24 NORMAL = 0,
25 ACTIVE = 1,
26 PRELIGHT = 2,
27 SELECTED = 3,
28 INSENSITIVE = 4,
29 };
30
31 // Same order as enum WidgetState above
32 const GtkStateFlags stateMap[] = {
33 GTK_STATE_FLAG_NORMAL, GTK_STATE_FLAG_ACTIVE,
34 GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_SELECTED,
35 GTK_STATE_FLAG_INSENSITIVE,
36 };
37
38 // The caller must g_object_unref the returned context.
39 GtkStyleContext* GetStyleContextFromCss(const char* css_selector) {
40 GtkWidgetPath* path = gtk_widget_path_new();
41 for (const auto& widget_type :
42 base::SplitString(css_selector, base::kWhitespaceASCII,
43 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
44 gtk_widget_path_append_type(path, G_TYPE_NONE);
45 for (const auto& widget_class :
46 base::SplitString(widget_type, ".", base::TRIM_WHITESPACE,
47 base::SPLIT_WANT_NONEMPTY)) {
48 gtk_widget_path_iter_add_class(path, -1, widget_class.c_str());
49 }
50 }
51
52 GtkStyleContext* context = gtk_style_context_new();
53 gtk_style_context_set_path(context, path);
54 gtk_widget_path_unref(path);
55 return context;
56 }
57
58 SkColor GdkRgbaToSkColor(const GdkRGBA& color) {
59 return SkColorSetARGB(color.alpha * 255, color.red * 255, color.green * 255,
60 color.blue * 255);
61 }
62
63 SkColor ColorFromContext(GtkStyleContext* context,
64 GtkStateFlags state,
65 const char* color_name) {
66 GdkRGBA* color = nullptr;
67 gtk_style_context_get(context, state, color_name, &color, nullptr);
68 DCHECK(color);
69 SkColor sk_color = GdkRgbaToSkColor(*color);
70 gdk_rgba_free(color);
71 return sk_color;
72 }
73
74 SkColor GetFGColor(GtkWidget* widget, WidgetState state) {
75 return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state],
76 "color");
77 }
78
79 SkColor GetBGColor(GtkWidget* widget, WidgetState state) {
80 return ColorFromContext(gtk_widget_get_style_context(widget), stateMap[state],
81 "background-color");
82 }
83
84 SkColor GetFGColor(const char* css_selector, GtkStateFlags state) {
85 GtkStyleContext* context = GetStyleContextFromCss(css_selector);
86 SkColor color = ColorFromContext(context, state, "color");
87 g_object_unref(context);
88 return color;
89 }
90
91 SkColor GetBGColor(const char* css_selector, GtkStateFlags state) {
92 GtkStyleContext* context = GetStyleContextFromCss(css_selector);
93 SkColor color = ColorFromContext(context, state, "background-color");
94 g_object_unref(context);
95 return color;
96 }
97
98 SkColor GetBorderColor(const char* css_selector, GtkStateFlags state) {
99 GtkStyleContext* context = GetStyleContextFromCss(css_selector);
100 GtkBorder border;
101 gtk_style_context_get_border(context, state, &border);
102 bool has_border = border.left || border.right || border.top || border.bottom;
103 SkColor color = ColorFromContext(
104 context, state, has_border ? "border-color" : "background-color");
105 g_object_unref(context);
106 return color;
107 }
108
109 void PaintWidget(SkCanvas* canvas, 22 void PaintWidget(SkCanvas* canvas,
110 const gfx::Rect& rect, 23 const gfx::Rect& rect,
111 const char* css_selector, 24 const char* css_selector,
112 GtkStateFlags state) { 25 GtkStateFlags state) {
113 SkBitmap bitmap; 26 SkBitmap bitmap;
114 bitmap.allocN32Pixels(rect.width(), rect.height()); 27 bitmap.allocN32Pixels(rect.width(), rect.height());
115 bitmap.eraseColor(0); 28 bitmap.eraseColor(0);
116 29
117 cairo_surface_t* surface = cairo_image_surface_create_for_data( 30 cairo_surface_t* surface = cairo_image_surface_create_for_data(
118 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32, 31 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32,
119 rect.width(), rect.height(), 32 rect.width(), rect.height(),
120 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rect.width())); 33 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, rect.width()));
121 cairo_t* cr = cairo_create(surface); 34 cairo_t* cr = cairo_create(surface);
122 35
123 GtkStyleContext* context = GetStyleContextFromCss(css_selector); 36 auto context = GetStyleContextFromCss(css_selector);
124 gtk_style_context_set_state(context, state); 37 gtk_style_context_set_state(context, state);
125 38
126 gtk_render_background(context, cr, 0, 0, rect.width(), rect.height()); 39 gtk_render_background(context, cr, 0, 0, rect.width(), rect.height());
127 gtk_render_frame(context, cr, 0, 0, rect.width(), rect.height()); 40 gtk_render_frame(context, cr, 0, 0, rect.width(), rect.height());
128 cairo_destroy(cr); 41 cairo_destroy(cr);
129 cairo_surface_destroy(surface); 42 cairo_surface_destroy(surface);
130 canvas->drawBitmap(bitmap, rect.x(), rect.y()); 43 canvas->drawBitmap(bitmap, rect.x(), rect.y());
131
132 g_object_unref(context);
133 } 44 }
134 45
135 GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) { 46 GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) {
136 switch (state) { 47 switch (state) {
137 case NativeThemeGtk3::kDisabled: 48 case NativeThemeGtk3::kDisabled:
138 return GTK_STATE_FLAG_INSENSITIVE; 49 return GTK_STATE_FLAG_INSENSITIVE;
139 case NativeThemeGtk3::kHovered: 50 case NativeThemeGtk3::kHovered:
140 return GTK_STATE_FLAG_PRELIGHT; 51 return GTK_STATE_FLAG_PRELIGHT;
141 case NativeThemeGtk3::kNormal: 52 case NativeThemeGtk3::kNormal:
142 return GTK_STATE_FLAG_NORMAL; 53 return GTK_STATE_FLAG_NORMAL;
143 case NativeThemeGtk3::kPressed: 54 case NativeThemeGtk3::kPressed:
144 return static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT | 55 return static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT |
145 GTK_STATE_FLAG_ACTIVE); 56 GTK_STATE_FLAG_ACTIVE);
146 default: 57 default:
147 NOTREACHED(); 58 NOTREACHED();
148 return GTK_STATE_FLAG_NORMAL; 59 return GTK_STATE_FLAG_NORMAL;
149 } 60 }
150 } 61 }
151 62
63 SkColor SkColorFromColorId(ui::NativeTheme::ColorId color_id) {
64 const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43);
65 const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29);
66
67 switch (color_id) {
68 // Windows
69 case ui::NativeTheme::kColorId_WindowBackground:
70 // Dialogs
71 case ui::NativeTheme::kColorId_DialogBackground:
72 case ui::NativeTheme::kColorId_BubbleBackground:
73 return GetBGColor("");
74
75 // FocusableBorder
76 case ui::NativeTheme::kColorId_FocusedBorderColor:
77 return GetBorderColor("GtkEntry.entry:focus");
78 case ui::NativeTheme::kColorId_UnfocusedBorderColor:
79 return GetBorderColor("GtkEntry.entry");
80
81 // Menu
82 case ui::NativeTheme::kColorId_MenuBackgroundColor:
83 return GetBGColor("GtkMenu.menu");
84 case ui::NativeTheme::kColorId_MenuBorderColor:
85 return GetBorderColor("GtkMenu.menu");
86 case ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor:
87 return GetBGColor("GtkMenu.menu GtkMenuItem.menuitem:focus");
88 case ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor:
89 return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label");
90 case ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor:
91 return GetFGColor(
92 "GtkMenu.menu GtkMenuItem.menuitem:selected GtkLabel.label");
93 case ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor:
94 return GetFGColor(
95 "GtkMenu.menu GtkMenuItem.menuitem:disabled GtkLabel.label");
96 case ui::NativeTheme::kColorId_MenuItemSubtitleColor:
97 return GetFGColor(
98 "GtkMenu.menu GtkMenuItem.menuitem GtkLabel.label.accelerator");
99 case ui::NativeTheme::kColorId_MenuSeparatorColor:
100 // MenuButton borders are used the same way as menu separators in Chrome.
101 case ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor:
102 case ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor:
103 case ui::NativeTheme::kColorId_HoverMenuButtonBorderColor:
104 return GetFGColor("GtkMenu.menu GtkMenuItem.menuitem.separator:disabled");
105
106 // Label
107 case ui::NativeTheme::kColorId_LabelEnabledColor:
108 return GetFGColor("GtkLabel.label");
109 case ui::NativeTheme::kColorId_LabelDisabledColor:
110 return GetFGColor("GtkLabel.label:disabled");
111 case ui::NativeTheme::kColorId_LabelTextSelectionColor:
112 return GetFGColor("GtkLabel.label .selection:selected");
113 case ui::NativeTheme::kColorId_LabelTextSelectionBackgroundFocused:
114 return GetBGColor("GtkLabel.label .selection:selected");
115
116 // Link
117 case ui::NativeTheme::kColorId_LinkDisabled:
118 return SkColorSetA(
119 SkColorFromColorId(ui::NativeTheme::kColorId_LinkEnabled), 0xBB);
120 case ui::NativeTheme::kColorId_LinkPressed:
121 case ui::NativeTheme::kColorId_LinkEnabled: {
122 // TODO(thomasanderson): Gtk changed the way links are colored in 3.12.
123 // Add code for later versions.
124 auto link_context = GetStyleContextFromCss("GtkLabel.label.view");
125 GdkColor* color;
126 gtk_style_context_get_style(link_context, "link-color", &color, nullptr);
127 if (color) {
128 SkColor ret_color = SkColorSetRGB(color->red / 255, color->green / 255,
129 color->blue / 255);
130 gdk_color_free(color);
131 return ret_color;
132 } else {
133 // Default color comes from gtklinkbutton.c.
134 return SkColorSetRGB(0x00, 0x00, 0xEE);
135 }
136 }
137
138 // Button
139 case ui::NativeTheme::kColorId_ButtonEnabledColor:
140 return GetFGColor("GtkButton.button.text-button GtkLabel.label");
141 case ui::NativeTheme::kColorId_ButtonDisabledColor:
142 return GetFGColor("GtkButton.button.text-button:disabled GtkLabel.label");
143 case ui::NativeTheme::kColorId_ButtonHoverColor:
144 return GetFGColor("GtkButton.button.text-button:hover GtkLabel.label");
145 case ui::NativeTheme::kColorId_ButtonPressedShade:
146 return SK_ColorTRANSPARENT;
147
148 case ui::NativeTheme::kColorId_BlueButtonEnabledColor:
149 return GetFGColor(
150 "GtkButton.button.text-button.suggested-action GtkLabel.label");
151 case ui::NativeTheme::kColorId_BlueButtonDisabledColor:
152 return GetFGColor(
153 "GtkButton.button.text-button.suggested-action:disabled "
154 "GtkLabel.label");
155 case ui::NativeTheme::kColorId_BlueButtonHoverColor:
156 return GetFGColor(
157 "GtkButton.button.text-button.suggested-action:hover GtkLabel.label");
158 case ui::NativeTheme::kColorId_BlueButtonPressedColor:
159 return GetFGColor(
160 "GtkButton.button.text-button.suggested-action:hover:active "
161 "GtkLabel.label");
162 case ui::NativeTheme::kColorId_BlueButtonShadowColor:
163 return SK_ColorTRANSPARENT;
164
165 case ui::NativeTheme::kColorId_ProminentButtonColor:
166 return GetBGColor("GtkButton.button.text-button.destructive-action");
167 case ui::NativeTheme::kColorId_TextOnProminentButtonColor:
168 return GetFGColor(
169 "GtkButton.button.text-button.destructive-action GtkLabel.label");
170
171 // Textfield
172 case ui::NativeTheme::kColorId_TextfieldDefaultColor:
173 return GetFGColor("GtkEntry.entry");
174 case ui::NativeTheme::kColorId_TextfieldDefaultBackground:
175 return GetBGColor("GtkEntry.entry");
176 case ui::NativeTheme::kColorId_TextfieldReadOnlyColor:
177 return GetFGColor("GtkEntry.entry:disabled");
178 case ui::NativeTheme::kColorId_TextfieldReadOnlyBackground:
179 return GetBGColor("GtkEntry.entry:disabled");
180 case ui::NativeTheme::kColorId_TextfieldSelectionColor:
181 return GetFGColor("GtkEntry.entry .selection:selected");
182 case ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused:
183 return GetBGColor("GtkEntry.entry .selection:selected");
184
185 // Tooltips
186 case ui::NativeTheme::kColorId_TooltipBackground:
187 return GetBGColor("GtkTooltip.tooltip");
188 case ui::NativeTheme::kColorId_TooltipText:
189 return color_utils::GetReadableColor(GetFGColor("GtkTooltip.tooltip"),
190 GetBGColor("GtkTooltip.tooltip"));
191
192 // Trees and Tables (implemented on GTK using the same class)
193 case ui::NativeTheme::kColorId_TableBackground:
194 case ui::NativeTheme::kColorId_TreeBackground:
195 return GetBGColor("GtkTreeView.view");
196 case ui::NativeTheme::kColorId_TableText:
197 case ui::NativeTheme::kColorId_TreeText:
198 case ui::NativeTheme::kColorId_TreeArrow:
199 case ui::NativeTheme::kColorId_TableGroupingIndicatorColor:
200 return GetFGColor("GtkTreeView.view .cell");
201 case ui::NativeTheme::kColorId_TableSelectedText:
202 case ui::NativeTheme::kColorId_TableSelectedTextUnfocused:
203 case ui::NativeTheme::kColorId_TreeSelectedText:
204 case ui::NativeTheme::kColorId_TreeSelectedTextUnfocused:
205 return GetFGColor("GtkTreeView.view .cell:selected");
206 case ui::NativeTheme::kColorId_TableSelectionBackgroundFocused:
207 case ui::NativeTheme::kColorId_TableSelectionBackgroundUnfocused:
208 case ui::NativeTheme::kColorId_TreeSelectionBackgroundFocused:
209 case ui::NativeTheme::kColorId_TreeSelectionBackgroundUnfocused:
210 return GetBGColor("GtkTreeView.view .cell:selected");
211
212 // Results Table
213 // TODO(thomasanderson): The GtkEntry selectors was how the gtk2 theme got
214 // these colors. Update this code to use a different widget.
215 case ui::NativeTheme::kColorId_ResultsTableNormalBackground:
216 return GetBGColor("GtkEntry.entry");
217 case ui::NativeTheme::kColorId_ResultsTableHoveredBackground:
218 return color_utils::AlphaBlend(
219 GetBGColor("GtkEntry.entry"),
220 GetBGColor("GtkEntry.entry .selection:selected"), 0x80);
221 case ui::NativeTheme::kColorId_ResultsTableSelectedBackground:
222 return GetBGColor("GtkEntry.entry .selection:selected");
223 case ui::NativeTheme::kColorId_ResultsTableNormalText:
224 case ui::NativeTheme::kColorId_ResultsTableHoveredText:
225 return GetFGColor("GtkEntry.entry");
226 case ui::NativeTheme::kColorId_ResultsTableSelectedText:
227 return GetFGColor("GtkEntry.entry .selection:selected");
228 case ui::NativeTheme::kColorId_ResultsTableNormalDimmedText:
229 case ui::NativeTheme::kColorId_ResultsTableHoveredDimmedText:
230 return color_utils::AlphaBlend(GetFGColor("GtkEntry.entry"),
231 GetBGColor("GtkEntry.entry"), 0x80);
232 case ui::NativeTheme::kColorId_ResultsTableSelectedDimmedText:
233 return color_utils::AlphaBlend(
234 GetFGColor("GtkEntry.entry .selection:selected"),
235 GetBGColor("GtkEntry.entry"), 0x80);
236 case ui::NativeTheme::kColorId_ResultsTableNormalUrl:
237 case ui::NativeTheme::kColorId_ResultsTableHoveredUrl:
238 return NormalURLColor(GetFGColor("GtkEntry.entry"));
239 case ui::NativeTheme::kColorId_ResultsTableSelectedUrl:
240 return SelectedURLColor(GetFGColor("GtkEntry.entry .selection:selected"),
241 GetBGColor("GtkEntry.entry .selection:selected"));
242
243 case ui::NativeTheme::kColorId_ResultsTablePositiveText:
244 return color_utils::GetReadableColor(kPositiveTextColor,
245 GetBGColor("GtkEntry.entry"));
246 case ui::NativeTheme::kColorId_ResultsTablePositiveHoveredText:
247 return color_utils::GetReadableColor(kPositiveTextColor,
248 GetBGColor("GtkEntry.entry:hover"));
249 case ui::NativeTheme::kColorId_ResultsTablePositiveSelectedText:
250 return color_utils::GetReadableColor(
251 kPositiveTextColor, GetBGColor("GtkEntry.entry:selected"));
252 case ui::NativeTheme::kColorId_ResultsTableNegativeText:
253 return color_utils::GetReadableColor(kNegativeTextColor,
254 GetBGColor("GtkEntry.entry"));
255 case ui::NativeTheme::kColorId_ResultsTableNegativeHoveredText:
256 return color_utils::GetReadableColor(kNegativeTextColor,
257 GetBGColor("GtkEntry.entry:hover"));
258 case ui::NativeTheme::kColorId_ResultsTableNegativeSelectedText:
259 return color_utils::GetReadableColor(
260 kNegativeTextColor, GetBGColor("GtkEntry.entry:selected"));
261
262 // Throbber
263 // TODO(thomasanderson): Render GtkSpinner directly.
264 case ui::NativeTheme::kColorId_ThrobberSpinningColor:
265 case ui::NativeTheme::kColorId_ThrobberWaitingColor:
266 return GetFGColor("GtkMenu.menu GtkSpinner.spinner");
267 case ui::NativeTheme::kColorId_ThrobberLightColor:
268 return GetFGColor("GtkMenu.menu GtkSpinner.spinner:disabled");
269
270 // Alert icons
271 case ui::NativeTheme::kColorId_AlertSeverityLow:
272 return GetBGColor("GtkInfoBar.infobar.info");
273 case ui::NativeTheme::kColorId_AlertSeverityMedium:
274 return GetBGColor("GtkInfoBar.infobar.warning");
275 case ui::NativeTheme::kColorId_AlertSeverityHigh:
276 return GetBGColor("GtkInfoBar.infobar.error");
277
278 case ui::NativeTheme::kColorId_NumColors:
279 NOTREACHED();
280 break;
281 }
282 return kInvalidColorIdColor;
283 }
284
285 void OnThemeChanged(GObject* obj, GParamSpec* param, NativeThemeGtk3* theme) {
286 theme->ResetColorCache();
287 }
288
152 } // namespace 289 } // namespace
153 290
154 // static 291 // static
155 NativeThemeGtk3* NativeThemeGtk3::instance() { 292 NativeThemeGtk3* NativeThemeGtk3::instance() {
156 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); 293 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ());
157 return &s_native_theme; 294 return &s_native_theme;
158 } 295 }
159 296
160 // Constructors automatically called 297 // Constructors automatically called
161 NativeThemeGtk3::NativeThemeGtk3() {} 298 NativeThemeGtk3::NativeThemeGtk3() {
299 // These types are needed by g_type_from_name(), but may not be registered at
300 // this point. We need the g_type_class magic to make sure the compiler
301 // doesn't optimize away this code.
302 g_type_class_unref(g_type_class_ref(gtk_button_get_type()));
303 g_type_class_unref(g_type_class_ref(gtk_label_get_type()));
304 g_type_class_unref(g_type_class_ref(gtk_window_get_type()));
305 g_type_class_unref(g_type_class_ref(gtk_link_button_get_type()));
306 g_type_class_unref(g_type_class_ref(gtk_spinner_get_type()));
307 g_type_class_unref(g_type_class_ref(gtk_menu_get_type()));
308 g_type_class_unref(g_type_class_ref(gtk_menu_item_get_type()));
309 g_type_class_unref(g_type_class_ref(gtk_entry_get_type()));
310 g_type_class_unref(g_type_class_ref(gtk_info_bar_get_type()));
311 g_type_class_unref(g_type_class_ref(gtk_tooltip_get_type()));
312 g_type_class_unref(g_type_class_ref(gtk_scrollbar_get_type()));
313 g_type_class_unref(g_type_class_ref(gtk_toolbar_get_type()));
314 g_type_class_unref(g_type_class_ref(gtk_text_view_get_type()));
315
316 g_signal_connect_after(gtk_settings_get_default(), "notify::gtk-theme-name",
317 G_CALLBACK(OnThemeChanged), this);
318 }
319
162 // This doesn't actually get called 320 // This doesn't actually get called
163 NativeThemeGtk3::~NativeThemeGtk3() {} 321 NativeThemeGtk3::~NativeThemeGtk3() {}
164 322
165 SkColor NativeThemeGtk3::LookupGtkThemeColor(ColorId color_id) const { 323 void NativeThemeGtk3::ResetColorCache() {
166 const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43); 324 for (auto& color : color_cache_)
167 const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29); 325 color = base::nullopt;
168
169 switch (color_id) {
170 // Windows
171 case kColorId_WindowBackground:
172 return GetBGColor(GetWindow(), SELECTED);
173
174 // Dialogs
175 case kColorId_DialogBackground:
176 case kColorId_BubbleBackground:
177 return GetBGColor(GetWindow(), NORMAL);
178
179 // FocusableBorder
180 case kColorId_FocusedBorderColor:
181 return GetBGColor(GetEntry(), SELECTED);
182 case kColorId_UnfocusedBorderColor:
183 return GetFGColor(GetEntry(), NORMAL);
184
185 // Menu
186 case kColorId_MenuBackgroundColor:
187 return GetBGColor("menu", GTK_STATE_FLAG_NORMAL);
188 case kColorId_MenuBorderColor:
189 return GetBorderColor("menu", GTK_STATE_FLAG_NORMAL);
190 case kColorId_FocusedMenuItemBackgroundColor:
191 return GetBGColor("menu menuitem", GTK_STATE_FLAG_FOCUSED);
192 case kColorId_EnabledMenuItemForegroundColor:
193 return GetFGColor("menu menuitem label", GTK_STATE_FLAG_NORMAL);
194 case kColorId_SelectedMenuItemForegroundColor:
195 return GetFGColor("menu menuitem label", GTK_STATE_FLAG_SELECTED);
196 case kColorId_DisabledMenuItemForegroundColor:
197 return GetFGColor("menu menuitem label", GTK_STATE_FLAG_INSENSITIVE);
198 case kColorId_MenuItemSubtitleColor:
199 return GetFGColor("menu menuitem accelerator", GTK_STATE_FLAG_NORMAL);
200 case kColorId_MenuSeparatorColor:
201 // MenuButton borders are used the same way as menu separtors in Chrome.
202 case kColorId_EnabledMenuButtonBorderColor:
203 case kColorId_FocusedMenuButtonBorderColor:
204 case kColorId_HoverMenuButtonBorderColor:
205 return GetFGColor("menu menuitem.separator", GTK_STATE_FLAG_INSENSITIVE);
206
207 // Label
208 case kColorId_LabelEnabledColor:
209 return GetFGColor(GetEntry(), NORMAL);
210 case kColorId_LabelDisabledColor:
211 return GetFGColor(GetLabel(), INSENSITIVE);
212 case kColorId_LabelTextSelectionColor:
213 return GetFGColor(GetLabel(), SELECTED);
214 case kColorId_LabelTextSelectionBackgroundFocused:
215 return GetBGColor(GetLabel(), SELECTED);
216
217 // Link
218 case kColorId_LinkDisabled:
219 return SkColorSetA(GetSystemColor(kColorId_LinkEnabled), 0xBB);
220 case kColorId_LinkEnabled: {
221 SkColor link_color = SK_ColorTRANSPARENT;
222 GdkColor* style_color = nullptr;
223 gtk_widget_style_get(GetWindow(), "link-color", &style_color, nullptr);
224 if (style_color) {
225 link_color = GdkColorToSkColor(*style_color);
226 gdk_color_free(style_color);
227 }
228 if (link_color != SK_ColorTRANSPARENT)
229 return link_color;
230 // Default color comes from gtklinkbutton.c.
231 return SkColorSetRGB(0x00, 0x00, 0xEE);
232 }
233 case kColorId_LinkPressed:
234 return SK_ColorRED;
235
236 // Button
237 case kColorId_ButtonEnabledColor:
238 return GetFGColor(GetButton(), NORMAL);
239 case kColorId_BlueButtonEnabledColor:
240 return GetFGColor(GetBlueButton(), NORMAL);
241 case kColorId_ButtonDisabledColor:
242 return GetFGColor(GetButton(), INSENSITIVE);
243 case kColorId_BlueButtonDisabledColor:
244 return GetFGColor(GetBlueButton(), INSENSITIVE);
245 case kColorId_ButtonHoverColor:
246 return GetFGColor(GetButton(), PRELIGHT);
247 case kColorId_BlueButtonHoverColor:
248 return GetFGColor(GetBlueButton(), PRELIGHT);
249 case kColorId_BlueButtonPressedColor:
250 return GetFGColor(GetBlueButton(), ACTIVE);
251 case kColorId_BlueButtonShadowColor:
252 return SK_ColorTRANSPARENT;
253 case kColorId_ProminentButtonColor:
254 return GetSystemColor(kColorId_LinkEnabled);
255 case kColorId_TextOnProminentButtonColor:
256 return GetFGColor(GetLabel(), SELECTED);
257 case kColorId_ButtonPressedShade:
258 return SK_ColorTRANSPARENT;
259
260 // Textfield
261 case kColorId_TextfieldDefaultColor:
262 return GetFGColor(GetEntry(), NORMAL);
263 case kColorId_TextfieldDefaultBackground:
264 return GetBGColor(GetEntry(), NORMAL);
265
266 case kColorId_TextfieldReadOnlyColor:
267 return GetFGColor(GetEntry(), SELECTED);
268 case kColorId_TextfieldReadOnlyBackground:
269 return GetBGColor(GetEntry(), SELECTED);
270 case kColorId_TextfieldSelectionColor:
271 return GetFGColor(GetLabel(), SELECTED);
272 case kColorId_TextfieldSelectionBackgroundFocused:
273 return GetBGColor(GetLabel(), SELECTED);
274
275 // Tooltips
276 case kColorId_TooltipBackground:
277 return GetBGColor(GetTooltip(), NORMAL);
278 case kColorId_TooltipText:
279 return GetFGColor(GetTooltip(), NORMAL);
280
281 // Trees and Tables (implemented on GTK using the same class)
282 case kColorId_TableBackground:
283 case kColorId_TreeBackground:
284 return GetBGColor(GetTree(), NORMAL);
285 case kColorId_TableText:
286 case kColorId_TreeText:
287 return GetFGColor(GetTree(), NORMAL);
288 case kColorId_TableSelectedText:
289 case kColorId_TableSelectedTextUnfocused:
290 case kColorId_TreeSelectedText:
291 case kColorId_TreeSelectedTextUnfocused:
292 return GetFGColor(GetTree(), SELECTED);
293 case kColorId_TableSelectionBackgroundFocused:
294 case kColorId_TableSelectionBackgroundUnfocused:
295 case kColorId_TreeSelectionBackgroundFocused:
296 case kColorId_TreeSelectionBackgroundUnfocused:
297 return GetBGColor(GetTree(), SELECTED);
298 case kColorId_TreeArrow:
299 return GetFGColor(GetTree(), NORMAL);
300 case kColorId_TableGroupingIndicatorColor:
301 return GetFGColor(GetTree(), NORMAL);
302
303 // Results Table
304 case kColorId_ResultsTableNormalBackground:
305 return GetSystemColor(kColorId_TextfieldDefaultBackground);
306 case kColorId_ResultsTableHoveredBackground:
307 return color_utils::AlphaBlend(
308 GetSystemColor(kColorId_TextfieldDefaultBackground),
309 GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused), 0x80);
310 case kColorId_ResultsTableSelectedBackground:
311 return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused);
312 case kColorId_ResultsTableNormalText:
313 case kColorId_ResultsTableHoveredText:
314 return GetSystemColor(kColorId_TextfieldDefaultColor);
315 case kColorId_ResultsTableSelectedText:
316 return GetSystemColor(kColorId_TextfieldSelectionColor);
317 case kColorId_ResultsTableNormalDimmedText:
318 case kColorId_ResultsTableHoveredDimmedText:
319 return color_utils::AlphaBlend(
320 GetSystemColor(kColorId_TextfieldDefaultColor),
321 GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80);
322 case kColorId_ResultsTableSelectedDimmedText:
323 return color_utils::AlphaBlend(
324 GetSystemColor(kColorId_TextfieldSelectionColor),
325 GetSystemColor(kColorId_TextfieldDefaultBackground), 0x80);
326 case kColorId_ResultsTableNormalUrl:
327 case kColorId_ResultsTableHoveredUrl:
328 return NormalURLColor(GetSystemColor(kColorId_TextfieldDefaultColor));
329
330 case kColorId_ResultsTableSelectedUrl:
331 return SelectedURLColor(
332 GetSystemColor(kColorId_TextfieldSelectionColor),
333 GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused));
334
335 case kColorId_ResultsTablePositiveText:
336 return color_utils::GetReadableColor(kPositiveTextColor,
337 GetBGColor(GetEntry(), NORMAL));
338 case kColorId_ResultsTablePositiveHoveredText:
339 return color_utils::GetReadableColor(kPositiveTextColor,
340 GetBGColor(GetEntry(), PRELIGHT));
341 case kColorId_ResultsTablePositiveSelectedText:
342 return color_utils::GetReadableColor(kPositiveTextColor,
343 GetBGColor(GetEntry(), SELECTED));
344 case kColorId_ResultsTableNegativeText:
345 return color_utils::GetReadableColor(kNegativeTextColor,
346 GetBGColor(GetEntry(), NORMAL));
347 case kColorId_ResultsTableNegativeHoveredText:
348 return color_utils::GetReadableColor(kNegativeTextColor,
349 GetBGColor(GetEntry(), PRELIGHT));
350 case kColorId_ResultsTableNegativeSelectedText:
351 return color_utils::GetReadableColor(kNegativeTextColor,
352 GetBGColor(GetEntry(), SELECTED));
353
354 // Throbber
355 case kColorId_ThrobberSpinningColor:
356 case kColorId_ThrobberLightColor:
357 return GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused);
358
359 case kColorId_ThrobberWaitingColor:
360 return color_utils::AlphaBlend(
361 GetSystemColor(kColorId_TextfieldSelectionBackgroundFocused),
362 GetBGColor(GetWindow(), NORMAL), 0x80);
363
364 // Alert icons
365 // Just fall back to the same colors as Aura.
366 case kColorId_AlertSeverityLow:
367 case kColorId_AlertSeverityMedium:
368 case kColorId_AlertSeverityHigh:
369 return SK_ColorTRANSPARENT;
370
371 case kColorId_NumColors:
372 NOTREACHED();
373 break;
374 }
375
376 return kInvalidColorIdColor;
377 } 326 }
378 327
379 SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { 328 SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const {
380 SkColor color = LookupGtkThemeColor(color_id); 329 if (color_cache_[color_id])
381 if (SkColorGetA(color)) 330 return color_cache_[color_id].value();
382 return color; 331
383 gboolean prefer_dark_theme = FALSE; 332 SkColor color = SkColorFromColorId(color_id);
384 g_object_get(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", 333 color_cache_[color_id] = color;
385 &prefer_dark_theme, nullptr); 334 return color;
386 ui::NativeTheme* fallback_theme =
387 prefer_dark_theme ? ui::NativeThemeDarkAura::instance()
388 : ui::NativeTheme::GetInstanceForNativeUi();
389 return fallback_theme->GetSystemColor(color_id);
390 } 335 }
391 336
392 void NativeThemeGtk3::PaintMenuPopupBackground( 337 void NativeThemeGtk3::PaintMenuPopupBackground(
393 SkCanvas* canvas, 338 SkCanvas* canvas,
394 const gfx::Size& size, 339 const gfx::Size& size,
395 const MenuBackgroundExtraParams& menu_background) const { 340 const MenuBackgroundExtraParams& menu_background) const {
396 PaintWidget(canvas, gfx::Rect(size), "menu", GTK_STATE_FLAG_NORMAL); 341 PaintWidget(canvas, gfx::Rect(size), "GtkMenu.menu", GTK_STATE_FLAG_NORMAL);
397 } 342 }
398 343
399 void NativeThemeGtk3::PaintMenuItemBackground( 344 void NativeThemeGtk3::PaintMenuItemBackground(
400 SkCanvas* canvas, 345 SkCanvas* canvas,
401 State state, 346 State state,
402 const gfx::Rect& rect, 347 const gfx::Rect& rect,
403 const MenuItemExtraParams& menu_item) const { 348 const MenuItemExtraParams& menu_item) const {
404 PaintWidget(canvas, rect, "menu menuitem", StateToStateFlags(state)); 349 PaintWidget(canvas, rect, "GtkMenu.menu GtkMenuItem.menuitem",
405 } 350 StateToStateFlags(state));
406
407 GtkWidget* NativeThemeGtk3::GetWindow() const {
408 static GtkWidget* fake_window = NULL;
409
410 if (!fake_window) {
411 fake_window = chrome_gtk_frame_new();
412 gtk_widget_realize(fake_window);
413 }
414
415 return fake_window;
416 }
417
418 GtkWidget* NativeThemeGtk3::GetEntry() const {
419 static GtkWidget* fake_entry = NULL;
420
421 if (!fake_entry) {
422 fake_entry = gtk_entry_new();
423
424 // The fake entry needs to be in the window so it can be realized so we can
425 // use the computed parts of the style.
426 gtk_container_add(GTK_CONTAINER(GetWindow()), fake_entry);
427 gtk_widget_realize(fake_entry);
428 }
429
430 return fake_entry;
431 }
432
433 GtkWidget* NativeThemeGtk3::GetLabel() const {
434 static GtkWidget* fake_label = NULL;
435
436 if (!fake_label)
437 fake_label = gtk_label_new("");
438
439 return fake_label;
440 }
441
442 GtkWidget* NativeThemeGtk3::GetButton() const {
443 static GtkWidget* fake_button = NULL;
444
445 if (!fake_button)
446 fake_button = gtk_button_new();
447
448 return fake_button;
449 }
450
451 GtkWidget* NativeThemeGtk3::GetBlueButton() const {
452 static GtkWidget* fake_bluebutton = NULL;
453
454 if (!fake_bluebutton) {
455 fake_bluebutton = gtk_button_new();
456 TurnButtonBlue(fake_bluebutton);
457 }
458
459 return fake_bluebutton;
460 }
461
462 GtkWidget* NativeThemeGtk3::GetTree() const {
463 static GtkWidget* fake_tree = NULL;
464
465 if (!fake_tree)
466 fake_tree = gtk_tree_view_new();
467
468 return fake_tree;
469 }
470
471 GtkWidget* NativeThemeGtk3::GetTooltip() const {
472 static GtkWidget* fake_tooltip = NULL;
473
474 if (!fake_tooltip) {
475 fake_tooltip = gtk_window_new(GTK_WINDOW_TOPLEVEL);
476 gtk_widget_set_name(fake_tooltip, "gtk-tooltip");
477 gtk_widget_realize(fake_tooltip);
478 }
479
480 return fake_tooltip;
481 }
482
483 GtkWidget* NativeThemeGtk3::GetMenu() const {
484 static GtkWidget* fake_menu = NULL;
485
486 if (!fake_menu)
487 fake_menu = gtk_custom_menu_new();
488
489 return fake_menu;
490 }
491
492 GtkWidget* NativeThemeGtk3::GetMenuItem() const {
493 static GtkWidget* fake_menu_item = NULL;
494
495 if (!fake_menu_item) {
496 fake_menu_item = gtk_custom_menu_item_new();
497 gtk_menu_shell_append(GTK_MENU_SHELL(GetMenu()), fake_menu_item);
498 }
499
500 return fake_menu_item;
501 } 351 }
502 352
503 } // namespace libgtkui 353 } // namespace libgtkui
OLDNEW
« no previous file with comments | « chrome/browser/ui/libgtkui/native_theme_gtk3.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698