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