1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
ash / wm / wm_shadow_controller_delegate.cc [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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 {
//------------------------------------------------------------------------------
// ShadowColorizer:
// Observes the given color provider source and updates the shadow colors with
// the colors map generated by the color provider.
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;
// ui::ColorProviderSourceObserver:
void OnColorProviderChanged() override {
// This function will also be called when color provider source is
// destroying. We should guarantee the observed color provider source
// exists.
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_;
};
} // namespace
DEFINE_UI_CLASS_PROPERTY_TYPE(ShadowColorizer*)
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(ShadowColorizer, kShadowColorizerKey)
namespace ash {
//------------------------------------------------------------------------------
// WmShadowControllerDelegate:
WmShadowControllerDelegate::WmShadowControllerDelegate() = default;
WmShadowControllerDelegate::~WmShadowControllerDelegate() = default;
bool WmShadowControllerDelegate::ShouldShowShadowForWindow(
const aura::Window* window) {
// Hide the shadow if it is one of the splitscreen snapped windows.
if (window->GetRootWindow() && RootWindowController::ForWindow(window)) {
SplitViewController* split_view_controller =
SplitViewController::Get(window);
if (split_view_controller &&
split_view_controller->IsWindowInSplitView(window)) {
return false;
}
}
// Hide the shadow while we are in overview mode.
OverviewController* overview_controller = Shell::Get()->overview_controller();
if (overview_controller && overview_controller->InOverviewSession()) {
OverviewSession* overview_session = overview_controller->overview_session();
// InOverviewSession() being true implies |overview_session| exists.
DCHECK(overview_session);
// Windows in overview that are not moving out of the active desk should not
// have shadows.
auto* overview_item = overview_session->GetOverviewItemForWindow(window);
if (overview_item && !overview_item->is_moving_to_another_desk()) {
return false;
}
}
// The shadow state will be updated when the window is added to a parent.
if (!window->parent())
return false;
// Show the shadow if it's currently being dragged no matter of the window's
// show state.
auto* window_state = WindowState::Get(window);
if (window_state && window_state->is_dragged())
return ::wm::GetShadowElevationConvertDefault(window) > 0;
// Hide the shadow if it's not being dragged and it's a maximized/fullscreen
// window.
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::kIsShowingInOverviewKey &&
window->GetProperty(chromeos::kIsShowingInOverviewKey) != old) ||
(key == chromeos::kWindowStateTypeKey &&
window->GetProperty(chromeos::kWindowStateTypeKey) !=
static_cast<chromeos::WindowStateType>(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));
}
}
} // namespace ash