views: Use default theme background color for all controls (see #3671)

Add new CefViewDelegate::OnThemeChanged callback for optionally overriding
default theme colors when the current theme changes.
This commit is contained in:
Marshall Greenblatt
2024-03-22 19:51:00 -04:00
parent a13b6dc7f6
commit 19ba8b2b8d
43 changed files with 510 additions and 102 deletions

View File

@@ -37,6 +37,7 @@
#include "chrome/browser/ui/ui_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "components/color/color_mixers.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/network_service_instance.h"
@@ -246,6 +247,8 @@ void AlloyBrowserMainParts::ToolkitInitialized() {
// On GTK that builds the native theme that, in turn, adds the GTK core color
// mixer; core mixers should all be added before we add chrome mixers.
ui::ColorProviderManager::Get().AppendColorProviderInitializer(
base::BindRepeating(color::AddComponentsColorMixers));
ui::ColorProviderManager::Get().AppendColorProviderInitializer(
base::BindRepeating(AddChromeColorMixers));
}

View File

@@ -85,7 +85,7 @@ CEF_BUTTON_IMPL_T void CEF_BUTTON_IMPL_D::SetInkDropEnabled(bool enabled) {
if (enabled) {
views::InkDrop::Get(ParentClass::root_view())
->SetBaseColor(color_utils::BlendTowardMaxContrast(
ParentClass::root_view()->background()->get_color(), 0x61));
ParentClass::GetBackgroundColor(), 0x61));
}
}

View File

@@ -193,8 +193,6 @@ void CefOverlayViewHost::Init(views::View* host_view,
: views::Widget::InitParams::Activatable::kNo;
widget_->Init(std::move(params));
view_ = widget_->GetContentsView()->AddChildView(std::move(controls_view));
// Make the Widget background transparent. The View might still be opaque.
if (widget_->GetCompositor()) {
widget_->GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
@@ -213,6 +211,11 @@ void CefOverlayViewHost::Init(views::View* host_view,
}
}
// Call AddChildView after the Widget properties have been configured.
// Notifications resulting from this call may attempt to access those
// properties (OnThemeChanged calling GetHostView, for example).
view_ = widget_->GetContentsView()->AddChildView(std::move(controls_view));
// Set the initial bounds after the View has been added to the Widget.
// Otherwise, preferred size won't calculate correctly.
gfx::Rect bounds;

View File

@@ -675,12 +675,15 @@ CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::RequestFocus() {
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBackgroundColor(cef_color_t color) {
CEF_REQUIRE_VALID_RETURN_VOID();
content_view()->SetBackground(views::CreateSolidBackground(color));
root_view()->SetBackground(views::CreateSolidBackground(color));
}
CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetBackgroundColor() {
CEF_REQUIRE_VALID_RETURN(0U);
return content_view()->background()->get_color();
if (root_view()->background()) {
return root_view()->background()->get_color();
}
return view_util::GetColor(root_view(), ui::kColorPrimaryBackground);
}
CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToScreen(CefPoint& point) {

View File

@@ -8,10 +8,13 @@
#include "libcef/browser/views/view_adapter.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_manager.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/non_client_view.h"
@@ -118,9 +121,24 @@ class UserData : public base::SupportsUserData::Data {
CefView* view_ref_;
};
// Based on Widget::GetNativeTheme.
const ui::NativeTheme* GetDefaultNativeTheme() {
return ui::NativeTheme::GetInstanceForNativeUi();
}
// Based on Widget::GetColorProviderKey.
ui::ColorProviderKey GetDefaultColorProviderKey() {
return GetDefaultNativeTheme()->GetColorProviderKey(/*custom_theme=*/nullptr);
}
// Based on Widget::GetColorProvider.
ui::ColorProvider* GetDefaultColorProvider() {
return ui::ColorProviderManager::Get().GetColorProviderFor(
GetDefaultColorProviderKey());
}
} // namespace
const SkColor kDefaultBackgroundColor = SkColorSetARGB(255, 255, 255, 255);
const char kDefaultFontList[] = "Arial, Helvetica, 14px";
void Register(CefRefPtr<CefView> view) {
@@ -323,4 +341,14 @@ bool ConvertPointFromWindow(views::View* view, gfx::Point* point) {
return true;
}
SkColor GetColor(views::View* view, ui::ColorId id) {
// |color_provider| will be nullptr if |view| has not yet been added to a
// Widget.
if (auto color_provider = view->GetColorProvider()) {
return color_provider->GetColor(id);
}
return GetDefaultColorProvider()->GetColor(id);
}
} // namespace view_util

View File

@@ -9,6 +9,7 @@
#include "include/views/cef_view.h"
#include "include/views/cef_window.h"
#include "ui/color/color_id.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/view.h"
@@ -45,7 +46,6 @@ class CefWindowDelegate;
namespace view_util {
// Default values.
extern const SkColor kDefaultBackgroundColor;
extern const char kDefaultFontList[];
// Called when a CefView is initialized to create the initial association
@@ -165,6 +165,11 @@ views::View* GetHostView(views::Widget* widget);
float GetNSWindowTitleBarHeight(views::Widget* widget);
#endif
// Returns the mixer color for |id|. If |view| has been added to a Widget it
// will use the Widget's ColorProvider, otherwise it will use the default theme
// ColorProvider. Returns gfx::kPlaceholderColor if |id| cannot be constructed.
SkColor GetColor(views::View* view, ui::ColorId id);
} // namespace view_util
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_

View File

@@ -44,10 +44,6 @@ CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
// CefViewImpl registration has completed so it is safe to call complex
// views::View-derived methods here.
virtual void Initialize() {
// Use our defaults instead of the Views framework defaults.
ParentClass::SetBackground(
views::CreateSolidBackground(view_util::kDefaultBackgroundColor));
// TODO(crbug.com/1218186): Remove this, if this view is focusable then it
// needs to add a name so that the screen reader knows what to announce.
ParentClass::SetProperty(views::kSkipAccessibilityPaintChecks, true);
@@ -80,6 +76,7 @@ CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
void RemovedFromWidget() override;
void OnFocus() override;
void OnBlur() override;
void OnThemeChanged() override;
// Return true if this View is expected to have a minimum size (for example,
// a button where the minimum size is based on the label).
@@ -214,6 +211,35 @@ CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::OnBlur() {
ParentClass::OnBlur();
}
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::OnThemeChanged() {
// Clear the background, if set.
if (ParentClass::background()) {
ParentClass::SetBackground(nullptr);
}
// Apply default theme colors.
ParentClass::OnThemeChanged();
// Allow the client to override the default colors.
if (cef_delegate()) {
cef_delegate()->OnThemeChanged(GetCefView());
}
// If the background is still unset, and the containing Widget is not an
// overlay (which has transparent background), then set the background based
// on the current theme.
if (!ParentClass::background()) {
const bool is_overlay_hosted =
ParentClass::GetWidget() &&
view_util::GetHostView(ParentClass::GetWidget()) != nullptr;
if (!is_overlay_hosted) {
const SkColor color =
view_util::GetColor(this, ui::kColorPrimaryBackground);
ParentClass::SetBackground(views::CreateSolidBackground(color));
}
}
}
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyChildViewChanged(
const views::ViewHierarchyChangedDetails& details) {
if (!cef_delegate()) {