OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/root_window_controller.h" | 5 #include "ash/root_window_controller.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "ash/ash_touch_exploration_manager_chromeos.h" | 10 #include "ash/ash_touch_exploration_manager_chromeos.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "ash/common/shell_delegate.h" | 22 #include "ash/common/shell_delegate.h" |
23 #include "ash/common/system/status_area_layout_manager.h" | 23 #include "ash/common/system/status_area_layout_manager.h" |
24 #include "ash/common/system/status_area_widget.h" | 24 #include "ash/common/system/status_area_widget.h" |
25 #include "ash/common/system/tray/system_tray_delegate.h" | 25 #include "ash/common/system/tray/system_tray_delegate.h" |
26 #include "ash/common/wallpaper/wallpaper_delegate.h" | 26 #include "ash/common/wallpaper/wallpaper_delegate.h" |
27 #include "ash/common/wallpaper/wallpaper_widget_controller.h" | 27 #include "ash/common/wallpaper/wallpaper_widget_controller.h" |
28 #include "ash/common/wm/always_on_top_controller.h" | 28 #include "ash/common/wm/always_on_top_controller.h" |
29 #include "ash/common/wm/container_finder.h" | 29 #include "ash/common/wm/container_finder.h" |
30 #include "ash/common/wm/dock/docked_window_layout_manager.h" | 30 #include "ash/common/wm/dock/docked_window_layout_manager.h" |
31 #include "ash/common/wm/fullscreen_window_finder.h" | 31 #include "ash/common/wm/fullscreen_window_finder.h" |
32 #include "ash/common/wm/lock_layout_manager.h" | |
32 #include "ash/common/wm/panels/panel_layout_manager.h" | 33 #include "ash/common/wm/panels/panel_layout_manager.h" |
33 #include "ash/common/wm/root_window_layout_manager.h" | 34 #include "ash/common/wm/root_window_layout_manager.h" |
34 #include "ash/common/wm/switchable_windows.h" | 35 #include "ash/common/wm/switchable_windows.h" |
35 #include "ash/common/wm/system_modal_container_layout_manager.h" | 36 #include "ash/common/wm/system_modal_container_layout_manager.h" |
36 #include "ash/common/wm/window_state.h" | 37 #include "ash/common/wm/window_state.h" |
37 #include "ash/common/wm/workspace/workspace_layout_manager.h" | 38 #include "ash/common/wm/workspace/workspace_layout_manager.h" |
38 #include "ash/common/wm/workspace_controller.h" | 39 #include "ash/common/wm/workspace_controller.h" |
39 #include "ash/common/wm_root_window_controller.h" | |
40 #include "ash/common/wm_shell.h" | 40 #include "ash/common/wm_shell.h" |
41 #include "ash/common/wm_window.h" | 41 #include "ash/common/wm_window.h" |
42 #include "ash/high_contrast/high_contrast_controller.h" | 42 #include "ash/high_contrast/high_contrast_controller.h" |
43 #include "ash/host/ash_window_tree_host.h" | 43 #include "ash/host/ash_window_tree_host.h" |
44 #include "ash/public/cpp/shelf_types.h" | 44 #include "ash/public/cpp/shelf_types.h" |
45 #include "ash/public/cpp/shell_window_ids.h" | 45 #include "ash/public/cpp/shell_window_ids.h" |
46 #include "ash/root_window_settings.h" | 46 #include "ash/root_window_settings.h" |
47 #include "ash/shelf/shelf_window_targeter.h" | 47 #include "ash/shelf/shelf_window_targeter.h" |
48 #include "ash/shell.h" | 48 #include "ash/shell.h" |
49 #include "ash/touch/touch_hud_debug.h" | 49 #include "ash/touch/touch_hud_debug.h" |
50 #include "ash/touch/touch_hud_projection.h" | 50 #include "ash/touch/touch_hud_projection.h" |
51 #include "ash/touch/touch_observer_hud.h" | 51 #include "ash/touch/touch_observer_hud.h" |
52 #include "ash/wm/boot_splash_screen_chromeos.h" | 52 #include "ash/wm/boot_splash_screen_chromeos.h" |
53 #include "ash/wm/panels/attached_panel_window_targeter.h" | 53 #include "ash/wm/panels/attached_panel_window_targeter.h" |
54 #include "ash/wm/panels/panel_window_event_handler.h" | 54 #include "ash/wm/panels/panel_window_event_handler.h" |
55 #include "ash/wm/stacking_controller.h" | 55 #include "ash/wm/stacking_controller.h" |
56 #include "ash/wm/system_wallpaper_controller.h" | 56 #include "ash/wm/system_wallpaper_controller.h" |
57 #include "ash/wm/window_properties.h" | 57 #include "ash/wm/window_properties.h" |
58 #include "ash/wm/window_state_aura.h" | 58 #include "ash/wm/window_state_aura.h" |
59 #include "ash/wm/window_util.h" | 59 #include "ash/wm/window_util.h" |
60 #include "base/command_line.h" | 60 #include "base/command_line.h" |
61 #include "base/macros.h" | 61 #include "base/macros.h" |
62 #include "base/memory/ptr_util.h" | 62 #include "base/memory/ptr_util.h" |
63 #include "base/time/time.h" | 63 #include "base/time/time.h" |
64 #include "chromeos/chromeos_switches.h" | 64 #include "chromeos/chromeos_switches.h" |
65 #include "ui/aura/client/aura_constants.h" | 65 #include "ui/aura/client/aura_constants.h" |
66 #include "ui/aura/client/drag_drop_client.h" | 66 #include "ui/aura/client/drag_drop_client.h" |
67 #include "ui/aura/client/screen_position_client.h" | 67 #include "ui/aura/client/screen_position_client.h" |
68 #include "ui/aura/mus/window_mus.h" | |
69 #include "ui/aura/mus/window_tree_client.h" | |
68 #include "ui/aura/window.h" | 70 #include "ui/aura/window.h" |
69 #include "ui/aura/window_event_dispatcher.h" | 71 #include "ui/aura/window_event_dispatcher.h" |
70 #include "ui/aura/window_observer.h" | 72 #include "ui/aura/window_observer.h" |
71 #include "ui/aura/window_tracker.h" | 73 #include "ui/aura/window_tracker.h" |
74 #include "ui/base/models/menu_model.h" | |
72 #include "ui/chromeos/touch_exploration_controller.h" | 75 #include "ui/chromeos/touch_exploration_controller.h" |
73 #include "ui/display/types/display_constants.h" | 76 #include "ui/display/types/display_constants.h" |
77 #include "ui/events/event_utils.h" | |
74 #include "ui/keyboard/keyboard_controller.h" | 78 #include "ui/keyboard/keyboard_controller.h" |
75 #include "ui/keyboard/keyboard_util.h" | 79 #include "ui/keyboard/keyboard_util.h" |
80 #include "ui/views/controls/menu/menu_model_adapter.h" | |
81 #include "ui/views/controls/menu/menu_runner.h" | |
76 #include "ui/views/view_model.h" | 82 #include "ui/views/view_model.h" |
77 #include "ui/views/view_model_utils.h" | 83 #include "ui/views/view_model_utils.h" |
78 #include "ui/wm/core/capture_controller.h" | 84 #include "ui/wm/core/capture_controller.h" |
85 #include "ui/wm/core/coordinate_conversion.h" | |
79 #include "ui/wm/core/visibility_controller.h" | 86 #include "ui/wm/core/visibility_controller.h" |
80 #include "ui/wm/core/window_util.h" | 87 #include "ui/wm/core/window_util.h" |
81 #include "ui/wm/public/tooltip_client.h" | 88 #include "ui/wm/public/tooltip_client.h" |
82 #include "ui/wm/public/window_types.h" | 89 #include "ui/wm/public/window_types.h" |
83 | 90 |
84 namespace ash { | 91 namespace ash { |
85 namespace { | 92 namespace { |
86 | 93 |
87 // Duration for the animation that hides the boot splash screen, in | 94 // Duration for the animation that hides the boot splash screen, in |
88 // milliseconds. This should be short enough in relation to | 95 // milliseconds. This should be short enough in relation to |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 aura::Window::Windows windows = common_parent->children(); | 137 aura::Window::Windows windows = common_parent->children(); |
131 auto blocking_iter = std::find(windows.begin(), windows.end(), blocking); | 138 auto blocking_iter = std::find(windows.begin(), windows.end(), blocking); |
132 // If the target window is above blocking window, the window can handle | 139 // If the target window is above blocking window, the window can handle |
133 // events. | 140 // events. |
134 return std::find(blocking_iter, windows.end(), target) != windows.end(); | 141 return std::find(blocking_iter, windows.end(), target) != windows.end(); |
135 } | 142 } |
136 | 143 |
137 return true; | 144 return true; |
138 } | 145 } |
139 | 146 |
147 // Creates a new window for use as a container. | |
148 // TODO(sky): This should create an aura::Window. http://crbug.com/671246. | |
149 WmWindow* CreateContainer(int window_id, const char* name, WmWindow* parent) { | |
150 WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN, | |
151 ui::LAYER_NOT_DRAWN); | |
152 window->SetShellWindowId(window_id); | |
153 window->SetName(name); | |
154 parent->AddChild(window); | |
155 if (window_id != kShellWindowId_UnparentedControlContainer) | |
156 window->Show(); | |
157 return window; | |
158 } | |
159 | |
160 // Scales |value| that is originally between 0 and |src_max| to be between | |
161 // 0 and |dst_max|. | |
162 float ToRelativeValue(int value, int src_max, int dst_max) { | |
163 return static_cast<float>(value) / static_cast<float>(src_max) * dst_max; | |
164 } | |
165 | |
166 // Uses ToRelativeValue() to scale the origin of |bounds_in_out|. The | |
167 // width/height are not changed. | |
168 void MoveOriginRelativeToSize(const gfx::Size& src_size, | |
169 const gfx::Size& dst_size, | |
170 gfx::Rect* bounds_in_out) { | |
171 gfx::Point origin = bounds_in_out->origin(); | |
172 bounds_in_out->set_origin(gfx::Point( | |
173 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()), | |
174 ToRelativeValue(origin.y(), src_size.height(), dst_size.height()))); | |
175 } | |
176 | |
177 // Reparents |window| to |new_parent|. | |
178 // TODO(sky): This should take an aura::Window. http://crbug.com/671246. | |
179 void ReparentWindow(WmWindow* window, WmWindow* new_parent) { | |
180 const gfx::Size src_size = window->GetParent()->GetBounds().size(); | |
181 const gfx::Size dst_size = new_parent->GetBounds().size(); | |
182 // Update the restore bounds to make it relative to the display. | |
183 wm::WindowState* state = window->GetWindowState(); | |
184 gfx::Rect restore_bounds; | |
185 bool has_restore_bounds = state->HasRestoreBounds(); | |
186 | |
187 bool update_bounds = | |
188 (state->IsNormalOrSnapped() || state->IsMinimized()) && | |
189 new_parent->GetShellWindowId() != kShellWindowId_DockedContainer; | |
190 gfx::Rect local_bounds; | |
191 if (update_bounds) { | |
192 local_bounds = state->window()->GetBounds(); | |
193 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds); | |
194 } | |
195 | |
196 if (has_restore_bounds) { | |
197 restore_bounds = state->GetRestoreBoundsInParent(); | |
198 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds); | |
199 } | |
200 | |
201 new_parent->AddChild(window); | |
202 | |
203 // Docked windows have bounds handled by the layout manager in AddChild(). | |
204 if (update_bounds) | |
205 window->SetBounds(local_bounds); | |
206 | |
207 if (has_restore_bounds) | |
208 state->SetRestoreBoundsInParent(restore_bounds); | |
209 } | |
210 | |
211 // Reparents the appropriate set of windows from |src| to |dst|. | |
212 // TODO(sky): This should take an aura::Window. http://crbug.com/671246. | |
213 void ReparentAllWindows(WmWindow* src, WmWindow* dst) { | |
214 // Set of windows to move. | |
215 const int kContainerIdsToMove[] = { | |
216 kShellWindowId_DefaultContainer, | |
217 kShellWindowId_DockedContainer, | |
218 kShellWindowId_PanelContainer, | |
219 kShellWindowId_AlwaysOnTopContainer, | |
220 kShellWindowId_SystemModalContainer, | |
221 kShellWindowId_LockSystemModalContainer, | |
222 kShellWindowId_UnparentedControlContainer, | |
223 kShellWindowId_OverlayContainer, | |
224 }; | |
225 const int kExtraContainerIdsToMoveInUnifiedMode[] = { | |
226 kShellWindowId_LockScreenContainer, | |
227 kShellWindowId_LockScreenWallpaperContainer, | |
228 }; | |
229 std::vector<int> container_ids( | |
230 kContainerIdsToMove, | |
231 kContainerIdsToMove + arraysize(kContainerIdsToMove)); | |
232 // Check the display mode as this is also necessary when trasitioning between | |
233 // mirror and unified mode. | |
234 if (WmShell::Get()->IsInUnifiedModeIgnoreMirroring()) { | |
235 for (int id : kExtraContainerIdsToMoveInUnifiedMode) | |
236 container_ids.push_back(id); | |
237 } | |
238 | |
239 for (int id : container_ids) { | |
240 WmWindow* src_container = src->GetChildByShellWindowId(id); | |
241 WmWindow* dst_container = dst->GetChildByShellWindowId(id); | |
242 while (!src_container->GetChildren().empty()) { | |
243 // Restart iteration from the source container windows each time as they | |
244 // may change as a result of moving other windows. | |
245 WmWindow::Windows src_container_children = src_container->GetChildren(); | |
246 WmWindow::Windows::const_iterator iter = src_container_children.begin(); | |
247 while (iter != src_container_children.end() && | |
248 SystemModalContainerLayoutManager::IsModalBackground(*iter)) { | |
249 ++iter; | |
250 } | |
251 // If the entire window list is modal background windows then stop. | |
252 if (iter == src_container_children.end()) | |
253 break; | |
254 ReparentWindow(*iter, dst_container); | |
255 } | |
256 } | |
257 } | |
258 | |
259 // TODO(sky): This should take an aura::Window. http://crbug.com/671246. | |
260 bool ShouldDestroyWindowInCloseChildWindows(WmWindow* window) { | |
261 if (!WmWindowAura::GetAuraWindow(window)->owned_by_parent()) | |
262 return false; | |
263 | |
264 if (!WmShell::Get()->IsRunningInMash()) | |
265 return true; | |
266 | |
267 aura::WindowMus* window_mus = | |
268 aura::WindowMus::Get(WmWindowAura::GetAuraWindow(window)); | |
269 return Shell::window_tree_client()->WasCreatedByThisClient(window_mus) || | |
270 Shell::window_tree_client()->IsRoot(window_mus); | |
271 } | |
272 | |
140 } // namespace | 273 } // namespace |
141 | 274 |
142 RootWindowController::~RootWindowController() { | 275 RootWindowController::~RootWindowController() { |
143 Shutdown(); | 276 Shutdown(); |
144 ash_host_.reset(); | 277 ash_host_.reset(); |
145 owned_window_tree_host_.reset(); | 278 owned_window_tree_host_.reset(); |
146 // The CaptureClient needs to be around for as long as the RootWindow is | 279 // The CaptureClient needs to be around for as long as the RootWindow is |
147 // valid. | 280 // valid. |
148 capture_client_.reset(); | 281 capture_client_.reset(); |
282 if (animating_wallpaper_widget_controller_.get()) | |
283 animating_wallpaper_widget_controller_->StopAnimating(); | |
149 } | 284 } |
150 | 285 |
151 void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) { | 286 void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) { |
152 RootWindowController* controller = new RootWindowController(host, nullptr); | 287 RootWindowController* controller = new RootWindowController(host, nullptr); |
153 controller->Init(RootWindowType::PRIMARY); | 288 controller->Init(RootWindowType::PRIMARY); |
154 } | 289 } |
155 | 290 |
156 void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) { | 291 void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) { |
157 RootWindowController* controller = new RootWindowController(host, nullptr); | 292 RootWindowController* controller = new RootWindowController(host, nullptr); |
158 controller->Init(RootWindowType::SECONDARY); | 293 controller->Init(RootWindowType::SECONDARY); |
159 } | 294 } |
160 | 295 |
161 // static | 296 // static |
162 RootWindowController* RootWindowController::ForWindow( | 297 RootWindowController* RootWindowController::ForWindow( |
163 const aura::Window* window) { | 298 const aura::Window* window) { |
164 DCHECK(window); | 299 DCHECK(window); |
165 CHECK(Shell::HasInstance()); | 300 CHECK(Shell::HasInstance()); |
166 return GetRootWindowController(window->GetRootWindow()); | 301 return GetRootWindowController(window->GetRootWindow()); |
167 } | 302 } |
168 | 303 |
169 // static | 304 // static |
170 RootWindowController* RootWindowController::ForTargetRootWindow() { | 305 RootWindowController* RootWindowController::ForTargetRootWindow() { |
171 CHECK(Shell::HasInstance()); | 306 CHECK(Shell::HasInstance()); |
172 return GetRootWindowController(Shell::GetTargetRootWindow()); | 307 return GetRootWindowController(Shell::GetTargetRootWindow()); |
173 } | 308 } |
174 | 309 |
310 void RootWindowController::ConfigureWidgetInitParamsForContainer( | |
311 views::Widget* widget, | |
312 int shell_container_id, | |
313 views::Widget::InitParams* init_params) { | |
314 init_params->parent = GetContainer(shell_container_id); | |
315 } | |
316 | |
175 aura::WindowTreeHost* RootWindowController::GetHost() { | 317 aura::WindowTreeHost* RootWindowController::GetHost() { |
176 return window_tree_host_; | 318 return window_tree_host_; |
177 } | 319 } |
178 | 320 |
179 const aura::WindowTreeHost* RootWindowController::GetHost() const { | 321 const aura::WindowTreeHost* RootWindowController::GetHost() const { |
180 return window_tree_host_; | 322 return window_tree_host_; |
181 } | 323 } |
182 | 324 |
183 aura::Window* RootWindowController::GetRootWindow() { | 325 aura::Window* RootWindowController::GetRootWindow() { |
184 return GetHost()->window(); | 326 return GetHost()->window(); |
185 } | 327 } |
186 | 328 |
187 const aura::Window* RootWindowController::GetRootWindow() const { | 329 const aura::Window* RootWindowController::GetRootWindow() const { |
188 return GetHost()->window(); | 330 return GetHost()->window(); |
189 } | 331 } |
190 | 332 |
191 WorkspaceController* RootWindowController::workspace_controller() { | 333 const WmWindow* RootWindowController::GetWindow() const { |
192 return wm_root_window_controller_->workspace_controller(); | 334 return WmWindowAura::Get(GetRootWindow()); |
335 } | |
336 | |
337 wm::WorkspaceWindowState RootWindowController::GetWorkspaceWindowState() { | |
338 return workspace_controller_ ? workspace_controller()->GetWindowState() | |
339 : wm::WORKSPACE_WINDOW_STATE_DEFAULT; | |
340 } | |
341 | |
342 bool RootWindowController::HasShelf() { | |
343 return wm_shelf_->shelf_widget() != nullptr; | |
344 } | |
345 | |
346 WmShelf* RootWindowController::GetShelf() { | |
347 return wm_shelf_.get(); | |
348 } | |
349 | |
350 void RootWindowController::CreateShelf() { | |
351 if (wm_shelf_->IsShelfInitialized()) | |
352 return; | |
353 wm_shelf_->InitializeShelf(); | |
354 | |
355 if (panel_layout_manager_) | |
356 panel_layout_manager_->SetShelf(wm_shelf_.get()); | |
357 if (docked_window_layout_manager_) { | |
358 docked_window_layout_manager_->SetShelf(wm_shelf_.get()); | |
359 if (wm_shelf_->shelf_layout_manager()) | |
360 docked_window_layout_manager_->AddObserver( | |
361 wm_shelf_->shelf_layout_manager()); | |
362 } | |
363 | |
364 // Notify shell observers that the shelf has been created. | |
365 // TODO(jamescook): Move this into WmShelf::InitializeShelf(). This will | |
366 // require changing AttachedPanelWidgetTargeter's access to WmShelf. | |
367 WmShell::Get()->NotifyShelfCreatedForRootWindow( | |
368 WmWindowAura::Get(GetRootWindow())); | |
369 | |
370 wm_shelf_->shelf_widget()->PostCreateShelf(); | |
371 } | |
372 | |
373 void RootWindowController::ShowShelf() { | |
374 if (!wm_shelf_->IsShelfInitialized()) | |
375 return; | |
376 // TODO(jamescook): Move this into WmShelf. | |
377 wm_shelf_->shelf_widget()->SetShelfVisibility(true); | |
378 wm_shelf_->shelf_widget()->status_area_widget()->Show(); | |
193 } | 379 } |
194 | 380 |
195 void RootWindowController::Shutdown() { | 381 void RootWindowController::Shutdown() { |
196 WmShell::Get()->RemoveShellObserver(this); | 382 WmShell::Get()->RemoveShellObserver(this); |
197 | 383 |
198 touch_exploration_manager_.reset(); | 384 touch_exploration_manager_.reset(); |
199 | 385 |
200 wm_root_window_controller_->ResetRootForNewWindowsIfNecessary(); | 386 ResetRootForNewWindowsIfNecessary(); |
201 | 387 |
202 CloseChildWindows(); | 388 CloseChildWindows(); |
203 aura::Window* root_window = GetRootWindow(); | 389 aura::Window* root_window = GetRootWindow(); |
204 GetRootWindowSettings(root_window)->controller = NULL; | 390 GetRootWindowSettings(root_window)->controller = NULL; |
205 // Forget with the display ID so that display lookup | 391 // Forget with the display ID so that display lookup |
206 // ends up with invalid display. | 392 // ends up with invalid display. |
207 GetRootWindowSettings(root_window)->display_id = display::kInvalidDisplayId; | 393 GetRootWindowSettings(root_window)->display_id = display::kInvalidDisplayId; |
208 if (ash_host_) | 394 if (ash_host_) |
209 ash_host_->PrepareForShutdown(); | 395 ash_host_->PrepareForShutdown(); |
210 | 396 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 | 436 |
251 // If the window is in the target modal container, only allow the top most | 437 // If the window is in the target modal container, only allow the top most |
252 // one. | 438 // one. |
253 if (modal_container && modal_container->Contains(window)) | 439 if (modal_container && modal_container->Contains(window)) |
254 return modal_layout_manager->IsPartOfActiveModalWindow( | 440 return modal_layout_manager->IsPartOfActiveModalWindow( |
255 WmWindowAura::Get(window)); | 441 WmWindowAura::Get(window)); |
256 | 442 |
257 return true; | 443 return true; |
258 } | 444 } |
259 | 445 |
446 WmWindow* RootWindowController::FindEventTarget( | |
447 const gfx::Point& location_in_screen) { | |
448 gfx::Point location_in_root(location_in_screen); | |
449 ::wm::ConvertPointFromScreen(GetRootWindow(), &location_in_root); | |
450 ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root, | |
451 location_in_root, ui::EventTimeForNow(), | |
452 ui::EF_NONE, ui::EF_NONE); | |
453 ui::EventTarget* event_handler = | |
454 static_cast<ui::EventTarget*>(GetRootWindow()) | |
455 ->GetEventTargeter() | |
456 ->FindTargetForEvent(GetRootWindow(), &test_event); | |
457 return WmWindowAura::Get(static_cast<aura::Window*>(event_handler)); | |
458 } | |
459 | |
460 gfx::Point RootWindowController::GetLastMouseLocationInRoot() { | |
461 return window_tree_host_->dispatcher()->GetLastMouseLocationInRoot(); | |
462 } | |
463 | |
260 aura::Window* RootWindowController::GetContainer(int container_id) { | 464 aura::Window* RootWindowController::GetContainer(int container_id) { |
261 return GetRootWindow()->GetChildById(container_id); | 465 return GetRootWindow()->GetChildById(container_id); |
262 } | 466 } |
263 | 467 |
264 const aura::Window* RootWindowController::GetContainer(int container_id) const { | 468 const aura::Window* RootWindowController::GetContainer(int container_id) const { |
265 return window_tree_host_->window()->GetChildById(container_id); | 469 return window_tree_host_->window()->GetChildById(container_id); |
266 } | 470 } |
267 | 471 |
472 const WmWindow* RootWindowController::GetWmContainer(int container_id) const { | |
473 const aura::Window* window = GetContainer(container_id); | |
474 return WmWindowAura::Get(window); | |
475 } | |
476 | |
477 void RootWindowController::SetWallpaperWidgetController( | |
478 WallpaperWidgetController* controller) { | |
479 wallpaper_widget_controller_.reset(controller); | |
480 } | |
481 | |
482 void RootWindowController::SetAnimatingWallpaperWidgetController( | |
483 AnimatingWallpaperWidgetController* controller) { | |
484 if (animating_wallpaper_widget_controller_.get()) | |
485 animating_wallpaper_widget_controller_->StopAnimating(); | |
486 animating_wallpaper_widget_controller_.reset(controller); | |
487 } | |
488 | |
268 void RootWindowController::OnInitialWallpaperAnimationStarted() { | 489 void RootWindowController::OnInitialWallpaperAnimationStarted() { |
269 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 490 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
270 switches::kAshAnimateFromBootSplashScreen) && | 491 switches::kAshAnimateFromBootSplashScreen) && |
271 boot_splash_screen_.get()) { | 492 boot_splash_screen_.get()) { |
272 // Make the splash screen fade out so it doesn't obscure the wallpaper's | 493 // Make the splash screen fade out so it doesn't obscure the wallpaper's |
273 // brightness/grayscale animation. | 494 // brightness/grayscale animation. |
274 boot_splash_screen_->StartHideAnimation( | 495 boot_splash_screen_->StartHideAnimation( |
275 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs)); | 496 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs)); |
276 } | 497 } |
277 } | 498 } |
278 | 499 |
279 void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) { | 500 void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) { |
280 // Make sure the wallpaper is visible. | 501 // Make sure the wallpaper is visible. |
281 system_wallpaper_->SetColor(SK_ColorBLACK); | 502 system_wallpaper_->SetColor(SK_ColorBLACK); |
282 boot_splash_screen_.reset(); | 503 boot_splash_screen_.reset(); |
504 WmShell::Get()->wallpaper_delegate()->OnWallpaperAnimationFinished(); | |
505 // Only removes old component when wallpaper animation finished. If we | |
506 // remove the old one before the new wallpaper is done fading in there will | |
507 // be a white flash during the animation. | |
508 if (animating_wallpaper_widget_controller()) { | |
509 WallpaperWidgetController* controller = | |
510 animating_wallpaper_widget_controller()->GetController(true); | |
511 DCHECK_EQ(controller->widget(), widget); | |
512 // Release the old controller and close its wallpaper widget. | |
513 SetWallpaperWidgetController(controller); | |
514 } | |
283 } | 515 } |
284 | 516 |
285 void RootWindowController::CloseChildWindows() { | 517 void RootWindowController::CloseChildWindows() { |
286 // Remove observer as deactivating keyboard causes | 518 // Remove observer as deactivating keyboard causes |
287 // docked_window_layout_manager() to fire notifications. | 519 // docked_window_layout_manager() to fire notifications. |
288 if (docked_window_layout_manager() && wm_shelf_->shelf_layout_manager()) { | 520 if (docked_window_layout_manager() && wm_shelf_->shelf_layout_manager()) { |
289 docked_window_layout_manager()->RemoveObserver( | 521 docked_window_layout_manager()->RemoveObserver( |
290 wm_shelf_->shelf_layout_manager()); | 522 wm_shelf_->shelf_layout_manager()); |
291 } | 523 } |
292 | 524 |
293 // Deactivate keyboard container before closing child windows and shutting | 525 // Deactivate keyboard container before closing child windows and shutting |
294 // down associated layout managers. | 526 // down associated layout managers. |
295 DeactivateKeyboard(keyboard::KeyboardController::GetInstance()); | 527 DeactivateKeyboard(keyboard::KeyboardController::GetInstance()); |
296 | 528 |
297 wm_root_window_controller_->CloseChildWindows(); | 529 // NOTE: this may be called multiple times. |
530 | |
531 // |panel_layout_manager_| needs to be shut down before windows are destroyed. | |
532 if (panel_layout_manager_) { | |
533 panel_layout_manager_->Shutdown(); | |
534 panel_layout_manager_ = nullptr; | |
535 } | |
536 | |
537 // |docked_window_layout_manager_| needs to be shut down before windows are | |
538 // destroyed. | |
539 if (docked_window_layout_manager_) { | |
540 docked_window_layout_manager_->Shutdown(); | |
541 docked_window_layout_manager_ = nullptr; | |
542 } | |
543 | |
544 WmShelf* shelf = GetShelf(); | |
545 shelf->ShutdownShelfWidget(); | |
546 | |
547 workspace_controller_.reset(); | |
548 | |
549 // Explicitly destroy top level windows. We do this because such windows may | |
550 // query the RootWindow for state. | |
551 WmWindowTracker non_toplevel_windows; | |
552 WmWindow* root = GetWindow(); | |
553 non_toplevel_windows.Add(root); | |
554 while (!non_toplevel_windows.windows().empty()) { | |
555 WmWindow* non_toplevel_window = non_toplevel_windows.Pop(); | |
556 WmWindowTracker toplevel_windows; | |
557 for (WmWindow* child : non_toplevel_window->GetChildren()) { | |
558 if (!ShouldDestroyWindowInCloseChildWindows(child)) | |
559 continue; | |
560 if (child->HasNonClientArea()) | |
561 toplevel_windows.Add(child); | |
562 else | |
563 non_toplevel_windows.Add(child); | |
564 } | |
565 while (!toplevel_windows.windows().empty()) | |
566 toplevel_windows.Pop()->Destroy(); | |
567 } | |
568 // And then remove the containers. | |
569 while (!root->GetChildren().empty()) { | |
570 WmWindow* child = root->GetChildren()[0]; | |
571 if (ShouldDestroyWindowInCloseChildWindows(child)) | |
572 child->Destroy(); | |
573 else | |
574 root->RemoveChild(child); | |
575 } | |
576 | |
577 shelf->DestroyShelfWidget(); | |
578 | |
579 // CloseChildWindows() may be called twice during the shutdown of ash | |
580 // unittests. Avoid notifying WmShelf that the shelf has been destroyed twice. | |
581 if (shelf->IsShelfInitialized()) | |
582 shelf->ShutdownShelf(); | |
298 | 583 |
299 aura::client::SetDragDropClient(GetRootWindow(), nullptr); | 584 aura::client::SetDragDropClient(GetRootWindow(), nullptr); |
300 aura::client::SetTooltipClient(GetRootWindow(), nullptr); | 585 aura::client::SetTooltipClient(GetRootWindow(), nullptr); |
301 } | 586 } |
302 | 587 |
303 void RootWindowController::MoveWindowsTo(aura::Window* dst) { | 588 void RootWindowController::MoveWindowsTo(aura::Window* dst) { |
304 wm_root_window_controller_->MoveWindowsTo(WmWindowAura::Get(dst)); | 589 // Clear the workspace controller, so it doesn't incorrectly update the shelf. |
590 workspace_controller_.reset(); | |
591 ReparentAllWindows(GetWindow(), WmWindowAura::Get(dst)); | |
305 } | 592 } |
306 | 593 |
307 ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() { | 594 ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() { |
308 return wm_shelf_->shelf_layout_manager(); | 595 return wm_shelf_->shelf_layout_manager(); |
309 } | 596 } |
310 | 597 |
598 SystemModalContainerLayoutManager* | |
599 RootWindowController::GetSystemModalLayoutManager(WmWindow* window) { | |
600 aura::Window* modal_container = nullptr; | |
601 if (window) { | |
602 WmWindow* window_container = wm::GetContainerForWindow(window); | |
603 const int container_id = (window_container && | |
604 window_container->GetShellWindowId() >= | |
605 kShellWindowId_LockScreenContainer) | |
606 ? kShellWindowId_LockSystemModalContainer | |
607 : kShellWindowId_SystemModalContainer; | |
608 modal_container = GetContainer(container_id); | |
609 } else { | |
610 int modal_window_id = | |
611 WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked() | |
612 ? kShellWindowId_LockSystemModalContainer | |
613 : kShellWindowId_SystemModalContainer; | |
614 modal_container = GetContainer(modal_window_id); | |
615 } | |
616 return modal_container | |
617 ? static_cast<SystemModalContainerLayoutManager*>( | |
618 WmWindowAura::Get(modal_container)->GetLayoutManager()) | |
619 : nullptr; | |
620 } | |
621 | |
311 StatusAreaWidget* RootWindowController::GetStatusAreaWidget() { | 622 StatusAreaWidget* RootWindowController::GetStatusAreaWidget() { |
312 ShelfWidget* shelf_widget = wm_shelf_->shelf_widget(); | 623 ShelfWidget* shelf_widget = wm_shelf_->shelf_widget(); |
313 return shelf_widget ? shelf_widget->status_area_widget() : nullptr; | 624 return shelf_widget ? shelf_widget->status_area_widget() : nullptr; |
314 } | 625 } |
315 | 626 |
316 SystemTray* RootWindowController::GetSystemTray() { | 627 SystemTray* RootWindowController::GetSystemTray() { |
317 // We assume in throughout the code that this will not return NULL. If code | 628 // We assume in throughout the code that this will not return NULL. If code |
318 // triggers this for valid reasons, it should test status_area_widget first. | 629 // triggers this for valid reasons, it should test status_area_widget first. |
319 CHECK(wm_shelf_->shelf_widget()->status_area_widget()); | 630 CHECK(wm_shelf_->shelf_widget()->status_area_widget()); |
631 // XXX verify this. WmRootWindowController had this: | |
632 // ShelfWidget* shelf_widget = GetShelf()->shelf_widget(); | |
sky
2017/01/10 22:45:22
One question here. The commented code is what mash
James Cook
2017/01/11 00:49:55
I would keep the CHECK. Feel free to ping me if yo
| |
633 // if (!shelf_widget || !shelf_widget->status_area_widget()) | |
634 // return nullptr; | |
320 return wm_shelf_->shelf_widget()->status_area_widget()->system_tray(); | 635 return wm_shelf_->shelf_widget()->status_area_widget()->system_tray(); |
321 } | 636 } |
322 | 637 |
323 void RootWindowController::UpdateShelfVisibility() { | 638 void RootWindowController::UpdateShelfVisibility() { |
324 wm_shelf_->UpdateVisibilityState(); | 639 wm_shelf_->UpdateVisibilityState(); |
325 } | 640 } |
326 | 641 |
327 aura::Window* RootWindowController::GetWindowForFullscreenMode() { | 642 aura::Window* RootWindowController::GetWindowForFullscreenMode() { |
328 return WmWindowAura::GetAuraWindow( | 643 return WmWindowAura::GetAuraWindow( |
329 wm::GetWindowForFullscreenMode(WmWindowAura::Get(GetRootWindow()))); | 644 wm::GetWindowForFullscreenMode(WmWindowAura::Get(GetRootWindow()))); |
330 } | 645 } |
331 | 646 |
332 void RootWindowController::ActivateKeyboard( | 647 void RootWindowController::ActivateKeyboard( |
333 keyboard::KeyboardController* keyboard_controller) { | 648 keyboard::KeyboardController* keyboard_controller) { |
334 if (!keyboard::IsKeyboardEnabled() || | 649 if (!keyboard::IsKeyboardEnabled() || |
335 GetContainer(kShellWindowId_VirtualKeyboardContainer)) { | 650 GetContainer(kShellWindowId_VirtualKeyboardContainer)) { |
336 return; | 651 return; |
337 } | 652 } |
338 DCHECK(keyboard_controller); | 653 DCHECK(keyboard_controller); |
339 keyboard_controller->AddObserver(wm_shelf_->shelf_layout_manager()); | 654 keyboard_controller->AddObserver(wm_shelf_->shelf_layout_manager()); |
340 keyboard_controller->AddObserver(panel_layout_manager()); | 655 keyboard_controller->AddObserver(panel_layout_manager()); |
341 keyboard_controller->AddObserver(docked_window_layout_manager()); | 656 keyboard_controller->AddObserver(docked_window_layout_manager()); |
342 keyboard_controller->AddObserver(workspace_controller()->layout_manager()); | 657 keyboard_controller->AddObserver(workspace_controller()->layout_manager()); |
343 keyboard_controller->AddObserver( | 658 keyboard_controller->AddObserver( |
344 wm_root_window_controller_->always_on_top_controller() | 659 always_on_top_controller_->GetLayoutManager()); |
345 ->GetLayoutManager()); | |
346 WmShell::Get()->NotifyVirtualKeyboardActivated(true); | 660 WmShell::Get()->NotifyVirtualKeyboardActivated(true); |
347 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer); | 661 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer); |
348 DCHECK(parent); | 662 DCHECK(parent); |
349 aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); | 663 aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); |
350 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer); | 664 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer); |
351 parent->AddChild(keyboard_container); | 665 parent->AddChild(keyboard_container); |
352 } | 666 } |
353 | 667 |
354 void RootWindowController::DeactivateKeyboard( | 668 void RootWindowController::DeactivateKeyboard( |
355 keyboard::KeyboardController* keyboard_controller) { | 669 keyboard::KeyboardController* keyboard_controller) { |
356 if (!keyboard_controller || | 670 if (!keyboard_controller || |
357 !keyboard_controller->keyboard_container_initialized()) { | 671 !keyboard_controller->keyboard_container_initialized()) { |
358 return; | 672 return; |
359 } | 673 } |
360 aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); | 674 aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); |
361 if (keyboard_container->GetRootWindow() == GetRootWindow()) { | 675 if (keyboard_container->GetRootWindow() == GetRootWindow()) { |
362 aura::Window* parent = | 676 aura::Window* parent = |
363 GetContainer(kShellWindowId_ImeWindowParentContainer); | 677 GetContainer(kShellWindowId_ImeWindowParentContainer); |
364 DCHECK(parent); | 678 DCHECK(parent); |
365 parent->RemoveChild(keyboard_container); | 679 parent->RemoveChild(keyboard_container); |
366 // Virtual keyboard may be deactivated while still showing, notify all | 680 // Virtual keyboard may be deactivated while still showing, notify all |
367 // observers that keyboard bounds changed to 0 before remove them. | 681 // observers that keyboard bounds changed to 0 before remove them. |
368 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect()); | 682 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect()); |
369 keyboard_controller->RemoveObserver(wm_shelf_->shelf_layout_manager()); | 683 keyboard_controller->RemoveObserver(wm_shelf_->shelf_layout_manager()); |
370 keyboard_controller->RemoveObserver(panel_layout_manager()); | 684 keyboard_controller->RemoveObserver(panel_layout_manager()); |
371 keyboard_controller->RemoveObserver(docked_window_layout_manager()); | 685 keyboard_controller->RemoveObserver(docked_window_layout_manager()); |
372 keyboard_controller->RemoveObserver( | 686 keyboard_controller->RemoveObserver( |
373 workspace_controller()->layout_manager()); | 687 workspace_controller()->layout_manager()); |
374 keyboard_controller->RemoveObserver( | 688 keyboard_controller->RemoveObserver( |
375 wm_root_window_controller_->always_on_top_controller() | 689 always_on_top_controller_->GetLayoutManager()); |
376 ->GetLayoutManager()); | |
377 WmShell::Get()->NotifyVirtualKeyboardActivated(false); | 690 WmShell::Get()->NotifyVirtualKeyboardActivated(false); |
378 } | 691 } |
379 } | 692 } |
380 | 693 |
381 bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) { | 694 bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) { |
382 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer); | 695 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer); |
383 return parent ? parent->Contains(window) : false; | 696 return parent ? parent->Contains(window) : false; |
384 } | 697 } |
385 | 698 |
386 void RootWindowController::SetTouchAccessibilityAnchorPoint( | 699 void RootWindowController::SetTouchAccessibilityAnchorPoint( |
387 const gfx::Point& anchor_point) { | 700 const gfx::Point& anchor_point) { |
388 if (touch_exploration_manager_) | 701 if (touch_exploration_manager_) |
389 touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point); | 702 touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point); |
390 } | 703 } |
391 | 704 |
705 void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen, | |
706 ui::MenuSourceType source_type) { | |
707 ShellDelegate* delegate = WmShell::Get()->delegate(); | |
708 DCHECK(delegate); | |
709 menu_model_.reset(delegate->CreateContextMenu(wm_shelf_.get(), nullptr)); | |
710 if (!menu_model_) | |
711 return; | |
712 | |
713 menu_model_adapter_ = base::MakeUnique<views::MenuModelAdapter>( | |
714 menu_model_.get(), | |
715 base::Bind(&RootWindowController::OnMenuClosed, base::Unretained(this))); | |
716 | |
717 // The wallpaper controller may not be set yet if the user clicked on the | |
718 // status area before the initial animation completion. See crbug.com/222218 | |
719 if (!wallpaper_widget_controller()) | |
720 return; | |
721 | |
722 menu_runner_ = base::MakeUnique<views::MenuRunner>( | |
723 menu_model_adapter_->CreateMenu(), | |
724 views::MenuRunner::CONTEXT_MENU | views::MenuRunner::ASYNC); | |
725 ignore_result( | |
726 menu_runner_->RunMenuAt(wallpaper_widget_controller()->widget(), nullptr, | |
727 gfx::Rect(location_in_screen, gfx::Size()), | |
728 views::MENU_ANCHOR_TOPLEFT, source_type)); | |
729 } | |
730 | |
731 void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) { | |
732 StatusAreaWidget* status_area_widget = | |
733 wm_shelf_->shelf_widget()->status_area_widget(); | |
734 if (status_area_widget) | |
735 status_area_widget->UpdateAfterLoginStatusChange(status); | |
736 } | |
737 | |
392 //////////////////////////////////////////////////////////////////////////////// | 738 //////////////////////////////////////////////////////////////////////////////// |
393 // RootWindowController, private: | 739 // RootWindowController, private: |
394 | 740 |
395 RootWindowController::RootWindowController( | 741 RootWindowController::RootWindowController( |
396 AshWindowTreeHost* ash_host, | 742 AshWindowTreeHost* ash_host, |
397 aura::WindowTreeHost* window_tree_host) | 743 aura::WindowTreeHost* window_tree_host) |
398 : ash_host_(ash_host), | 744 : ash_host_(ash_host), |
399 owned_window_tree_host_(window_tree_host), | 745 owned_window_tree_host_(window_tree_host), |
400 window_tree_host_(ash_host ? ash_host->AsWindowTreeHost() | 746 window_tree_host_(ash_host ? ash_host->AsWindowTreeHost() |
401 : window_tree_host), | 747 : window_tree_host), |
402 wm_shelf_(base::MakeUnique<WmShelf>()), | 748 wm_shelf_(base::MakeUnique<WmShelf>()), |
403 touch_hud_debug_(NULL), | 749 touch_hud_debug_(NULL), |
404 touch_hud_projection_(NULL) { | 750 touch_hud_projection_(NULL) { |
405 DCHECK((ash_host && !window_tree_host) || (!ash_host && window_tree_host)); | 751 DCHECK((ash_host && !window_tree_host) || (!ash_host && window_tree_host)); |
406 aura::Window* root_window = GetRootWindow(); | 752 aura::Window* root_window = GetRootWindow(); |
407 GetRootWindowSettings(root_window)->controller = this; | 753 GetRootWindowSettings(root_window)->controller = this; |
408 | 754 |
409 // Has to happen after this is set as |controller| of RootWindowSettings. | |
410 wm_root_window_controller_ = base::MakeUnique<WmRootWindowController>( | |
411 this, WmWindowAura::Get(root_window)); | |
412 | |
413 stacking_controller_.reset(new StackingController); | 755 stacking_controller_.reset(new StackingController); |
414 aura::client::SetWindowParentingClient(root_window, | 756 aura::client::SetWindowParentingClient(root_window, |
415 stacking_controller_.get()); | 757 stacking_controller_.get()); |
416 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window)); | 758 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window)); |
417 } | 759 } |
418 | 760 |
419 void RootWindowController::Init(RootWindowType root_window_type) { | 761 void RootWindowController::Init(RootWindowType root_window_type) { |
420 aura::Window* root_window = GetRootWindow(); | 762 aura::Window* root_window = GetRootWindow(); |
421 WmShell* wm_shell = WmShell::Get(); | 763 WmShell* wm_shell = WmShell::Get(); |
422 Shell* shell = nullptr; | 764 Shell* shell = nullptr; |
423 if (!wm_shell->IsRunningInMash()) { | 765 if (!wm_shell->IsRunningInMash()) { |
424 shell = Shell::GetInstance(); | 766 shell = Shell::GetInstance(); |
425 shell->InitRootWindow(root_window); | 767 shell->InitRootWindow(root_window); |
426 } | 768 } |
427 | 769 |
428 wm_root_window_controller_->CreateContainers(); | 770 CreateContainers(); |
429 | 771 |
430 CreateSystemWallpaper(root_window_type); | 772 CreateSystemWallpaper(root_window_type); |
431 | 773 |
432 InitLayoutManagers(); | 774 InitLayoutManagers(); |
433 InitTouchHuds(); | 775 InitTouchHuds(); |
434 | 776 |
435 if (wm_shell->GetPrimaryRootWindowController() | 777 if (wm_shell->GetPrimaryRootWindowController() |
436 ->GetSystemModalLayoutManager(nullptr) | 778 ->GetSystemModalLayoutManager(nullptr) |
437 ->has_window_dimmer()) { | 779 ->has_window_dimmer()) { |
438 wm_root_window_controller_->GetSystemModalLayoutManager(nullptr) | 780 GetSystemModalLayoutManager(nullptr)->CreateModalBackground(); |
439 ->CreateModalBackground(); | |
440 } | 781 } |
441 | 782 |
442 wm_shell->AddShellObserver(this); | 783 wm_shell->AddShellObserver(this); |
443 | 784 |
444 wm_root_window_controller_->root_window_layout_manager()->OnWindowResized(); | 785 root_window_layout_manager_->OnWindowResized(); |
445 if (root_window_type == RootWindowType::PRIMARY) { | 786 if (root_window_type == RootWindowType::PRIMARY) { |
446 if (!wm_shell->IsRunningInMash()) | 787 if (!wm_shell->IsRunningInMash()) |
447 shell->InitKeyboard(); | 788 shell->InitKeyboard(); |
448 } else { | 789 } else { |
449 window_tree_host_->Show(); | 790 window_tree_host_->Show(); |
450 | 791 |
451 // Create a shelf if a user is already logged in. | 792 // Create a shelf if a user is already logged in. |
452 if (wm_shell->GetSessionStateDelegate()->NumberOfLoggedInUsers()) | 793 if (wm_shell->GetSessionStateDelegate()->NumberOfLoggedInUsers()) |
453 wm_root_window_controller_->CreateShelf(); | 794 CreateShelf(); |
454 | 795 |
455 // Notify shell observers about new root window. | 796 // Notify shell observers about new root window. |
456 if (!wm_shell->IsRunningInMash()) | 797 if (!wm_shell->IsRunningInMash()) |
457 shell->OnRootWindowAdded(WmWindowAura::Get(root_window)); | 798 shell->OnRootWindowAdded(WmWindowAura::Get(root_window)); |
458 } | 799 } |
459 | 800 |
460 // TODO: AshTouchExplorationManager doesn't work with mus. | 801 // TODO: AshTouchExplorationManager doesn't work with mus. |
461 // http://crbug.com/679782 | 802 // http://crbug.com/679782 |
462 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 803 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
463 switches::kAshDisableTouchExplorationMode) && | 804 switches::kAshDisableTouchExplorationMode) && |
464 !wm_shell->IsRunningInMash()) { | 805 !wm_shell->IsRunningInMash()) { |
465 touch_exploration_manager_.reset(new AshTouchExplorationManager(this)); | 806 touch_exploration_manager_.reset(new AshTouchExplorationManager(this)); |
466 } | 807 } |
467 } | 808 } |
468 | 809 |
469 void RootWindowController::InitLayoutManagers() { | 810 void RootWindowController::InitLayoutManagers() { |
470 // Create the shelf and status area widgets. | 811 // Create the shelf and status area widgets. |
471 DCHECK(!wm_shelf_->shelf_widget()); | 812 DCHECK(!wm_shelf_->shelf_widget()); |
472 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer); | 813 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer); |
473 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer); | 814 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer); |
474 WmWindow* wm_shelf_container = WmWindowAura::Get(shelf_container); | 815 WmWindow* wm_shelf_container = WmWindowAura::Get(shelf_container); |
475 WmWindow* wm_status_container = WmWindowAura::Get(status_container); | 816 WmWindow* wm_status_container = WmWindowAura::Get(status_container); |
476 | 817 |
477 wm_root_window_controller_->CreateLayoutManagers(); | 818 CreateLayoutManagers(); |
478 | 819 |
479 // Make it easier to resize windows that partially overlap the shelf. Must | 820 // Make it easier to resize windows that partially overlap the shelf. Must |
480 // occur after the ShelfLayoutManager is constructed by ShelfWidget. | 821 // occur after the ShelfLayoutManager is constructed by ShelfWidget. |
481 shelf_container->SetEventTargeter(base::MakeUnique<ShelfWindowTargeter>( | 822 shelf_container->SetEventTargeter(base::MakeUnique<ShelfWindowTargeter>( |
482 wm_shelf_container, wm_shelf_.get())); | 823 wm_shelf_container, wm_shelf_.get())); |
483 status_container->SetEventTargeter(base::MakeUnique<ShelfWindowTargeter>( | 824 status_container->SetEventTargeter(base::MakeUnique<ShelfWindowTargeter>( |
484 wm_status_container, wm_shelf_.get())); | 825 wm_status_container, wm_shelf_.get())); |
485 | 826 |
486 panel_container_handler_ = base::MakeUnique<PanelWindowEventHandler>(); | 827 panel_container_handler_ = base::MakeUnique<PanelWindowEventHandler>(); |
487 GetContainer(kShellWindowId_PanelContainer) | 828 GetContainer(kShellWindowId_PanelContainer) |
488 ->AddPreTargetHandler(panel_container_handler_.get()); | 829 ->AddPreTargetHandler(panel_container_handler_.get()); |
489 | 830 |
490 // Install an AttachedPanelWindowTargeter on the panel container to make it | 831 // Install an AttachedPanelWindowTargeter on the panel container to make it |
491 // easier to correctly target shelf buttons with touch. | 832 // easier to correctly target shelf buttons with touch. |
492 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize, -kResizeOutsideBoundsSize, | 833 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize, -kResizeOutsideBoundsSize, |
493 -kResizeOutsideBoundsSize, | 834 -kResizeOutsideBoundsSize, |
494 -kResizeOutsideBoundsSize); | 835 -kResizeOutsideBoundsSize); |
495 gfx::Insets touch_extend = | 836 gfx::Insets touch_extend = |
496 mouse_extend.Scale(kResizeOutsideBoundsScaleForTouch); | 837 mouse_extend.Scale(kResizeOutsideBoundsScaleForTouch); |
497 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer); | 838 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer); |
498 panel_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( | 839 panel_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( |
499 new AttachedPanelWindowTargeter(panel_container, mouse_extend, | 840 new AttachedPanelWindowTargeter(panel_container, mouse_extend, |
500 touch_extend, panel_layout_manager()))); | 841 touch_extend, panel_layout_manager()))); |
501 } | 842 } |
502 | 843 |
844 void RootWindowController::CreateContainers() { | |
845 WmWindow* root = GetWindow(); | |
846 // These containers are just used by PowerButtonController to animate groups | |
847 // of containers simultaneously without messing up the current transformations | |
848 // on those containers. These are direct children of the root window; all of | |
849 // the other containers are their children. | |
850 | |
851 // The wallpaper container is not part of the lock animation, so it is not | |
852 // included in those animate groups. When the screen is locked, the wallpaper | |
853 // is moved to the lock screen wallpaper container (and moved back on unlock). | |
854 // Ensure that there's an opaque layer occluding the non-lock-screen layers. | |
855 WmWindow* wallpaper_container = CreateContainer( | |
856 kShellWindowId_WallpaperContainer, "WallpaperContainer", root); | |
857 wallpaper_container->SetChildWindowVisibilityChangesAnimated(); | |
858 | |
859 WmWindow* non_lock_screen_containers = | |
860 CreateContainer(kShellWindowId_NonLockScreenContainersContainer, | |
861 "NonLockScreenContainersContainer", root); | |
862 // Clip all windows inside this container, as half pixel of the window's | |
863 // texture may become visible when the screen is scaled. crbug.com/368591. | |
864 non_lock_screen_containers->SetMasksToBounds(true); | |
865 | |
866 WmWindow* lock_wallpaper_containers = | |
867 CreateContainer(kShellWindowId_LockScreenWallpaperContainer, | |
868 "LockScreenWallpaperContainer", root); | |
869 lock_wallpaper_containers->SetChildWindowVisibilityChangesAnimated(); | |
870 | |
871 WmWindow* lock_screen_containers = | |
872 CreateContainer(kShellWindowId_LockScreenContainersContainer, | |
873 "LockScreenContainersContainer", root); | |
874 WmWindow* lock_screen_related_containers = | |
875 CreateContainer(kShellWindowId_LockScreenRelatedContainersContainer, | |
876 "LockScreenRelatedContainersContainer", root); | |
877 | |
878 CreateContainer(kShellWindowId_UnparentedControlContainer, | |
879 "UnparentedControlContainer", non_lock_screen_containers); | |
880 | |
881 WmWindow* default_container = | |
882 CreateContainer(kShellWindowId_DefaultContainer, "DefaultContainer", | |
883 non_lock_screen_containers); | |
884 default_container->SetChildWindowVisibilityChangesAnimated(); | |
885 default_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
886 default_container->SetBoundsInScreenBehaviorForChildren( | |
887 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
888 default_container->SetChildrenUseExtendedHitRegion(); | |
889 | |
890 WmWindow* always_on_top_container = | |
891 CreateContainer(kShellWindowId_AlwaysOnTopContainer, | |
892 "AlwaysOnTopContainer", non_lock_screen_containers); | |
893 always_on_top_container->SetChildWindowVisibilityChangesAnimated(); | |
894 always_on_top_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
895 always_on_top_container->SetBoundsInScreenBehaviorForChildren( | |
896 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
897 | |
898 WmWindow* docked_container = | |
899 CreateContainer(kShellWindowId_DockedContainer, "DockedContainer", | |
900 non_lock_screen_containers); | |
901 docked_container->SetChildWindowVisibilityChangesAnimated(); | |
902 docked_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
903 docked_container->SetBoundsInScreenBehaviorForChildren( | |
904 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
905 docked_container->SetChildrenUseExtendedHitRegion(); | |
906 | |
907 WmWindow* shelf_container = | |
908 CreateContainer(kShellWindowId_ShelfContainer, "ShelfContainer", | |
909 non_lock_screen_containers); | |
910 shelf_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
911 shelf_container->SetBoundsInScreenBehaviorForChildren( | |
912 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
913 shelf_container->SetLockedToRoot(true); | |
914 | |
915 WmWindow* panel_container = | |
916 CreateContainer(kShellWindowId_PanelContainer, "PanelContainer", | |
917 non_lock_screen_containers); | |
918 panel_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
919 panel_container->SetBoundsInScreenBehaviorForChildren( | |
920 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
921 | |
922 WmWindow* shelf_bubble_container = | |
923 CreateContainer(kShellWindowId_ShelfBubbleContainer, | |
924 "ShelfBubbleContainer", non_lock_screen_containers); | |
925 shelf_bubble_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
926 shelf_bubble_container->SetBoundsInScreenBehaviorForChildren( | |
927 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
928 shelf_bubble_container->SetLockedToRoot(true); | |
929 | |
930 WmWindow* app_list_container = | |
931 CreateContainer(kShellWindowId_AppListContainer, "AppListContainer", | |
932 non_lock_screen_containers); | |
933 app_list_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
934 app_list_container->SetBoundsInScreenBehaviorForChildren( | |
935 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
936 | |
937 WmWindow* modal_container = | |
938 CreateContainer(kShellWindowId_SystemModalContainer, | |
939 "SystemModalContainer", non_lock_screen_containers); | |
940 modal_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
941 modal_container->SetChildWindowVisibilityChangesAnimated(); | |
942 modal_container->SetBoundsInScreenBehaviorForChildren( | |
943 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
944 modal_container->SetChildrenUseExtendedHitRegion(); | |
945 | |
946 // TODO(beng): Figure out if we can make this use | |
947 // SystemModalContainerEventFilter instead of stops_event_propagation. | |
948 WmWindow* lock_container = | |
949 CreateContainer(kShellWindowId_LockScreenContainer, "LockScreenContainer", | |
950 lock_screen_containers); | |
951 lock_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
952 lock_container->SetBoundsInScreenBehaviorForChildren( | |
953 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
954 // TODO(beng): stopsevents | |
955 | |
956 WmWindow* lock_modal_container = | |
957 CreateContainer(kShellWindowId_LockSystemModalContainer, | |
958 "LockSystemModalContainer", lock_screen_containers); | |
959 lock_modal_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
960 lock_modal_container->SetChildWindowVisibilityChangesAnimated(); | |
961 lock_modal_container->SetBoundsInScreenBehaviorForChildren( | |
962 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
963 lock_modal_container->SetChildrenUseExtendedHitRegion(); | |
964 | |
965 WmWindow* status_container = | |
966 CreateContainer(kShellWindowId_StatusContainer, "StatusContainer", | |
967 lock_screen_related_containers); | |
968 status_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
969 status_container->SetBoundsInScreenBehaviorForChildren( | |
970 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
971 status_container->SetLockedToRoot(true); | |
972 | |
973 WmWindow* settings_bubble_container = | |
974 CreateContainer(kShellWindowId_SettingBubbleContainer, | |
975 "SettingBubbleContainer", lock_screen_related_containers); | |
976 settings_bubble_container->SetChildWindowVisibilityChangesAnimated(); | |
977 settings_bubble_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
978 settings_bubble_container->SetBoundsInScreenBehaviorForChildren( | |
979 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
980 settings_bubble_container->SetLockedToRoot(true); | |
981 | |
982 WmWindow* virtual_keyboard_parent_container = CreateContainer( | |
983 kShellWindowId_ImeWindowParentContainer, "VirtualKeyboardParentContainer", | |
984 lock_screen_related_containers); | |
985 virtual_keyboard_parent_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
986 virtual_keyboard_parent_container->SetBoundsInScreenBehaviorForChildren( | |
987 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
988 | |
989 WmWindow* menu_container = | |
990 CreateContainer(kShellWindowId_MenuContainer, "MenuContainer", | |
991 lock_screen_related_containers); | |
992 menu_container->SetChildWindowVisibilityChangesAnimated(); | |
993 menu_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
994 menu_container->SetBoundsInScreenBehaviorForChildren( | |
995 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
996 | |
997 WmWindow* drag_drop_container = CreateContainer( | |
998 kShellWindowId_DragImageAndTooltipContainer, | |
999 "DragImageAndTooltipContainer", lock_screen_related_containers); | |
1000 drag_drop_container->SetChildWindowVisibilityChangesAnimated(); | |
1001 drag_drop_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
1002 drag_drop_container->SetBoundsInScreenBehaviorForChildren( | |
1003 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
1004 | |
1005 WmWindow* overlay_container = | |
1006 CreateContainer(kShellWindowId_OverlayContainer, "OverlayContainer", | |
1007 lock_screen_related_containers); | |
1008 overlay_container->SetSnapsChildrenToPhysicalPixelBoundary(); | |
1009 overlay_container->SetBoundsInScreenBehaviorForChildren( | |
1010 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
1011 | |
1012 WmWindow* mouse_cursor_container = CreateContainer( | |
1013 kShellWindowId_MouseCursorContainer, "MouseCursorContainer", root); | |
1014 mouse_cursor_container->SetBoundsInScreenBehaviorForChildren( | |
1015 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES); | |
1016 | |
1017 CreateContainer(kShellWindowId_PowerButtonAnimationContainer, | |
1018 "PowerButtonAnimationContainer", root); | |
1019 } | |
1020 | |
1021 void RootWindowController::CreateLayoutManagers() { | |
1022 GetShelf()->CreateShelfWidget(GetWindow()); | |
1023 | |
1024 WmWindow* root = GetWindow(); | |
1025 root_window_layout_manager_ = new wm::RootWindowLayoutManager(root); | |
1026 root->SetLayoutManager(base::WrapUnique(root_window_layout_manager_)); | |
1027 | |
1028 WmWindow* default_container = GetWmContainer(kShellWindowId_DefaultContainer); | |
1029 // Installs WorkspaceLayoutManager on |default_container|. | |
1030 workspace_controller_.reset(new WorkspaceController(default_container)); | |
1031 | |
1032 WmWindow* modal_container = | |
1033 GetWmContainer(kShellWindowId_SystemModalContainer); | |
1034 DCHECK(modal_container); | |
1035 modal_container->SetLayoutManager( | |
1036 base::MakeUnique<SystemModalContainerLayoutManager>(modal_container)); | |
1037 | |
1038 WmWindow* lock_modal_container = | |
1039 GetWmContainer(kShellWindowId_LockSystemModalContainer); | |
1040 DCHECK(lock_modal_container); | |
1041 lock_modal_container->SetLayoutManager( | |
1042 base::MakeUnique<SystemModalContainerLayoutManager>( | |
1043 lock_modal_container)); | |
1044 | |
1045 WmWindow* lock_container = GetWmContainer(kShellWindowId_LockScreenContainer); | |
1046 DCHECK(lock_container); | |
1047 lock_container->SetLayoutManager( | |
1048 base::MakeUnique<LockLayoutManager>(lock_container)); | |
1049 | |
1050 WmWindow* always_on_top_container = | |
1051 GetWmContainer(kShellWindowId_AlwaysOnTopContainer); | |
1052 DCHECK(always_on_top_container); | |
1053 always_on_top_controller_ = | |
1054 base::MakeUnique<AlwaysOnTopController>(always_on_top_container); | |
1055 | |
1056 // Create Docked windows layout manager | |
1057 WmWindow* docked_container = GetWmContainer(kShellWindowId_DockedContainer); | |
1058 docked_window_layout_manager_ = | |
1059 new DockedWindowLayoutManager(docked_container); | |
1060 docked_container->SetLayoutManager( | |
1061 base::WrapUnique(docked_window_layout_manager_)); | |
1062 | |
1063 // Create Panel layout manager | |
1064 WmWindow* panel_container = GetWmContainer(kShellWindowId_PanelContainer); | |
1065 panel_layout_manager_ = new PanelLayoutManager(panel_container); | |
1066 panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_)); | |
1067 | |
1068 wm::WmSnapToPixelLayoutManager::InstallOnContainers(root); | |
1069 } | |
1070 | |
503 void RootWindowController::InitTouchHuds() { | 1071 void RootWindowController::InitTouchHuds() { |
504 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 1072 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
505 if (command_line->HasSwitch(switches::kAshTouchHud)) | 1073 if (command_line->HasSwitch(switches::kAshTouchHud)) |
506 set_touch_hud_debug(new TouchHudDebug(GetRootWindow())); | 1074 set_touch_hud_debug(new TouchHudDebug(GetRootWindow())); |
507 if (!WmShell::Get()->IsRunningInMash() && | 1075 if (!WmShell::Get()->IsRunningInMash() && |
508 Shell::GetInstance()->is_touch_hud_projection_enabled()) { | 1076 Shell::GetInstance()->is_touch_hud_projection_enabled()) { |
509 EnableTouchHudProjection(); | 1077 EnableTouchHudProjection(); |
510 } | 1078 } |
511 } | 1079 } |
512 | 1080 |
(...skipping 27 matching lines...) Expand all Loading... | |
540 return; | 1108 return; |
541 set_touch_hud_projection(new TouchHudProjection(GetRootWindow())); | 1109 set_touch_hud_projection(new TouchHudProjection(GetRootWindow())); |
542 } | 1110 } |
543 | 1111 |
544 void RootWindowController::DisableTouchHudProjection() { | 1112 void RootWindowController::DisableTouchHudProjection() { |
545 if (!touch_hud_projection_) | 1113 if (!touch_hud_projection_) |
546 return; | 1114 return; |
547 touch_hud_projection_->Remove(); | 1115 touch_hud_projection_->Remove(); |
548 } | 1116 } |
549 | 1117 |
550 DockedWindowLayoutManager* | 1118 void RootWindowController::ResetRootForNewWindowsIfNecessary() { |
551 RootWindowController::docked_window_layout_manager() { | 1119 WmShell* shell = WmShell::Get(); |
552 return wm_root_window_controller_->docked_window_layout_manager(); | 1120 // Change the target root window before closing child windows. If any child |
1121 // being removed triggers a relayout of the shelf it will try to build a | |
1122 // window list adding windows from the target root window's containers which | |
1123 // may have already gone away. | |
1124 WmWindow* root = GetWindow(); | |
1125 if (shell->GetRootWindowForNewWindows() == root) { | |
1126 // The root window for new windows is being destroyed. Switch to the primary | |
1127 // root window if possible. | |
1128 WmWindow* primary_root = shell->GetPrimaryRootWindow(); | |
1129 shell->set_root_window_for_new_windows(primary_root == root ? nullptr | |
1130 : primary_root); | |
1131 } | |
553 } | 1132 } |
554 | 1133 |
555 PanelLayoutManager* RootWindowController::panel_layout_manager() { | 1134 void RootWindowController::OnMenuClosed() { |
556 return wm_root_window_controller_->panel_layout_manager(); | 1135 menu_runner_.reset(); |
1136 menu_model_adapter_.reset(); | |
1137 menu_model_.reset(); | |
1138 wm_shelf_->UpdateVisibilityState(); | |
557 } | 1139 } |
558 | 1140 |
559 void RootWindowController::OnLoginStateChanged(LoginStatus status) { | 1141 void RootWindowController::OnLoginStateChanged(LoginStatus status) { |
560 wm_shelf_->UpdateVisibilityState(); | 1142 wm_shelf_->UpdateVisibilityState(); |
561 } | 1143 } |
562 | 1144 |
563 void RootWindowController::OnTouchHudProjectionToggled(bool enabled) { | 1145 void RootWindowController::OnTouchHudProjectionToggled(bool enabled) { |
564 if (enabled) | 1146 if (enabled) |
565 EnableTouchHudProjection(); | 1147 EnableTouchHudProjection(); |
566 else | 1148 else |
567 DisableTouchHudProjection(); | 1149 DisableTouchHudProjection(); |
568 } | 1150 } |
569 | 1151 |
570 RootWindowController* GetRootWindowController(const aura::Window* root_window) { | 1152 RootWindowController* GetRootWindowController(const aura::Window* root_window) { |
571 return root_window ? GetRootWindowSettings(root_window)->controller : nullptr; | 1153 return root_window ? GetRootWindowSettings(root_window)->controller : nullptr; |
572 } | 1154 } |
573 | 1155 |
574 } // namespace ash | 1156 } // namespace ash |
OLD | NEW |