#include "ash/wm/wm_shadow_controller_delegate.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_session.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/window_state.h"
#include "chromeos/ui/base/window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/base/class_property.h"
#include "ui/base/mojom/window_show_state.mojom.h"
#include "ui/color/color_provider_source_observer.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/shadow_types.h"
namespace {
class ShadowColorizer : public ui::ColorProviderSourceObserver {
public:
ShadowColorizer(aura::Window* window,
ui::ColorProviderSource* color_provider_source)
: window_(window) {
Observe(color_provider_source);
}
ShadowColorizer(const ShadowColorizer&) = delete;
ShadowColorizer& operator=(const ShadowColorizer&) = delete;
~ShadowColorizer() override = default;
void OnColorProviderChanged() override {
if (auto* color_provider_source = GetColorProviderSource()) {
const auto* color_provider = color_provider_source->GetColorProvider();
auto* shadow = wm::ShadowController::GetShadowForWindow(window_.get());
shadow->SetElevationToColorsMap(
wm::ShadowController::GenerateShadowColorsMap(color_provider));
}
}
private:
const raw_ptr<aura::Window> window_;
};
}
DEFINE_UI_CLASS_PROPERTY_TYPE(ShadowColorizer*)
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(ShadowColorizer, kShadowColorizerKey)
namespace ash {
WmShadowControllerDelegate::WmShadowControllerDelegate() = default;
WmShadowControllerDelegate::~WmShadowControllerDelegate() = default;
bool WmShadowControllerDelegate::ShouldObserveWindow(
const aura::Window* window) {
return ((window->delegate() ||
window->GetType() != aura::client::WINDOW_TYPE_UNKNOWN) &&
window->GetType() != aura::client::WINDOW_TYPE_CONTROL);
}
bool WmShadowControllerDelegate::ShouldShowShadowForWindow(
const aura::Window* window) {
if (window->GetRootWindow() && RootWindowController::ForWindow(window)) {
SplitViewController* split_view_controller =
SplitViewController::Get(window);
if (split_view_controller &&
split_view_controller->IsWindowInSplitView(window)) {
return false;
}
}
OverviewController* overview_controller = Shell::Get()->overview_controller();
if (overview_controller && overview_controller->InOverviewSession()) {
OverviewSession* overview_session = overview_controller->overview_session();
DCHECK(overview_session);
auto* overview_item = overview_session->GetOverviewItemForWindow(window);
if (overview_item && !overview_item->is_moving_to_another_desk()) {
return false;
}
}
if (!window->parent())
return false;
auto* window_state = WindowState::Get(window);
if (window_state && window_state->is_dragged())
return ::wm::GetShadowElevationConvertDefault(window) > 0;
ui::mojom::WindowShowState show_state =
window->GetProperty(aura::client::kShowStateKey);
if (show_state == ui::mojom::WindowShowState::kFullscreen ||
show_state == ui::mojom::WindowShowState::kMaximized) {
return false;
}
return ::wm::GetShadowElevationConvertDefault(window) > 0;
}
bool WmShadowControllerDelegate::ShouldUpdateShadowOnWindowPropertyChange(
const aura::Window* window,
const void* key,
intptr_t old) {
return (key == chromeos::kWindowHasRoundedCornersKey &&
window->GetProperty(chromeos::kWindowHasRoundedCornersKey) != old);
}
void WmShadowControllerDelegate::ApplyColorThemeToWindowShadow(
aura::Window* window) {
if (auto* color_provider_source =
views::Widget::GetWidgetForNativeWindow(window)) {
window->SetProperty(
kShadowColorizerKey,
std::make_unique<ShadowColorizer>(window, color_provider_source));
}
}
bool WmShadowControllerDelegate::ShouldRoundShadowForWindow(
const aura::Window* window) {
auto* window_state = WindowState::Get(window);
return window_state ? window_state->ShouldWindowHaveRoundedCorners() : true;
}
}