shell.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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 3// found in the LICENSE file. 4 5#include "ash/shell.h" 6 7#include <algorithm> 8#include <string> 9 10#include "ash/accelerators/accelerator_controller.h" 11#include "ash/accelerators/accelerator_filter.h" 12#include "ash/accelerators/focus_manager_factory.h" 13#include "ash/accelerators/nested_dispatcher_controller.h" 14#include "ash/ash_switches.h" 15#include "ash/caps_lock_delegate.h" 16#include "ash/desktop_background/desktop_background_controller.h" 17#include "ash/desktop_background/desktop_background_view.h" 18#include "ash/desktop_background/user_wallpaper_delegate.h" 19#include "ash/display/display_controller.h" 20#include "ash/display/display_manager.h" 21#include "ash/display/event_transformation_handler.h" 22#include "ash/display/mouse_cursor_event_filter.h" 23#include "ash/display/resolution_notification_controller.h" 24#include "ash/display/screen_position_controller.h" 25#include "ash/drag_drop/drag_drop_controller.h" 26#include "ash/focus_cycler.h" 27#include "ash/high_contrast/high_contrast_controller.h" 28#include "ash/host/root_window_host_factory.h" 29#include "ash/launcher/launcher_delegate.h" 30#include "ash/launcher/launcher_item_delegate.h" 31#include "ash/launcher/launcher_item_delegate_manager.h" 32#include "ash/launcher/launcher_model.h" 33#include "ash/magnifier/magnification_controller.h" 34#include "ash/magnifier/partial_magnification_controller.h" 35#include "ash/root_window_controller.h" 36#include "ash/screen_ash.h" 37#include "ash/session_state_delegate.h" 38#include "ash/shelf/app_list_shelf_item_delegate.h" 39#include "ash/shelf/shelf_layout_manager.h" 40#include "ash/shelf/shelf_widget.h" 41#include "ash/shell_delegate.h" 42#include "ash/shell_factory.h" 43#include "ash/shell_window_ids.h" 44#include "ash/system/locale/locale_notification_controller.h" 45#include "ash/system/status_area_widget.h" 46#include "ash/system/tray/system_tray_delegate.h" 47#include "ash/system/tray/system_tray_notifier.h" 48#include "ash/wm/app_list_controller.h" 49#include "ash/wm/ash_focus_rules.h" 50#include "ash/wm/ash_native_cursor_manager.h" 51#include "ash/wm/base_layout_manager.h" 52#include "ash/wm/coordinate_conversion.h" 53#include "ash/wm/custom_frame_view_ash.h" 54#include "ash/wm/event_client_impl.h" 55#include "ash/wm/event_rewriter_event_filter.h" 56#include "ash/wm/lock_state_controller.h" 57#include "ash/wm/lock_state_controller_impl2.h" 58#include "ash/wm/mru_window_tracker.h" 59#include "ash/wm/overlay_event_filter.h" 60#include "ash/wm/overview/window_selector_controller.h" 61#include "ash/wm/power_button_controller.h" 62#include "ash/wm/resize_shadow_controller.h" 63#include "ash/wm/root_window_layout_manager.h" 64#include "ash/wm/screen_dimmer.h" 65#include "ash/wm/session_state_controller_impl.h" 66#include "ash/wm/system_gesture_event_filter.h" 67#include "ash/wm/system_modal_container_event_filter.h" 68#include "ash/wm/system_modal_container_layout_manager.h" 69#include "ash/wm/user_activity_detector.h" 70#include "ash/wm/video_detector.h" 71#include "ash/wm/window_animations.h" 72#include "ash/wm/window_cycle_controller.h" 73#include "ash/wm/window_properties.h" 74#include "ash/wm/window_util.h" 75#include "ash/wm/workspace_controller.h" 76#include "base/bind.h" 77#include "base/command_line.h" 78#include "base/debug/leak_annotations.h" 79#include "base/debug/trace_event.h" 80#include "ui/aura/client/aura_constants.h" 81#include "ui/aura/client/user_action_client.h" 82#include "ui/aura/env.h" 83#include "ui/aura/focus_manager.h" 84#include "ui/aura/layout_manager.h" 85#include "ui/aura/root_window.h" 86#include "ui/aura/window.h" 87#include "ui/base/ui_base_switches.h" 88#include "ui/compositor/layer.h" 89#include "ui/compositor/layer_animator.h" 90#include "ui/gfx/display.h" 91#include "ui/gfx/image/image_skia.h" 92#include "ui/gfx/screen.h" 93#include "ui/gfx/size.h" 94#include "ui/keyboard/keyboard.h" 95#include "ui/keyboard/keyboard_util.h" 96#include "ui/message_center/message_center.h" 97#include "ui/views/corewm/compound_event_filter.h" 98#include "ui/views/corewm/corewm_switches.h" 99#include "ui/views/corewm/focus_controller.h" 100#include "ui/views/corewm/input_method_event_filter.h" 101#include "ui/views/corewm/shadow_controller.h" 102#include "ui/views/corewm/tooltip_controller.h" 103#include "ui/views/corewm/visibility_controller.h" 104#include "ui/views/corewm/window_modality_controller.h" 105#include "ui/views/focus/focus_manager_factory.h" 106#include "ui/views/widget/native_widget_aura.h" 107#include "ui/views/widget/widget.h" 108 109#if defined(OS_CHROMEOS) 110#if defined(USE_X11) 111#include "ash/ash_constants.h" 112#include "ash/display/display_change_observer_chromeos.h" 113#include "ash/display/display_error_observer_chromeos.h" 114#include "ash/display/output_configurator_animation.h" 115#include "base/chromeos/chromeos_version.h" 116#include "base/message_loop/message_pump_x11.h" 117#include "chromeos/display/output_configurator.h" 118#include "content/public/browser/gpu_data_manager.h" 119#include "gpu/config/gpu_feature_type.h" 120#endif // defined(USE_X11) 121#include "ash/system/chromeos/power/power_status.h" 122#endif // defined(OS_CHROMEOS) 123 124namespace ash { 125 126namespace { 127 128using aura::Window; 129using views::Widget; 130 131// A Corewm VisibilityController subclass that calls the Ash animation routine 132// so we can pick up our extended animations. See ash/wm/window_animations.h. 133class AshVisibilityController : public views::corewm::VisibilityController { 134 public: 135 AshVisibilityController() {} 136 virtual ~AshVisibilityController() {} 137 138 private: 139 // Overridden from views::corewm::VisibilityController: 140 virtual bool CallAnimateOnChildWindowVisibilityChanged( 141 aura::Window* window, 142 bool visible) OVERRIDE { 143 return AnimateOnChildWindowVisibilityChanged(window, visible); 144 } 145 146 DISALLOW_COPY_AND_ASSIGN(AshVisibilityController); 147}; 148 149} // namespace 150 151// static 152Shell* Shell::instance_ = NULL; 153// static 154bool Shell::initially_hide_cursor_ = false; 155 156//////////////////////////////////////////////////////////////////////////////// 157// Shell, public: 158 159Shell::Shell(ShellDelegate* delegate) 160 : screen_(new ScreenAsh), 161 target_root_window_(NULL), 162 scoped_target_root_window_(NULL), 163 delegate_(delegate), 164 activation_client_(NULL), 165#if defined(OS_CHROMEOS) && defined(USE_X11) 166 output_configurator_(new chromeos::OutputConfigurator()), 167#endif // defined(OS_CHROMEOS) 168 native_cursor_manager_(new AshNativeCursorManager), 169 cursor_manager_(scoped_ptr<views::corewm::NativeCursorManager>( 170 native_cursor_manager_)), 171 browser_context_(NULL), 172 simulate_modal_window_open_for_testing_(false), 173 is_touch_hud_projection_enabled_(false) { 174 DCHECK(delegate_.get()); 175 display_manager_.reset(new internal::DisplayManager); 176 177 ANNOTATE_LEAKING_OBJECT_PTR(screen_); // see crbug.com/156466 178 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_); 179 if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)) 180 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_); 181 display_controller_.reset(new DisplayController); 182#if defined(OS_CHROMEOS) && defined(USE_X11) 183 bool is_panel_fitting_disabled = 184 content::GpuDataManager::GetInstance()->IsFeatureBlacklisted( 185 gpu::GPU_FEATURE_TYPE_PANEL_FITTING); 186 187 output_configurator_->Init(!is_panel_fitting_disabled); 188 189 base::MessagePumpX11::Current()->AddDispatcherForRootWindow( 190 output_configurator()); 191 // We can't do this with a root window listener because XI_HierarchyChanged 192 // messages don't have a target window. 193 base::MessagePumpX11::Current()->AddObserver(output_configurator()); 194#endif // defined(OS_CHROMEOS) 195 AddPreTargetHandler(this); 196 197#if defined(OS_CHROMEOS) 198 internal::PowerStatus::Initialize(); 199#endif 200} 201 202Shell::~Shell() { 203 TRACE_EVENT0("shutdown", "ash::Shell::Destructor"); 204 205 views::FocusManagerFactory::Install(NULL); 206 207 // Remove the focus from any window. This will prevent overhead and side 208 // effects (e.g. crashes) from changing focus during shutdown. 209 // See bug crbug.com/134502. 210 aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(NULL); 211 212 // Please keep in same order as in Init() because it's easy to miss one. 213 RemovePreTargetHandler(event_rewriter_filter_.get()); 214 RemovePreTargetHandler(user_activity_detector_.get()); 215 RemovePreTargetHandler(overlay_filter_.get()); 216 RemovePreTargetHandler(input_method_filter_.get()); 217 RemovePreTargetHandler(window_modality_controller_.get()); 218 if (mouse_cursor_filter_) 219 RemovePreTargetHandler(mouse_cursor_filter_.get()); 220 RemovePreTargetHandler(system_gesture_filter_.get()); 221 RemovePreTargetHandler(event_transformation_handler_.get()); 222 RemovePreTargetHandler(accelerator_filter_.get()); 223 224 // TooltipController is deleted with the Shell so removing its references. 225 RemovePreTargetHandler(tooltip_controller_.get()); 226 227 // AppList needs to be released before shelf layout manager, which is 228 // destroyed with launcher container in the loop below. However, app list 229 // container is now on top of launcher container and released after it. 230 // TODO(xiyuan): Move it back when app list container is no longer needed. 231 app_list_controller_.reset(); 232 233 // Destroy SystemTrayDelegate before destroying the status area(s). 234 system_tray_delegate_->Shutdown(); 235 system_tray_delegate_.reset(); 236 237 locale_notification_controller_.reset(); 238 239 // Drag-and-drop must be canceled prior to close all windows. 240 drag_drop_controller_.reset(); 241 242 // Destroy all child windows including widgets. 243 display_controller_->CloseChildWindows(); 244 245 // Destroy SystemTrayNotifier after destroying SystemTray as TrayItems 246 // needs to remove observers from it. 247 system_tray_notifier_.reset(); 248 249 // These need a valid Shell instance to clean up properly, so explicitly 250 // delete them before invalidating the instance. 251 // Alphabetical. TODO(oshima): sort. 252 magnification_controller_.reset(); 253 partial_magnification_controller_.reset(); 254 resize_shadow_controller_.reset(); 255 shadow_controller_.reset(); 256 tooltip_controller_.reset(); 257 event_client_.reset(); 258 window_cycle_controller_.reset(); 259 nested_dispatcher_controller_.reset(); 260 user_action_client_.reset(); 261 visibility_controller_.reset(); 262 launcher_delegate_.reset(); 263 launcher_model_.reset(); 264 video_detector_.reset(); 265 266 power_button_controller_.reset(); 267 lock_state_controller_.reset(); 268 mru_window_tracker_.reset(); 269 270 resolution_notification_controller_.reset(); 271 desktop_background_controller_.reset(); 272 273 // This also deletes all RootWindows. Note that we invoke Shutdown() on 274 // DisplayController before resetting |display_controller_|, since destruction 275 // of its owned RootWindowControllers relies on the value. 276 display_controller_->Shutdown(); 277 display_controller_.reset(); 278 screen_position_controller_.reset(); 279 280#if defined(OS_CHROMEOS) && defined(USE_X11) 281 if (display_change_observer_) 282 output_configurator_->RemoveObserver(display_change_observer_.get()); 283 if (output_configurator_animation_) 284 output_configurator_->RemoveObserver(output_configurator_animation_.get()); 285 if (display_error_observer_) 286 output_configurator_->RemoveObserver(display_error_observer_.get()); 287 base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow( 288 output_configurator()); 289 base::MessagePumpX11::Current()->RemoveObserver(output_configurator()); 290 display_change_observer_.reset(); 291#endif // defined(OS_CHROMEOS) 292 293#if defined(OS_CHROMEOS) 294 internal::PowerStatus::Shutdown(); 295#endif 296 297 DCHECK(instance_ == this); 298 instance_ = NULL; 299} 300 301// static 302Shell* Shell::CreateInstance(ShellDelegate* delegate) { 303 CHECK(!instance_); 304 instance_ = new Shell(delegate); 305 instance_->Init(); 306 return instance_; 307} 308 309// static 310Shell* Shell::GetInstance() { 311 DCHECK(instance_); 312 return instance_; 313} 314 315// static 316bool Shell::HasInstance() { 317 return !!instance_; 318} 319 320// static 321void Shell::DeleteInstance() { 322 delete instance_; 323 instance_ = NULL; 324} 325 326// static 327internal::RootWindowController* Shell::GetPrimaryRootWindowController() { 328 return internal::GetRootWindowController(GetPrimaryRootWindow()); 329} 330 331// static 332Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() { 333 return Shell::GetInstance()->display_controller()-> 334 GetAllRootWindowControllers(); 335} 336 337// static 338aura::RootWindow* Shell::GetPrimaryRootWindow() { 339 return GetInstance()->display_controller()->GetPrimaryRootWindow(); 340} 341 342// static 343aura::RootWindow* Shell::GetTargetRootWindow() { 344 Shell* shell = GetInstance(); 345 if (shell->scoped_target_root_window_) 346 return shell->scoped_target_root_window_; 347 return shell->target_root_window_; 348} 349 350// static 351gfx::Screen* Shell::GetScreen() { 352 return gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 353} 354 355// static 356Shell::RootWindowList Shell::GetAllRootWindows() { 357 return Shell::GetInstance()->display_controller()-> 358 GetAllRootWindows(); 359} 360 361// static 362aura::Window* Shell::GetContainer(aura::RootWindow* root_window, 363 int container_id) { 364 return root_window->GetChildById(container_id); 365} 366 367// static 368const aura::Window* Shell::GetContainer(const aura::RootWindow* root_window, 369 int container_id) { 370 return root_window->GetChildById(container_id); 371} 372 373// static 374std::vector<aura::Window*> Shell::GetContainersFromAllRootWindows( 375 int container_id, 376 aura::RootWindow* priority_root) { 377 std::vector<aura::Window*> containers; 378 RootWindowList root_windows = GetAllRootWindows(); 379 for (RootWindowList::const_iterator it = root_windows.begin(); 380 it != root_windows.end(); ++it) { 381 aura::Window* container = (*it)->GetChildById(container_id); 382 if (container) { 383 if (priority_root && priority_root->Contains(container)) 384 containers.insert(containers.begin(), container); 385 else 386 containers.push_back(container); 387 } 388 } 389 return containers; 390} 391 392// static 393bool Shell::IsForcedMaximizeMode() { 394 CommandLine* command_line = CommandLine::ForCurrentProcess(); 395 return command_line->HasSwitch(switches::kForcedMaximizeMode); 396} 397 398void Shell::Init() { 399 CommandLine* command_line = CommandLine::ForCurrentProcess(); 400 401 delegate_->PreInit(); 402 bool display_initialized = false; 403#if defined(OS_CHROMEOS) && defined(USE_X11) 404 output_configurator_animation_.reset( 405 new internal::OutputConfiguratorAnimation()); 406 output_configurator_->AddObserver(output_configurator_animation_.get()); 407 if (base::chromeos::IsRunningOnChromeOS()) { 408 display_change_observer_.reset(new internal::DisplayChangeObserver); 409 // Register |display_change_observer_| first so that the rest of 410 // observer gets invoked after the root windows are configured. 411 output_configurator_->AddObserver(display_change_observer_.get()); 412 display_error_observer_.reset(new internal::DisplayErrorObserver()); 413 output_configurator_->AddObserver(display_error_observer_.get()); 414 output_configurator_->set_state_controller(display_change_observer_.get()); 415 if (!command_line->HasSwitch(ash::switches::kAshDisableSoftwareMirroring)) 416 output_configurator_->set_mirroring_controller(display_manager_.get()); 417 output_configurator_->Start( 418 delegate_->IsFirstRunAfterBoot() ? kChromeOsBootColor : 0); 419 display_initialized = true; 420 } 421#endif // defined(OS_CHROMEOS) && defined(USE_X11) 422 if (!display_initialized) 423 display_manager_->InitFromCommandLine(); 424 425 // Install the custom factory first so that views::FocusManagers for Tray, 426 // Launcher, and WallPaper could be created by the factory. 427 views::FocusManagerFactory::Install(new AshFocusManagerFactory); 428 429 env_filter_.reset(new views::corewm::CompoundEventFilter); 430 AddPreTargetHandler(env_filter_.get()); 431 432 // Env creates the compositor. Historically it seems to have been implicitly 433 // initialized first by the ActivationController, but now that FocusController 434 // no longer does this we need to do it explicitly. 435 aura::Env::GetInstance(); 436 views::corewm::FocusController* focus_controller = 437 new views::corewm::FocusController(new wm::AshFocusRules); 438 focus_client_.reset(focus_controller); 439 activation_client_ = focus_controller; 440 activation_client_->AddObserver(this); 441 focus_cycler_.reset(new internal::FocusCycler()); 442 443 screen_position_controller_.reset(new internal::ScreenPositionController); 444 root_window_host_factory_.reset(delegate_->CreateRootWindowHostFactory()); 445 446 display_controller_->Start(); 447 display_controller_->InitPrimaryDisplay(); 448 aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow(); 449 target_root_window_ = root_window; 450 451 resolution_notification_controller_.reset( 452 new internal::ResolutionNotificationController); 453 454 cursor_manager_.SetDisplay(DisplayController::GetPrimaryDisplay()); 455 456 nested_dispatcher_controller_.reset(new NestedDispatcherController); 457 accelerator_controller_.reset(new AcceleratorController); 458 459 // The order in which event filters are added is significant. 460 event_rewriter_filter_.reset(new internal::EventRewriterEventFilter); 461 AddPreTargetHandler(event_rewriter_filter_.get()); 462 463 // UserActivityDetector passes events to observers, so let them get 464 // rewritten first. 465 user_activity_detector_.reset(new UserActivityDetector); 466 AddPreTargetHandler(user_activity_detector_.get()); 467 468 overlay_filter_.reset(new internal::OverlayEventFilter); 469 AddPreTargetHandler(overlay_filter_.get()); 470 AddShellObserver(overlay_filter_.get()); 471 472 input_method_filter_.reset(new views::corewm::InputMethodEventFilter( 473 root_window->GetAcceleratedWidget())); 474 AddPreTargetHandler(input_method_filter_.get()); 475 476 accelerator_filter_.reset(new internal::AcceleratorFilter); 477 AddPreTargetHandler(accelerator_filter_.get()); 478 479 event_transformation_handler_.reset(new internal::EventTransformationHandler); 480 AddPreTargetHandler(event_transformation_handler_.get()); 481 482 system_gesture_filter_.reset(new internal::SystemGestureEventFilter); 483 AddPreTargetHandler(system_gesture_filter_.get()); 484 485 // The keyboard system must be initialized before the RootWindowController is 486 // created. 487 if (keyboard::IsKeyboardEnabled()) 488 keyboard::InitializeKeyboard(); 489 490 if (command_line->HasSwitch(ash::switches::kAshDisableNewLockAnimations)) 491 lock_state_controller_.reset(new SessionStateControllerImpl); 492 else 493 lock_state_controller_.reset(new LockStateControllerImpl2); 494 power_button_controller_.reset(new PowerButtonController( 495 lock_state_controller_.get())); 496 AddShellObserver(lock_state_controller_.get()); 497 498 drag_drop_controller_.reset(new internal::DragDropController); 499 mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter()); 500 PrependPreTargetHandler(mouse_cursor_filter_.get()); 501 502 // Create Controllers that may need root window. 503 // TODO(oshima): Move as many controllers before creating 504 // RootWindowController as possible. 505 visibility_controller_.reset(new AshVisibilityController); 506 user_action_client_.reset(delegate_->CreateUserActionClient()); 507 window_modality_controller_.reset( 508 new views::corewm::WindowModalityController); 509 AddPreTargetHandler(window_modality_controller_.get()); 510 511 magnification_controller_.reset( 512 MagnificationController::CreateInstance()); 513 mru_window_tracker_.reset(new MruWindowTracker(activation_client_)); 514 515 partial_magnification_controller_.reset( 516 new PartialMagnificationController()); 517 518 high_contrast_controller_.reset(new HighContrastController); 519 video_detector_.reset(new VideoDetector); 520 window_cycle_controller_.reset(new WindowCycleController()); 521 window_selector_controller_.reset(new WindowSelectorController()); 522 523 tooltip_controller_.reset(new views::corewm::TooltipController( 524 gfx::SCREEN_TYPE_ALTERNATE)); 525 AddPreTargetHandler(tooltip_controller_.get()); 526 527 event_client_.reset(new internal::EventClientImpl); 528 529 // This controller needs to be set before SetupManagedWindowMode. 530 desktop_background_controller_.reset(new DesktopBackgroundController()); 531 user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate()); 532 533 // StatusAreaWidget uses Shell's CapsLockDelegate. 534 caps_lock_delegate_.reset(delegate_->CreateCapsLockDelegate()); 535 536 session_state_delegate_.reset(delegate_->CreateSessionStateDelegate()); 537 538 if (!command_line->HasSwitch(views::corewm::switches::kNoDropShadows)) { 539 resize_shadow_controller_.reset(new internal::ResizeShadowController()); 540 shadow_controller_.reset( 541 new views::corewm::ShadowController(activation_client_)); 542 } 543 544 // Create system_tray_notifier_ before the delegate. 545 system_tray_notifier_.reset(new ash::SystemTrayNotifier()); 546 547 // Initialize system_tray_delegate_ before initializing StatusAreaWidget. 548 system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate()); 549 DCHECK(system_tray_delegate_.get()); 550 551 internal::RootWindowController* root_window_controller = 552 new internal::RootWindowController(root_window); 553 InitRootWindowController(root_window_controller, 554 delegate_->IsFirstRunAfterBoot()); 555 556 locale_notification_controller_.reset( 557 new internal::LocaleNotificationController); 558 559 // Initialize system_tray_delegate_ after StatusAreaWidget is created. 560 system_tray_delegate_->Initialize(); 561 562 display_controller_->InitSecondaryDisplays(); 563 564 // Force Layout 565 root_window_controller->root_window_layout()->OnWindowResized(); 566 567 // It needs to be created after OnWindowResized has been called, otherwise the 568 // widget will not paint when restoring after a browser crash. Also it needs 569 // to be created after InitSecondaryDisplays() to initialize the wallpapers in 570 // the correct size. 571 user_wallpaper_delegate_->InitializeWallpaper(); 572 573 if (initially_hide_cursor_) 574 cursor_manager_.HideCursor(); 575 cursor_manager_.SetCursor(ui::kCursorPointer); 576 577 if (!cursor_manager_.IsCursorVisible()) { 578 // Cursor might have been hidden by something other than chrome. 579 // Let the first mouse event show the cursor. 580 env_filter_->set_cursor_hidden_by_filter(true); 581 } 582 583 // The compositor thread and main message loop have to be running in 584 // order to create mirror window. Run it after the main message loop 585 // is started. 586 base::MessageLoopForUI::current()->PostTask( 587 FROM_HERE, 588 base::Bind(&internal::DisplayManager::CreateMirrorWindowIfAny, 589 base::Unretained(display_manager_.get()))); 590} 591 592void Shell::ShowContextMenu(const gfx::Point& location_in_screen, 593 ui::MenuSourceType source_type) { 594 // No context menus if there is no session with an active user. 595 if (!session_state_delegate_->NumberOfLoggedInUsers()) 596 return; 597 // No context menus when screen is locked. 598 if (session_state_delegate_->IsScreenLocked()) 599 return; 600 601 aura::RootWindow* root = 602 wm::GetRootWindowMatching(gfx::Rect(location_in_screen, gfx::Size())); 603 // TODO(oshima): The root and root window controller shouldn't be 604 // NULL even for the out-of-bounds |location_in_screen| (It should 605 // return the primary root). Investigate why/how this is 606 // happening. crbug.com/165214. 607 internal::RootWindowController* rwc = internal::GetRootWindowController(root); 608 CHECK(rwc) << "root=" << root 609 << ", location:" << location_in_screen.ToString(); 610 if (rwc) 611 rwc->ShowContextMenu(location_in_screen, source_type); 612} 613 614void Shell::ToggleAppList(aura::Window* window) { 615 // If the context window is not given, show it on the target root window. 616 if (!window) 617 window = GetTargetRootWindow(); 618 if (!app_list_controller_) 619 app_list_controller_.reset(new internal::AppListController); 620 app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window); 621} 622 623bool Shell::GetAppListTargetVisibility() const { 624 return app_list_controller_.get() && 625 app_list_controller_->GetTargetVisibility(); 626} 627 628aura::Window* Shell::GetAppListWindow() { 629 return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL; 630} 631 632bool Shell::IsSystemModalWindowOpen() const { 633 if (simulate_modal_window_open_for_testing_) 634 return true; 635 const std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( 636 internal::kShellWindowId_SystemModalContainer, NULL); 637 for (std::vector<aura::Window*>::const_iterator cit = containers.begin(); 638 cit != containers.end(); ++cit) { 639 for (aura::Window::Windows::const_iterator wit = (*cit)->children().begin(); 640 wit != (*cit)->children().end(); ++wit) { 641 if ((*wit)->GetProperty(aura::client::kModalKey) == 642 ui::MODAL_TYPE_SYSTEM && (*wit)->TargetVisibility()) { 643 return true; 644 } 645 } 646 } 647 return false; 648} 649 650views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( 651 views::Widget* widget) { 652 // Use translucent-style window frames for dialogs. 653 CustomFrameViewAsh* frame_view = new CustomFrameViewAsh; 654 frame_view->Init(widget); 655 return frame_view; 656} 657 658void Shell::RotateFocus(Direction direction) { 659 focus_cycler_->RotateFocus( 660 direction == FORWARD ? internal::FocusCycler::FORWARD : 661 internal::FocusCycler::BACKWARD); 662} 663 664void Shell::SetDisplayWorkAreaInsets(Window* contains, 665 const gfx::Insets& insets) { 666 if (!display_controller_->UpdateWorkAreaOfDisplayNearestWindow( 667 contains, insets)) { 668 return; 669 } 670 FOR_EACH_OBSERVER(ShellObserver, observers_, 671 OnDisplayWorkAreaInsetsChanged()); 672} 673 674void Shell::OnLoginStateChanged(user::LoginStatus status) { 675 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLoginStateChanged(status)); 676} 677 678void Shell::UpdateAfterLoginStatusChange(user::LoginStatus status) { 679 RootWindowControllerList controllers = GetAllRootWindowControllers(); 680 for (RootWindowControllerList::iterator iter = controllers.begin(); 681 iter != controllers.end(); ++iter) 682 (*iter)->UpdateAfterLoginStatusChange(status); 683} 684 685void Shell::OnAppTerminating() { 686 FOR_EACH_OBSERVER(ShellObserver, observers_, OnAppTerminating()); 687} 688 689void Shell::OnLockStateChanged(bool locked) { 690 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLockStateChanged(locked)); 691#ifndef NDEBUG 692 // Make sure that there is no system modal in Lock layer when unlocked. 693 if (!locked) { 694 std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( 695 internal::kShellWindowId_LockSystemModalContainer, 696 GetPrimaryRootWindow()); 697 for (std::vector<aura::Window*>::const_iterator iter = containers.begin(); 698 iter != containers.end(); ++iter) { 699 DCHECK_EQ(0u, (*iter)->children().size()); 700 } 701 } 702#endif 703} 704 705void Shell::CreateLauncher() { 706 RootWindowControllerList controllers = GetAllRootWindowControllers(); 707 for (RootWindowControllerList::iterator iter = controllers.begin(); 708 iter != controllers.end(); ++iter) 709 (*iter)->shelf()->CreateLauncher(); 710} 711 712void Shell::ShowLauncher() { 713 RootWindowControllerList controllers = GetAllRootWindowControllers(); 714 for (RootWindowControllerList::iterator iter = controllers.begin(); 715 iter != controllers.end(); ++iter) 716 (*iter)->ShowLauncher(); 717} 718 719void Shell::AddShellObserver(ShellObserver* observer) { 720 observers_.AddObserver(observer); 721} 722 723void Shell::RemoveShellObserver(ShellObserver* observer) { 724 observers_.RemoveObserver(observer); 725} 726 727void Shell::UpdateShelfVisibility() { 728 RootWindowControllerList controllers = GetAllRootWindowControllers(); 729 for (RootWindowControllerList::iterator iter = controllers.begin(); 730 iter != controllers.end(); ++iter) 731 if ((*iter)->shelf()) 732 (*iter)->UpdateShelfVisibility(); 733} 734 735void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior, 736 aura::RootWindow* root_window) { 737 ash::internal::ShelfLayoutManager::ForLauncher(root_window)-> 738 SetAutoHideBehavior(behavior); 739} 740 741ShelfAutoHideBehavior Shell::GetShelfAutoHideBehavior( 742 aura::RootWindow* root_window) const { 743 return ash::internal::ShelfLayoutManager::ForLauncher(root_window)-> 744 auto_hide_behavior(); 745} 746 747void Shell::SetShelfAlignment(ShelfAlignment alignment, 748 aura::RootWindow* root_window) { 749 if (ash::internal::ShelfLayoutManager::ForLauncher(root_window)-> 750 SetAlignment(alignment)) { 751 FOR_EACH_OBSERVER( 752 ShellObserver, observers_, OnShelfAlignmentChanged(root_window)); 753 } 754} 755 756ShelfAlignment Shell::GetShelfAlignment(aura::RootWindow* root_window) { 757 return internal::GetRootWindowController(root_window)-> 758 GetShelfLayoutManager()->GetAlignment(); 759} 760 761void Shell::SetDimming(bool should_dim) { 762 RootWindowControllerList controllers = GetAllRootWindowControllers(); 763 for (RootWindowControllerList::iterator iter = controllers.begin(); 764 iter != controllers.end(); ++iter) 765 (*iter)->screen_dimmer()->SetDimming(should_dim); 766} 767 768void Shell::CreateModalBackground(aura::Window* window) { 769 if (!modality_filter_) { 770 modality_filter_.reset(new internal::SystemModalContainerEventFilter(this)); 771 AddPreTargetHandler(modality_filter_.get()); 772 } 773 RootWindowControllerList controllers = GetAllRootWindowControllers(); 774 for (RootWindowControllerList::iterator iter = controllers.begin(); 775 iter != controllers.end(); ++iter) 776 (*iter)->GetSystemModalLayoutManager(window)->CreateModalBackground(); 777} 778 779void Shell::OnModalWindowRemoved(aura::Window* removed) { 780 RootWindowControllerList controllers = GetAllRootWindowControllers(); 781 bool activated = false; 782 for (RootWindowControllerList::iterator iter = controllers.begin(); 783 iter != controllers.end() && !activated; ++iter) { 784 activated = (*iter)->GetSystemModalLayoutManager(removed)-> 785 ActivateNextModalWindow(); 786 } 787 if (!activated) { 788 RemovePreTargetHandler(modality_filter_.get()); 789 modality_filter_.reset(); 790 for (RootWindowControllerList::iterator iter = controllers.begin(); 791 iter != controllers.end(); ++iter) 792 (*iter)->GetSystemModalLayoutManager(removed)->DestroyModalBackground(); 793 } 794} 795 796WebNotificationTray* Shell::GetWebNotificationTray() { 797 return GetPrimaryRootWindowController()->shelf()-> 798 status_area_widget()->web_notification_tray(); 799} 800 801bool Shell::HasPrimaryStatusArea() { 802 ShelfWidget* shelf = GetPrimaryRootWindowController()->shelf(); 803 return shelf && shelf->status_area_widget(); 804} 805 806SystemTray* Shell::GetPrimarySystemTray() { 807 return GetPrimaryRootWindowController()->GetSystemTray(); 808} 809 810LauncherDelegate* Shell::GetLauncherDelegate() { 811 if (!launcher_delegate_) { 812 // Creates LauncherItemDelegateManager before LauncherDelegate. 813 launcher_item_delegate_manager_.reset(new LauncherItemDelegateManager); 814 launcher_model_.reset(new LauncherModel); 815 launcher_delegate_.reset( 816 delegate_->CreateLauncherDelegate(launcher_model_.get())); 817 app_list_shelf_item_delegate_.reset( 818 new internal::AppListShelfItemDelegate); 819 } 820 return launcher_delegate_.get(); 821} 822 823void Shell::SetTouchHudProjectionEnabled(bool enabled) { 824 if (is_touch_hud_projection_enabled_ == enabled) 825 return; 826 827 is_touch_hud_projection_enabled_ = enabled; 828 FOR_EACH_OBSERVER(ShellObserver, observers_, 829 OnTouchHudProjectionToggled(enabled)); 830} 831 832void Shell::InitRootWindowForSecondaryDisplay(aura::RootWindow* root) { 833 internal::RootWindowController* controller = 834 new internal::RootWindowController(root); 835 // Pass false for the |is_first_run_after_boot| parameter so we'll show a 836 // black background on this display instead of trying to mimic the boot splash 837 // screen. 838 InitRootWindowController(controller, false); 839 840 controller->root_window_layout()->OnWindowResized(); 841 desktop_background_controller_->OnRootWindowAdded(root); 842 high_contrast_controller_->OnRootWindowAdded(root); 843 root->ShowRootWindow(); 844 // Activate new root for testing. 845 // TODO(oshima): remove this. 846 target_root_window_ = root; 847 848 // Create a launcher if a user is already logged. 849 if (Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers()) 850 controller->shelf()->CreateLauncher(); 851} 852 853void Shell::DoInitialWorkspaceAnimation() { 854 return GetPrimaryRootWindowController()->workspace_controller()-> 855 DoInitialAnimation(); 856} 857 858void Shell::InitRootWindowController( 859 internal::RootWindowController* controller, 860 bool first_run_after_boot) { 861 862 aura::RootWindow* root_window = controller->root_window(); 863 DCHECK(activation_client_); 864 DCHECK(visibility_controller_.get()); 865 DCHECK(drag_drop_controller_.get()); 866 DCHECK(window_cycle_controller_.get()); 867 868 aura::client::SetFocusClient(root_window, focus_client_.get()); 869 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); 870 aura::client::SetActivationClient(root_window, activation_client_); 871 views::corewm::FocusController* focus_controller = 872 static_cast<views::corewm::FocusController*>(activation_client_); 873 root_window->AddPreTargetHandler(focus_controller); 874 aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); 875 aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); 876 aura::client::SetScreenPositionClient(root_window, 877 screen_position_controller_.get()); 878 aura::client::SetCursorClient(root_window, &cursor_manager_); 879 aura::client::SetTooltipClient(root_window, tooltip_controller_.get()); 880 aura::client::SetEventClient(root_window, event_client_.get()); 881 882 if (nested_dispatcher_controller_) { 883 aura::client::SetDispatcherClient(root_window, 884 nested_dispatcher_controller_.get()); 885 } 886 if (user_action_client_) 887 aura::client::SetUserActionClient(root_window, user_action_client_.get()); 888 889 controller->Init(first_run_after_boot); 890} 891 892//////////////////////////////////////////////////////////////////////////////// 893// Shell, private: 894 895bool Shell::CanWindowReceiveEvents(aura::Window* window) { 896 RootWindowControllerList controllers = GetAllRootWindowControllers(); 897 for (RootWindowControllerList::iterator iter = controllers.begin(); 898 iter != controllers.end(); ++iter) { 899 internal::SystemModalContainerLayoutManager* layout_manager = 900 (*iter)->GetSystemModalLayoutManager(window); 901 if (layout_manager && layout_manager->CanWindowReceiveEvents(window)) 902 return true; 903 } 904 return false; 905} 906 907//////////////////////////////////////////////////////////////////////////////// 908// Shell, ui::EventTarget overrides: 909 910bool Shell::CanAcceptEvent(const ui::Event& event) { 911 return true; 912} 913 914ui::EventTarget* Shell::GetParentTarget() { 915 return NULL; 916} 917 918void Shell::OnEvent(ui::Event* event) { 919} 920 921//////////////////////////////////////////////////////////////////////////////// 922// Shell, aura::client::ActivationChangeObserver implementation: 923 924void Shell::OnWindowActivated(aura::Window* gained_active, 925 aura::Window* lost_active) { 926 if (gained_active) 927 target_root_window_ = gained_active->GetRootWindow(); 928} 929 930} // namespace ash 931