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

Side by Side Diff: ash/common/wm/maximize_mode/maximize_mode_window_manager.cc

Issue 2736573002: chromeos: Move files in //ash/common to //ash, part 2 (Closed)
Patch Set: Created 3 years, 9 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
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/common/wm/maximize_mode/maximize_mode_window_manager.h"
6
7 #include "ash/common/ash_switches.h"
8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/wm/maximize_mode/maximize_mode_event_handler.h"
10 #include "ash/common/wm/maximize_mode/maximize_mode_window_state.h"
11 #include "ash/common/wm/maximize_mode/workspace_backdrop_delegate.h"
12 #include "ash/common/wm/mru_window_tracker.h"
13 #include "ash/common/wm/overview/window_selector_controller.h"
14 #include "ash/common/wm/window_state.h"
15 #include "ash/common/wm/wm_event.h"
16 #include "ash/common/wm/workspace_controller.h"
17 #include "ash/common/wm_shell.h"
18 #include "ash/common/wm_window.h"
19 #include "ash/public/cpp/shell_window_ids.h"
20 #include "ash/root_window_controller.h"
21 #include "ash/shell.h"
22 #include "ash/wm/window_state_aura.h"
23 #include "base/command_line.h"
24 #include "base/memory/ptr_util.h"
25 #include "base/stl_util.h"
26 #include "ui/aura/client/aura_constants.h"
27 #include "ui/display/screen.h"
28
29 namespace ash {
30
31 namespace {
32
33 // Exits overview mode if it is currently active.
34 void CancelOverview() {
35 WindowSelectorController* controller =
36 WmShell::Get()->window_selector_controller();
37 if (controller->IsSelecting())
38 controller->OnSelectionEnded();
39 }
40
41 } // namespace
42
43 MaximizeModeWindowManager::~MaximizeModeWindowManager() {
44 // Overview mode needs to be ended before exiting maximize mode to prevent
45 // transforming windows which are currently in
46 // overview: http://crbug.com/366605
47 CancelOverview();
48 for (aura::Window* window : added_windows_)
49 window->RemoveObserver(this);
50 added_windows_.clear();
51 WmShell::Get()->RemoveShellObserver(this);
52 display::Screen::GetScreen()->RemoveObserver(this);
53 EnableBackdropBehindTopWindowOnEachDisplay(false);
54 RemoveWindowCreationObservers();
55 RestoreAllWindows();
56 }
57
58 int MaximizeModeWindowManager::GetNumberOfManagedWindows() {
59 return window_state_map_.size();
60 }
61
62 void MaximizeModeWindowManager::AddWindow(WmWindow* window) {
63 // Only add the window if it is a direct dependent of a container window
64 // and not yet tracked.
65 if (!ShouldHandleWindow(window) ||
66 base::ContainsKey(window_state_map_, window) ||
67 !IsContainerWindow(window->GetParent()->aura_window())) {
68 return;
69 }
70
71 MaximizeAndTrackWindow(window);
72 }
73
74 void MaximizeModeWindowManager::WindowStateDestroyed(WmWindow* window) {
75 // At this time ForgetWindow() should already have been called. If not,
76 // someone else must have replaced the "window manager's state object".
77 DCHECK(!window->aura_window()->HasObserver(this));
78
79 auto it = window_state_map_.find(window);
80 DCHECK(it != window_state_map_.end());
81 window_state_map_.erase(it);
82 }
83
84 void MaximizeModeWindowManager::OnOverviewModeStarting() {
85 if (backdrops_hidden_)
86 return;
87
88 EnableBackdropBehindTopWindowOnEachDisplay(false);
89 SetDeferBoundsUpdates(true);
90 backdrops_hidden_ = true;
91 }
92
93 void MaximizeModeWindowManager::OnOverviewModeEnded() {
94 if (!backdrops_hidden_)
95 return;
96
97 backdrops_hidden_ = false;
98 EnableBackdropBehindTopWindowOnEachDisplay(true);
99 SetDeferBoundsUpdates(false);
100 }
101
102 void MaximizeModeWindowManager::OnWindowDestroying(aura::Window* window) {
103 if (IsContainerWindow(window)) {
104 // container window can be removed on display destruction.
105 window->RemoveObserver(this);
106 observed_container_windows_.erase(window);
107 } else if (base::ContainsValue(added_windows_, window)) {
108 // Added window was destroyed before being shown.
109 added_windows_.erase(window);
110 window->RemoveObserver(this);
111 } else {
112 // If a known window gets destroyed we need to remove all knowledge about
113 // it.
114 ForgetWindow(WmWindow::Get(window));
115 }
116 }
117
118 void MaximizeModeWindowManager::OnWindowHierarchyChanged(
119 const HierarchyChangeParams& params) {
120 // A window can get removed and then re-added by a drag and drop operation.
121 if (params.new_parent && IsContainerWindow(params.new_parent) &&
122 !base::ContainsKey(window_state_map_, WmWindow::Get(params.target))) {
123 // Don't register the window if the window is invisible. Instead,
124 // wait until it becomes visible because the client may update the
125 // flag to control if the window should be added.
126 if (!params.target->IsVisible()) {
127 if (!base::ContainsValue(added_windows_, params.target)) {
128 added_windows_.insert(params.target);
129 params.target->AddObserver(this);
130 }
131 return;
132 }
133 MaximizeAndTrackWindow(WmWindow::Get(params.target));
134 // When the state got added, the "WM_EVENT_ADDED_TO_WORKSPACE" event got
135 // already sent and we have to notify our state again.
136 if (base::ContainsKey(window_state_map_, WmWindow::Get(params.target))) {
137 wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE);
138 wm::GetWindowState(params.target)->OnWMEvent(&event);
139 }
140 }
141 }
142
143 void MaximizeModeWindowManager::OnWindowPropertyChanged(aura::Window* window,
144 const void* key,
145 intptr_t old) {
146 // Stop managing |window| if the always-on-top property is added.
147 if (key == aura::client::kAlwaysOnTopKey &&
148 window->GetProperty(aura::client::kAlwaysOnTopKey)) {
149 ForgetWindow(WmWindow::Get(window));
150 }
151 }
152
153 void MaximizeModeWindowManager::OnWindowBoundsChanged(
154 aura::Window* window,
155 const gfx::Rect& old_bounds,
156 const gfx::Rect& new_bounds) {
157 if (!IsContainerWindow(window))
158 return;
159 // Reposition all non maximizeable windows.
160 for (auto& pair : window_state_map_)
161 pair.second->UpdateWindowPosition(pair.first->GetWindowState());
162 }
163
164 void MaximizeModeWindowManager::OnWindowVisibilityChanged(aura::Window* window,
165 bool visible) {
166 // Skip if it's already managed.
167 if (base::ContainsKey(window_state_map_, WmWindow::Get(window)))
168 return;
169
170 if (IsContainerWindow(window->parent()) &&
171 base::ContainsValue(added_windows_, window) && visible) {
172 added_windows_.erase(window);
173 window->RemoveObserver(this);
174 MaximizeAndTrackWindow(WmWindow::Get(window));
175 // When the state got added, the "WM_EVENT_ADDED_TO_WORKSPACE" event got
176 // already sent and we have to notify our state again.
177 if (base::ContainsKey(window_state_map_, WmWindow::Get(window))) {
178 wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE);
179 wm::GetWindowState(window)->OnWMEvent(&event);
180 }
181 }
182 }
183
184 void MaximizeModeWindowManager::OnDisplayAdded(
185 const display::Display& display) {
186 DisplayConfigurationChanged();
187 }
188
189 void MaximizeModeWindowManager::OnDisplayRemoved(
190 const display::Display& display) {
191 DisplayConfigurationChanged();
192 }
193
194 void MaximizeModeWindowManager::OnDisplayMetricsChanged(const display::Display&,
195 uint32_t) {
196 // Nothing to do here.
197 }
198
199 MaximizeModeWindowManager::MaximizeModeWindowManager()
200 : backdrops_hidden_(false) {
201 // The overview mode needs to be ended before the maximize mode is started. To
202 // guarantee the proper order, it will be turned off from here.
203 CancelOverview();
204
205 MaximizeAllWindows();
206 AddWindowCreationObservers();
207 EnableBackdropBehindTopWindowOnEachDisplay(true);
208 display::Screen::GetScreen()->AddObserver(this);
209 WmShell::Get()->AddShellObserver(this);
210 event_handler_ = WmShell::Get()->CreateMaximizeModeEventHandler();
211 }
212
213 void MaximizeModeWindowManager::MaximizeAllWindows() {
214 MruWindowTracker::WindowList windows =
215 WmShell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
216 // Add all existing Mru windows.
217 for (WmWindow* window : windows)
218 MaximizeAndTrackWindow(window);
219 }
220
221 void MaximizeModeWindowManager::RestoreAllWindows() {
222 while (window_state_map_.size())
223 ForgetWindow(window_state_map_.begin()->first);
224 }
225
226 void MaximizeModeWindowManager::SetDeferBoundsUpdates(
227 bool defer_bounds_updates) {
228 for (auto& pair : window_state_map_)
229 pair.second->SetDeferBoundsUpdates(defer_bounds_updates);
230 }
231
232 void MaximizeModeWindowManager::MaximizeAndTrackWindow(WmWindow* window) {
233 if (!ShouldHandleWindow(window))
234 return;
235
236 DCHECK(!base::ContainsKey(window_state_map_, window));
237 window->aura_window()->AddObserver(this);
238
239 // We create and remember a maximize mode state which will attach itself to
240 // the provided state object.
241 window_state_map_[window] = new MaximizeModeWindowState(window, this);
242 }
243
244 void MaximizeModeWindowManager::ForgetWindow(WmWindow* window) {
245 WindowToState::iterator it = window_state_map_.find(window);
246
247 // The following DCHECK could fail if our window state object was destroyed
248 // earlier by someone else. However - at this point there is no other client
249 // which replaces the state object and therefore this should not happen.
250 DCHECK(it != window_state_map_.end());
251 window->aura_window()->RemoveObserver(this);
252
253 // By telling the state object to revert, it will switch back the old
254 // State object and destroy itself, calling WindowStateDestroyed().
255 it->second->LeaveMaximizeMode(it->first->GetWindowState());
256 DCHECK(!base::ContainsKey(window_state_map_, window));
257 }
258
259 bool MaximizeModeWindowManager::ShouldHandleWindow(WmWindow* window) {
260 DCHECK(window);
261
262 // Windows with the always-on-top property should be free-floating and thus
263 // not managed by us.
264 if (window->IsAlwaysOnTop())
265 return false;
266
267 // Windows in the dock should not be managed by us.
268 if (window->GetWindowState()->IsDocked())
269 return false;
270
271 // If the changing bounds in the maximized/fullscreen is allowed, then
272 // let the client manage it even in maximized mode.
273 if (window->GetWindowState()->allow_set_bounds_in_maximized())
274 return false;
275
276 return window->GetType() == ui::wm::WINDOW_TYPE_NORMAL;
277 }
278
279 void MaximizeModeWindowManager::AddWindowCreationObservers() {
280 DCHECK(observed_container_windows_.empty());
281 // Observe window activations/creations in the default containers on all root
282 // windows.
283 for (aura::Window* root : Shell::GetInstance()->GetAllRootWindows()) {
284 aura::Window* default_container =
285 root->GetChildById(kShellWindowId_DefaultContainer);
286 DCHECK(!base::ContainsKey(observed_container_windows_, default_container));
287 default_container->AddObserver(this);
288 observed_container_windows_.insert(default_container);
289 }
290 }
291
292 void MaximizeModeWindowManager::RemoveWindowCreationObservers() {
293 for (aura::Window* window : observed_container_windows_)
294 window->RemoveObserver(this);
295 observed_container_windows_.clear();
296 }
297
298 void MaximizeModeWindowManager::DisplayConfigurationChanged() {
299 EnableBackdropBehindTopWindowOnEachDisplay(false);
300 RemoveWindowCreationObservers();
301 AddWindowCreationObservers();
302 EnableBackdropBehindTopWindowOnEachDisplay(true);
303 }
304
305 bool MaximizeModeWindowManager::IsContainerWindow(aura::Window* window) {
306 return base::ContainsKey(observed_container_windows_, window);
307 }
308
309 void MaximizeModeWindowManager::EnableBackdropBehindTopWindowOnEachDisplay(
310 bool enable) {
311 // This function should be a no-op if backdrops have been disabled.
312 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
313 switches::kAshDisableMaximizeModeWindowBackdrop)) {
314 return;
315 }
316
317 if (backdrops_hidden_)
318 return;
319
320 // Inform the WorkspaceLayoutManager that we want to show a backdrop behind
321 // the topmost window of its container.
322 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) {
323 RootWindowController* controller = root->GetRootWindowController();
324 WmWindow* default_container =
325 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer);
326 controller->workspace_controller()->SetMaximizeBackdropDelegate(
327 enable ? base::MakeUnique<WorkspaceBackdropDelegate>(default_container)
328 : nullptr);
329 }
330 }
331
332 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/maximize_mode/maximize_mode_window_manager.h ('k') | ash/common/wm/maximize_mode/maximize_mode_window_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698