| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/desktop_background/desktop_background_widget_controller.h" | 9 #include "ash/desktop_background/desktop_background_widget_controller.h" |
| 10 #include "ash/display/display_controller.h" | 10 #include "ash/display/display_controller.h" |
| 11 #include "ash/display/multi_display_manager.h" | 11 #include "ash/display/multi_display_manager.h" |
| 12 #include "ash/focus_cycler.h" |
| 12 #include "ash/shell.h" | 13 #include "ash/shell.h" |
| 14 #include "ash/shell_delegate.h" |
| 13 #include "ash/shell_factory.h" | 15 #include "ash/shell_factory.h" |
| 14 #include "ash/shell_window_ids.h" | 16 #include "ash/shell_window_ids.h" |
| 17 #include "ash/system/status_area_widget.h" |
| 15 #include "ash/wm/base_layout_manager.h" | 18 #include "ash/wm/base_layout_manager.h" |
| 16 #include "ash/wm/event_client_impl.h" | 19 #include "ash/wm/event_client_impl.h" |
| 20 #include "ash/wm/panel_layout_manager.h" |
| 21 #include "ash/wm/panel_window_event_filter.h" |
| 17 #include "ash/wm/property_util.h" | 22 #include "ash/wm/property_util.h" |
| 18 #include "ash/wm/root_window_layout_manager.h" | 23 #include "ash/wm/root_window_layout_manager.h" |
| 19 #include "ash/wm/screen_dimmer.h" | 24 #include "ash/wm/screen_dimmer.h" |
| 25 #include "ash/wm/shelf_layout_manager.h" |
| 26 #include "ash/wm/shelf_types.h" |
| 27 #include "ash/wm/status_area_layout_manager.h" |
| 20 #include "ash/wm/system_modal_container_layout_manager.h" | 28 #include "ash/wm/system_modal_container_layout_manager.h" |
| 21 #include "ash/wm/toplevel_window_event_handler.h" | 29 #include "ash/wm/toplevel_window_event_handler.h" |
| 22 #include "ash/wm/visibility_controller.h" | 30 #include "ash/wm/visibility_controller.h" |
| 23 #include "ash/wm/window_properties.h" | 31 #include "ash/wm/window_properties.h" |
| 24 #include "ash/wm/workspace/system_background_controller.h" | 32 #include "ash/wm/workspace/system_background_controller.h" |
| 25 #include "ash/wm/workspace_controller.h" | 33 #include "ash/wm/workspace_controller.h" |
| 26 #include "ui/aura/client/activation_client.h" | 34 #include "ui/aura/client/activation_client.h" |
| 27 #include "ui/aura/client/aura_constants.h" | 35 #include "ui/aura/client/aura_constants.h" |
| 28 #include "ui/aura/client/capture_client.h" | 36 #include "ui/aura/client/capture_client.h" |
| 29 #include "ui/aura/client/tooltip_client.h" | 37 #include "ui/aura/client/tooltip_client.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 // use the virtual screeen coordinates instead of parent. | 143 // use the virtual screeen coordinates instead of parent. |
| 136 void SetUsesScreenCoordinates(aura::Window* container) { | 144 void SetUsesScreenCoordinates(aura::Window* container) { |
| 137 container->SetProperty(internal::kUsesScreenCoordinatesKey, true); | 145 container->SetProperty(internal::kUsesScreenCoordinatesKey, true); |
| 138 } | 146 } |
| 139 | 147 |
| 140 } // namespace | 148 } // namespace |
| 141 | 149 |
| 142 namespace internal { | 150 namespace internal { |
| 143 | 151 |
| 144 RootWindowController::RootWindowController(aura::RootWindow* root_window) | 152 RootWindowController::RootWindowController(aura::RootWindow* root_window) |
| 145 : root_window_(root_window) { | 153 : root_window_(root_window), |
| 154 root_window_layout_(NULL), |
| 155 status_area_widget_(NULL), |
| 156 shelf_(NULL), |
| 157 panel_layout_manager_(NULL) { |
| 146 SetRootWindowController(root_window, this); | 158 SetRootWindowController(root_window, this); |
| 147 | 159 |
| 148 event_client_.reset(new EventClientImpl(root_window)); | 160 event_client_.reset(new EventClientImpl(root_window)); |
| 149 screen_dimmer_.reset(new ScreenDimmer(root_window)); | 161 screen_dimmer_.reset(new ScreenDimmer(root_window)); |
| 150 } | 162 } |
| 151 | 163 |
| 152 RootWindowController::~RootWindowController() { | 164 RootWindowController::~RootWindowController() { |
| 153 Shutdown(); | 165 Shutdown(); |
| 154 root_window_.reset(); | 166 root_window_.reset(); |
| 155 } | 167 } |
| 156 | 168 |
| 157 void RootWindowController::Shutdown() { | 169 void RootWindowController::Shutdown() { |
| 158 CloseChildWindows(); | 170 CloseChildWindows(); |
| 159 if (Shell::GetActiveRootWindow() == root_window_.get()) { | 171 if (Shell::GetActiveRootWindow() == root_window_.get()) { |
| 160 Shell::GetInstance()->set_active_root_window( | 172 Shell::GetInstance()->set_active_root_window( |
| 161 Shell::GetPrimaryRootWindow() == root_window_.get() ? | 173 Shell::GetPrimaryRootWindow() == root_window_.get() ? |
| 162 NULL : Shell::GetPrimaryRootWindow()); | 174 NULL : Shell::GetPrimaryRootWindow()); |
| 163 } | 175 } |
| 164 SetRootWindowController(root_window_.get(), NULL); | 176 SetRootWindowController(root_window_.get(), NULL); |
| 165 event_client_.reset(); | 177 event_client_.reset(); |
| 166 screen_dimmer_.reset(); | 178 screen_dimmer_.reset(); |
| 167 workspace_controller_.reset(); | 179 workspace_controller_.reset(); |
| 168 // Forget with the display ID so that display lookup | 180 // Forget with the display ID so that display lookup |
| 169 // ends up with invalid display. | 181 // ends up with invalid display. |
| 170 root_window_->ClearProperty(kDisplayIdKey); | 182 root_window_->ClearProperty(kDisplayIdKey); |
| 171 // And this root window should no longer process events. | 183 // And this root window should no longer process events. |
| 172 root_window_->PrepareForShutdown(); | 184 root_window_->PrepareForShutdown(); |
| 185 |
| 186 // Launcher widget has a InputMethodBridge that references to |
| 187 // input_method_filter_'s input_method_. So explicitly release launcher_ |
| 188 // before input_method_filter_. And this needs to be after we delete all |
| 189 // containers in case there are still live browser windows which access |
| 190 // LauncherModel during close. |
| 191 launcher_.reset(); |
| 173 } | 192 } |
| 174 | 193 |
| 175 SystemModalContainerLayoutManager* | 194 SystemModalContainerLayoutManager* |
| 176 RootWindowController::GetSystemModalLayoutManager() { | 195 RootWindowController::GetSystemModalLayoutManager() { |
| 177 return static_cast<SystemModalContainerLayoutManager*>( | 196 return static_cast<SystemModalContainerLayoutManager*>( |
| 178 GetContainer(kShellWindowId_SystemModalContainer)->layout_manager()); | 197 GetContainer(kShellWindowId_SystemModalContainer)->layout_manager()); |
| 179 } | 198 } |
| 180 | 199 |
| 181 aura::Window* RootWindowController::GetContainer(int container_id) { | 200 aura::Window* RootWindowController::GetContainer(int container_id) { |
| 182 return root_window_->GetChildById(container_id); | 201 return root_window_->GetChildById(container_id); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 193 workspace_controller_.reset( | 212 workspace_controller_.reset( |
| 194 new WorkspaceController(default_container)); | 213 new WorkspaceController(default_container)); |
| 195 | 214 |
| 196 aura::Window* always_on_top_container = | 215 aura::Window* always_on_top_container = |
| 197 GetContainer(kShellWindowId_AlwaysOnTopContainer); | 216 GetContainer(kShellWindowId_AlwaysOnTopContainer); |
| 198 always_on_top_container->SetLayoutManager( | 217 always_on_top_container->SetLayoutManager( |
| 199 new BaseLayoutManager( | 218 new BaseLayoutManager( |
| 200 always_on_top_container->GetRootWindow())); | 219 always_on_top_container->GetRootWindow())); |
| 201 } | 220 } |
| 202 | 221 |
| 222 void RootWindowController::InitForPrimaryDisplay() { |
| 223 DCHECK(!status_area_widget_); |
| 224 ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
| 225 |
| 226 // Initialize Primary RootWindow specific items. |
| 227 status_area_widget_ = new internal::StatusAreaWidget(); |
| 228 status_area_widget_->CreateTrayViews(delegate); |
| 229 // Login screen manages status area visibility by itself. |
| 230 if (delegate && delegate->IsSessionStarted()) |
| 231 status_area_widget_->Show(); |
| 232 |
| 233 Shell::GetInstance()->focus_cycler()->AddWidget(status_area_widget_); |
| 234 |
| 235 internal::ShelfLayoutManager* shelf_layout_manager = |
| 236 new internal::ShelfLayoutManager(status_area_widget_); |
| 237 GetContainer(internal::kShellWindowId_LauncherContainer)-> |
| 238 SetLayoutManager(shelf_layout_manager); |
| 239 shelf_ = shelf_layout_manager; |
| 240 |
| 241 internal::StatusAreaLayoutManager* status_area_layout_manager = |
| 242 new internal::StatusAreaLayoutManager(shelf_layout_manager); |
| 243 GetContainer(internal::kShellWindowId_StatusContainer)-> |
| 244 SetLayoutManager(status_area_layout_manager); |
| 245 |
| 246 shelf_layout_manager->set_workspace_controller( |
| 247 workspace_controller()); |
| 248 |
| 249 workspace_controller()->SetShelf(shelf_); |
| 250 |
| 251 // Create Panel layout manager |
| 252 aura::Window* panel_container = GetContainer( |
| 253 internal::kShellWindowId_PanelContainer); |
| 254 panel_layout_manager_ = |
| 255 new internal::PanelLayoutManager(panel_container); |
| 256 panel_container->SetEventFilter( |
| 257 new internal::PanelWindowEventFilter( |
| 258 panel_container, panel_layout_manager_)); |
| 259 panel_container->SetLayoutManager(panel_layout_manager_); |
| 260 |
| 261 if (!delegate || delegate->IsUserLoggedIn()) |
| 262 CreateLauncher(); |
| 263 } |
| 264 |
| 203 void RootWindowController::CreateContainers() { | 265 void RootWindowController::CreateContainers() { |
| 204 CreateContainersInRootWindow(root_window_.get()); | 266 CreateContainersInRootWindow(root_window_.get()); |
| 205 } | 267 } |
| 206 | 268 |
| 207 void RootWindowController::CreateSystemBackground( | 269 void RootWindowController::CreateSystemBackground( |
| 208 bool is_first_run_after_boot) { | 270 bool is_first_run_after_boot) { |
| 209 SkColor color = SK_ColorBLACK; | 271 SkColor color = SK_ColorBLACK; |
| 210 #if defined(OS_CHROMEOS) | 272 #if defined(OS_CHROMEOS) |
| 211 if (is_first_run_after_boot) | 273 if (is_first_run_after_boot) |
| 212 color = kBootSystemBackgroundColor; | 274 color = kBootSystemBackgroundColor; |
| 213 #endif | 275 #endif |
| 214 background_.reset(new SystemBackgroundController(root_window_.get(), color)); | 276 background_.reset(new SystemBackgroundController(root_window_.get(), color)); |
| 215 } | 277 } |
| 216 | 278 |
| 279 void RootWindowController::CreateLauncher() { |
| 280 if (launcher_.get()) |
| 281 return; |
| 282 |
| 283 aura::Window* default_container = |
| 284 GetContainer(internal::kShellWindowId_DefaultContainer); |
| 285 launcher_.reset(new Launcher(default_container, shelf_)); |
| 286 |
| 287 launcher_->SetFocusCycler(Shell::GetInstance()->focus_cycler()); |
| 288 shelf_->SetLauncher(launcher_.get()); |
| 289 |
| 290 if (panel_layout_manager_) |
| 291 panel_layout_manager_->SetLauncher(launcher_.get()); |
| 292 |
| 293 ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
| 294 if (delegate) |
| 295 launcher_->SetVisible(delegate->IsSessionStarted()); |
| 296 launcher_->widget()->Show(); |
| 297 } |
| 298 |
| 299 void RootWindowController::ShowLauncher() { |
| 300 if (!launcher_.get()) |
| 301 return; |
| 302 launcher_->SetVisible(true); |
| 303 } |
| 304 |
| 217 void RootWindowController::HandleDesktopBackgroundVisible() { | 305 void RootWindowController::HandleDesktopBackgroundVisible() { |
| 218 if (background_.get()) | 306 if (background_.get()) |
| 219 background_->SetColor(SK_ColorBLACK); | 307 background_->SetColor(SK_ColorBLACK); |
| 220 } | 308 } |
| 221 | 309 |
| 222 void RootWindowController::CloseChildWindows() { | 310 void RootWindowController::CloseChildWindows() { |
| 311 // The status area needs to be shut down before the windows are destroyed. |
| 312 if (status_area_widget_) |
| 313 status_area_widget_->Shutdown(); |
| 314 |
| 315 // Closing the windows frees the workspace controller. |
| 316 if (shelf_) |
| 317 shelf_->set_workspace_controller(NULL); |
| 318 |
| 223 // Close background widget first as it depends on tooltip. | 319 // Close background widget first as it depends on tooltip. |
| 224 root_window_->SetProperty(kDesktopController, | 320 root_window_->SetProperty(kDesktopController, |
| 225 static_cast<DesktopBackgroundWidgetController*>(NULL)); | 321 static_cast<DesktopBackgroundWidgetController*>(NULL)); |
| 226 root_window_->SetProperty(kAnimatingDesktopController, | 322 root_window_->SetProperty(kAnimatingDesktopController, |
| 227 static_cast<AnimatingDesktopController*>(NULL)); | 323 static_cast<AnimatingDesktopController*>(NULL)); |
| 228 | 324 |
| 229 workspace_controller_.reset(); | 325 workspace_controller_.reset(); |
| 230 aura::client::SetTooltipClient(root_window_.get(), NULL); | 326 aura::client::SetTooltipClient(root_window_.get(), NULL); |
| 231 | 327 |
| 232 while (!root_window_->children().empty()) { | 328 while (!root_window_->children().empty()) { |
| 233 aura::Window* child = root_window_->children()[0]; | 329 aura::Window* child = root_window_->children()[0]; |
| 234 delete child; | 330 delete child; |
| 235 } | 331 } |
| 332 |
| 333 // TODO(oshima): Closing window triggers access to status area widget |
| 334 // in ShelfLayoutManager. We probably should disalb/remove shelf layout |
| 335 // manager before destorying windows? |
| 336 status_area_widget_ = NULL; |
| 236 } | 337 } |
| 237 | 338 |
| 238 bool RootWindowController::IsInMaximizedMode() const { | 339 bool RootWindowController::IsInMaximizedMode() const { |
| 239 return workspace_controller_->IsInMaximizedMode(); | 340 return workspace_controller_->IsInMaximizedMode(); |
| 240 } | 341 } |
| 241 | 342 |
| 242 void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) { | 343 void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) { |
| 243 aura::Window* focused = dst->GetFocusManager()->GetFocusedWindow(); | 344 aura::Window* focused = dst->GetFocusManager()->GetFocusedWindow(); |
| 244 aura::WindowTracker tracker; | 345 aura::WindowTracker tracker; |
| 245 if (focused) | 346 if (focused) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 263 ReparentAllWindows(root_window_.get(), dst); | 364 ReparentAllWindows(root_window_.get(), dst); |
| 264 | 365 |
| 265 // Restore focused or active window if it's still alive. | 366 // Restore focused or active window if it's still alive. |
| 266 if (focused && tracker.Contains(focused) && dst->Contains(focused)) { | 367 if (focused && tracker.Contains(focused) && dst->Contains(focused)) { |
| 267 dst->GetFocusManager()->SetFocusedWindow(focused, NULL); | 368 dst->GetFocusManager()->SetFocusedWindow(focused, NULL); |
| 268 } else if (active && tracker.Contains(active) && dst->Contains(active)) { | 369 } else if (active && tracker.Contains(active) && dst->Contains(active)) { |
| 269 activation_client->ActivateWindow(active); | 370 activation_client->ActivateWindow(active); |
| 270 } | 371 } |
| 271 } | 372 } |
| 272 | 373 |
| 374 void RootWindowController::UpdateShelfVisibility() { |
| 375 shelf_->UpdateVisibilityState(); |
| 376 } |
| 377 |
| 378 void RootWindowController::SetShelfAutoHideBehavior( |
| 379 ShelfAutoHideBehavior behavior) { |
| 380 shelf_->SetAutoHideBehavior(behavior); |
| 381 } |
| 382 |
| 383 ShelfAutoHideBehavior RootWindowController::GetShelfAutoHideBehavior() const { |
| 384 return shelf_->auto_hide_behavior(); |
| 385 } |
| 386 |
| 387 bool RootWindowController::SetShelfAlignment(ShelfAlignment alignment) { |
| 388 return shelf_->SetAlignment(alignment); |
| 389 } |
| 390 |
| 391 ShelfAlignment RootWindowController::GetShelfAlignment() { |
| 392 return shelf_->alignment(); |
| 393 } |
| 394 |
| 273 //////////////////////////////////////////////////////////////////////////////// | 395 //////////////////////////////////////////////////////////////////////////////// |
| 274 // RootWindowController, private: | 396 // RootWindowController, private: |
| 275 | 397 |
| 276 void RootWindowController::CreateContainersInRootWindow( | 398 void RootWindowController::CreateContainersInRootWindow( |
| 277 aura::RootWindow* root_window) { | 399 aura::RootWindow* root_window) { |
| 278 // These containers are just used by PowerButtonController to animate groups | 400 // These containers are just used by PowerButtonController to animate groups |
| 279 // of containers simultaneously without messing up the current transformations | 401 // of containers simultaneously without messing up the current transformations |
| 280 // on those containers. These are direct children of the root window; all of | 402 // on those containers. These are direct children of the root window; all of |
| 281 // the other containers are their children. | 403 // the other containers are their children. |
| 282 // Desktop and lock screen background containers are not part of the | 404 // Desktop and lock screen background containers are not part of the |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 | 546 |
| 425 aura::Window* overlay_container = CreateContainer( | 547 aura::Window* overlay_container = CreateContainer( |
| 426 kShellWindowId_OverlayContainer, | 548 kShellWindowId_OverlayContainer, |
| 427 "OverlayContainer", | 549 "OverlayContainer", |
| 428 lock_screen_related_containers); | 550 lock_screen_related_containers); |
| 429 SetUsesScreenCoordinates(overlay_container); | 551 SetUsesScreenCoordinates(overlay_container); |
| 430 } | 552 } |
| 431 | 553 |
| 432 } // namespace internal | 554 } // namespace internal |
| 433 } // namespace ash | 555 } // namespace ash |
| OLD | NEW |