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

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

Powered by Google App Engine
This is Rietveld 408576698