Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <pango/pango.h> | 8 #include <pango/pango.h> |
| 9 #include <X11/Xcursor/Xcursor.h> | 9 #include <X11/Xcursor/Xcursor.h> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL | 78 // linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL |
| 79 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. | 79 // to 0, which breaks -Wsentinel. Get back the normal definition of NULL. |
| 80 // TODO(thakis): Remove this once we update sysroots. | 80 // TODO(thakis): Remove this once we update sysroots. |
| 81 #define __need_NULL | 81 #define __need_NULL |
| 82 #include <stddef.h> | 82 #include <stddef.h> |
| 83 | 83 |
| 84 namespace libgtk2ui { | 84 namespace libgtk2ui { |
| 85 | 85 |
| 86 namespace { | 86 namespace { |
| 87 | 87 |
| 88 class GtkThemeIconSource : public gfx::ImageSkiaSource { | 88 class GtkThemeIconSource : public gfx::ImageSkiaSource { |
|
Elliot Glaysher
2016/08/31 17:53:21
Are you able to delete this class now? Gtk2UI::Gen
Evan Stade
2016/08/31 20:45:38
Done.
| |
| 89 public: | 89 public: |
| 90 GtkThemeIconSource(int id, const char* icon, bool enabled) | 90 GtkThemeIconSource(int id, const char* icon, bool enabled) |
| 91 : id_(id), icon_(icon), enabled_(enabled) {} | 91 : id_(id), icon_(icon), enabled_(enabled) {} |
| 92 | 92 |
| 93 ~GtkThemeIconSource() override {} | 93 ~GtkThemeIconSource() override {} |
| 94 | 94 |
| 95 gfx::ImageSkiaRep GetImageForScale(float scale) override { | 95 gfx::ImageSkiaRep GetImageForScale(float scale) override { |
| 96 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 96 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 97 SkBitmap default_icon = rb.GetImageNamed(id_).AsBitmap(); | 97 SkBitmap default_icon = rb.GetImageNamed(id_).AsBitmap(); |
| 98 | 98 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 | 290 |
| 291 // Prefix for app indicator ids | 291 // Prefix for app indicator ids |
| 292 const char kAppIndicatorIdPrefix[] = "chrome_app_indicator_"; | 292 const char kAppIndicatorIdPrefix[] = "chrome_app_indicator_"; |
| 293 | 293 |
| 294 // Number of app indicators used (used as part of app-indicator id). | 294 // Number of app indicators used (used as part of app-indicator id). |
| 295 int indicators_count; | 295 int indicators_count; |
| 296 | 296 |
| 297 // The unknown content type. | 297 // The unknown content type. |
| 298 const char* kUnknownContentType = "application/octet-stream"; | 298 const char* kUnknownContentType = "application/octet-stream"; |
| 299 | 299 |
| 300 // The size of the rendered toolbar image. | |
| 301 const int kToolbarImageWidth = 64; | |
| 302 const int kToolbarImageHeight = 128; | |
| 303 | |
| 304 // Values used as the new luminance and saturation values in the inactive tab | 300 // Values used as the new luminance and saturation values in the inactive tab |
| 305 // text color. | 301 // text color. |
| 306 const double kInactiveLuminance = 0.15; | 302 const double kInactiveLuminance = 0.15; |
| 307 const double kInactiveSaturation = 0.3; | 303 const double kInactiveSaturation = 0.3; |
| 308 | 304 |
| 309 // TODO(erg): ThemeService has a whole interface just for reading default | 305 // TODO(erg): ThemeService has a whole interface just for reading default |
| 310 // constants. Figure out what to do with that more long term; for now, just | 306 // constants. Figure out what to do with that more long term; for now, just |
| 311 // copy the constants themselves here. | 307 // copy the constants themselves here. |
| 312 // | 308 // |
| 313 // Default tints. | 309 // Default tints. |
| 314 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; | 310 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; |
| 315 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; | 311 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; |
| 316 const color_utils::HSL kDefaultTintBackgroundTab = { -1, 0.5, 0.75 }; | |
| 317 | 312 |
| 318 #if GTK_MAJOR_VERSION == 3 | 313 #if GTK_MAJOR_VERSION == 3 |
| 319 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; | 314 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; |
| 320 #endif | 315 #endif |
| 321 | 316 |
| 322 // Picks a button tint from a set of background colors. While | 317 // Picks a button tint from a set of background colors. While |
| 323 // |accent_color| will usually be the same color through a theme, this | 318 // |accent_color| will usually be the same color through a theme, this |
| 324 // function will get called with the normal GtkLabel |text_color|/GtkWindow | 319 // function will get called with the normal GtkLabel |text_color|/GtkWindow |
| 325 // |background_color| pair and the GtkEntry |text_color|/|background_color| | 320 // |background_color| pair and the GtkEntry |text_color|/|background_color| |
| 326 // pair. While 3/4 of the time the resulting tint will be the same, themes that | 321 // pair. While 3/4 of the time the resulting tint will be the same, themes that |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 | 486 |
| 492 Gtk2UI::Gtk2UI() | 487 Gtk2UI::Gtk2UI() |
| 493 : default_font_size_pixels_(0), | 488 : default_font_size_pixels_(0), |
| 494 default_font_style_(gfx::Font::NORMAL), | 489 default_font_style_(gfx::Font::NORMAL), |
| 495 default_font_weight_(gfx::Font::Weight::NORMAL), | 490 default_font_weight_(gfx::Font::Weight::NORMAL), |
| 496 middle_click_action_(GetDefaultMiddleClickAction()), | 491 middle_click_action_(GetDefaultMiddleClickAction()), |
| 497 device_scale_factor_(1.0) { | 492 device_scale_factor_(1.0) { |
| 498 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 493 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
| 499 } | 494 } |
| 500 | 495 |
| 501 | 496 Gtk2UI::~Gtk2UI() {} |
| 502 | 497 |
| 503 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { | 498 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { |
| 504 gtkui->ResetStyle(); | 499 gtkui->ResetStyle(); |
| 505 } | 500 } |
| 506 | 501 |
| 507 void Gtk2UI::Initialize() { | 502 void Gtk2UI::Initialize() { |
| 508 GtkSettings* settings = gtk_settings_get_default(); | 503 GtkSettings* settings = gtk_settings_get_default(); |
| 509 g_signal_connect_after(settings, | 504 g_signal_connect_after(settings, |
| 510 "notify::gtk-theme-name", | 505 "notify::gtk-theme-name", |
| 511 G_CALLBACK(OnThemeChanged), | 506 G_CALLBACK(OnThemeChanged), |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 534 indicators_count = 0; | 529 indicators_count = 0; |
| 535 | 530 |
| 536 // Instantiate the singleton instance of Gtk2EventLoop. | 531 // Instantiate the singleton instance of Gtk2EventLoop. |
| 537 Gtk2EventLoop::GetInstance(); | 532 Gtk2EventLoop::GetInstance(); |
| 538 } | 533 } |
| 539 | 534 |
| 540 void Gtk2UI::MaterialDesignControllerReady() { | 535 void Gtk2UI::MaterialDesignControllerReady() { |
| 541 UpdateMaterialDesignColors(); | 536 UpdateMaterialDesignColors(); |
| 542 } | 537 } |
| 543 | 538 |
| 544 Gtk2UI::~Gtk2UI() { | |
| 545 ClearAllThemeData(); | |
| 546 } | |
| 547 | |
| 548 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { | |
| 549 // Try to get our cached version: | |
| 550 ImageCache::const_iterator it = gtk_images_.find(id); | |
| 551 if (it != gtk_images_.end()) | |
| 552 return it->second; | |
| 553 | |
| 554 gfx::Image image = GenerateGtkThemeImage(id); | |
| 555 | |
| 556 if (image.IsEmpty()) { | |
| 557 SkBitmap bitmap = GenerateGtkThemeBitmap(id); | |
| 558 if (!bitmap.empty()) | |
| 559 image = gfx::Image::CreateFrom1xBitmap(bitmap); | |
| 560 } | |
| 561 | |
| 562 gtk_images_[id] = image; | |
| 563 return image; | |
| 564 } | |
| 565 | |
| 566 bool Gtk2UI::GetTint(int id, color_utils::HSL* tint) const { | 539 bool Gtk2UI::GetTint(int id, color_utils::HSL* tint) const { |
| 567 switch (id) { | 540 switch (id) { |
| 568 // Tints for which the cross-platform default is fine. Before adding new | 541 // Tints for which the cross-platform default is fine. Before adding new |
| 569 // values here, specifically verify they work well on Linux. | 542 // values here, specifically verify they work well on Linux. |
| 570 case ThemeProperties::TINT_BACKGROUND_TAB: | 543 case ThemeProperties::TINT_BACKGROUND_TAB: |
| 571 // TODO(estade): Return something useful for TINT_BUTTONS so that chrome:// | 544 // TODO(estade): Return something useful for TINT_BUTTONS so that chrome:// |
| 572 // page icons are colored appropriately. | 545 // page icons are colored appropriately. |
| 573 case ThemeProperties::TINT_BUTTONS: | 546 case ThemeProperties::TINT_BUTTONS: |
| 574 break; | 547 break; |
| 575 default: | 548 default: |
| 576 // Assume any tints not specifically verified on Linux aren't usable. | 549 // Assume any tints not specifically verified on Linux aren't usable. |
| 577 // TODO(pkasting): Try to remove values from |colors_| that could just be | 550 // TODO(pkasting): Try to remove values from |colors_| that could just be |
| 578 // added to the group above instead. | 551 // added to the group above instead. |
| 579 NOTREACHED(); | 552 NOTREACHED(); |
| 580 } | 553 } |
| 581 return false; | 554 return false; |
| 582 } | 555 } |
| 583 | 556 |
| 584 bool Gtk2UI::GetColor(int id, SkColor* color) const { | 557 bool Gtk2UI::GetColor(int id, SkColor* color) const { |
| 585 ColorMap::const_iterator it = colors_.find(id); | 558 ColorMap::const_iterator it = colors_.find(id); |
| 586 if (it != colors_.end()) { | 559 if (it != colors_.end()) { |
| 587 *color = it->second; | 560 *color = it->second; |
| 588 return true; | 561 return true; |
| 589 } | 562 } |
| 590 | 563 |
| 591 return false; | 564 return false; |
| 592 } | 565 } |
| 593 | 566 |
| 594 bool Gtk2UI::HasCustomImage(int id) const { | |
| 595 return !GetThemeImageNamed(id).IsEmpty(); | |
| 596 } | |
| 597 | |
| 598 SkColor Gtk2UI::GetFocusRingColor() const { | 567 SkColor Gtk2UI::GetFocusRingColor() const { |
| 599 return focus_ring_color_; | 568 return focus_ring_color_; |
| 600 } | 569 } |
| 601 | 570 |
| 602 SkColor Gtk2UI::GetThumbActiveColor() const { | 571 SkColor Gtk2UI::GetThumbActiveColor() const { |
| 603 return thumb_active_color_; | 572 return thumb_active_color_; |
| 604 } | 573 } |
| 605 | 574 |
| 606 SkColor Gtk2UI::GetThumbInactiveColor() const { | 575 SkColor Gtk2UI::GetThumbInactiveColor() const { |
| 607 return thumb_inactive_color_; | 576 return thumb_inactive_color_; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 921 | 890 |
| 922 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; | 891 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; |
| 923 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; | 892 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; |
| 924 | 893 |
| 925 UpdateDefaultFont(); | 894 UpdateDefaultFont(); |
| 926 | 895 |
| 927 // Build the various icon tints. | 896 // Build the various icon tints. |
| 928 GetNormalButtonTintHSL(&button_tint_); | 897 GetNormalButtonTintHSL(&button_tint_); |
| 929 GetNormalEntryForegroundHSL(&entry_tint_); | 898 GetNormalEntryForegroundHSL(&entry_tint_); |
| 930 GetSelectedEntryForegroundHSL(&selected_entry_tint_); | 899 GetSelectedEntryForegroundHSL(&selected_entry_tint_); |
| 931 SkColor frame_color = BuildFrameColors(); | |
| 932 | 900 |
| 933 // The inactive frame color never occurs naturally in the theme, as it is a | 901 // The inactive frame color never occurs naturally in the theme, as it is a |
| 934 // tinted version of |frame_color|. We generate another color based on the | 902 // tinted version of the normal frame color. We generate another color based |
| 935 // background tab color, with the lightness and saturation moved in the | 903 // on the background tab color, with the lightness and saturation moved in the |
| 936 // opposite direction. (We don't touch the hue, since there should be subtle | 904 // opposite direction. (We don't touch the hue, since there should be subtle |
| 937 // hints of the color in the text.) | 905 // hints of the color in the text.) |
| 938 color_utils::HSL inactive_tab_text_hsl; | 906 color_utils::HSL inactive_tab_text_hsl; |
| 939 color_utils::SkColorToHSL( | 907 color_utils::SkColorToHSL( |
| 940 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), | 908 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), |
| 941 &inactive_tab_text_hsl); | 909 &inactive_tab_text_hsl); |
| 942 inactive_tab_text_hsl.s = kInactiveLuminance; | 910 inactive_tab_text_hsl.s = kInactiveLuminance; |
| 943 inactive_tab_text_hsl.l = kInactiveSaturation; | 911 inactive_tab_text_hsl.l = kInactiveSaturation; |
| 944 | 912 |
| 945 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 913 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 960 | 928 |
| 961 colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = ntp_background; | 929 colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = ntp_background; |
| 962 colors_[ThemeProperties::COLOR_NTP_TEXT] = ntp_foreground; | 930 colors_[ThemeProperties::COLOR_NTP_TEXT] = ntp_foreground; |
| 963 | 931 |
| 964 // The NTP header is the color that surrounds the current active thumbnail on | 932 // The NTP header is the color that surrounds the current active thumbnail on |
| 965 // the NTP, and acts as the border of the "Recent Links" box. It would be | 933 // the NTP, and acts as the border of the "Recent Links" box. It would be |
| 966 // awesome if they were separated so we could use GetBorderColor() for the | 934 // awesome if they were separated so we could use GetBorderColor() for the |
| 967 // border around the "Recent Links" section, but matching the frame color is | 935 // border around the "Recent Links" section, but matching the frame color is |
| 968 // more important. | 936 // more important. |
| 969 | 937 |
| 938 BuildFrameColors(); | |
| 939 SkColor frame_color = colors_[ThemeProperties::COLOR_FRAME]; | |
| 970 colors_[ThemeProperties::COLOR_NTP_HEADER] = frame_color; | 940 colors_[ThemeProperties::COLOR_NTP_HEADER] = frame_color; |
| 971 colors_[ThemeProperties::COLOR_NTP_SECTION] = toolbar_color; | 941 colors_[ThemeProperties::COLOR_NTP_SECTION] = toolbar_color; |
| 972 colors_[ThemeProperties::COLOR_NTP_SECTION_TEXT] = label_color; | 942 colors_[ThemeProperties::COLOR_NTP_SECTION_TEXT] = label_color; |
| 973 | 943 |
| 974 SkColor link_color = | 944 SkColor link_color = |
| 975 theme->GetSystemColor(ui::NativeTheme::kColorId_LinkEnabled); | 945 theme->GetSystemColor(ui::NativeTheme::kColorId_LinkEnabled); |
| 976 colors_[ThemeProperties::COLOR_NTP_LINK] = link_color; | 946 colors_[ThemeProperties::COLOR_NTP_LINK] = link_color; |
| 977 colors_[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] = link_color; | 947 colors_[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] = link_color; |
| 978 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK] = link_color; | 948 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK] = link_color; |
| 979 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] = link_color; | 949 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] = link_color; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1032 !ui::MaterialDesignController::IsModeMaterial()) { | 1002 !ui::MaterialDesignController::IsModeMaterial()) { |
| 1033 return; | 1003 return; |
| 1034 } | 1004 } |
| 1035 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); | 1005 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 1036 SkColor label_color = | 1006 SkColor label_color = |
| 1037 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); | 1007 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); |
| 1038 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 1008 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
| 1039 color_utils::BlendTowardOppositeLuma(label_color, 50); | 1009 color_utils::BlendTowardOppositeLuma(label_color, 50); |
| 1040 } | 1010 } |
| 1041 | 1011 |
| 1042 SkColor Gtk2UI::BuildFrameColors() { | 1012 void Gtk2UI::BuildFrameColors() { |
| 1013 #if GTK_MAJOR_VERSION == 2 | |
| 1043 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); | 1014 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 1015 color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 }; | |
| 1044 SkColor frame_color = | 1016 SkColor frame_color = |
| 1045 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground); | 1017 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground); |
| 1046 SkColor temp_color; | |
| 1047 | |
| 1048 #if GTK_MAJOR_VERSION == 2 | |
| 1049 color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 }; | |
| 1050 GtkStyle* style = gtk_rc_get_style(theme->GetWindow()); | |
| 1051 | |
| 1052 frame_color = color_utils::HSLShift(frame_color, kDefaultFrameShift); | 1018 frame_color = color_utils::HSLShift(frame_color, kDefaultFrameShift); |
| 1053 theme->GetChromeStyleColor("frame-color", &frame_color); | 1019 theme->GetChromeStyleColor("frame-color", &frame_color); |
| 1020 colors_[ThemeProperties::COLOR_FRAME] = frame_color; | |
| 1054 | 1021 |
| 1055 temp_color = frame_color; | 1022 GtkStyle* style = gtk_rc_get_style(theme->GetWindow()); |
| 1056 colors_[ThemeProperties::COLOR_FRAME] = temp_color; | 1023 SkColor temp_color = color_utils::HSLShift( |
| 1057 | |
| 1058 temp_color = color_utils::HSLShift( | |
| 1059 GdkColorToSkColor(style->bg[GTK_STATE_INSENSITIVE]), | 1024 GdkColorToSkColor(style->bg[GTK_STATE_INSENSITIVE]), |
| 1060 kDefaultFrameShift); | 1025 kDefaultFrameShift); |
| 1061 theme->GetChromeStyleColor("inactive-frame-color", &temp_color); | 1026 theme->GetChromeStyleColor("inactive-frame-color", &temp_color); |
| 1062 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color; | 1027 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color; |
| 1063 | 1028 |
| 1064 temp_color = color_utils::HSLShift( | 1029 temp_color = color_utils::HSLShift( |
| 1065 frame_color, | 1030 frame_color, |
| 1066 kDefaultTintFrameIncognito); | 1031 kDefaultTintFrameIncognito); |
| 1067 theme->GetChromeStyleColor("incognito-frame-color", &temp_color); | 1032 theme->GetChromeStyleColor("incognito-frame-color", &temp_color); |
| 1068 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color; | 1033 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color; |
| 1069 | 1034 |
| 1070 temp_color = color_utils::HSLShift( | 1035 temp_color = color_utils::HSLShift( |
| 1071 frame_color, | 1036 frame_color, |
| 1072 kDefaultTintFrameIncognitoInactive); | 1037 kDefaultTintFrameIncognitoInactive); |
| 1073 theme->GetChromeStyleColor("incognito-inactive-frame-color", &temp_color); | 1038 theme->GetChromeStyleColor("incognito-inactive-frame-color", &temp_color); |
| 1074 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; | 1039 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; |
| 1075 #else | 1040 #else |
| 1076 const SkBitmap* bitmap; | 1041 auto set_frame_color = [this](int color_id) { |
| 1042 // Render a GtkHeaderBar as our title bar, cropping out any curved edges | |
| 1043 // on the left and right sides. Also remove the bottom border for good | |
| 1044 // measure. | |
| 1045 SkBitmap bitmap; | |
| 1046 bitmap.allocN32Pixels(kToolbarImageWidth, 40); | |
| 1047 bitmap.eraseColor(0); | |
| 1077 | 1048 |
| 1078 bitmap = GetThemeImageNamed(IDR_THEME_FRAME).ToSkBitmap(); | 1049 static GtkWidget* title = nullptr; |
| 1079 bitmap->lockPixels(); | 1050 if (!title) { |
| 1080 temp_color = bitmap->getColor(bitmap->width() / 2, bitmap->height() - 1); | 1051 title = gtk_header_bar_new(); |
| 1081 bitmap->unlockPixels(); | 1052 gtk_widget_set_size_request(title, kToolbarImageWidth * 2, 48); |
| 1082 colors_[ThemeProperties::COLOR_FRAME] = temp_color; | |
| 1083 | 1053 |
| 1084 bitmap = GetThemeImageNamed(IDR_THEME_FRAME_INACTIVE).ToSkBitmap(); | 1054 GtkWidget* window = gtk_offscreen_window_new(); |
| 1085 bitmap->lockPixels(); | 1055 gtk_container_add(GTK_CONTAINER(window), title); |
| 1086 temp_color = bitmap->getColor(bitmap->width() / 2, bitmap->height() - 1); | |
| 1087 bitmap->unlockPixels(); | |
| 1088 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color; | |
| 1089 | 1056 |
| 1090 bitmap = GetThemeImageNamed(IDR_THEME_FRAME_INCOGNITO).ToSkBitmap(); | 1057 gtk_widget_show_all(window); |
| 1091 bitmap->lockPixels(); | |
| 1092 temp_color = bitmap->getColor(bitmap->width() / 2, bitmap->height() - 1); | |
| 1093 bitmap->unlockPixels(); | |
| 1094 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color; | |
| 1095 | |
| 1096 bitmap = GetThemeImageNamed(IDR_THEME_FRAME_INCOGNITO_INACTIVE).ToSkBitmap(); | |
| 1097 bitmap->lockPixels(); | |
| 1098 temp_color = bitmap->getColor(bitmap->width() / 2, bitmap->height() - 1); | |
| 1099 bitmap->unlockPixels(); | |
| 1100 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; | |
| 1101 #endif | |
| 1102 | |
| 1103 return frame_color; | |
| 1104 } | |
| 1105 | |
| 1106 gfx::Image Gtk2UI::GenerateGtkThemeImage(int id) const { | |
| 1107 gfx::ImageSkiaSource* source = NULL; | |
| 1108 | |
| 1109 switch (id) { | |
| 1110 case IDR_BACK: | |
| 1111 source = new GtkThemeIconSource(id, "go-previous", true); | |
| 1112 break; | |
| 1113 case IDR_BACK_D: | |
| 1114 source = new GtkThemeIconSource(id, "go-previous", false); | |
| 1115 break; | |
| 1116 | |
| 1117 case IDR_FORWARD: | |
| 1118 source = new GtkThemeIconSource(id, "go-next", true); | |
| 1119 break; | |
| 1120 case IDR_FORWARD_D: | |
| 1121 source = new GtkThemeIconSource(id, "go-next", false); | |
| 1122 break; | |
| 1123 | |
| 1124 case IDR_HOME: | |
| 1125 source = new GtkThemeIconSource(id, "go-home", true); | |
| 1126 break; | |
| 1127 | |
| 1128 case IDR_RELOAD: | |
| 1129 source = new GtkThemeIconSource(id, "view-refresh", true); | |
| 1130 break; | |
| 1131 case IDR_RELOAD_D: | |
| 1132 source = new GtkThemeIconSource(id, "view-refresh", false); | |
| 1133 break; | |
| 1134 | |
| 1135 case IDR_STOP: | |
| 1136 source = new GtkThemeIconSource(id, "process-stop", true); | |
| 1137 break; | |
| 1138 case IDR_STOP_D: | |
| 1139 source = new GtkThemeIconSource(id, "process-stop", false); | |
| 1140 break; | |
| 1141 | |
| 1142 | |
| 1143 // The toolbar bezels don't seem to be in use anymore, remove at your | |
| 1144 // discretion | |
| 1145 case IDR_TOOLBAR_BEZEL_HOVER: { | |
| 1146 gfx::Size size = ResourceBundle::GetSharedInstance(). | |
| 1147 GetImageSkiaNamed(id)->size(); | |
| 1148 source = new GtkButtonImageSource("IDR_BUTTON_HOVER", size); | |
| 1149 break; | |
| 1150 } | |
| 1151 case IDR_TOOLBAR_BEZEL_PRESSED: { | |
| 1152 gfx::Size size = ResourceBundle::GetSharedInstance(). | |
| 1153 GetImageSkiaNamed(id)->size(); | |
| 1154 source = new GtkButtonImageSource("IDR_BUTTON_PRESSED", size); | |
| 1155 break; | |
| 1156 } | |
| 1157 } | |
| 1158 | |
| 1159 if (source) | |
| 1160 return gfx::Image(gfx::ImageSkia(source, 1)); | |
| 1161 | |
| 1162 return gfx::Image(); | |
| 1163 } | |
| 1164 | |
| 1165 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { | |
| 1166 switch (id) { | |
| 1167 case IDR_THEME_TOOLBAR: { | |
| 1168 if (ui::MaterialDesignController::IsModeMaterial()) | |
| 1169 break; | |
| 1170 | |
| 1171 SkBitmap bitmap; | |
| 1172 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); | |
| 1173 bitmap.eraseColor( | |
| 1174 NativeThemeGtk2::instance()->GetSystemColor( | |
| 1175 ui::NativeTheme::kColorId_LabelBackgroundColor)); | |
| 1176 return bitmap; | |
| 1177 } | 1058 } |
| 1178 | 1059 |
| 1179 case IDR_THEME_TAB_BACKGROUND: | 1060 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
| 1180 return GenerateTabImage(IDR_THEME_FRAME); | 1061 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), CAIRO_FORMAT_ARGB32, |
| 1181 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: | 1062 bitmap.width(), bitmap.height(), bitmap.width() * 4); |
| 1182 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); | 1063 cairo_t* cr = cairo_create(surface); |
| 1183 case IDR_FRAME: | 1064 cairo_translate(cr, kToolbarImageWidth / -2, 0); |
| 1184 case IDR_THEME_FRAME: | 1065 gtk_widget_draw(title, cr); |
| 1185 return GenerateFrameImage(ThemeProperties::COLOR_FRAME, | 1066 cairo_destroy(cr); |
| 1186 "frame-gradient-color"); | 1067 cairo_surface_destroy(surface); |
| 1187 case IDR_FRAME_INACTIVE: | 1068 |
| 1188 case IDR_THEME_FRAME_INACTIVE: | 1069 switch (color_id) { |
| 1189 return GenerateFrameImage(ThemeProperties::COLOR_FRAME_INACTIVE, | 1070 case ThemeProperties::COLOR_FRAME_INACTIVE: |
| 1190 "inactive-frame-gradient-color"); | 1071 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( |
| 1191 case IDR_THEME_FRAME_INCOGNITO: | 1072 bitmap, kDefaultTintFrameInactive); |
| 1192 return GenerateFrameImage(ThemeProperties::COLOR_FRAME_INCOGNITO, | 1073 break; |
| 1193 "incognito-frame-gradient-color"); | 1074 case ThemeProperties::COLOR_FRAME_INCOGNITO: |
| 1194 case IDR_THEME_FRAME_INCOGNITO_INACTIVE: { | 1075 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( |
| 1195 return GenerateFrameImage( | 1076 bitmap, kDefaultTintFrameIncognito); |
| 1196 ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE, | 1077 break; |
| 1197 "incognito-inactive-frame-gradient-color"); | 1078 case ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE: |
| 1198 } | 1079 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( |
| 1199 // Icons that sit inside the omnibox shouldn't receive TINT_BUTTONS and | 1080 bitmap, kDefaultTintFrameIncognitoInactive); |
| 1200 // instead should tint based on the foreground text entry color in GTK+ | 1081 break; |
| 1201 // mode because some themes that try to be dark *and* light have very | |
| 1202 // different colors between the omnibox and the normal background area. | |
| 1203 // TODO(erg): Decide what to do about other icons that appear in the | |
| 1204 // omnibox, e.g. content settings icons. | |
| 1205 case IDR_OMNIBOX_CALCULATOR: | |
| 1206 case IDR_OMNIBOX_EXTENSION_APP: | |
| 1207 case IDR_OMNIBOX_HTTP: | |
| 1208 case IDR_OMNIBOX_SEARCH: | |
| 1209 case IDR_OMNIBOX_STAR: | |
| 1210 case IDR_OMNIBOX_TTS: { | |
| 1211 return GenerateTintedIcon(id, entry_tint_); | |
| 1212 } | 1082 } |
| 1213 | 1083 |
| 1214 // TODO(erg): The dropdown arrow should be tinted because we're injecting | 1084 bitmap.lockPixels(); |
| 1215 // various background GTK colors, but the code that accesses them needs to | 1085 colors_[color_id] = |
| 1216 // be modified so that they ask their ui::ThemeProvider instead of the | 1086 bitmap.getColor(bitmap.width() / 2, bitmap.height() - 1); |
| 1217 // ResourceBundle. (i.e. in a light on dark theme, the dropdown arrow will | 1087 bitmap.unlockPixels(); |
| 1218 // be dark on dark) | 1088 }; |
| 1219 case IDR_MENU_DROPARROW: | |
| 1220 return GenerateTintedIcon(id, button_tint_); | |
| 1221 } | |
| 1222 | 1089 |
| 1223 return SkBitmap(); | 1090 set_frame_color(ThemeProperties::COLOR_FRAME); |
| 1224 } | 1091 set_frame_color(ThemeProperties::COLOR_FRAME_INACTIVE); |
| 1225 | 1092 set_frame_color(ThemeProperties::COLOR_FRAME_INCOGNITO); |
| 1226 SkBitmap Gtk2UI::GenerateFrameImage( | 1093 set_frame_color(ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE); |
| 1227 int color_id, | |
| 1228 const char* gradient_name) const { | |
| 1229 #if GTK_MAJOR_VERSION == 2 | |
| 1230 if (ui::MaterialDesignController::IsModeMaterial()) | |
| 1231 return SkBitmap(); | |
| 1232 | |
| 1233 ColorMap::const_iterator it = colors_.find(color_id); | |
| 1234 DCHECK(it != colors_.end()); | |
| 1235 SkColor base = it->second; | |
| 1236 | |
| 1237 // We use two colors: the main color (passed in) and a lightened version of | |
| 1238 // that color (which is supposed to match the light gradient at the top of | |
| 1239 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). | |
| 1240 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.58 }; | |
| 1241 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), | |
| 1242 1.0f, true); | |
| 1243 | |
| 1244 SkColor gradient_top_color = color_utils::HSLShift(base, kGtkFrameShift); | |
| 1245 int gradient_size; | |
| 1246 | |
| 1247 NativeThemeGtk2::instance()->GetChromeStyleColor(gradient_name, | |
| 1248 &gradient_top_color); | |
| 1249 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(), | |
| 1250 "frame-gradient-size", &gradient_size, | |
| 1251 NULL); | |
| 1252 | |
| 1253 if (gradient_size) { | |
| 1254 SkPaint paint; | |
| 1255 paint.setStyle(SkPaint::kFill_Style); | |
| 1256 paint.setAntiAlias(true); | |
| 1257 paint.setShader(gfx::CreateGradientShader( | |
| 1258 0, gradient_size, gradient_top_color, base)); | |
| 1259 | |
| 1260 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); | |
| 1261 } | |
| 1262 | |
| 1263 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, | |
| 1264 kToolbarImageHeight - gradient_size), base); | |
| 1265 return canvas.ExtractImageRep().sk_bitmap(); | |
| 1266 #else | |
| 1267 // Render a GtkHeaderBar as our title bar, cropping out any curved edges on | |
| 1268 // the left and right sides. Also remove the bottom border for good measure. | |
| 1269 SkBitmap bitmap; | |
| 1270 bitmap.allocN32Pixels(kToolbarImageWidth, 40); | |
| 1271 bitmap.eraseColor(0); | |
| 1272 | |
| 1273 static GtkWidget* title = NULL; | |
| 1274 if (!title) { | |
| 1275 title = gtk_header_bar_new(); | |
| 1276 gtk_widget_set_size_request(title, kToolbarImageWidth * 2, 48); | |
| 1277 | |
| 1278 GtkWidget* window = gtk_offscreen_window_new(); | |
| 1279 gtk_container_add(GTK_CONTAINER(window), title); | |
| 1280 | |
| 1281 gtk_widget_show_all(window); | |
| 1282 } | |
| 1283 | |
| 1284 cairo_surface_t* surface = cairo_image_surface_create_for_data( | |
| 1285 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), | |
| 1286 CAIRO_FORMAT_ARGB32, | |
| 1287 bitmap.width(), bitmap.height(), | |
| 1288 bitmap.width() * 4); | |
| 1289 cairo_t* cr = cairo_create(surface); | |
| 1290 cairo_translate(cr, kToolbarImageWidth / -2, 0); | |
| 1291 gtk_widget_draw(title, cr); | |
| 1292 cairo_destroy(cr); | |
| 1293 cairo_surface_destroy(surface); | |
| 1294 | |
| 1295 switch (color_id) { | |
| 1296 case ThemeProperties::COLOR_FRAME_INACTIVE: | |
| 1297 return SkBitmapOperations::CreateHSLShiftedBitmap(bitmap, | |
| 1298 kDefaultTintFrameInactive); | |
| 1299 case ThemeProperties::COLOR_FRAME_INCOGNITO: | |
| 1300 return SkBitmapOperations::CreateHSLShiftedBitmap(bitmap, | |
| 1301 kDefaultTintFrameIncognito); | |
| 1302 case ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE: | |
| 1303 return SkBitmapOperations::CreateHSLShiftedBitmap(bitmap, | |
| 1304 kDefaultTintFrameIncognitoInactive); | |
| 1305 } | |
| 1306 | |
| 1307 return bitmap; | |
| 1308 #endif | 1094 #endif |
| 1309 } | 1095 } |
| 1310 | 1096 |
| 1311 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { | |
| 1312 if (ui::MaterialDesignController::IsModeMaterial()) | |
| 1313 return SkBitmap(); | |
| 1314 | |
| 1315 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); | |
| 1316 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( | |
| 1317 *base_image, kDefaultTintBackgroundTab); | |
| 1318 return SkBitmapOperations::CreateTiledBitmap( | |
| 1319 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); | |
| 1320 } | |
| 1321 | |
| 1322 SkBitmap Gtk2UI::GenerateTintedIcon( | |
| 1323 int base_id, | |
| 1324 const color_utils::HSL& tint) const { | |
| 1325 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 1326 return SkBitmapOperations::CreateHSLShiftedBitmap( | |
| 1327 rb.GetImageNamed(base_id).AsBitmap(), tint); | |
| 1328 } | |
| 1329 | |
| 1330 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { | 1097 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { |
| 1331 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); | 1098 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 1332 | 1099 |
| 1333 SkColor accent_color = | 1100 SkColor accent_color = |
| 1334 theme->GetSystemColor( | 1101 theme->GetSystemColor( |
| 1335 ui::NativeTheme::kColorId_ButtonHighlightColor); | 1102 ui::NativeTheme::kColorId_ButtonHighlightColor); |
| 1336 SkColor text_color = | 1103 SkColor text_color = |
| 1337 theme->GetSystemColor( | 1104 theme->GetSystemColor( |
| 1338 ui::NativeTheme::kColorId_LabelEnabledColor); | 1105 ui::NativeTheme::kColorId_LabelEnabledColor); |
| 1339 SkColor base_color = | 1106 SkColor base_color = |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1363 // The simplest of all the tints. We just use the selected text in the entry | 1130 // The simplest of all the tints. We just use the selected text in the entry |
| 1364 // since the icons tinted this way will only be displayed against | 1131 // since the icons tinted this way will only be displayed against |
| 1365 // base[GTK_STATE_SELECTED]. | 1132 // base[GTK_STATE_SELECTED]. |
| 1366 SkColor color = | 1133 SkColor color = |
| 1367 NativeThemeGtk2::instance()->GetSystemColor( | 1134 NativeThemeGtk2::instance()->GetSystemColor( |
| 1368 ui::NativeTheme::kColorId_TextfieldSelectionColor); | 1135 ui::NativeTheme::kColorId_TextfieldSelectionColor); |
| 1369 | 1136 |
| 1370 color_utils::SkColorToHSL(color, tint); | 1137 color_utils::SkColorToHSL(color, tint); |
| 1371 } | 1138 } |
| 1372 | 1139 |
| 1373 void Gtk2UI::ClearAllThemeData() { | |
| 1374 gtk_images_.clear(); | |
| 1375 } | |
| 1376 | |
| 1377 void Gtk2UI::UpdateDefaultFont() { | 1140 void Gtk2UI::UpdateDefaultFont() { |
| 1378 PangoContext* pc = gtk_widget_get_pango_context( | 1141 PangoContext* pc = gtk_widget_get_pango_context( |
| 1379 NativeThemeGtk2::instance()->GetLabel()); | 1142 NativeThemeGtk2::instance()->GetLabel()); |
| 1380 const PangoFontDescription* desc = pango_context_get_font_description(pc); | 1143 const PangoFontDescription* desc = pango_context_get_font_description(pc); |
| 1381 | 1144 |
| 1382 // Use gfx::FontRenderParams to select a family and determine the rendering | 1145 // Use gfx::FontRenderParams to select a family and determine the rendering |
| 1383 // settings. | 1146 // settings. |
| 1384 gfx::FontRenderParamsQuery query; | 1147 gfx::FontRenderParamsQuery query; |
| 1385 query.families = base::SplitString(pango_font_description_get_family(desc), | 1148 query.families = base::SplitString(pango_font_description_get_family(desc), |
| 1386 ",", base::TRIM_WHITESPACE, | 1149 ",", base::TRIM_WHITESPACE, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1408 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? | 1171 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? |
| 1409 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) | 1172 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) |
| 1410 query.style |= gfx::Font::ITALIC; | 1173 query.style |= gfx::Font::ITALIC; |
| 1411 | 1174 |
| 1412 default_font_render_params_ = | 1175 default_font_render_params_ = |
| 1413 gfx::GetFontRenderParams(query, &default_font_family_); | 1176 gfx::GetFontRenderParams(query, &default_font_family_); |
| 1414 default_font_style_ = query.style; | 1177 default_font_style_ = query.style; |
| 1415 } | 1178 } |
| 1416 | 1179 |
| 1417 void Gtk2UI::ResetStyle() { | 1180 void Gtk2UI::ResetStyle() { |
| 1418 ClearAllThemeData(); | |
| 1419 LoadGtkValues(); | 1181 LoadGtkValues(); |
| 1420 // TODO(varkha): There will be no need to call UpdateMaterialDesignColors() | 1182 // TODO(varkha): There will be no need to call UpdateMaterialDesignColors() |
| 1421 // once Material Design is on unconditionally. | 1183 // once Material Design is on unconditionally. |
| 1422 UpdateMaterialDesignColors(); | 1184 UpdateMaterialDesignColors(); |
| 1423 NativeThemeGtk2::instance()->NotifyObservers(); | 1185 NativeThemeGtk2::instance()->NotifyObservers(); |
| 1424 } | 1186 } |
| 1425 | 1187 |
| 1426 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { | 1188 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { |
| 1427 device_scale_factor_ = device_scale_factor; | 1189 device_scale_factor_ = device_scale_factor; |
| 1428 UpdateDefaultFont(); | 1190 UpdateDefaultFont(); |
| 1429 } | 1191 } |
| 1430 | 1192 |
| 1431 float Gtk2UI::GetDeviceScaleFactor() const { | 1193 float Gtk2UI::GetDeviceScaleFactor() const { |
| 1432 if (display::Display::HasForceDeviceScaleFactor()) | 1194 if (display::Display::HasForceDeviceScaleFactor()) |
| 1433 return display::Display::GetForcedDeviceScaleFactor(); | 1195 return display::Display::GetForcedDeviceScaleFactor(); |
| 1434 const int kCSSDefaultDPI = 96; | 1196 const int kCSSDefaultDPI = 96; |
| 1435 const float scale = GetDPI() / kCSSDefaultDPI; | 1197 const float scale = GetDPI() / kCSSDefaultDPI; |
| 1436 | 1198 |
| 1437 // Blacklist scaling factors <130% (crbug.com/484400) and round | 1199 // Blacklist scaling factors <130% (crbug.com/484400) and round |
| 1438 // to 1 decimal to prevent rendering problems (crbug.com/485183). | 1200 // to 1 decimal to prevent rendering problems (crbug.com/485183). |
| 1439 return scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; | 1201 return scale < 1.3f ? 1.0f : roundf(scale * 10) / 10; |
| 1440 } | 1202 } |
| 1441 | 1203 |
| 1442 } // namespace libgtk2ui | 1204 } // namespace libgtk2ui |
| 1443 | 1205 |
| 1444 views::LinuxUI* BuildGtk2UI() { | 1206 views::LinuxUI* BuildGtk2UI() { |
| 1445 return new libgtk2ui::Gtk2UI; | 1207 return new libgtk2ui::Gtk2UI; |
| 1446 } | 1208 } |
| OLD | NEW |