| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" | 5 #include "chrome/browser/ui/libgtkui/native_theme_gtk3.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" | 9 #include "chrome/browser/ui/libgtkui/chrome_gtk_frame.h" |
| 10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" | 10 #include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" |
| 11 #include "chrome/browser/ui/libgtkui/gtk_util.h" | 11 #include "chrome/browser/ui/libgtkui/gtk_util.h" |
| 12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" | 12 #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" |
| 13 #include "ui/gfx/color_palette.h" | 13 #include "ui/gfx/color_palette.h" |
| 14 #include "ui/gfx/color_utils.h" | 14 #include "ui/gfx/color_utils.h" |
| 15 #include "ui/gfx/geometry/rect.h" | 15 #include "ui/gfx/geometry/rect.h" |
| 16 #include "ui/gfx/skbitmap_operations.h" | 16 #include "ui/gfx/skbitmap_operations.h" |
| 17 #include "ui/native_theme/native_theme_dark_aura.h" | 17 #include "ui/native_theme/native_theme_dark_aura.h" |
| 18 | 18 |
| 19 namespace libgtkui { | 19 namespace libgtkui { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 enum BackgroundRenderMode { | 23 enum BackgroundRenderMode { |
| 24 BG_RENDER_NORMAL, | 24 BG_RENDER_NORMAL, |
| 25 BG_RENDER_NONE, | 25 BG_RENDER_NONE, |
| 26 BG_RENDER_RECURSIVE, | 26 BG_RENDER_RECURSIVE, |
| 27 }; | 27 }; |
| 28 | 28 |
| 29 std::string GetGtkSettingsStringProperty(GtkSettings* settings, |
| 30 const gchar* prop_name) { |
| 31 GValue layout = G_VALUE_INIT; |
| 32 g_value_init(&layout, G_TYPE_STRING); |
| 33 g_object_get_property(G_OBJECT(settings), prop_name, &layout); |
| 34 DCHECK(G_VALUE_HOLDS_STRING(&layout)); |
| 35 std::string prop_value(g_value_get_string(&layout)); |
| 36 g_value_unset(&layout); |
| 37 return prop_value; |
| 38 } |
| 39 |
| 29 SkBitmap GetWidgetBitmap(const gfx::Size& size, | 40 SkBitmap GetWidgetBitmap(const gfx::Size& size, |
| 30 GtkStyleContext* context, | 41 GtkStyleContext* context, |
| 31 BackgroundRenderMode bg_mode, | 42 BackgroundRenderMode bg_mode, |
| 32 bool render_frame) { | 43 bool render_frame) { |
| 33 DCHECK(bg_mode != BG_RENDER_NONE || render_frame); | 44 DCHECK(bg_mode != BG_RENDER_NONE || render_frame); |
| 34 SkBitmap bitmap; | 45 SkBitmap bitmap; |
| 35 bitmap.allocN32Pixels(size.width(), size.height()); | 46 bitmap.allocN32Pixels(size.width(), size.height()); |
| 36 bitmap.eraseColor(0); | 47 bitmap.eraseColor(0); |
| 37 | 48 |
| 38 CairoSurface surface(bitmap); | 49 CairoSurface surface(bitmap); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 return fallback_theme->GetSystemColor(color_id); | 377 return fallback_theme->GetSystemColor(color_id); |
| 367 } | 378 } |
| 368 | 379 |
| 369 case ui::NativeTheme::kColorId_NumColors: | 380 case ui::NativeTheme::kColorId_NumColors: |
| 370 NOTREACHED(); | 381 NOTREACHED(); |
| 371 break; | 382 break; |
| 372 } | 383 } |
| 373 return kInvalidColorIdColor; | 384 return kInvalidColorIdColor; |
| 374 } | 385 } |
| 375 | 386 |
| 376 void OnThemeChanged(GObject* obj, GParamSpec* param, NativeThemeGtk3* theme) { | |
| 377 theme->ResetColorCache(); | |
| 378 } | |
| 379 | |
| 380 } // namespace | 387 } // namespace |
| 381 | 388 |
| 382 // static | 389 // static |
| 383 NativeThemeGtk3* NativeThemeGtk3::instance() { | 390 NativeThemeGtk3* NativeThemeGtk3::instance() { |
| 384 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); | 391 CR_DEFINE_STATIC_LOCAL(NativeThemeGtk3, s_native_theme, ()); |
| 385 return &s_native_theme; | 392 return &s_native_theme; |
| 386 } | 393 } |
| 387 | 394 |
| 388 // Constructors automatically called | |
| 389 NativeThemeGtk3::NativeThemeGtk3() { | 395 NativeThemeGtk3::NativeThemeGtk3() { |
| 390 // These types are needed by g_type_from_name(), but may not be registered at | 396 // These types are needed by g_type_from_name(), but may not be registered at |
| 391 // this point. We need the g_type_class magic to make sure the compiler | 397 // this point. We need the g_type_class magic to make sure the compiler |
| 392 // doesn't optimize away this code. | 398 // doesn't optimize away this code. |
| 393 g_type_class_unref(g_type_class_ref(gtk_button_get_type())); | 399 g_type_class_unref(g_type_class_ref(gtk_button_get_type())); |
| 394 g_type_class_unref(g_type_class_ref(gtk_entry_get_type())); | 400 g_type_class_unref(g_type_class_ref(gtk_entry_get_type())); |
| 395 g_type_class_unref(g_type_class_ref(gtk_info_bar_get_type())); | 401 g_type_class_unref(g_type_class_ref(gtk_info_bar_get_type())); |
| 396 g_type_class_unref(g_type_class_ref(gtk_label_get_type())); | 402 g_type_class_unref(g_type_class_ref(gtk_label_get_type())); |
| 397 g_type_class_unref(g_type_class_ref(gtk_menu_get_type())); | 403 g_type_class_unref(g_type_class_ref(gtk_menu_get_type())); |
| 398 g_type_class_unref(g_type_class_ref(gtk_menu_bar_get_type())); | 404 g_type_class_unref(g_type_class_ref(gtk_menu_bar_get_type())); |
| 399 g_type_class_unref(g_type_class_ref(gtk_menu_item_get_type())); | 405 g_type_class_unref(g_type_class_ref(gtk_menu_item_get_type())); |
| 400 g_type_class_unref(g_type_class_ref(gtk_range_get_type())); | 406 g_type_class_unref(g_type_class_ref(gtk_range_get_type())); |
| 401 g_type_class_unref(g_type_class_ref(gtk_scrollbar_get_type())); | 407 g_type_class_unref(g_type_class_ref(gtk_scrollbar_get_type())); |
| 402 g_type_class_unref(g_type_class_ref(gtk_scrolled_window_get_type())); | 408 g_type_class_unref(g_type_class_ref(gtk_scrolled_window_get_type())); |
| 403 g_type_class_unref(g_type_class_ref(gtk_separator_get_type())); | 409 g_type_class_unref(g_type_class_ref(gtk_separator_get_type())); |
| 404 g_type_class_unref(g_type_class_ref(gtk_spinner_get_type())); | 410 g_type_class_unref(g_type_class_ref(gtk_spinner_get_type())); |
| 405 g_type_class_unref(g_type_class_ref(gtk_text_view_get_type())); | 411 g_type_class_unref(g_type_class_ref(gtk_text_view_get_type())); |
| 406 g_type_class_unref(g_type_class_ref(gtk_tooltip_get_type())); | 412 g_type_class_unref(g_type_class_ref(gtk_tooltip_get_type())); |
| 407 g_type_class_unref(g_type_class_ref(gtk_tree_view_get_type())); | 413 g_type_class_unref(g_type_class_ref(gtk_tree_view_get_type())); |
| 408 g_type_class_unref(g_type_class_ref(gtk_window_get_type())); | 414 g_type_class_unref(g_type_class_ref(gtk_window_get_type())); |
| 409 | 415 |
| 410 g_signal_connect_after(gtk_settings_get_default(), "notify::gtk-theme-name", | 416 g_signal_connect_after(gtk_settings_get_default(), "notify::gtk-theme-name", |
| 411 G_CALLBACK(OnThemeChanged), this); | 417 G_CALLBACK(OnThemeChangedThunk), this); |
| 418 OnThemeChanged(gtk_settings_get_default(), nullptr); |
| 412 } | 419 } |
| 413 | 420 |
| 414 // This doesn't actually get called | 421 NativeThemeGtk3::~NativeThemeGtk3() { |
| 415 NativeThemeGtk3::~NativeThemeGtk3() {} | 422 NOTREACHED(); |
| 423 } |
| 416 | 424 |
| 417 void NativeThemeGtk3::ResetColorCache() { | 425 void NativeThemeGtk3::SetThemeCssOverride(ScopedCssProvider provider) { |
| 426 if (theme_css_override_) { |
| 427 gtk_style_context_remove_provider_for_screen( |
| 428 gdk_screen_get_default(), |
| 429 GTK_STYLE_PROVIDER(theme_css_override_.get())); |
| 430 } |
| 431 theme_css_override_ = std::move(provider); |
| 432 if (theme_css_override_) { |
| 433 gtk_style_context_add_provider_for_screen( |
| 434 gdk_screen_get_default(), GTK_STYLE_PROVIDER(theme_css_override_.get()), |
| 435 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); |
| 436 } |
| 437 } |
| 438 |
| 439 void NativeThemeGtk3::OnThemeChanged(GtkSettings* settings, |
| 440 GtkParamSpec* param) { |
| 441 SetThemeCssOverride(ScopedCssProvider()); |
| 418 for (auto& color : color_cache_) | 442 for (auto& color : color_cache_) |
| 419 color = base::nullopt; | 443 color = base::nullopt; |
| 444 |
| 445 // Hack to workaround a bug on GNOME standard themes which would |
| 446 // cause black patches to be rendered on GtkFileChooser dialogs. |
| 447 std::string theme_name = |
| 448 GetGtkSettingsStringProperty(settings, "gtk-theme-name"); |
| 449 if (!GtkVersionCheck(3, 14)) { |
| 450 if (theme_name == "Adwaita") { |
| 451 SetThemeCssOverride(GetCssProvider( |
| 452 "GtkFileChooser GtkPaned { background-color: @theme_bg_color; }")); |
| 453 } else if (theme_name == "HighContrast") { |
| 454 SetThemeCssOverride(GetCssProvider( |
| 455 "GtkFileChooser GtkPaned { background-color: @theme_base_color; }")); |
| 456 } |
| 457 } |
| 420 } | 458 } |
| 421 | 459 |
| 422 SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { | 460 SkColor NativeThemeGtk3::GetSystemColor(ColorId color_id) const { |
| 423 if (color_cache_[color_id]) | 461 if (color_cache_[color_id]) |
| 424 return color_cache_[color_id].value(); | 462 return color_cache_[color_id].value(); |
| 425 | 463 |
| 426 SkColor color = SkColorFromColorId(color_id); | 464 SkColor color = SkColorFromColorId(color_id); |
| 427 color_cache_[color_id] = color; | 465 color_cache_[color_id] = color; |
| 428 return color; | 466 return color; |
| 429 } | 467 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 630 |
| 593 if (frame_top_area.incognito) { | 631 if (frame_top_area.incognito) { |
| 594 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( | 632 bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( |
| 595 bitmap, kDefaultTintFrameIncognito); | 633 bitmap, kDefaultTintFrameIncognito); |
| 596 } | 634 } |
| 597 | 635 |
| 598 canvas->drawBitmap(bitmap, rect.x(), rect.y()); | 636 canvas->drawBitmap(bitmap, rect.x(), rect.y()); |
| 599 } | 637 } |
| 600 | 638 |
| 601 } // namespace libgtkui | 639 } // namespace libgtkui |
| OLD | NEW |