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

Side by Side Diff: chrome/browser/ui/libgtk2ui/gtk2_ui.cc

Issue 1234223005: Initial gtk3 support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix colors Created 5 years, 4 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/libgtk2ui/gtk2_ui.h ('k') | chrome/browser/ui/libgtk2ui/gtk2_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/libgtk2ui/gtk2_ui.h" 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <set> 8 #include <set>
9 9
10 #include <pango/pango.h> 10 #include <pango/pango.h>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/leak_annotations.h" 13 #include "base/debug/leak_annotations.h"
14 #include "base/environment.h" 14 #include "base/environment.h"
15 #include "base/i18n/rtl.h" 15 #include "base/i18n/rtl.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/nix/mime_util_xdg.h" 17 #include "base/nix/mime_util_xdg.h"
18 #include "base/nix/xdg_util.h" 18 #include "base/nix/xdg_util.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "chrome/browser/themes/theme_properties.h" 22 #include "chrome/browser/themes/theme_properties.h"
23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" 23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h"
24 #include "chrome/browser/ui/libgtk2ui/chrome_gtk_frame.h"
25 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" 24 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h"
26 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" 25 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h"
27 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" 26 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h"
28 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" 27 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h"
29 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" 28 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h"
30 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" 29 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
31 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" 30 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h"
32 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" 31 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h"
33 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" 32 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h"
34 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" 33 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h"
(...skipping 10 matching lines...) Expand all
45 #include "ui/base/resource/resource_bundle.h" 44 #include "ui/base/resource/resource_bundle.h"
46 #include "ui/gfx/canvas.h" 45 #include "ui/gfx/canvas.h"
47 #include "ui/gfx/display.h" 46 #include "ui/gfx/display.h"
48 #include "ui/gfx/geometry/rect.h" 47 #include "ui/gfx/geometry/rect.h"
49 #include "ui/gfx/geometry/size.h" 48 #include "ui/gfx/geometry/size.h"
50 #include "ui/gfx/image/image.h" 49 #include "ui/gfx/image/image.h"
51 #include "ui/gfx/skbitmap_operations.h" 50 #include "ui/gfx/skbitmap_operations.h"
52 #include "ui/gfx/skia_util.h" 51 #include "ui/gfx/skia_util.h"
53 #include "ui/native_theme/native_theme.h" 52 #include "ui/native_theme/native_theme.h"
54 #include "ui/resources/grit/ui_resources.h" 53 #include "ui/resources/grit/ui_resources.h"
54 #include "ui/views/controls/button/blue_button.h"
55 #include "ui/views/controls/button/label_button.h" 55 #include "ui/views/controls/button/label_button.h"
56 #include "ui/views/controls/button/label_button_border.h" 56 #include "ui/views/controls/button/label_button_border.h"
57 #include "ui/views/linux_ui/window_button_order_observer.h" 57 #include "ui/views/linux_ui/window_button_order_observer.h"
58 #include "ui/views/resources/grit/views_resources.h" 58 #include "ui/views/resources/grit/views_resources.h"
59 59
60 #if defined(USE_GCONF) 60 #if defined(USE_GCONF)
61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h" 61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h"
62 #endif 62 #endif
63 63
64 // A minimized port of GtkThemeService into something that can provide colors 64 // A minimized port of GtkThemeService into something that can provide colors
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // Number of app indicators used (used as part of app-indicator id). 100 // Number of app indicators used (used as part of app-indicator id).
101 int indicators_count; 101 int indicators_count;
102 102
103 // The unknown content type. 103 // The unknown content type.
104 const char* kUnknownContentType = "application/octet-stream"; 104 const char* kUnknownContentType = "application/octet-stream";
105 105
106 // The size of the rendered toolbar image. 106 // The size of the rendered toolbar image.
107 const int kToolbarImageWidth = 64; 107 const int kToolbarImageWidth = 64;
108 const int kToolbarImageHeight = 128; 108 const int kToolbarImageHeight = 128;
109 109
110 // How much to tint the GTK+ color lighter at the top of the window.
111 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.58 };
112
113 // How much to tint the GTK+ color when an explicit frame color hasn't been
114 // specified.
115 const color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 };
116
117 // Values used as the new luminance and saturation values in the inactive tab 110 // Values used as the new luminance and saturation values in the inactive tab
118 // text color. 111 // text color.
119 const double kDarkInactiveLuminance = 0.85; 112 const double kDarkInactiveLuminance = 0.85;
120 const double kLightInactiveLuminance = 0.15; 113 const double kLightInactiveLuminance = 0.15;
121 const double kHeavyInactiveSaturation = 0.7; 114 const double kHeavyInactiveSaturation = 0.7;
122 const double kLightInactiveSaturation = 0.3; 115 const double kLightInactiveSaturation = 0.3;
123 116
124 // Default color for links on the NTP when the GTK+ theme doesn't define a
125 // link color. Constant taken from gtklinkbutton.c.
126 const GdkColor kDefaultLinkColor = { 0, 0, 0, 0xeeee };
127
128 const int kSkiaToGDKMultiplier = 257;
129
130 // TODO(erg): ThemeService has a whole interface just for reading default 117 // TODO(erg): ThemeService has a whole interface just for reading default
131 // constants. Figure out what to do with that more long term; for now, just 118 // constants. Figure out what to do with that more long term; for now, just
132 // copy the constants themselves here. 119 // copy the constants themselves here.
133 // 120 //
134 // Default tints. 121 // Default tints.
135 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; 122 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 };
136 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; 123 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 };
137 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; 124 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f };
138 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; 125 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f };
139 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; 126 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f };
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 IDR_OMNIBOX_STAR, 161 IDR_OMNIBOX_STAR,
175 IDR_OMNIBOX_STAR_DARK, 162 IDR_OMNIBOX_STAR_DARK,
176 IDR_OMNIBOX_TTS, 163 IDR_OMNIBOX_TTS,
177 IDR_OMNIBOX_TTS_DARK, 164 IDR_OMNIBOX_TTS_DARK,
178 }; 165 };
179 166
180 // This table converts button ids into a pair of gtk-stock id and state. 167 // This table converts button ids into a pair of gtk-stock id and state.
181 struct IDRGtkMapping { 168 struct IDRGtkMapping {
182 int idr; 169 int idr;
183 const char* stock_id; 170 const char* stock_id;
184 GtkStateType gtk_state; 171 bool enabled;
185 } const kGtkIcons[] = { 172 } const kGtkIcons[] = {
186 { IDR_BACK, GTK_STOCK_GO_BACK, GTK_STATE_NORMAL }, 173 { IDR_BACK, "go-previous", true },
187 { IDR_BACK_D, GTK_STOCK_GO_BACK, GTK_STATE_INSENSITIVE }, 174 { IDR_BACK_D, "go-previous", false },
188 175
189 { IDR_FORWARD, GTK_STOCK_GO_FORWARD, GTK_STATE_NORMAL }, 176 { IDR_FORWARD, "go-next", true },
190 { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_INSENSITIVE }, 177 { IDR_FORWARD_D, "go-next", false },
191 178
192 { IDR_HOME, GTK_STOCK_HOME, GTK_STATE_NORMAL }, 179 { IDR_HOME, "go-home", true },
193 180
194 { IDR_RELOAD, GTK_STOCK_REFRESH, GTK_STATE_NORMAL }, 181 { IDR_RELOAD, "view-refresh", true },
195 { IDR_RELOAD_D, GTK_STOCK_REFRESH, GTK_STATE_INSENSITIVE }, 182 { IDR_RELOAD_D, "view-refresh", false },
196 183
197 { IDR_STOP, GTK_STOCK_STOP, GTK_STATE_NORMAL }, 184 { IDR_STOP, "process-stop", true },
198 { IDR_STOP_D, GTK_STOCK_STOP, GTK_STATE_INSENSITIVE }, 185 { IDR_STOP_D, "process-stop", false },
199 }; 186 };
200 187
201 // The image resources that will be tinted by the 'button' tint value. 188 // The image resources that will be tinted by the 'button' tint value.
202 const int kOtherToolbarButtonIDs[] = { 189 const int kOtherToolbarButtonIDs[] = {
203 IDR_TOOLBAR_BEZEL_HOVER, 190 IDR_TOOLBAR_BEZEL_HOVER,
204 IDR_TOOLBAR_BEZEL_PRESSED, 191 IDR_TOOLBAR_BEZEL_PRESSED,
205 IDR_BROWSER_ACTIONS_OVERFLOW, 192 IDR_BROWSER_ACTIONS_OVERFLOW,
206 193
207 // TODO(erg): The dropdown arrow should be tinted because we're injecting 194 // TODO(erg): The dropdown arrow should be tinted because we're injecting
208 // various background GTK colors, but the code that accesses them needs to be 195 // various background GTK colors, but the code that accesses them needs to be
(...skipping 13 matching lines...) Expand all
222 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) 209 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i)
223 images.insert(kGtkIcons[i].idr); 210 images.insert(kGtkIcons[i].idr);
224 211
225 images.insert(kOtherToolbarButtonIDs, 212 images.insert(kOtherToolbarButtonIDs,
226 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs)); 213 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs));
227 } 214 }
228 215
229 return images.count(id) > 0; 216 return images.count(id) > 0;
230 } 217 }
231 218
219 // Get ChromeGtkFrame theme colors. No-op in GTK3.
220 void GetChromeStyleColor(const char* style_property, SkColor* ret_color) {
221 #if GTK_MAJOR_VERSION == 2
222 GdkColor* style_color = NULL;
223
224 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(),
225 style_property, &style_color,
226 NULL);
227
228 if (style_color) {
229 *ret_color = GdkColorToSkColor(*style_color);
230 gdk_color_free(style_color);
231 }
232 #endif
233 }
234
232 // Picks a button tint from a set of background colors. While 235 // Picks a button tint from a set of background colors. While
233 // |accent_gdk_color| will usually be the same color through a theme, this 236 // |accent_color| will usually be the same color through a theme, this
234 // function will get called with the normal GtkLabel |text_color|/GtkWindow 237 // function will get called with the normal GtkLabel |text_color|/GtkWindow
235 // |background_color| pair and the GtkEntry |text_color|/|background_color| 238 // |background_color| pair and the GtkEntry |text_color|/|background_color|
236 // pair. While 3/4 of the time the resulting tint will be the same, themes that 239 // pair. While 3/4 of the time the resulting tint will be the same, themes that
237 // have a dark window background (with light text) and a light text entry (with 240 // have a dark window background (with light text) and a light text entry (with
238 // dark text) will get better icons with this separated out. 241 // dark text) will get better icons with this separated out.
239 void PickButtonTintFromColors(const GdkColor& accent_gdk_color, 242 void PickButtonTintFromColors(SkColor accent_color,
240 const GdkColor& text_color, 243 SkColor text_color,
241 const GdkColor& background_color, 244 SkColor background_color,
242 color_utils::HSL* tint) { 245 color_utils::HSL* tint) {
243 SkColor accent_color = GdkColorToSkColor(accent_gdk_color); 246 color_utils::HSL accent_tint, text_tint, background_tint;
244 color_utils::HSL accent_tint;
245 color_utils::SkColorToHSL(accent_color, &accent_tint); 247 color_utils::SkColorToHSL(accent_color, &accent_tint);
246 248 color_utils::SkColorToHSL(text_color, &text_tint);
247 color_utils::HSL text_tint; 249 color_utils::SkColorToHSL(background_color, &background_tint);
248 color_utils::SkColorToHSL(GdkColorToSkColor(text_color),
249 &text_tint);
250
251 color_utils::HSL background_tint;
252 color_utils::SkColorToHSL(GdkColorToSkColor(background_color),
253 &background_tint);
254 250
255 // If the accent color is gray, then our normal HSL tomfoolery will bring out 251 // If the accent color is gray, then our normal HSL tomfoolery will bring out
256 // whatever color is oddly dominant (for example, in rgb space [125, 128, 252 // whatever color is oddly dominant (for example, in rgb space [125, 128,
257 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to 253 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to
258 // all color components) should be interpreted as this color being gray and 254 // all color components) should be interpreted as this color being gray and
259 // we should switch into a special grayscale mode. 255 // we should switch into a special grayscale mode.
260 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - 256 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) -
261 static_cast<int>(SkColorGetB(accent_color))); 257 static_cast<int>(SkColorGetB(accent_color)));
262 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - 258 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) -
263 static_cast<int>(SkColorGetG(accent_color))); 259 static_cast<int>(SkColorGetG(accent_color)));
(...skipping 26 matching lines...) Expand all
290 // white. 286 // white.
291 if (text_tint.l < 0.5) 287 if (text_tint.l < 0.5)
292 tint->l = -1; 288 tint->l = -1;
293 else if (text_tint.l <= 0.9) 289 else if (text_tint.l <= 0.9)
294 tint->l = text_tint.l; 290 tint->l = text_tint.l;
295 else 291 else
296 tint->l = 0.9; 292 tint->l = 0.9;
297 } 293 }
298 } 294 }
299 295
300 // Applies an HSL shift to a GdkColor (instead of an SkColor)
301 void GdkColorHSLShift(const color_utils::HSL& shift, GdkColor* frame_color) {
302 SkColor shifted = color_utils::HSLShift(
303 GdkColorToSkColor(*frame_color), shift);
304
305 frame_color->pixel = 0;
306 frame_color->red = SkColorGetR(shifted) * kSkiaToGDKMultiplier;
307 frame_color->green = SkColorGetG(shifted) * kSkiaToGDKMultiplier;
308 frame_color->blue = SkColorGetB(shifted) * kSkiaToGDKMultiplier;
309 }
310
311 // Copied Default blah sections from ThemeService. 296 // Copied Default blah sections from ThemeService.
312 color_utils::HSL GetDefaultTint(int id) { 297 color_utils::HSL GetDefaultTint(int id) {
313 switch (id) { 298 switch (id) {
314 case ThemeProperties::TINT_FRAME: 299 case ThemeProperties::TINT_FRAME:
315 return kDefaultTintFrame; 300 return kDefaultTintFrame;
316 case ThemeProperties::TINT_FRAME_INACTIVE: 301 case ThemeProperties::TINT_FRAME_INACTIVE:
317 return kDefaultTintFrameInactive; 302 return kDefaultTintFrameInactive;
318 case ThemeProperties::TINT_FRAME_INCOGNITO: 303 case ThemeProperties::TINT_FRAME_INCOGNITO:
319 return kDefaultTintFrameIncognito; 304 return kDefaultTintFrameIncognito;
320 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE: 305 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE:
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 } // namespace 406 } // namespace
422 407
423 Gtk2UI::Gtk2UI() 408 Gtk2UI::Gtk2UI()
424 : default_font_size_pixels_(0), 409 : default_font_size_pixels_(0),
425 default_font_style_(gfx::Font::NORMAL), 410 default_font_style_(gfx::Font::NORMAL),
426 middle_click_action_(GetDefaultMiddleClickAction()), 411 middle_click_action_(GetDefaultMiddleClickAction()),
427 device_scale_factor_(1.0) { 412 device_scale_factor_(1.0) {
428 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); 413 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
429 } 414 }
430 415
416
417
418 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) {
419 gtkui->ResetStyle();
420 }
421
431 void Gtk2UI::Initialize() { 422 void Gtk2UI::Initialize() {
432 signals_.reset(new Gtk2SignalRegistrar); 423 GtkSettings* settings = gtk_settings_get_default();
424 g_signal_connect_after(settings,
425 "notify::gtk-theme-name",
426 G_CALLBACK(OnThemeChanged),
427 this);
428 g_signal_connect_after(settings,
429 "notify::gtk-icon-theme-name",
430 G_CALLBACK(OnThemeChanged),
431 this);
433 432
434 // Create our fake widgets.
435 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
436 fake_frame_ = chrome_gtk_frame_new();
437 fake_label_.Own(gtk_label_new(""));
438 fake_entry_.Own(gtk_entry_new());
439
440 // Only realized widgets receive style-set notifications, which we need to
441 // broadcast new theme images and colors. Only realized widgets have style
442 // properties, too, which we query for some colors.
443 gtk_widget_realize(fake_frame_);
444 gtk_widget_realize(fake_window_);
445
446 signals_->Connect(fake_frame_, "style-set",
447 G_CALLBACK(&OnStyleSetThunk), this);
448 433
449 LoadGtkValues(); 434 LoadGtkValues();
450 435
451 printing::PrintingContextLinux::SetCreatePrintDialogFunction( 436 printing::PrintingContextLinux::SetCreatePrintDialogFunction(
452 &PrintDialogGtk2::CreatePrintDialog); 437 &PrintDialogGtk2::CreatePrintDialog);
453 printing::PrintingContextLinux::SetPdfPaperSizeFunction( 438 printing::PrintingContextLinux::SetPdfPaperSizeFunction(
454 &GetPdfPaperSizeDeviceUnitsGtk); 439 &GetPdfPaperSizeDeviceUnitsGtk);
455 440
456 #if defined(USE_GCONF) 441 #if defined(USE_GCONF)
457 // We must build this after GTK gets initialized. 442 // We must build this after GTK gets initialized.
458 gconf_listener_.reset(new GConfListener(this)); 443 gconf_listener_.reset(new GConfListener(this));
459 #endif // defined(USE_GCONF) 444 #endif // defined(USE_GCONF)
460 445
461 indicators_count = 0; 446 indicators_count = 0;
462 447
463 // Instantiate the singleton instance of Gtk2EventLoop. 448 // Instantiate the singleton instance of Gtk2EventLoop.
464 Gtk2EventLoop::GetInstance(); 449 Gtk2EventLoop::GetInstance();
465 } 450 }
466 451
467 Gtk2UI::~Gtk2UI() { 452 Gtk2UI::~Gtk2UI() {
468 gtk_widget_destroy(fake_window_);
469 gtk_widget_destroy(fake_frame_);
470 fake_label_.Destroy();
471 fake_entry_.Destroy();
472
473 ClearAllThemeData(); 453 ClearAllThemeData();
474 } 454 }
475 455
476 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { 456 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const {
477 // Try to get our cached version: 457 // Try to get our cached version:
478 ImageCache::const_iterator it = gtk_images_.find(id); 458 ImageCache::const_iterator it = gtk_images_.find(id);
479 if (it != gtk_images_.end()) 459 if (it != gtk_images_.end())
480 return it->second; 460 return it->second;
481 461
482 if (IsOverridableImage(id)) { 462 if (IsOverridableImage(id)) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 714
735 bool Gtk2UI::MatchEvent(const ui::Event& event, 715 bool Gtk2UI::MatchEvent(const ui::Event& event,
736 std::vector<ui::TextEditCommandAuraLinux>* commands) { 716 std::vector<ui::TextEditCommandAuraLinux>* commands) {
737 // Ensure that we have a keyboard handler. 717 // Ensure that we have a keyboard handler.
738 if (!key_bindings_handler_) 718 if (!key_bindings_handler_)
739 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); 719 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler);
740 720
741 return key_bindings_handler_->MatchEvent(event, commands); 721 return key_bindings_handler_->MatchEvent(event, commands);
742 } 722 }
743 723
744 void Gtk2UI::GetScrollbarColors(GdkColor* thumb_active_color, 724 void Gtk2UI::SetScrollbarColors() {
745 GdkColor* thumb_inactive_color, 725 thumb_active_color_ = SkColorSetRGB(244, 244, 244);
746 GdkColor* track_color) { 726 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234);
747 GdkColor* theme_thumb_active = NULL; 727 track_color_ = SkColorSetRGB(211, 211, 211);
748 GdkColor* theme_thumb_inactive = NULL;
749 GdkColor* theme_trough_color = NULL;
750 gtk_widget_style_get(GTK_WIDGET(fake_frame_),
751 "scrollbar-slider-prelight-color", &theme_thumb_active,
752 "scrollbar-slider-normal-color", &theme_thumb_inactive,
753 "scrollbar-trough-color", &theme_trough_color,
754 NULL);
755 728
756 // Ask the theme if the theme specifies all the scrollbar colors and short 729 GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_);
757 // circuit the expensive painting/compositing if we have all of them. 730 GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_);
758 if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { 731 GetChromeStyleColor("scrollbar-trough-color", &track_color_);
759 *thumb_active_color = *theme_thumb_active;
760 *thumb_inactive_color = *theme_thumb_inactive;
761 *track_color = *theme_trough_color;
762
763 gdk_color_free(theme_thumb_active);
764 gdk_color_free(theme_thumb_inactive);
765 gdk_color_free(theme_trough_color);
766 return;
767 }
768
769 // Create window containing scrollbar elements
770 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
771 GtkWidget* fixed = gtk_fixed_new();
772 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL);
773 gtk_container_add(GTK_CONTAINER(window), fixed);
774 gtk_container_add(GTK_CONTAINER(fixed), scrollbar);
775 gtk_widget_realize(window);
776 gtk_widget_realize(scrollbar);
777
778 // Draw scrollbar thumb part and track into offscreen image
779 const int kWidth = 100;
780 const int kHeight = 20;
781 GtkStyle* style = gtk_rc_get_style(scrollbar);
782 GdkWindow* gdk_window = gtk_widget_get_window(window);
783 GdkPixmap* pm = gdk_pixmap_new(gdk_window, kWidth, kHeight, -1);
784 GdkRectangle rect = { 0, 0, kWidth, kHeight };
785 unsigned char data[3 * kWidth * kHeight];
786 for (int i = 0; i < 3; ++i) {
787 if (i < 2) {
788 // Thumb part
789 gtk_paint_slider(style, pm,
790 i == 0 ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
791 GTK_SHADOW_OUT, &rect, scrollbar, "slider", 0, 0,
792 kWidth, kHeight, GTK_ORIENTATION_HORIZONTAL);
793 } else {
794 // Track
795 gtk_paint_box(style, pm, GTK_STATE_ACTIVE, GTK_SHADOW_IN, &rect,
796 scrollbar, "trough-upper", 0, 0, kWidth, kHeight);
797 }
798 GdkPixbuf* pb = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB,
799 FALSE, 8, kWidth, kHeight,
800 3 * kWidth, 0, 0);
801 gdk_pixbuf_get_from_drawable(pb, pm, NULL, 0, 0, 0, 0, kWidth, kHeight);
802
803 // Sample pixels
804 int components[3] = { 0 };
805 for (int y = 2; y < kHeight - 2; ++y) {
806 for (int c = 0; c < 3; ++c) {
807 // Sample a vertical slice of pixels at about one-thirds from the
808 // left edge. This allows us to avoid any fixed graphics that might be
809 // located at the edges or in the center of the scrollbar.
810 // Each pixel is made up of a red, green, and blue component; taking up
811 // a total of three bytes.
812 components[c] += data[3 * (kWidth / 3 + y * kWidth) + c];
813 }
814 }
815 GdkColor* color = i == 0 ? thumb_active_color :
816 i == 1 ? thumb_inactive_color :
817 track_color;
818 color->pixel = 0;
819 // We sampled pixels across the full height of the image, ignoring a two
820 // pixel border. In some themes, the border has a completely different
821 // color which we do not want to factor into our average color computation.
822 //
823 // We now need to scale the colors from the 0..255 range, to the wider
824 // 0..65535 range, and we need to actually compute the average color; so,
825 // we divide by the total number of pixels in the sample.
826 color->red = components[0] * 65535 / (255 * (kHeight - 4));
827 color->green = components[1] * 65535 / (255 * (kHeight - 4));
828 color->blue = components[2] * 65535 / (255 * (kHeight - 4));
829
830 g_object_unref(pb);
831 }
832 g_object_unref(pm);
833
834 gtk_widget_destroy(window);
835
836 // Override any of the default colors with ones that were specified by the
837 // theme.
838 if (theme_thumb_active) {
839 *thumb_active_color = *theme_thumb_active;
840 gdk_color_free(theme_thumb_active);
841 }
842
843 if (theme_thumb_inactive) {
844 *thumb_inactive_color = *theme_thumb_inactive;
845 gdk_color_free(theme_thumb_inactive);
846 }
847
848 if (theme_trough_color) {
849 *track_color = *theme_trough_color;
850 gdk_color_free(theme_trough_color);
851 }
852 } 732 }
853 733
854 void Gtk2UI::LoadGtkValues() { 734 void Gtk2UI::LoadGtkValues() {
855 // TODO(erg): GtkThemeService had a comment here about having to muck with 735 // TODO(erg): GtkThemeService had a comment here about having to muck with
856 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd 736 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd
857 // regress startup time. Figure out how to do that when we can't access the 737 // regress startup time. Figure out how to do that when we can't access the
858 // prefs system from here. 738 // prefs system from here.
859 739
860 GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); 740 NativeThemeGtk2* theme = NativeThemeGtk2::instance();
861 741
862 GtkStyle* window_style = gtk_rc_get_style(fake_window_); 742 SkColor toolbar_color =
863 SetThemeColorFromGtk(ThemeProperties::COLOR_CONTROL_BACKGROUND, 743 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground);
864 &window_style->bg[GTK_STATE_NORMAL]); 744 SkColor button_color =
745 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor);
746 SkColor label_color =
747 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor);
865 748
866 GdkColor toolbar_color = window_style->bg[GTK_STATE_NORMAL]; 749 colors_[ThemeProperties::COLOR_CONTROL_BACKGROUND] = toolbar_color;
867 SetThemeColorFromGtk(ThemeProperties::COLOR_TOOLBAR, &toolbar_color); 750 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color;
868 751
869 GdkColor button_color = window_style->bg[GTK_STATE_SELECTED]; 752 SetThemeTint(ThemeProperties::TINT_BUTTONS, button_color);
870 SetThemeTintFromGtk(ThemeProperties::TINT_BUTTONS, &button_color);
871 753
872 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); 754 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color;
873 GdkColor label_color = label_style->fg[GTK_STATE_NORMAL]; 755 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color;
874 SetThemeColorFromGtk(ThemeProperties::COLOR_TAB_TEXT, &label_color); 756 colors_[ThemeProperties::COLOR_STATUS_BAR_TEXT] = label_color;
875 SetThemeColorFromGtk(ThemeProperties::COLOR_BOOKMARK_TEXT, &label_color);
876 SetThemeColorFromGtk(ThemeProperties::COLOR_STATUS_BAR_TEXT, &label_color);
877 757
878 UpdateDefaultFont(label_style->font_desc); 758 UpdateDefaultFont();
879 759
880 // Build the various icon tints. 760 // Build the various icon tints.
881 GetNormalButtonTintHSL(&button_tint_); 761 GetNormalButtonTintHSL(&button_tint_);
882 GetNormalEntryForegroundHSL(&entry_tint_); 762 GetNormalEntryForegroundHSL(&entry_tint_);
883 GetSelectedEntryForegroundHSL(&selected_entry_tint_); 763 GetSelectedEntryForegroundHSL(&selected_entry_tint_);
884 GdkColor frame_color = BuildFrameColors(frame_style); 764 SkColor frame_color = BuildFrameColors();
885 765
886 // The inactive frame color never occurs naturally in the theme, as it is a 766 // The inactive frame color never occurs naturally in the theme, as it is a
887 // tinted version of |frame_color|. We generate another color based on the 767 // tinted version of |frame_color|. We generate another color based on the
888 // background tab color, with the lightness and saturation moved in the 768 // background tab color, with the lightness and saturation moved in the
889 // opposite direction. (We don't touch the hue, since there should be subtle 769 // opposite direction. (We don't touch the hue, since there should be subtle
890 // hints of the color in the text.) 770 // hints of the color in the text.)
891 color_utils::HSL inactive_tab_text_hsl = 771 color_utils::HSL inactive_tab_text_hsl =
892 tints_[ThemeProperties::TINT_BACKGROUND_TAB]; 772 tints_[ThemeProperties::TINT_BACKGROUND_TAB];
893 if (inactive_tab_text_hsl.l < 0.5) 773 if (inactive_tab_text_hsl.l < 0.5)
894 inactive_tab_text_hsl.l = kDarkInactiveLuminance; 774 inactive_tab_text_hsl.l = kDarkInactiveLuminance;
895 else 775 else
896 inactive_tab_text_hsl.l = kLightInactiveLuminance; 776 inactive_tab_text_hsl.l = kLightInactiveLuminance;
897 777
898 if (inactive_tab_text_hsl.s < 0.5) 778 if (inactive_tab_text_hsl.s < 0.5)
899 inactive_tab_text_hsl.s = kHeavyInactiveSaturation; 779 inactive_tab_text_hsl.s = kHeavyInactiveSaturation;
900 else 780 else
901 inactive_tab_text_hsl.s = kLightInactiveSaturation; 781 inactive_tab_text_hsl.s = kLightInactiveSaturation;
902 782
903 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = 783 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
904 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); 784 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255);
905 785
906 // We pick the text and background colors for the NTP out of the colors for a 786 // We pick the text and background colors for the NTP out of the colors for a
907 // GtkEntry. We do this because GtkEntries background color is never the same 787 // GtkEntry. We do this because GtkEntries background color is never the same
908 // as |toolbar_color|, is usually a white, and when it isn't a white, 788 // as |toolbar_color|, is usually a white, and when it isn't a white,
909 // provides sufficient contrast to |toolbar_color|. Try this out with 789 // provides sufficient contrast to |toolbar_color|. Try this out with
910 // Darklooks, HighContrastInverse or ThinIce. 790 // Darklooks, HighContrastInverse or ThinIce.
911 GtkStyle* entry_style = gtk_rc_get_style(fake_entry_.get()); 791
912 GdkColor ntp_background = entry_style->base[GTK_STATE_NORMAL]; 792 SkColor ntp_background =
913 GdkColor ntp_foreground = entry_style->text[GTK_STATE_NORMAL]; 793 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground );
914 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_BACKGROUND, 794 SkColor ntp_foreground =
915 &ntp_background); 795 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor);
916 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_TEXT, 796
917 &ntp_foreground); 797 colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = ntp_background;
798 colors_[ThemeProperties::COLOR_NTP_TEXT] = ntp_foreground;
918 799
919 // The NTP header is the color that surrounds the current active thumbnail on 800 // The NTP header is the color that surrounds the current active thumbnail on
920 // the NTP, and acts as the border of the "Recent Links" box. It would be 801 // the NTP, and acts as the border of the "Recent Links" box. It would be
921 // awesome if they were separated so we could use GetBorderColor() for the 802 // awesome if they were separated so we could use GetBorderColor() for the
922 // border around the "Recent Links" section, but matching the frame color is 803 // border around the "Recent Links" section, but matching the frame color is
923 // more important. 804 // more important.
924 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_HEADER,
925 &frame_color);
926 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION,
927 &toolbar_color);
928 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_TEXT,
929 &label_color);
930 805
931 // Override the link color if the theme provides it. 806 colors_[ThemeProperties::COLOR_NTP_HEADER] = frame_color;
932 const GdkColor* link_color = NULL; 807 colors_[ThemeProperties::COLOR_NTP_SECTION] = toolbar_color;
933 gtk_widget_style_get(GTK_WIDGET(fake_window_), 808 colors_[ThemeProperties::COLOR_NTP_SECTION_TEXT] = label_color;
934 "link-color", &link_color, NULL);
935 809
936 bool is_default_link_color = false; 810 // Default link color, taken from gtklinkbutton.c.
937 if (!link_color) { 811 SkColor link_color = SkColorSetRGB(0, 0, 0xee);
938 link_color = &kDefaultLinkColor; 812 GetChromeStyleColor("link-color", &link_color);
939 is_default_link_color = true;
940 }
941 813
942 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK, 814 colors_[ThemeProperties::COLOR_NTP_LINK] = link_color;
943 link_color); 815 colors_[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] = link_color;
944 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK_UNDERLINE, 816 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK] = link_color;
945 link_color); 817 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] = link_color;
946 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK,
947 link_color);
948 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE,
949 link_color);
950
951 if (!is_default_link_color)
952 gdk_color_free(const_cast<GdkColor*>(link_color));
953 818
954 // Generate the colors that we pass to WebKit. 819 // Generate the colors that we pass to WebKit.
955 focus_ring_color_ = GdkColorToSkColor(frame_color); 820 focus_ring_color_ = frame_color;
956 821
957 GdkColor thumb_active_color, thumb_inactive_color, track_color; 822 SetScrollbarColors();
958 Gtk2UI::GetScrollbarColors(&thumb_active_color,
959 &thumb_inactive_color,
960 &track_color);
961 thumb_active_color_ = GdkColorToSkColor(thumb_active_color);
962 thumb_inactive_color_ = GdkColorToSkColor(thumb_inactive_color);
963 track_color_ = GdkColorToSkColor(track_color);
964 823
965 // Some GTK themes only define the text selection colors on the GtkEntry 824 // Some GTK themes only define the text selection colors on the GtkEntry
966 // class, so we need to use that for getting selection colors. 825 // class, so we need to use that for getting selection colors.
967 active_selection_bg_color_ = 826 active_selection_bg_color_ =
968 GdkColorToSkColor(entry_style->base[GTK_STATE_SELECTED]); 827 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionBackgrou ndFocused);
969 active_selection_fg_color_ = 828 active_selection_fg_color_ =
970 GdkColorToSkColor(entry_style->text[GTK_STATE_SELECTED]); 829 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionColor);
971 inactive_selection_bg_color_ = 830 inactive_selection_bg_color_ =
972 GdkColorToSkColor(entry_style->base[GTK_STATE_ACTIVE]); 831 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyBackgroun d);
973 inactive_selection_fg_color_ = 832 inactive_selection_fg_color_ =
974 GdkColorToSkColor(entry_style->text[GTK_STATE_ACTIVE]); 833 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyColor);
975 834
976 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = 835 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] =
977 NativeThemeGtk2::instance()->GetSystemColor( 836 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberSpinningColor);
978 ui::NativeTheme::kColorId_ThrobberSpinningColor);
979 colors_[ThemeProperties::COLOR_THROBBER_WAITING] = 837 colors_[ThemeProperties::COLOR_THROBBER_WAITING] =
980 NativeThemeGtk2::instance()->GetSystemColor( 838 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberWaitingColor);
981 ui::NativeTheme::kColorId_ThrobberWaitingColor);
982 } 839 }
983 840
984 GdkColor Gtk2UI::BuildFrameColors(GtkStyle* frame_style) { 841 SkColor Gtk2UI::BuildFrameColors() {
985 GdkColor* theme_frame = NULL; 842 SkColor frame_color =
986 GdkColor* theme_inactive_frame = NULL; 843 NativeThemeGtk2::instance()->GetSystemColor(
987 GdkColor* theme_incognito_frame = NULL; 844 ui::NativeTheme::kColorId_WindowBackground);
988 GdkColor* theme_incognito_inactive_frame = NULL; 845 SkColor temp_color;
989 gtk_widget_style_get(GTK_WIDGET(fake_frame_), 846 SetThemeTint(ThemeProperties::TINT_BACKGROUND_TAB, frame_color);
990 "frame-color", &theme_frame,
991 "inactive-frame-color", &theme_inactive_frame,
992 "incognito-frame-color", &theme_incognito_frame,
993 "incognito-inactive-frame-color",
994 &theme_incognito_inactive_frame,
995 NULL);
996 847
997 GdkColor frame_color = BuildAndSetFrameColor(
998 &frame_style->bg[GTK_STATE_SELECTED],
999 theme_frame,
1000 kDefaultFrameShift,
1001 ThemeProperties::COLOR_FRAME,
1002 ThemeProperties::TINT_FRAME);
1003 if (theme_frame)
1004 gdk_color_free(theme_frame);
1005 SetThemeTintFromGtk(ThemeProperties::TINT_BACKGROUND_TAB, &frame_color);
1006 848
1007 BuildAndSetFrameColor( 849 temp_color = color_utils::HSLShift(
1008 &frame_style->bg[GTK_STATE_INSENSITIVE], 850 frame_color,
1009 theme_inactive_frame, 851 GetDefaultTint(ThemeProperties::TINT_FRAME));
1010 kDefaultFrameShift, 852 GetChromeStyleColor("frame-color", &temp_color);
1011 ThemeProperties::COLOR_FRAME_INACTIVE,
1012 ThemeProperties::TINT_FRAME_INACTIVE);
1013 if (theme_inactive_frame)
1014 gdk_color_free(theme_inactive_frame);
1015 853
1016 BuildAndSetFrameColor( 854 colors_[ThemeProperties::COLOR_FRAME] = temp_color;
1017 &frame_color, 855 SetThemeTint(ThemeProperties::TINT_FRAME, temp_color);
1018 theme_incognito_frame,
1019 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO),
1020 ThemeProperties::COLOR_FRAME_INCOGNITO,
1021 ThemeProperties::TINT_FRAME_INCOGNITO);
1022 if (theme_incognito_frame)
1023 gdk_color_free(theme_incognito_frame);
1024 856
1025 BuildAndSetFrameColor( 857
1026 &frame_color, 858 temp_color = color_utils::HSLShift(
1027 theme_incognito_inactive_frame, 859 frame_color,
1028 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE), 860 GetDefaultTint(ThemeProperties::TINT_FRAME_INACTIVE));
1029 ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE, 861 GetChromeStyleColor("inactive-frame-color", &temp_color);
1030 ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE); 862
1031 if (theme_incognito_inactive_frame) 863 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color;
1032 gdk_color_free(theme_incognito_inactive_frame); 864 SetThemeTint(ThemeProperties::TINT_FRAME_INACTIVE, temp_color);
865
866
867 temp_color = color_utils::HSLShift(
868 frame_color,
869 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO));
870 GetChromeStyleColor("incognito-frame-color", &temp_color);
871
872 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color;
873 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO, temp_color);
874
875
876 temp_color = color_utils::HSLShift(
877 frame_color,
878 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE));
879 GetChromeStyleColor("incognito-inactive-frame-color", &temp_color);
880
881 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color;
882 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE, temp_color);
883
1033 884
1034 return frame_color; 885 return frame_color;
1035 } 886 }
1036 887
1037 void Gtk2UI::SetThemeColorFromGtk(int id, const GdkColor* color) { 888 void Gtk2UI::SetThemeTint(int id, SkColor color) {
1038 colors_[id] = GdkColorToSkColor(*color);
1039 }
1040
1041 void Gtk2UI::SetThemeTintFromGtk(int id, const GdkColor* color) {
1042 color_utils::HSL default_tint = GetDefaultTint(id); 889 color_utils::HSL default_tint = GetDefaultTint(id);
1043 color_utils::HSL hsl; 890 color_utils::HSL hsl;
1044 color_utils::SkColorToHSL(GdkColorToSkColor(*color), &hsl); 891 color_utils::SkColorToHSL(color, &hsl);
1045 892
1046 if (default_tint.s != -1) 893 if (default_tint.s != -1)
1047 hsl.s = default_tint.s; 894 hsl.s = default_tint.s;
1048 895
1049 if (default_tint.l != -1) 896 if (default_tint.l != -1)
1050 hsl.l = default_tint.l; 897 hsl.l = default_tint.l;
1051 898
1052 tints_[id] = hsl; 899 tints_[id] = hsl;
1053 } 900 }
1054 901
1055 GdkColor Gtk2UI::BuildAndSetFrameColor(const GdkColor* base,
1056 const GdkColor* gtk_base,
1057 const color_utils::HSL& tint,
1058 int color_id,
1059 int tint_id) {
1060 GdkColor out_color = *base;
1061 if (gtk_base) {
1062 // The theme author specified a color to use, use it without modification.
1063 out_color = *gtk_base;
1064 } else {
1065 // Tint the basic color since this is a heuristic color instead of one
1066 // specified by the theme author.
1067 GdkColorHSLShift(tint, &out_color);
1068 }
1069 SetThemeColorFromGtk(color_id, &out_color);
1070 SetThemeTintFromGtk(tint_id, &out_color);
1071
1072 return out_color;
1073 }
1074
1075 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { 902 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const {
1076 switch (id) { 903 switch (id) {
1077 case IDR_THEME_TOOLBAR: { 904 case IDR_THEME_TOOLBAR: {
1078 GtkStyle* style = gtk_rc_get_style(fake_window_);
1079 GdkColor* color = &style->bg[GTK_STATE_NORMAL];
1080 SkBitmap bitmap; 905 SkBitmap bitmap;
1081 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); 906 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight);
1082 bitmap.eraseARGB(0xff, color->red >> 8, color->green >> 8, 907 bitmap.eraseColor(
1083 color->blue >> 8); 908 NativeThemeGtk2::instance()->GetSystemColor(
909 ui::NativeTheme::kColorId_WindowBackground));
1084 return bitmap; 910 return bitmap;
1085 } 911 }
1086 case IDR_THEME_TAB_BACKGROUND: 912 case IDR_THEME_TAB_BACKGROUND:
1087 case IDR_THEME_TAB_BACKGROUND_DESKTOP: 913 case IDR_THEME_TAB_BACKGROUND_DESKTOP:
1088 return GenerateTabImage(IDR_THEME_FRAME); 914 return GenerateTabImage(IDR_THEME_FRAME);
1089 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: 915 case IDR_THEME_TAB_BACKGROUND_INCOGNITO:
1090 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP: 916 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP:
1091 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); 917 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO);
1092 case IDR_FRAME: 918 case IDR_FRAME:
1093 case IDR_THEME_FRAME: 919 case IDR_THEME_FRAME:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 case IDR_FORWARD: 962 case IDR_FORWARD:
1137 case IDR_FORWARD_D: 963 case IDR_FORWARD_D:
1138 case IDR_HOME: 964 case IDR_HOME:
1139 case IDR_RELOAD: 965 case IDR_RELOAD:
1140 case IDR_RELOAD_D: 966 case IDR_RELOAD_D:
1141 case IDR_STOP: 967 case IDR_STOP:
1142 case IDR_STOP_D: { 968 case IDR_STOP_D: {
1143 return GenerateGTKIcon(id); 969 return GenerateGTKIcon(id);
1144 } 970 }
1145 case IDR_TOOLBAR_BEZEL_HOVER: 971 case IDR_TOOLBAR_BEZEL_HOVER:
1146 return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER); 972 return GenerateToolbarBezel(ui::NativeTheme::kHovered, IDR_TOOLBAR_BEZEL_H OVER);
1147 case IDR_TOOLBAR_BEZEL_PRESSED: 973 case IDR_TOOLBAR_BEZEL_PRESSED:
1148 return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED); 974 return GenerateToolbarBezel(ui::NativeTheme::kPressed, IDR_TOOLBAR_BEZEL_P RESSED);
1149 default: { 975 default: {
1150 return GenerateTintedIcon(id, button_tint_); 976 return GenerateTintedIcon(id, button_tint_);
1151 } 977 }
1152 } 978 }
1153 979
1154 return SkBitmap(); 980 return SkBitmap();
1155 } 981 }
1156 982
1157 SkBitmap Gtk2UI::GenerateFrameImage( 983 SkBitmap Gtk2UI::GenerateFrameImage(
1158 int color_id, 984 int color_id,
1159 const char* gradient_name) const { 985 const char* gradient_name) const {
1160 // We use two colors: the main color (passed in) and a lightened version of
1161 // that color (which is supposed to match the light gradient at the top of
1162 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird).
1163 ColorMap::const_iterator it = colors_.find(color_id); 986 ColorMap::const_iterator it = colors_.find(color_id);
1164 DCHECK(it != colors_.end()); 987 DCHECK(it != colors_.end());
1165 SkColor base = it->second; 988 SkColor base = it->second;
1166 989
990
991 #if GTK_MAJOR_VERSION == 2
992 // We use two colors: the main color (passed in) and a lightened version of
993 // that color (which is supposed to match the light gradient at the top of
994 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird).
995 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.8 };
1167 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), 996 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight),
1168 1.0f, true); 997 1.0f, true);
1169 998
999 SkColor gradient_top_color = color_utils::HSLShift(base, kGtkFrameShift);
1170 int gradient_size; 1000 int gradient_size;
1171 GdkColor* gradient_top_color = NULL; 1001
1172 gtk_widget_style_get(GTK_WIDGET(fake_frame_), 1002 GetChromeStyleColor(gradient_name, &gradient_top_color);
1003 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(),
1173 "frame-gradient-size", &gradient_size, 1004 "frame-gradient-size", &gradient_size,
1174 gradient_name, &gradient_top_color,
1175 NULL); 1005 NULL);
1006
1176 if (gradient_size) { 1007 if (gradient_size) {
1177 SkColor lighter = gradient_top_color ?
1178 GdkColorToSkColor(*gradient_top_color) :
1179 color_utils::HSLShift(base, kGtkFrameShift);
1180 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader( 1008 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader(
1181 0, gradient_size, lighter, base); 1009 0, gradient_size, gradient_top_color, base);
1182 SkPaint paint; 1010 SkPaint paint;
1183 paint.setStyle(SkPaint::kFill_Style); 1011 paint.setStyle(SkPaint::kFill_Style);
1184 paint.setAntiAlias(true); 1012 paint.setAntiAlias(true);
1185 paint.setShader(shader.get()); 1013 paint.setShader(shader.get());
1186 1014
1187 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); 1015 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint);
1188 } 1016 }
1189 1017
1190 if (gradient_top_color)
1191 gdk_color_free(gradient_top_color);
1192
1193 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, 1018 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth,
1194 kToolbarImageHeight - gradient_size), base); 1019 kToolbarImageHeight - gradient_size), base);
1195 return canvas.ExtractImageRep().sk_bitmap(); 1020 return canvas.ExtractImageRep().sk_bitmap();
1021
1022 #else
knthzh 2015/08/24 03:58:18 So, I ended up deciding that the best way to rende
Elliot Glaysher 2015/08/24 17:14:38 Probably not. You should still be able to do by re
knthzh 2015/08/24 20:04:18 Wait, huh?
Elliot Glaysher 2015/08/24 20:14:23 I should not be allowed to write anything before m
1023 // Render a GtkHeaderBar as our title bar, cropping out any curved edges on
1024 // the left and right sides. Also remove the bottom border for good measure.
1025 SkBitmap bitmap;
1026 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight);
1027 bitmap.eraseColor(base);
1028
1029
1030 static GtkWidget* title = NULL;
1031 if (!title) {
1032 title = gtk_header_bar_new();
1033 gtk_widget_set_size_request(title, kToolbarImageWidth * 2, 48);
1034
1035 GtkWidget* window = gtk_offscreen_window_new();
1036 gtk_container_add(GTK_CONTAINER(window), title);
1037
1038 gtk_widget_show_all(window);
1039 }
1040
1041 cairo_surface_t* surface = cairo_image_surface_create_for_data(
1042 static_cast<unsigned char*>(bitmap.getAddr(0, 0)),
1043 CAIRO_FORMAT_ARGB32,
1044 kToolbarImageWidth, 40,
1045 kToolbarImageWidth * 4);
1046 cairo_t* cr = cairo_create(surface);
1047 cairo_translate(cr, kToolbarImageWidth / -2, 0);
1048 gtk_widget_draw(title, cr);
1049 cairo_destroy(cr);
1050 cairo_surface_destroy(surface);
1051
1052
1053 return bitmap;
1054 #endif
1196 } 1055 }
1197 1056
1198 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { 1057 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const {
1199 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); 1058 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap();
1200 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( 1059 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap(
1201 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); 1060 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB));
1202 return SkBitmapOperations::CreateTiledBitmap( 1061 return SkBitmapOperations::CreateTiledBitmap(
1203 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); 1062 bg_tint, 0, 0, bg_tint.width(), bg_tint.height());
1204 } 1063 }
1205 1064
1206 SkBitmap Gtk2UI::GenerateTintedIcon( 1065 SkBitmap Gtk2UI::GenerateTintedIcon(
1207 int base_id, 1066 int base_id,
1208 const color_utils::HSL& tint) const { 1067 const color_utils::HSL& tint) const {
1209 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1068 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1210 return SkBitmapOperations::CreateHSLShiftedBitmap( 1069 return SkBitmapOperations::CreateHSLShiftedBitmap(
1211 rb.GetImageNamed(base_id).AsBitmap(), tint); 1070 rb.GetImageNamed(base_id).AsBitmap(), tint);
1212 } 1071 }
1213 1072
1214 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { 1073 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const {
1215 const char* stock_id = NULL; 1074 const char* stock_id = NULL;
1216 GtkStateType gtk_state = GTK_STATE_NORMAL; 1075 bool enabled = true;
1217 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { 1076 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) {
1218 if (kGtkIcons[i].idr == base_id) { 1077 if (kGtkIcons[i].idr == base_id) {
1219 stock_id = kGtkIcons[i].stock_id; 1078 stock_id = kGtkIcons[i].stock_id;
1220 gtk_state = kGtkIcons[i].gtk_state; 1079 enabled = kGtkIcons[i].enabled;
1221 break; 1080 break;
1222 } 1081 }
1223 } 1082 }
1224 DCHECK(stock_id); 1083 DCHECK(stock_id);
1225 1084
1226 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1085 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1227 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); 1086 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap();
1228 1087
1229 gtk_widget_ensure_style(fake_frame_);
1230 GtkStyle* style = gtk_widget_get_style(fake_frame_);
1231 GtkIconSet* icon_set = gtk_style_lookup_icon_set(style, stock_id);
1232 if (!icon_set)
1233 return default_bitmap;
1234
1235 // Ask GTK to render the icon to a buffer, which we will steal from. 1088 // Ask GTK to render the icon to a buffer, which we will steal from.
1236 GdkPixbuf* gdk_icon = gtk_icon_set_render_icon( 1089 GtkIconTheme* icon_theme = gtk_icon_theme_get_default();
1237 icon_set, 1090 GdkPixbuf* gdk_icon = gtk_icon_theme_load_icon(
1238 style, 1091 icon_theme,
1239 base::i18n::IsRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR, 1092 stock_id,
1240 gtk_state, 1093 16,
1241 GTK_ICON_SIZE_SMALL_TOOLBAR, 1094 (GtkIconLookupFlags)0,
1242 fake_frame_,
1243 NULL); 1095 NULL);
1244 1096
1245 if (!gdk_icon) { 1097 if (!gdk_icon) {
1246 // This can theoretically happen if an icon theme doesn't provide a 1098 // This can theoretically happen if an icon theme doesn't provide a
1247 // specific image. This should realistically never happen, but I bet there 1099 // specific image. This should realistically never happen, but I bet there
1248 // are some theme authors who don't reliably provide all icons. 1100 // are some theme authors who don't reliably provide all icons.
1249 return default_bitmap; 1101 return default_bitmap;
1250 } 1102 }
1251 1103
1252 SkBitmap retval; 1104 SkBitmap retval;
1253 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); 1105 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height());
1254 retval.eraseColor(0); 1106 retval.eraseColor(0);
1255 1107
1256 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); 1108 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon);
1257 g_object_unref(gdk_icon); 1109 g_object_unref(gdk_icon);
1258 1110
1259 SkCanvas canvas(retval); 1111 SkCanvas canvas(retval);
1260 1112
1261 if (gtk_state == GTK_STATE_ACTIVE || gtk_state == GTK_STATE_PRELIGHT) { 1113 SkPaint paint;
1262 SkBitmap border = DrawGtkButtonBorder(gtk_state, 1114
1263 false, 1115 // GTK3 behavior
1264 false, 1116 if (!enabled)
1265 default_bitmap.width(), 1117 paint.setAlpha(128);
1266 default_bitmap.height());
1267 canvas.drawBitmap(border, 0, 0);
1268 }
1269 1118
1270 canvas.drawBitmap(icon, 1119 canvas.drawBitmap(icon,
1271 (default_bitmap.width() / 2) - (icon.width() / 2), 1120 (default_bitmap.width() / 2) - (icon.width() / 2),
1272 (default_bitmap.height() / 2) - (icon.height() / 2)); 1121 (default_bitmap.height() / 2) - (icon.height() / 2),
1122 &paint);
1273 1123
1274 return retval; 1124 return retval;
1275 } 1125 }
1276 1126
1277 SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const { 1127 SkBitmap Gtk2UI::GenerateToolbarBezel(
1128 ui::NativeTheme::State state,
1129 int sizing_idr) const {
1278 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1130 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1279 SkBitmap default_bitmap = 1131 SkBitmap default_bitmap =
1280 rb.GetImageNamed(sizing_idr).AsBitmap(); 1132 rb.GetImageNamed(sizing_idr).AsBitmap();
1281 1133
1282 SkBitmap retval; 1134 return DrawGtkButtonBorder(
1283 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); 1135 NULL,
1284 retval.eraseColor(0); 1136 state,
1285
1286 SkCanvas canvas(retval);
1287 SkBitmap border = DrawGtkButtonBorder(
1288 gtk_state,
1289 false,
1290 false,
1291 default_bitmap.width(), 1137 default_bitmap.width(),
1292 default_bitmap.height()); 1138 default_bitmap.height());
1293 canvas.drawBitmap(border, 0, 0);
1294
1295 return retval;
1296 } 1139 }
1297 1140
1298 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { 1141 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const {
1299 GtkStyle* window_style = gtk_rc_get_style(fake_window_); 1142 NativeThemeGtk2* theme = NativeThemeGtk2::instance();
1300 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED];
1301 const GdkColor base_color = window_style->base[GTK_STATE_NORMAL];
1302 1143
1303 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); 1144 SkColor accent_color =
1304 const GdkColor text_color = label_style->fg[GTK_STATE_NORMAL]; 1145 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor);
1146 SkColor text_color =
1147 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor);
1148 SkColor base_color =
1149 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelBackgroundColor);
1305 1150
1306 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); 1151 PickButtonTintFromColors(accent_color, text_color, base_color, tint);
1307 } 1152 }
1308 1153
1309 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const { 1154 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const {
1310 GtkStyle* window_style = gtk_rc_get_style(fake_window_); 1155 NativeThemeGtk2* theme = NativeThemeGtk2::instance();
1311 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED];
1312 1156
1313 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); 1157 SkColor accent_color =
1314 const GdkColor text_color = style->text[GTK_STATE_NORMAL]; 1158 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor);
1315 const GdkColor base_color = style->base[GTK_STATE_NORMAL]; 1159 SkColor text_color =
1160 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor);
1161 SkColor base_color =
1162 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground );
1316 1163
1317 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); 1164 PickButtonTintFromColors(accent_color, text_color, base_color, tint);
1318 } 1165 }
1319 1166
1320 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { 1167 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const {
1321 // The simplest of all the tints. We just use the selected text in the entry 1168 // The simplest of all the tints. We just use the selected text in the entry
1322 // since the icons tinted this way will only be displayed against 1169 // since the icons tinted this way will only be displayed against
1323 // base[GTK_STATE_SELECTED]. 1170 // base[GTK_STATE_SELECTED].
1324 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); 1171 SkColor color =
1325 const GdkColor color = style->text[GTK_STATE_SELECTED]; 1172 NativeThemeGtk2::instance()->GetSystemColor(
1326 color_utils::SkColorToHSL(GdkColorToSkColor(color), tint); 1173 ui::NativeTheme::kColorId_TextfieldSelectionColor);
1174
1175 color_utils::SkColorToHSL(color, tint);
1327 } 1176 }
1328 1177
1329 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, 1178 SkBitmap Gtk2UI::DrawGtkButtonBorder(const char* class_name,
1330 bool focused, 1179 ui::NativeTheme::State state,
1331 bool call_to_action,
1332 int width, 1180 int width,
1333 int height) const { 1181 int height) const {
1182 SkBitmap border;
1183 border.allocN32Pixels(width, height);
1184 border.eraseColor(0);
1185
1334 // Create a temporary GTK button to snapshot 1186 // Create a temporary GTK button to snapshot
1335 GtkWidget* window = gtk_offscreen_window_new(); 1187 GtkWidget* window = gtk_offscreen_window_new();
1336 GtkWidget* button = gtk_button_new(); 1188 GtkWidget* button = gtk_toggle_button_new();
1189
1190 if (state == ui::NativeTheme::kPressed)
1191 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true);
1192 else if (state == ui::NativeTheme::kDisabled)
1193 gtk_widget_set_sensitive(button, false);
1194
1337 gtk_widget_set_size_request(button, width, height); 1195 gtk_widget_set_size_request(button, width, height);
1338 gtk_container_add(GTK_CONTAINER(window), button); 1196 gtk_container_add(GTK_CONTAINER(window), button);
1339 gtk_widget_realize(window);
1340 gtk_widget_realize(button);
1341 gtk_widget_show(button);
1342 gtk_widget_show(window);
1343 1197
1344 if (call_to_action) 1198 if (class_name == views::BlueButton::kViewClassName) {
1345 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_DEFAULT); 1199 gtk_widget_set_can_default(button, true);
1346 1200 gtk_widget_grab_default(button);
1347 if (focused) {
1348 // We can't just use gtk_widget_grab_focus() here because that sets
1349 // gtk_widget_is_focus(), but not gtk_widget_has_focus(), which is what the
1350 // GtkButton's paint checks.
1351 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS);
1352 } 1201 }
1353 1202
1354 gtk_widget_set_state(button, static_cast<GtkStateType>(gtk_state)); 1203 gtk_widget_show_all(window);
1355 1204
1356 GdkPixmap* pixmap; 1205
1357 { 1206 cairo_surface_t* surface = cairo_image_surface_create_for_data(
1358 // http://crbug.com/346740 1207 static_cast<unsigned char*>(border.getAddr(0, 0)),
1359 ANNOTATE_SCOPED_MEMORY_LEAK; 1208 CAIRO_FORMAT_ARGB32,
1360 pixmap = gtk_widget_get_snapshot(button, NULL); 1209 width, height,
1361 } 1210 width * 4);
1211 cairo_t* cr = cairo_create(surface);
1212
1213 #if GTK_MAJOR_VERSION == 2
1362 int w, h; 1214 int w, h;
1215 GdkPixmap* pixmap = gtk_widget_get_snapshot(button, NULL);
1363 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); 1216 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h);
1364 DCHECK_EQ(w, width);
1365 DCHECK_EQ(h, height);
1366
1367 // We render the Pixmap to a Pixbuf. This can be slow, as we're scrapping
1368 // bits from X.
1369 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); 1217 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap);
1370 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, 1218 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL,
1371 GDK_DRAWABLE(pixmap), 1219 GDK_DRAWABLE(pixmap),
1372 colormap, 1220 colormap,
1373 0, 0, 0, 0, w, h); 1221 0, 0, 0, 0, w, h);
1374 1222
1375 // Finally, we convert our pixbuf into a type we can use. 1223 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
1376 SkBitmap border = GdkPixbufToImageSkia(pixbuf); 1224 cairo_paint(cr);
1225
1377 g_object_unref(pixbuf); 1226 g_object_unref(pixbuf);
1378 g_object_unref(pixmap); 1227 g_object_unref(pixmap);
1228 #else
1229 gtk_widget_draw(button, cr);
1230 #endif
1231
1232 cairo_destroy(cr);
1233 cairo_surface_destroy(surface);
1234
1235
1379 gtk_widget_destroy(window); 1236 gtk_widget_destroy(window);
1380 1237
1381 return border; 1238 return border;
1382 } 1239 }
1383 1240
1384 void Gtk2UI::ClearAllThemeData() { 1241 void Gtk2UI::ClearAllThemeData() {
1385 gtk_images_.clear(); 1242 gtk_images_.clear();
1386 } 1243 }
1387 1244
1388 void Gtk2UI::UpdateDefaultFont(const PangoFontDescription* desc) { 1245 void Gtk2UI::UpdateDefaultFont() {
1246 GtkStyle* style = gtk_rc_get_style(NativeThemeGtk2::instance()->GetLabel());
1247 const PangoFontDescription* desc = style->font_desc;
1248
1389 // Use gfx::FontRenderParams to select a family and determine the rendering 1249 // Use gfx::FontRenderParams to select a family and determine the rendering
1390 // settings. 1250 // settings.
1391 gfx::FontRenderParamsQuery query; 1251 gfx::FontRenderParamsQuery query;
1392 query.families = base::SplitString(pango_font_description_get_family(desc), 1252 query.families = base::SplitString(pango_font_description_get_family(desc),
1393 ",", base::TRIM_WHITESPACE, 1253 ",", base::TRIM_WHITESPACE,
1394 base::SPLIT_WANT_ALL); 1254 base::SPLIT_WANT_ALL);
1395 1255
1396 if (pango_font_description_get_size_is_absolute(desc)) { 1256 if (pango_font_description_get_size_is_absolute(desc)) {
1397 // If the size is absolute, it's specified in Pango units. There are 1257 // If the size is absolute, it's specified in Pango units. There are
1398 // PANGO_SCALE Pango units in a device unit (pixel). 1258 // PANGO_SCALE Pango units in a device unit (pixel).
(...skipping 16 matching lines...) Expand all
1415 query.style |= gfx::Font::BOLD; 1275 query.style |= gfx::Font::BOLD;
1416 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? 1276 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE?
1417 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) 1277 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC)
1418 query.style |= gfx::Font::ITALIC; 1278 query.style |= gfx::Font::ITALIC;
1419 1279
1420 default_font_render_params_ = 1280 default_font_render_params_ =
1421 gfx::GetFontRenderParams(query, &default_font_family_); 1281 gfx::GetFontRenderParams(query, &default_font_family_);
1422 default_font_style_ = query.style; 1282 default_font_style_ = query.style;
1423 } 1283 }
1424 1284
1425 void Gtk2UI::OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) { 1285 void Gtk2UI::ResetStyle() {
1426 ClearAllThemeData(); 1286 ClearAllThemeData();
1427 LoadGtkValues(); 1287 LoadGtkValues();
1428 NativeThemeGtk2::instance()->NotifyObservers(); 1288 NativeThemeGtk2::instance()->NotifyObservers();
1429 } 1289 }
1430 1290
1431 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { 1291 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) {
1432 device_scale_factor_ = device_scale_factor; 1292 device_scale_factor_ = device_scale_factor;
1433 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); 1293 UpdateDefaultFont();
1434 UpdateDefaultFont(label_style->font_desc);
1435 } 1294 }
1436 1295
1437 float Gtk2UI::GetDeviceScaleFactor() const { 1296 float Gtk2UI::GetDeviceScaleFactor() const {
1438 if (gfx::Display::HasForceDeviceScaleFactor()) 1297 if (gfx::Display::HasForceDeviceScaleFactor())
1439 return gfx::Display::GetForcedDeviceScaleFactor(); 1298 return gfx::Display::GetForcedDeviceScaleFactor();
1440 const int kCSSDefaultDPI = 96; 1299 const int kCSSDefaultDPI = 96;
1441 float scale = GetDPI() / kCSSDefaultDPI; 1300 float scale = GetDPI() / kCSSDefaultDPI;
1442 // Round to 1 decimal, e.g. to 1.4. 1301 // Round to 1 decimal, e.g. to 1.4.
1443 return roundf(scale * 10) / 10; 1302 return roundf(scale * 10) / 10;
1444 } 1303 }
1445 1304
1446 } // namespace libgtk2ui 1305 } // namespace libgtk2ui
1447 1306
1448 views::LinuxUI* BuildGtk2UI() { 1307 views::LinuxUI* BuildGtk2UI() {
1449 return new libgtk2ui::Gtk2UI; 1308 return new libgtk2ui::Gtk2UI;
1450 } 1309 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/libgtk2ui/gtk2_ui.h ('k') | chrome/browser/ui/libgtk2ui/gtk2_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698