Revert "Paint controls using Page's color provider"
This reverts commit 73317c46c9
.
Reason for revert: Causing a crasher in Lacros, See: crbug.com/1519536
Original change's description:
> Paint controls using Page's color provider
>
> This CL is a follow up on CL:5042390 and CL:5046572, where we plumbed
> the page's color providers and added color provider support for tests.
> This CL uses the plumbed provider to paint by passing it as an argument
> to the NativeTheme Paint function in WebThemeEngineDefault::Paint.
>
> This CL cleans up the previous pipeline which originally saw color
> provider instances exist in Blink::WebThemeEngineDefault. This clean up
> also saw us change the ExecutePageBroadcastMethod call to
> ExecutePageBroadcastMethodForAllPages in
> WebContentsImpl::OnColorProviderChanged.
>
> Additionally, this CL moves the logic of determining the color scheme
> based on the accent color to the ThemePainterDefault and ensures the
> correct color scheme is calculated before painting.
>
> Bug: 1430181
> Change-Id: I0c492bd6c37f63033afbfb6ead1ea6b78387d737
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5068491
> Reviewed-by: Thomas Lukaszewicz <tluk@chromium.org>
> Reviewed-by: Nasko Oskov <nasko@chromium.org>
> Reviewed-by: Alison Maher <almaher@microsoft.com>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Commit-Queue: Sam Davis Omekara <samomekarajr@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#1248508}
Bug: 1430181
Change-Id: I6bbf8e37204569a499f03a3cab70f51ea68b7c38
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5212311
Reviewed-by: Thomas Lukaszewicz <tluk@chromium.org>
Commit-Queue: Sam Davis Omekara <samomekarajr@microsoft.com>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Owners-Override: Nasko Oskov <nasko@chromium.org>
Reviewed-by: Alison Maher <almaher@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1249044}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
96f9569fd4
commit
5e9733a9e1
content
browser
common
renderer
third_party/blink
public
platform
renderer
core
dom
exported
layout
page
paint
testing
platform
ui/color
@ -8,6 +8,8 @@
|
||||
#include "build/build_config.h"
|
||||
#include "content/browser/renderer_host/render_process_host_impl.h"
|
||||
#include "content/common/renderer.mojom.h"
|
||||
#include "ui/color/color_provider_key.h"
|
||||
#include "ui/color/color_provider_utils.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
@ -36,6 +38,38 @@ mojom::UpdateSystemColorInfoParamsPtr MakeUpdateSystemColorInfoParams(
|
||||
params->accent_color = native_theme->user_color();
|
||||
#endif
|
||||
|
||||
// TODO(crbug.com/1251637): We should not be using ColorProviders sourced from
|
||||
// the global NativeTheme web instance and instead have WebContents instances
|
||||
// propagate their specific ColorProviders to hosted frames.
|
||||
const auto get_renderer_color_map =
|
||||
[](ui::ColorProviderKey::ColorMode color_mode,
|
||||
bool override_forced_colors) {
|
||||
auto key =
|
||||
ui::NativeTheme::GetInstanceForWeb()->GetColorProviderKey(nullptr);
|
||||
key.color_mode = color_mode;
|
||||
// TODO(samomekarajr): Currently, the light/dark providers are used to
|
||||
// paint controls when the OS triggers forced colors mode. To keep
|
||||
// current behavior, we shouldn't modify the `forced_colors` key. We
|
||||
// should remove the conditional check when we use the forced colors
|
||||
// provider for painitng.
|
||||
if (override_forced_colors) {
|
||||
key.forced_colors = ui::ColorProviderKey::ForcedColors::kActive;
|
||||
}
|
||||
const auto* color_provider =
|
||||
ui::ColorProviderManager::Get().GetColorProviderFor(key);
|
||||
DCHECK(color_provider);
|
||||
return ui::CreateRendererColorMap(*color_provider);
|
||||
};
|
||||
params->light_colors =
|
||||
get_renderer_color_map(ui::ColorProviderKey::ColorMode::kLight,
|
||||
/*override_forced_colors=*/false);
|
||||
params->dark_colors = get_renderer_color_map(
|
||||
ui::ColorProviderKey::ColorMode::kDark, /*override_forced_colors=*/false);
|
||||
params->forced_colors_map =
|
||||
get_renderer_color_map(native_theme->ShouldUseDarkColors()
|
||||
? ui::ColorProviderKey::ColorMode::kDark
|
||||
: ui::ColorProviderKey::ColorMode::kLight,
|
||||
/*override_forced_colors=*/true);
|
||||
return params;
|
||||
}
|
||||
|
||||
|
@ -10142,7 +10142,7 @@ void WebContentsImpl::OnColorProviderChanged() {
|
||||
}
|
||||
|
||||
blink::ColorProviderColorMaps color_map = GetColorProviderColorMaps();
|
||||
ExecutePageBroadcastMethodForAllPages(base::BindRepeating(
|
||||
ExecutePageBroadcastMethod(base::BindRepeating(
|
||||
[](const blink::ColorProviderColorMaps& color_map,
|
||||
RenderViewHostImpl* rvh) {
|
||||
if (auto& broadcast = rvh->GetAssociatedPageBroadcast()) {
|
||||
|
@ -723,6 +723,7 @@ mojom("mojo_bindings") {
|
||||
"//ui/accessibility/mojom",
|
||||
"//ui/base/ime/mojom",
|
||||
"//ui/base/mojom",
|
||||
"//ui/color:mojom",
|
||||
"//ui/display/mojom",
|
||||
"//ui/events/mojom",
|
||||
"//ui/events/mojom:event_latency_metadata_mojom",
|
||||
|
@ -10,9 +10,11 @@ import "ipc/ipc.mojom";
|
||||
import "mojo/public/mojom/base/generic_pending_receiver.mojom";
|
||||
import "mojo/public/mojom/base/time.mojom";
|
||||
import "services/network/public/mojom/network_types.mojom";
|
||||
import "skia/public/mojom/skcolor.mojom";
|
||||
import "third_party/blink/public/mojom/browser_interface_broker.mojom";
|
||||
import "third_party/blink/public/mojom/origin_trials/origin_trials_settings.mojom";
|
||||
import "third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom";
|
||||
import "ui/color/color_id.mojom";
|
||||
|
||||
struct UpdateScrollbarThemeParams {
|
||||
// TODO(avi): Update these to optional values when optional numeric types are
|
||||
@ -40,6 +42,11 @@ struct UpdateSystemColorInfoParams {
|
||||
|
||||
// Accent color used by the system. Currently only set on ChromeOS.
|
||||
uint32? accent_color;
|
||||
|
||||
// Maps used to reconstruct ColorProvider instances in the renderer.
|
||||
map<color.mojom.RendererColorId, skia.mojom.SkColor> light_colors;
|
||||
map<color.mojom.RendererColorId, skia.mojom.SkColor> dark_colors;
|
||||
map<color.mojom.RendererColorId, skia.mojom.SkColor> forced_colors_map;
|
||||
};
|
||||
|
||||
// The background state for the render process. When backgrounded the process's
|
||||
|
@ -1488,6 +1488,17 @@ void RenderThreadImpl::OnSystemColorsChanged(int32_t aqua_color_variant) {
|
||||
|
||||
void RenderThreadImpl::UpdateSystemColorInfo(
|
||||
mojom::UpdateSystemColorInfoParamsPtr params) {
|
||||
bool color_providers_changed =
|
||||
blink_platform_impl_->ThemeEngine()->UpdateColorProviders(
|
||||
params->light_colors, params->dark_colors, params->forced_colors_map);
|
||||
if (color_providers_changed) {
|
||||
// Notify blink that the global ColorProvider instances for this renderer
|
||||
// have changed. These color providers are only used to paint native
|
||||
// controls and only require us to invalidate paint for local frames in this
|
||||
// renderer.
|
||||
blink::ColorProvidersChanged();
|
||||
}
|
||||
|
||||
auto* native_theme = ui::NativeTheme::GetInstanceForWeb();
|
||||
|
||||
bool did_system_color_info_change = native_theme->UpdateSystemColorInfo(
|
||||
|
@ -311,6 +311,17 @@ class WebThemeEngine {
|
||||
SystemColorInfoState state;
|
||||
return state;
|
||||
}
|
||||
virtual void EmulateForcedColors(bool is_dark_theme, bool is_web_test) {}
|
||||
|
||||
// Updates the WebThemeEngine's global light, dark and forced colors
|
||||
// ColorProvider instances using the RendererColorMaps provided. Returns true
|
||||
// if new ColorProviders were created, returns false otherwise.
|
||||
virtual bool UpdateColorProviders(
|
||||
const ui::RendererColorMap& light_colors,
|
||||
const ui::RendererColorMap& dark_colors,
|
||||
const ui::RendererColorMap& forced_colors_map) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
@ -9174,12 +9174,8 @@ const ui::ColorProvider* Document::GetColorProviderForPainting(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(crbug.com/1516529): This should be changed to use
|
||||
// `in_forced_colors_mode_` once forced colors becomes a web setting in Blink.
|
||||
return GetPage()->GetColorProviderForPainting(
|
||||
color_scheme,
|
||||
WebThemeEngineHelper::GetNativeThemeEngine()->GetForcedColors() !=
|
||||
ForcedColors::kNone);
|
||||
return GetPage()->GetColorProviderForPainting(color_scheme,
|
||||
in_forced_colors_mode_);
|
||||
}
|
||||
|
||||
void Document::CountUse(mojom::WebFeature feature) const {
|
||||
|
@ -67,4 +67,8 @@ void ColorSchemeChanged() {
|
||||
LayoutTheme::GetTheme().ColorSchemeDidChange();
|
||||
}
|
||||
|
||||
void ColorProvidersChanged() {
|
||||
LayoutTheme::GetTheme().ColorProvidersDidChange();
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
@ -517,6 +517,10 @@ void LayoutTheme::ColorSchemeDidChange() {
|
||||
Page::ColorSchemeChanged();
|
||||
}
|
||||
|
||||
void LayoutTheme::ColorProvidersDidChange() {
|
||||
Page::ColorProvidersChanged();
|
||||
}
|
||||
|
||||
void LayoutTheme::SetCaretBlinkInterval(base::TimeDelta interval) {
|
||||
caret_blink_interval_ = interval;
|
||||
}
|
||||
|
51
third_party/blink/renderer/core/page/page.cc
vendored
51
third_party/blink/renderer/core/page/page.cc
vendored
@ -471,7 +471,9 @@ void Page::ColorSchemeChanged() {
|
||||
}
|
||||
|
||||
void Page::ColorProvidersChanged() {
|
||||
InvalidatePaint();
|
||||
for (Page* page : AllPages()) {
|
||||
page->InvalidatePaint();
|
||||
}
|
||||
}
|
||||
|
||||
void Page::EmulateForcedColors(bool is_dark_theme) {
|
||||
@ -493,38 +495,21 @@ void Page::UpdateColorProviders(
|
||||
return;
|
||||
}
|
||||
|
||||
bool did_color_provider_update = false;
|
||||
if (!ui::IsRendererColorMappingEquivalent(
|
||||
light_color_provider_.get(),
|
||||
color_provider_colors.light_colors_map)) {
|
||||
light_color_provider_ = std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.light_colors_map));
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
if (!ui::IsRendererColorMappingEquivalent(
|
||||
dark_color_provider_.get(), color_provider_colors.dark_colors_map)) {
|
||||
dark_color_provider_ = std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.dark_colors_map));
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
if (!ui::IsRendererColorMappingEquivalent(
|
||||
forced_colors_color_provider_.get(),
|
||||
color_provider_colors.forced_colors_map)) {
|
||||
forced_colors_color_provider_ =
|
||||
WebTestSupport::IsRunningWebTest()
|
||||
? std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateEmulatedForcedColorsColorProviderForTest())
|
||||
: std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.forced_colors_map));
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
|
||||
if (did_color_provider_update) {
|
||||
ColorProvidersChanged();
|
||||
}
|
||||
// TODO(samomekarajr): Might want to only create new ColorProviders if the
|
||||
// renderer color maps do not match the existing ColorProviders.
|
||||
light_color_provider_ = std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.light_colors_map));
|
||||
dark_color_provider_ = std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.dark_colors_map));
|
||||
forced_colors_color_provider_ =
|
||||
WebTestSupport::IsRunningWebTest()
|
||||
? std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateEmulatedForcedColorsColorProviderForTest())
|
||||
: std::make_unique<ui::ColorProvider>(
|
||||
ui::CreateColorProviderFromRendererColorMap(
|
||||
color_provider_colors.forced_colors_map));
|
||||
}
|
||||
|
||||
void Page::UpdateColorProvidersForTest() {
|
||||
|
2
third_party/blink/renderer/core/page/page.h
vendored
2
third_party/blink/renderer/core/page/page.h
vendored
@ -160,7 +160,7 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
|
||||
static void UsesOverlayScrollbarsChanged();
|
||||
static void PlatformColorsChanged();
|
||||
static void ColorSchemeChanged();
|
||||
void ColorProvidersChanged();
|
||||
static void ColorProvidersChanged();
|
||||
|
||||
void EmulateForcedColors(bool is_dark_theme);
|
||||
void DisableEmulatedForcedColors();
|
||||
|
@ -77,79 +77,6 @@ WebThemeEngine::State GetWebThemeState(const Element& element) {
|
||||
return WebThemeEngine::kStateNormal;
|
||||
}
|
||||
|
||||
SkColor GetContrastingColorFor(const Element& element,
|
||||
const mojom::ColorScheme color_scheme,
|
||||
WebThemeEngine::Part part) {
|
||||
WebThemeEngine::State state = GetWebThemeState(element);
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
element.GetDocument().GetColorProviderForPainting(color_scheme);
|
||||
|
||||
const bool is_disabled = (state == WebThemeEngine::kStateDisabled);
|
||||
switch (part) {
|
||||
case WebThemeEngine::kPartCheckbox:
|
||||
case WebThemeEngine::kPartRadio:
|
||||
return is_disabled ? color_provider->GetColor(
|
||||
ui::kColorWebNativeControlBackgroundDisabled)
|
||||
: color_provider->GetColor(
|
||||
ui::kColorWebNativeControlBackground);
|
||||
case WebThemeEngine::kPartSliderTrack:
|
||||
case WebThemeEngine::kPartSliderThumb:
|
||||
case WebThemeEngine::kPartProgressBar:
|
||||
// We use `kStateNormal` here because the user hovering or clicking on the
|
||||
// slider will change the state to something else, and we don't want the
|
||||
// color-scheme to flicker back and forth when the user interacts with it.
|
||||
return color_provider->GetColor(ui::kColorWebNativeControlFill);
|
||||
default:
|
||||
NOTREACHED_NORETURN();
|
||||
}
|
||||
}
|
||||
|
||||
mojom::ColorScheme CalculateColorSchemeForAccentColor(
|
||||
absl::optional<SkColor> accent_color,
|
||||
mojom::ColorScheme color_scheme,
|
||||
SkColor light_contrasting_color,
|
||||
SkColor dark_contrasting_color) {
|
||||
if (!accent_color) {
|
||||
return color_scheme;
|
||||
}
|
||||
|
||||
const float contrast_with_light =
|
||||
color_utils::GetContrastRatio(*accent_color, light_contrasting_color);
|
||||
const float contrast_with_dark =
|
||||
color_utils::GetContrastRatio(*accent_color, dark_contrasting_color);
|
||||
|
||||
// If there is enough contrast between `accent_color` and `color_scheme`, then
|
||||
// let's keep it the same. Otherwise, flip the `color_scheme` to guarantee
|
||||
// contrast.
|
||||
if (color_scheme == mojom::ColorScheme::kDark) {
|
||||
if (contrast_with_dark < color_utils::kMinimumVisibleContrastRatio &&
|
||||
contrast_with_dark < contrast_with_light) {
|
||||
// TODO(crbug.com/1216137): what if `contrast_with_light` is less than
|
||||
// `kMinimumContrast`? Should we modify `accent_color`...?
|
||||
return mojom::ColorScheme::kLight;
|
||||
}
|
||||
} else {
|
||||
if (contrast_with_light < color_utils::kMinimumVisibleContrastRatio &&
|
||||
contrast_with_light < contrast_with_dark) {
|
||||
return mojom::ColorScheme::kDark;
|
||||
}
|
||||
}
|
||||
|
||||
return color_scheme;
|
||||
}
|
||||
|
||||
mojom::blink::ColorScheme GetColorSchemeForAccentColor(
|
||||
const Element& element,
|
||||
const mojom::blink::ColorScheme color_scheme,
|
||||
const absl::optional<SkColor> accent_color,
|
||||
WebThemeEngine::Part part) {
|
||||
return CalculateColorSchemeForAccentColor(
|
||||
accent_color, color_scheme,
|
||||
GetContrastingColorFor(element, mojom::blink::ColorScheme::kLight, part),
|
||||
GetContrastingColorFor(element, mojom::blink::ColorScheme::kDark, part));
|
||||
}
|
||||
|
||||
class DirectionFlippingScope {
|
||||
STACK_ALLOCATED();
|
||||
|
||||
@ -304,20 +231,6 @@ bool ThemePainterDefault::PaintCheckbox(const Element& element,
|
||||
ApplyZoomToRect(rect, paint_info, state_saver, zoom_level);
|
||||
WebThemeEngine::ExtraParams extra_params(button);
|
||||
mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
|
||||
|
||||
// This is used for `kPartCheckbox`, which gets drawn adjacent to
|
||||
// `accent_color`. In order to guarantee contrast between `kPartCheckbox` and
|
||||
// `accent_color`, we choose the `color_scheme` here based on the two possible
|
||||
// color values for `kPartCheckbox`.
|
||||
bool accent_color_affects_color_scheme =
|
||||
button.checked &&
|
||||
GetWebThemeState(element) != WebThemeEngine::kStateDisabled;
|
||||
if (accent_color_affects_color_scheme) {
|
||||
color_scheme = GetColorSchemeForAccentColor(element, color_scheme,
|
||||
GetAccentColor(style, document),
|
||||
WebThemeEngine::kPartCheckbox);
|
||||
}
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
document.GetColorProviderForPainting(color_scheme);
|
||||
WebThemeEngineHelper::GetNativeThemeEngine()->Paint(
|
||||
@ -342,20 +255,6 @@ bool ThemePainterDefault::PaintRadio(const Element& element,
|
||||
gfx::Rect unzoomed_rect =
|
||||
ApplyZoomToRect(rect, paint_info, state_saver, zoom_level);
|
||||
mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
|
||||
|
||||
// This is used for `kPartRadio`, which gets drawn adjacent to `accent_color`.
|
||||
// In order to guarantee contrast between `kPartRadio` and `accent_color`, we
|
||||
// choose the `color_scheme` here based on the two possible color values for
|
||||
// `kPartRadio`.
|
||||
bool accent_color_affects_color_scheme =
|
||||
button.checked &&
|
||||
GetWebThemeState(element) != WebThemeEngine::kStateDisabled;
|
||||
if (accent_color_affects_color_scheme) {
|
||||
color_scheme = GetColorSchemeForAccentColor(element, color_scheme,
|
||||
GetAccentColor(style, document),
|
||||
WebThemeEngine::kPartRadio);
|
||||
}
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
document.GetColorProviderForPainting(color_scheme);
|
||||
WebThemeEngineHelper::GetNativeThemeEngine()->Paint(
|
||||
@ -589,19 +488,6 @@ bool ThemePainterDefault::PaintSliderTrack(const Element& element,
|
||||
}
|
||||
WebThemeEngine::ExtraParams extra_params(slider);
|
||||
mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
|
||||
|
||||
// This is used for `kPartSliderTrack`, which gets drawn adjacent to
|
||||
// `accent_color`. In order to guarantee contrast between `kPartSliderTrack`
|
||||
// and `accent_color`, we choose the `color_scheme` here based on the two
|
||||
// possible color values for `kPartSliderTrack`.
|
||||
bool accent_color_affects_color_scheme =
|
||||
GetWebThemeState(element) != WebThemeEngine::kStateDisabled;
|
||||
if (accent_color_affects_color_scheme) {
|
||||
color_scheme = GetColorSchemeForAccentColor(
|
||||
element, color_scheme, GetAccentColor(style, element.GetDocument()),
|
||||
WebThemeEngine::kPartSliderTrack);
|
||||
}
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
element.GetDocument().GetColorProviderForPainting(color_scheme);
|
||||
|
||||
@ -638,19 +524,6 @@ bool ThemePainterDefault::PaintSliderThumb(const Element& element,
|
||||
element.GetDocument());
|
||||
WebThemeEngine::ExtraParams extra_params(slider);
|
||||
mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
|
||||
|
||||
// This is used for `kPartSliderThumb`, which gets drawn adjacent to
|
||||
// `accent_color`. In order to guarantee contrast between `kPartSliderThumb`
|
||||
// and `accent_color`, we choose the `color_scheme` here based on the two
|
||||
// possible color values for `kPartSliderThumb`.
|
||||
bool accent_color_affects_color_scheme =
|
||||
GetWebThemeState(element) != WebThemeEngine::kStateDisabled;
|
||||
if (accent_color_affects_color_scheme) {
|
||||
color_scheme = GetColorSchemeForAccentColor(
|
||||
element, color_scheme, GetAccentColor(style, element.GetDocument()),
|
||||
WebThemeEngine::kPartSliderThumb);
|
||||
}
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
element.GetDocument().GetColorProviderForPainting(color_scheme);
|
||||
|
||||
@ -719,15 +592,6 @@ bool ThemePainterDefault::PaintProgressBar(const Element& element,
|
||||
WebThemeEngine::ExtraParams extra_params(progress_bar);
|
||||
DirectionFlippingScope scope(layout_object, paint_info, rect);
|
||||
mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
|
||||
|
||||
// This is used for `kPartProgressBar`, which gets drawn adjacent to
|
||||
// `accent_color`. In order to guarantee contrast between `kPartProgressBar`
|
||||
// and `accent_color`, we choose the `color_scheme` here based on the two
|
||||
// possible color values for `kPartProgressBar`.
|
||||
color_scheme = GetColorSchemeForAccentColor(
|
||||
element, color_scheme, GetAccentColor(style, element.GetDocument()),
|
||||
WebThemeEngine::kPartProgressBar);
|
||||
|
||||
const ui::ColorProvider* color_provider =
|
||||
element.GetDocument().GetColorProviderForPainting(color_scheme);
|
||||
WebThemeEngineHelper::GetNativeThemeEngine()->Paint(
|
||||
|
@ -60,6 +60,7 @@ void ColorSchemeHelper::SetForcedColors(Page& page,
|
||||
|
||||
void ColorSchemeHelper::SetEmulatedForcedColors(Document& document,
|
||||
bool is_dark_theme) {
|
||||
web_theme_engine_->EmulateForcedColors(is_dark_theme, /*is_web_test=*/true);
|
||||
document.GetPage()->EmulateForcedColors(is_dark_theme);
|
||||
document.ColorSchemeChanged();
|
||||
}
|
||||
|
@ -200,7 +200,12 @@ static ui::NativeTheme::ExtraParams GetNativeThemeExtraParams(
|
||||
}
|
||||
}
|
||||
|
||||
WebThemeEngineDefault::WebThemeEngineDefault() = default;
|
||||
WebThemeEngineDefault::WebThemeEngineDefault() {
|
||||
light_color_provider_.GenerateColorMap();
|
||||
dark_color_provider_.GenerateColorMap();
|
||||
emulated_forced_colors_provider_.GenerateColorMap();
|
||||
forced_colors_provider_.GenerateColorMap();
|
||||
}
|
||||
|
||||
WebThemeEngineDefault::~WebThemeEngineDefault() = default;
|
||||
|
||||
@ -243,10 +248,21 @@ void WebThemeEngineDefault::Paint(
|
||||
ui::NativeTheme::ExtraParams native_theme_extra_params =
|
||||
GetNativeThemeExtraParams(part, state, extra_params);
|
||||
|
||||
if (ShouldPartBeAffectedByAccentColor(part, state, extra_params)) {
|
||||
// This is used for `part`, which gets drawn adjacent to `accent_color`. In
|
||||
// order to guarantee contrast between `part` and `accent_color`, we choose
|
||||
// the `color_scheme` here based on the two possible color values for
|
||||
// `part`.
|
||||
color_scheme = CalculateColorSchemeForAccentColor(
|
||||
accent_color, color_scheme,
|
||||
GetContrastingColorFor(mojom::ColorScheme::kLight, part, state),
|
||||
GetContrastingColorFor(mojom::ColorScheme::kDark, part, state));
|
||||
}
|
||||
|
||||
ui::NativeTheme::GetInstanceForWeb()->Paint(
|
||||
canvas, color_provider, NativeThemePart(part), NativeThemeState(state),
|
||||
rect, native_theme_extra_params, NativeColorScheme(color_scheme),
|
||||
accent_color);
|
||||
canvas, GetColorProviderForPainting(color_scheme), NativeThemePart(part),
|
||||
NativeThemeState(state), rect, native_theme_extra_params,
|
||||
NativeColorScheme(color_scheme), accent_color);
|
||||
}
|
||||
|
||||
void WebThemeEngineDefault::GetOverlayScrollbarStyle(ScrollbarStyle* style) {
|
||||
@ -344,10 +360,18 @@ void WebThemeEngineDefault::OverrideForcedColorsTheme(bool is_dark_theme) {
|
||||
{ui::NativeTheme::SystemThemeColor::kWindow, 0xFFFFFFFF},
|
||||
{ui::NativeTheme::SystemThemeColor::kWindowText, 0xFF000000},
|
||||
};
|
||||
EmulateForcedColors(is_dark_theme, /*is_web_test=*/false);
|
||||
ui::NativeTheme::GetInstanceForWeb()->UpdateSystemColorInfo(
|
||||
false, true, is_dark_theme ? dark_theme : light_theme);
|
||||
}
|
||||
|
||||
void WebThemeEngineDefault::EmulateForcedColors(bool is_dark_theme,
|
||||
bool is_web_test) {
|
||||
SetEmulateForcedColors(true);
|
||||
emulated_forced_colors_provider_ =
|
||||
is_web_test ? ui::CreateEmulatedForcedColorsColorProviderForTest()
|
||||
: ui::CreateEmulatedForcedColorsColorProvider(is_dark_theme);
|
||||
}
|
||||
|
||||
void WebThemeEngineDefault::SetForcedColors(const ForcedColors forced_colors) {
|
||||
ui::NativeTheme::GetInstanceForWeb()->set_forced_colors(
|
||||
@ -366,6 +390,7 @@ void WebThemeEngineDefault::ResetToSystemColors(
|
||||
system_color_info_state.is_dark_mode,
|
||||
system_color_info_state.forced_colors, colors);
|
||||
|
||||
SetEmulateForcedColors(false);
|
||||
}
|
||||
|
||||
WebThemeEngine::SystemColorInfoState
|
||||
@ -387,4 +412,133 @@ WebThemeEngineDefault::GetSystemColorInfo() {
|
||||
return state;
|
||||
}
|
||||
|
||||
bool WebThemeEngineDefault::UpdateColorProviders(
|
||||
const ui::RendererColorMap& light_colors,
|
||||
const ui::RendererColorMap& dark_colors,
|
||||
const ui::RendererColorMap& forced_colors_map) {
|
||||
if (WebTestSupport::IsRunningWebTest() &&
|
||||
GetForcedColors() == ForcedColors::kActive) {
|
||||
// Web tests use a different set of colors when determining which system
|
||||
// colors to render in forced colors mode.
|
||||
EmulateForcedColors(/*is_dark_theme=*/false, /*is_web_test=*/true);
|
||||
}
|
||||
|
||||
// Do not create new ColorProviders if the renderer color maps match the
|
||||
// existing ColorProviders.
|
||||
bool did_color_provider_update = false;
|
||||
if (!IsRendererColorMappingEquivalent(light_color_provider_, light_colors)) {
|
||||
light_color_provider_ =
|
||||
ui::CreateColorProviderFromRendererColorMap(light_colors);
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
if (!IsRendererColorMappingEquivalent(dark_color_provider_, dark_colors)) {
|
||||
dark_color_provider_ =
|
||||
ui::CreateColorProviderFromRendererColorMap(dark_colors);
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
if (!IsRendererColorMappingEquivalent(forced_colors_provider_,
|
||||
forced_colors_map)) {
|
||||
forced_colors_provider_ =
|
||||
ui::CreateColorProviderFromRendererColorMap(forced_colors_map);
|
||||
did_color_provider_update = true;
|
||||
}
|
||||
|
||||
return did_color_provider_update;
|
||||
}
|
||||
|
||||
bool WebThemeEngineDefault::ShouldPartBeAffectedByAccentColor(
|
||||
WebThemeEngine::Part part,
|
||||
WebThemeEngine::State state,
|
||||
const WebThemeEngine::ExtraParams* extra_params) const {
|
||||
switch (part) {
|
||||
case WebThemeEngine::kPartCheckbox:
|
||||
case WebThemeEngine::kPartRadio: {
|
||||
const auto& button =
|
||||
absl::get<WebThemeEngine::ButtonExtraParams>(*extra_params);
|
||||
return button.checked && state != WebThemeEngine::kStateDisabled;
|
||||
}
|
||||
|
||||
case WebThemeEngine::kPartSliderTrack:
|
||||
case WebThemeEngine::kPartSliderThumb:
|
||||
return state != WebThemeEngine::kStateDisabled;
|
||||
case WebThemeEngine::kPartProgressBar:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SkColor WebThemeEngineDefault::GetContrastingColorFor(
|
||||
mojom::ColorScheme color_scheme,
|
||||
WebThemeEngine::Part part,
|
||||
WebThemeEngine::State state) const {
|
||||
const ui::ColorProvider* color_provider =
|
||||
color_scheme == mojom::ColorScheme::kLight ? &light_color_provider_
|
||||
: &dark_color_provider_;
|
||||
bool isDisabled = (state == WebThemeEngine::kStateDisabled);
|
||||
switch (part) {
|
||||
case WebThemeEngine::kPartCheckbox:
|
||||
case WebThemeEngine::kPartRadio:
|
||||
return isDisabled ? color_provider->GetColor(
|
||||
ui::kColorWebNativeControlBackgroundDisabled)
|
||||
: color_provider->GetColor(
|
||||
ui::kColorWebNativeControlBackground);
|
||||
case WebThemeEngine::kPartSliderTrack:
|
||||
case WebThemeEngine::kPartSliderThumb:
|
||||
case WebThemeEngine::kPartProgressBar:
|
||||
// We use `kStateNormal` here because the user hovering or clicking on the
|
||||
// slider will change the state to something else, and we don't want the
|
||||
// color-scheme to flicker back and forth when the user interacts with it.
|
||||
return color_provider->GetColor(ui::kColorWebNativeControlFill);
|
||||
default:
|
||||
NOTREACHED_NORETURN();
|
||||
}
|
||||
}
|
||||
|
||||
mojom::ColorScheme WebThemeEngineDefault::CalculateColorSchemeForAccentColor(
|
||||
absl::optional<SkColor> accent_color,
|
||||
mojom::ColorScheme color_scheme,
|
||||
SkColor light_contrasting_color,
|
||||
SkColor dark_contrasting_color) const {
|
||||
if (!accent_color) {
|
||||
return color_scheme;
|
||||
}
|
||||
|
||||
float contrast_with_light =
|
||||
color_utils::GetContrastRatio(*accent_color, light_contrasting_color);
|
||||
float contrast_with_dark =
|
||||
color_utils::GetContrastRatio(*accent_color, dark_contrasting_color);
|
||||
|
||||
// If there is enough contrast between `accent_color` and `color_scheme`, then
|
||||
// let's keep it the same. Otherwise, flip the `color_scheme` to guarantee
|
||||
// contrast.
|
||||
if (color_scheme == mojom::ColorScheme::kDark) {
|
||||
if (contrast_with_dark < color_utils::kMinimumVisibleContrastRatio &&
|
||||
contrast_with_dark < contrast_with_light) {
|
||||
// TODO(crbug.com/1216137): what if `contrast_with_light` is less than
|
||||
// `kMinimumContrast`? Should we modify `accent_color`...?
|
||||
return mojom::ColorScheme::kLight;
|
||||
}
|
||||
} else {
|
||||
if (contrast_with_light < color_utils::kMinimumVisibleContrastRatio &&
|
||||
contrast_with_light < contrast_with_dark) {
|
||||
return mojom::ColorScheme::kDark;
|
||||
}
|
||||
}
|
||||
|
||||
return color_scheme;
|
||||
}
|
||||
|
||||
const ui::ColorProvider* WebThemeEngineDefault::GetColorProviderForPainting(
|
||||
mojom::ColorScheme color_scheme) const {
|
||||
if (GetForcedColors() == ForcedColors::kActive) {
|
||||
if (emulate_forced_colors_) {
|
||||
return &emulated_forced_colors_provider_;
|
||||
}
|
||||
return &forced_colors_provider_;
|
||||
}
|
||||
return color_scheme == mojom::ColorScheme::kLight ? &light_color_provider_
|
||||
: &dark_color_provider_;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
@ -50,9 +50,57 @@ class WebThemeEngineDefault : public WebThemeEngine {
|
||||
void ResetToSystemColors(
|
||||
WebThemeEngine::SystemColorInfoState system_color_info_state) override;
|
||||
WebThemeEngine::SystemColorInfoState GetSystemColorInfo() override;
|
||||
bool UpdateColorProviders(
|
||||
const ui::RendererColorMap& light_colors,
|
||||
const ui::RendererColorMap& dark_colors,
|
||||
const ui::RendererColorMap& forced_colors_map) override;
|
||||
void EmulateForcedColors(bool is_dark_theme, bool is_web_test) override;
|
||||
bool IsFluentOverlayScrollbarEnabled() const override;
|
||||
int GetPaintedScrollbarTrackInset() const override;
|
||||
|
||||
protected:
|
||||
const ui::ColorProvider* GetColorProviderForPainting(
|
||||
mojom::ColorScheme color_scheme) const;
|
||||
|
||||
private:
|
||||
void SetEmulateForcedColors(bool emulate_forced_colors) {
|
||||
emulate_forced_colors_ = emulate_forced_colors;
|
||||
}
|
||||
// Returns whether `part` should be affected by the accent color depending on
|
||||
// the type of part and its state.
|
||||
bool ShouldPartBeAffectedByAccentColor(
|
||||
WebThemeEngine::Part part,
|
||||
WebThemeEngine::State state,
|
||||
const WebThemeEngine::ExtraParams* extra_params) const;
|
||||
SkColor GetContrastingColorFor(mojom::ColorScheme color_scheme,
|
||||
WebThemeEngine::Part part,
|
||||
WebThemeEngine::State state) const;
|
||||
// This returns a color scheme which provides enough contrast with the custom
|
||||
// `accent_color` to make it easy to see. `light_contrasting_color` is the
|
||||
// color which is used to paint adjacent to `accent_color` from the
|
||||
// `light_color_provider_`, and `dark_contrasting_color` is the one used from
|
||||
// `dark_color_provider_`.
|
||||
mojom::ColorScheme CalculateColorSchemeForAccentColor(
|
||||
absl::optional<SkColor> accent_color,
|
||||
mojom::ColorScheme color_scheme,
|
||||
SkColor light_contrasting_color,
|
||||
SkColor dark_contrasting_color) const;
|
||||
bool emulate_forced_colors_ = false;
|
||||
// These providers are kept in sync with ColorProviders in the browser and
|
||||
// will be updated when the theme changes.
|
||||
// TODO(crbug.com/1251637): Currently these reflect the ColorProviders
|
||||
// corresponding to the global NativeTheme for web instance in the browser. We
|
||||
// should instead update blink to use ColorProviders that correspond to their
|
||||
// hosting Page.
|
||||
ui::ColorProvider light_color_provider_;
|
||||
ui::ColorProvider dark_color_provider_;
|
||||
ui::ColorProvider forced_colors_provider_;
|
||||
|
||||
// This provider is used when forced color emulation is enabled, overriding
|
||||
// the light, dark or forced colors color providers.
|
||||
// TODO(samomekarajr): Remove this provider when we figure out how to change
|
||||
// the ForcedColors key from the renderer.
|
||||
ui::ColorProvider emulated_forced_colors_provider_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
@ -18,8 +18,8 @@ void WebThemeEngineMac::Paint(cc::PaintCanvas* canvas,
|
||||
const ui::ColorProvider* color_provider,
|
||||
const absl::optional<SkColor>& accent_color) {
|
||||
if (IsScrollbarPart(part)) {
|
||||
PaintMacScrollBarParts(canvas, color_provider, part, state, rect,
|
||||
extra_params, color_scheme);
|
||||
PaintMacScrollBarParts(canvas, GetColorProviderForPainting(color_scheme),
|
||||
part, state, rect, extra_params, color_scheme);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -668,17 +668,12 @@ void CompleteControlsForcedColorsDefinition(ui::ColorMixer& mixer) {
|
||||
}
|
||||
|
||||
bool IsRendererColorMappingEquivalent(
|
||||
const ColorProvider* color_provider,
|
||||
const ColorProvider& color_provider,
|
||||
const RendererColorMap& renderer_color_map) {
|
||||
if (!color_provider) {
|
||||
return false;
|
||||
}
|
||||
CHECK(!renderer_color_map.empty());
|
||||
|
||||
for (const auto& table : kRendererColorIdMap) {
|
||||
// The `renderer_color_map_` should map the full set of renderer color ids.
|
||||
DCHECK(base::Contains(renderer_color_map, table.renderer_color_id));
|
||||
if (color_provider->GetColor(table.color_id) !=
|
||||
if (color_provider.GetColor(table.color_id) !=
|
||||
renderer_color_map.at(table.renderer_color_id)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ void COMPONENT_EXPORT(COLOR)
|
||||
// Returns true if `color_provider` and `renderer_color_map` map renderer
|
||||
// color ids to the same SkColor.
|
||||
bool COMPONENT_EXPORT(COLOR) IsRendererColorMappingEquivalent(
|
||||
const ColorProvider* color_provider,
|
||||
const ColorProvider& color_provider,
|
||||
const RendererColorMap& renderer_color_map);
|
||||
|
||||
// Sets the callback for converting a ChromeColorId to a string name. This is
|
||||
|
@ -79,12 +79,12 @@ TEST_F(ColorProviderUtilsTest, ColorProviderRendererColorMapEquivalence) {
|
||||
ui::RendererColorMap renderer_color_map =
|
||||
ui::CreateRendererColorMap(color_provider);
|
||||
EXPECT_TRUE(
|
||||
IsRendererColorMappingEquivalent(&color_provider, renderer_color_map));
|
||||
IsRendererColorMappingEquivalent(color_provider, renderer_color_map));
|
||||
|
||||
// Providers with different renderer color mappings should not be flagged as
|
||||
// equivalent.
|
||||
ui::ColorProvider new_color_provider;
|
||||
new_color_provider.GenerateColorMap();
|
||||
EXPECT_FALSE(IsRendererColorMappingEquivalent(&new_color_provider,
|
||||
renderer_color_map));
|
||||
EXPECT_FALSE(
|
||||
IsRendererColorMappingEquivalent(new_color_provider, renderer_color_map));
|
||||
}
|
||||
|
Reference in New Issue
Block a user