Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: ash/wm/workspace/backdrop_controller.cc

Issue 2890733005: Refactor backdrop that is currently used in the maximized mode. (Closed)
Patch Set: fix memory issue in AshTouchExplorationManager Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/wm/workspace/backdrop_controller.h ('k') | ash/wm/workspace/backdrop_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/workspace/backdrop_controller.h"
6
7 #include "ash/accessibility_delegate.h"
8 #include "ash/public/cpp/shell_window_ids.h"
9 #include "ash/root_window_controller.h"
10 #include "ash/shared/app_types.h"
11 #include "ash/shell.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "ash/wm/window_util.h"
14 #include "ash/wm/workspace/backdrop_delegate.h"
15 #include "ash/wm_window.h"
16 #include "base/auto_reset.h"
17 #include "chromeos/audio/chromeos_sounds.h"
18 #include "ui/aura/client/aura_constants.h"
19 #include "ui/compositor/layer.h"
20 #include "ui/compositor/scoped_layer_animation_settings.h"
21 #include "ui/views/widget/widget.h"
22 #include "ui/wm/core/window_animations.h"
23 #include "ui/wm/core/window_util.h"
24
25 namespace ash {
26 namespace {
27
28 class BackdropEventHandler : public ui::EventHandler {
29 public:
30 BackdropEventHandler() = default;
31 ~BackdropEventHandler() override = default;
32
33 // ui::EventHandler:
34 void OnEvent(ui::Event* event) override {
35 // If the event is targeted at the backdrop, it means the user has made an
36 // interaction that is outside the window's bounds and we want to capture
37 // it (usually when in spoken feedback mode). Handle the event (to prevent
38 // behind-windows from receiving it) and play an earcon to notify the user.
39 if (event->IsLocatedEvent()) {
40 switch (event->type()) {
41 case ui::ET_MOUSE_PRESSED:
42 case ui::ET_MOUSEWHEEL:
43 case ui::ET_TOUCH_PRESSED:
44 case ui::ET_POINTER_DOWN:
45 case ui::ET_POINTER_WHEEL_CHANGED:
46 case ui::ET_GESTURE_BEGIN:
47 case ui::ET_SCROLL:
48 case ui::ET_SCROLL_FLING_START:
49 Shell::Get()->accessibility_delegate()->PlayEarcon(
50 chromeos::SOUND_VOLUME_ADJUST);
51 break;
52 default:
53 break;
54 }
55 event->SetHandled();
56 }
57 }
58
59 private:
60 DISALLOW_COPY_AND_ASSIGN(BackdropEventHandler);
61 };
62
63 } // namespace
64
65 BackdropController::BackdropController(aura::Window* container)
66 : container_(container), in_restacking_(false) {
67 DCHECK(container_);
68 Shell::Get()->AddShellObserver(this);
69 Shell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
70 }
71
72 BackdropController::~BackdropController() {
73 Shell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(this);
74 Shell::Get()->RemoveShellObserver(this);
75 // TODO: animations won't work right with mus: http://crbug.com/548396.
76 Hide();
77 }
78
79 void BackdropController::OnWindowAddedToLayout(aura::Window* child) {
80 UpdateBackdrop();
81 }
82
83 void BackdropController::OnWindowRemovedFromLayout(aura::Window* child) {
84 UpdateBackdrop();
85 }
86
87 void BackdropController::OnChildWindowVisibilityChanged(aura::Window* child,
88 bool visible) {
89 UpdateBackdrop();
90 }
91
92 void BackdropController::OnWindowStackingChanged(aura::Window* window) {
93 UpdateBackdrop();
94 }
95
96 void BackdropController::OnPostWindowStateTypeChange(
97 wm::WindowState* window_state,
98 wm::WindowStateType old_type) {
99 UpdateBackdrop();
100 }
101
102 void BackdropController::SetBackdropDelegate(
103 std::unique_ptr<BackdropDelegate> delegate) {
104 delegate_ = std::move(delegate);
105 UpdateBackdrop();
106 }
107
108 void BackdropController::UpdateBackdrop() {
109 // Avoid recursive calls.
110 if (in_restacking_ || force_hidden_)
111 return;
112
113 aura::Window* window = GetTopmostWindowWithBackdrop();
114 if (!window) {
115 // Hide backdrop since no suitable window was found.
116 Hide();
117 return;
118 }
119 // We are changing the order of windows which will cause recursion.
120 base::AutoReset<bool> lock(&in_restacking_, true);
121 EnsureBackdropWidget();
122 UpdateAccessibilityMode();
123
124 if (window == backdrop_window_ && backdrop_->IsVisible())
125 return;
126 if (window->GetRootWindow() != backdrop_window_->GetRootWindow())
127 return;
128
129 if (!backdrop_->IsVisible())
130 Show();
131
132 // Since the backdrop needs to be immediately behind the window and the
133 // stacking functions only guarantee a "it's above or below", we need
134 // to re-arrange the two windows twice.
135 container_->StackChildAbove(backdrop_window_, window);
136 container_->StackChildAbove(window, backdrop_window_);
137 }
138
139 void BackdropController::OnOverviewModeStarting() {
140 force_hidden_ = true;
141 Hide();
142 }
143
144 void BackdropController::OnOverviewModeEnded() {
145 force_hidden_ = false;
146 UpdateBackdrop();
147 }
148
149 void BackdropController::OnAccessibilityModeChanged(
150 AccessibilityNotificationVisibility notify) {
151 UpdateBackdrop();
152 }
153
154 void BackdropController::EnsureBackdropWidget() {
155 if (backdrop_)
156 return;
157
158 backdrop_ = new views::Widget;
159 views::Widget::InitParams params(
160 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
161 params.bounds = container_->GetBoundsInScreen();
162 params.layer_type = ui::LAYER_SOLID_COLOR;
163 params.name = "WorkspaceBackdropDelegate";
164 // To disallow the MRU list from picking this window up it should not be
165 // activateable.
166 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
167 DCHECK_NE(kShellWindowId_Invalid, container_->id());
168 RootWindowController::ForWindow(container_)
169 ->ConfigureWidgetInitParamsForContainer(backdrop_, container_->id(),
170 &params);
171 backdrop_->Init(params);
172 backdrop_window_ = backdrop_->GetNativeWindow();
173 backdrop_window_->SetName("Backdrop");
174 ::wm::SetWindowVisibilityAnimationType(
175 backdrop_window_, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
176 backdrop_window_->layer()->SetColor(SK_ColorBLACK);
177 }
178
179 void BackdropController::UpdateAccessibilityMode() {
180 if (!backdrop_)
181 return;
182
183 bool enabled =
184 Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
185 if (enabled) {
186 if (!backdrop_event_handler_) {
187 backdrop_event_handler_ = base::MakeUnique<BackdropEventHandler>();
188 original_event_handler_ =
189 backdrop_window_->SetTargetHandler(backdrop_event_handler_.get());
190 }
191 } else if (backdrop_event_handler_) {
192 backdrop_window_->SetTargetHandler(original_event_handler_);
193 backdrop_event_handler_.reset();
194 }
195 }
196
197 aura::Window* BackdropController::GetTopmostWindowWithBackdrop() {
198 // ARC app should always have a backdrop when spoken feedback is enabled.
199 if (Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled()) {
200 aura::Window* active_window = wm::GetActiveWindow();
201 if (active_window && active_window->parent() == container_ &&
202 active_window->GetProperty(aura::client::kAppType) ==
203 static_cast<int>(AppType::ARC_APP)) {
204 return active_window;
205 }
206 }
207
208 const aura::Window::Windows windows = container_->children();
209 for (auto window_iter = windows.rbegin(); window_iter != windows.rend();
210 ++window_iter) {
211 aura::Window* window = *window_iter;
212 if (window != backdrop_window_ && window->layer()->GetTargetVisibility() &&
213 window->type() == ui::wm::WINDOW_TYPE_NORMAL &&
214 ::wm::CanActivateWindow(window) && WindowShouldHaveBackdrop(window)) {
215 return window;
216 }
217 }
218 return nullptr;
219 }
220
221 bool BackdropController::WindowShouldHaveBackdrop(aura::Window* window) {
222 if (window->GetAllPropertyKeys().count(aura::client::kHasBackdrop) &&
223 window->GetProperty(aura::client::kHasBackdrop)) {
224 return true;
225 }
226 return delegate_ ? delegate_->HasBackdrop(window) : false;
227 }
228
229 void BackdropController::Show() {
230 backdrop_->Show();
231 backdrop_->SetFullscreen(true);
232 }
233
234 void BackdropController::Hide() {
235 if (!backdrop_)
236 return;
237 backdrop_->Close();
238 backdrop_ = nullptr;
239 backdrop_window_ = nullptr;
240 original_event_handler_ = nullptr;
241 backdrop_event_handler_.reset();
242 }
243
244 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/backdrop_controller.h ('k') | ash/wm/workspace/backdrop_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698