Index: ash/shell.cc |
diff --git a/ash/shell.cc b/ash/shell.cc |
index 85740f81cb72fbf28f1e9ccb1c68e93c52ecbdb1..6726b2c1b6926476458ac07731bbdbfdefd2ffe6 100644 |
--- a/ash/shell.cc |
+++ b/ash/shell.cc |
@@ -92,6 +92,7 @@ |
#include "ui/gfx/screen.h" |
#include "ui/gfx/size.h" |
#include "ui/keyboard/keyboard.h" |
+#include "ui/keyboard/keyboard_controller.h" |
#include "ui/keyboard/keyboard_util.h" |
#include "ui/message_center/message_center.h" |
#include "ui/views/corewm/compound_event_filter.h" |
@@ -157,150 +158,6 @@ bool Shell::initially_hide_cursor_ = false; |
//////////////////////////////////////////////////////////////////////////////// |
// Shell, public: |
-Shell::Shell(ShellDelegate* delegate) |
oshima
2013/10/04 16:50:17
thank you for fixing this. next time, please do th
bshe
2013/10/04 17:38:32
Sorry about it. I should have done it in a separat
|
- : screen_(new ScreenAsh), |
- target_root_window_(NULL), |
- scoped_target_root_window_(NULL), |
- delegate_(delegate), |
- window_positioner_(new WindowPositioner), |
- activation_client_(NULL), |
-#if defined(OS_CHROMEOS) && defined(USE_X11) |
- output_configurator_(new chromeos::OutputConfigurator()), |
-#endif // defined(OS_CHROMEOS) |
- native_cursor_manager_(new AshNativeCursorManager), |
- cursor_manager_(scoped_ptr<views::corewm::NativeCursorManager>( |
- native_cursor_manager_)), |
- browser_context_(NULL), |
- simulate_modal_window_open_for_testing_(false), |
- is_touch_hud_projection_enabled_(false) { |
- DCHECK(delegate_.get()); |
- display_manager_.reset(new internal::DisplayManager); |
- |
- ANNOTATE_LEAKING_OBJECT_PTR(screen_); // see crbug.com/156466 |
- gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_); |
- if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)) |
- gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_); |
- display_controller_.reset(new DisplayController); |
-#if defined(OS_CHROMEOS) && defined(USE_X11) |
- bool is_panel_fitting_disabled = |
- content::GpuDataManager::GetInstance()->IsFeatureBlacklisted( |
- gpu::GPU_FEATURE_TYPE_PANEL_FITTING); |
- |
- output_configurator_->Init(!is_panel_fitting_disabled); |
- |
- base::MessagePumpX11::Current()->AddDispatcherForRootWindow( |
- output_configurator()); |
- // We can't do this with a root window listener because XI_HierarchyChanged |
- // messages don't have a target window. |
- base::MessagePumpX11::Current()->AddObserver(output_configurator()); |
-#endif // defined(OS_CHROMEOS) |
- |
-#if defined(OS_CHROMEOS) |
- internal::PowerStatus::Initialize(); |
-#endif |
-} |
- |
-Shell::~Shell() { |
- TRACE_EVENT0("shutdown", "ash::Shell::Destructor"); |
- |
- views::FocusManagerFactory::Install(NULL); |
- |
- // Remove the focus from any window. This will prevent overhead and side |
- // effects (e.g. crashes) from changing focus during shutdown. |
- // See bug crbug.com/134502. |
- aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(NULL); |
- |
- // Please keep in same order as in Init() because it's easy to miss one. |
- if (window_modality_controller_) |
- window_modality_controller_.reset(); |
- RemovePreTargetHandler(event_rewriter_filter_.get()); |
- RemovePreTargetHandler(user_activity_detector_.get()); |
- RemovePreTargetHandler(overlay_filter_.get()); |
- RemovePreTargetHandler(input_method_filter_.get()); |
- if (mouse_cursor_filter_) |
- RemovePreTargetHandler(mouse_cursor_filter_.get()); |
- RemovePreTargetHandler(system_gesture_filter_.get()); |
- RemovePreTargetHandler(keyboard_metrics_filter_.get()); |
- RemovePreTargetHandler(event_transformation_handler_.get()); |
- RemovePreTargetHandler(accelerator_filter_.get()); |
- |
- // TooltipController is deleted with the Shell so removing its references. |
- RemovePreTargetHandler(tooltip_controller_.get()); |
- |
- // AppList needs to be released before shelf layout manager, which is |
- // destroyed with launcher container in the loop below. However, app list |
- // container is now on top of launcher container and released after it. |
- // TODO(xiyuan): Move it back when app list container is no longer needed. |
- app_list_controller_.reset(); |
- |
- // Destroy SystemTrayDelegate before destroying the status area(s). |
- system_tray_delegate_->Shutdown(); |
- system_tray_delegate_.reset(); |
- |
- locale_notification_controller_.reset(); |
- |
- // Drag-and-drop must be canceled prior to close all windows. |
- drag_drop_controller_.reset(); |
- |
- // Destroy all child windows including widgets. |
- display_controller_->CloseChildWindows(); |
- |
- // Destroy SystemTrayNotifier after destroying SystemTray as TrayItems |
- // needs to remove observers from it. |
- system_tray_notifier_.reset(); |
- |
- // These need a valid Shell instance to clean up properly, so explicitly |
- // delete them before invalidating the instance. |
- // Alphabetical. TODO(oshima): sort. |
- magnification_controller_.reset(); |
- partial_magnification_controller_.reset(); |
- resize_shadow_controller_.reset(); |
- shadow_controller_.reset(); |
- tooltip_controller_.reset(); |
- event_client_.reset(); |
- window_cycle_controller_.reset(); |
- nested_dispatcher_controller_.reset(); |
- user_action_client_.reset(); |
- visibility_controller_.reset(); |
- launcher_delegate_.reset(); |
- launcher_model_.reset(); |
- video_detector_.reset(); |
- |
- power_button_controller_.reset(); |
- lock_state_controller_.reset(); |
- mru_window_tracker_.reset(); |
- |
- resolution_notification_controller_.reset(); |
- desktop_background_controller_.reset(); |
- |
- // This also deletes all RootWindows. Note that we invoke Shutdown() on |
- // DisplayController before resetting |display_controller_|, since destruction |
- // of its owned RootWindowControllers relies on the value. |
- display_controller_->Shutdown(); |
- display_controller_.reset(); |
- screen_position_controller_.reset(); |
- |
-#if defined(OS_CHROMEOS) && defined(USE_X11) |
- if (display_change_observer_) |
- output_configurator_->RemoveObserver(display_change_observer_.get()); |
- if (output_configurator_animation_) |
- output_configurator_->RemoveObserver(output_configurator_animation_.get()); |
- if (display_error_observer_) |
- output_configurator_->RemoveObserver(display_error_observer_.get()); |
- base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow( |
- output_configurator()); |
- base::MessagePumpX11::Current()->RemoveObserver(output_configurator()); |
- display_change_observer_.reset(); |
-#endif // defined(OS_CHROMEOS) |
- |
-#if defined(OS_CHROMEOS) |
- internal::PowerStatus::Shutdown(); |
-#endif |
- |
- DCHECK(instance_ == this); |
- instance_ = NULL; |
-} |
- |
// static |
Shell* Shell::CreateInstance(ShellDelegate* delegate) { |
CHECK(!instance_); |
@@ -398,283 +255,77 @@ bool Shell::IsForcedMaximizeMode() { |
return command_line->HasSwitch(switches::kForcedMaximizeMode); |
} |
-void Shell::Init() { |
- CommandLine* command_line = CommandLine::ForCurrentProcess(); |
+void Shell::ShowContextMenu(const gfx::Point& location_in_screen, |
+ ui::MenuSourceType source_type) { |
+ // No context menus if there is no session with an active user. |
+ if (!session_state_delegate_->NumberOfLoggedInUsers()) |
+ return; |
+ // No context menus when screen is locked. |
+ if (session_state_delegate_->IsScreenLocked()) |
+ return; |
- delegate_->PreInit(); |
- bool display_initialized = false; |
-#if defined(OS_CHROMEOS) && defined(USE_X11) |
- output_configurator_animation_.reset( |
- new internal::OutputConfiguratorAnimation()); |
- output_configurator_->AddObserver(output_configurator_animation_.get()); |
- if (base::SysInfo::IsRunningOnChromeOS()) { |
- display_change_observer_.reset(new internal::DisplayChangeObserver); |
- // Register |display_change_observer_| first so that the rest of |
- // observer gets invoked after the root windows are configured. |
- output_configurator_->AddObserver(display_change_observer_.get()); |
- display_error_observer_.reset(new internal::DisplayErrorObserver()); |
- output_configurator_->AddObserver(display_error_observer_.get()); |
- output_configurator_->set_state_controller(display_change_observer_.get()); |
- if (!command_line->HasSwitch(ash::switches::kAshDisableSoftwareMirroring)) |
- output_configurator_->set_mirroring_controller(display_manager_.get()); |
- output_configurator_->Start( |
- delegate_->IsFirstRunAfterBoot() ? kChromeOsBootColor : 0); |
- display_initialized = true; |
- } |
-#endif // defined(OS_CHROMEOS) && defined(USE_X11) |
- if (!display_initialized) |
- display_manager_->InitFromCommandLine(); |
+ aura::RootWindow* root = |
+ wm::GetRootWindowMatching(gfx::Rect(location_in_screen, gfx::Size())); |
+ // TODO(oshima): The root and root window controller shouldn't be |
+ // NULL even for the out-of-bounds |location_in_screen| (It should |
+ // return the primary root). Investigate why/how this is |
+ // happening. crbug.com/165214. |
+ internal::RootWindowController* rwc = internal::GetRootWindowController(root); |
+ CHECK(rwc) << "root=" << root |
+ << ", location:" << location_in_screen.ToString(); |
+ if (rwc) |
+ rwc->ShowContextMenu(location_in_screen, source_type); |
+} |
- // Install the custom factory first so that views::FocusManagers for Tray, |
- // Launcher, and WallPaper could be created by the factory. |
- views::FocusManagerFactory::Install(new AshFocusManagerFactory); |
+void Shell::ToggleAppList(aura::Window* window) { |
+ // If the context window is not given, show it on the target root window. |
+ if (!window) |
+ window = GetTargetRootWindow(); |
+ if (!app_list_controller_) |
+ app_list_controller_.reset(new internal::AppListController); |
+ app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window); |
+} |
- // The WindowModalityController needs to be at the front of the input event |
- // pretarget handler list to ensure that it processes input events when modal |
- // windows are active. |
- window_modality_controller_.reset( |
- new views::corewm::WindowModalityController(this)); |
+bool Shell::GetAppListTargetVisibility() const { |
+ return app_list_controller_.get() && |
+ app_list_controller_->GetTargetVisibility(); |
+} |
- AddPreTargetHandler(this); |
+aura::Window* Shell::GetAppListWindow() { |
+ return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL; |
+} |
- env_filter_.reset(new views::corewm::CompoundEventFilter); |
- AddPreTargetHandler(env_filter_.get()); |
+bool Shell::IsSystemModalWindowOpen() const { |
+ if (simulate_modal_window_open_for_testing_) |
+ return true; |
+ const std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( |
+ internal::kShellWindowId_SystemModalContainer, NULL); |
+ for (std::vector<aura::Window*>::const_iterator cit = containers.begin(); |
+ cit != containers.end(); ++cit) { |
+ for (aura::Window::Windows::const_iterator wit = (*cit)->children().begin(); |
+ wit != (*cit)->children().end(); ++wit) { |
+ if ((*wit)->GetProperty(aura::client::kModalKey) == |
+ ui::MODAL_TYPE_SYSTEM && (*wit)->TargetVisibility()) { |
+ return true; |
+ } |
+ } |
+ } |
+ return false; |
+} |
- // Env creates the compositor. Historically it seems to have been implicitly |
- // initialized first by the ActivationController, but now that FocusController |
- // no longer does this we need to do it explicitly. |
- aura::Env::GetInstance(); |
- views::corewm::FocusController* focus_controller = |
- new views::corewm::FocusController(new wm::AshFocusRules); |
- focus_client_.reset(focus_controller); |
- activation_client_ = focus_controller; |
- activation_client_->AddObserver(this); |
- focus_cycler_.reset(new internal::FocusCycler()); |
+views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( |
+ views::Widget* widget) { |
+ // Use translucent-style window frames for dialogs. |
+ CustomFrameViewAsh* frame_view = new CustomFrameViewAsh; |
+ frame_view->Init(widget); |
+ return frame_view; |
+} |
- screen_position_controller_.reset(new internal::ScreenPositionController); |
- root_window_host_factory_.reset(delegate_->CreateRootWindowHostFactory()); |
- |
- display_controller_->Start(); |
- display_controller_->InitPrimaryDisplay(); |
- aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow(); |
- target_root_window_ = root_window; |
- |
- resolution_notification_controller_.reset( |
- new internal::ResolutionNotificationController); |
- |
- cursor_manager_.SetDisplay(DisplayController::GetPrimaryDisplay()); |
- |
- nested_dispatcher_controller_.reset(new NestedDispatcherController); |
- accelerator_controller_.reset(new AcceleratorController); |
- |
- // The order in which event filters are added is significant. |
- event_rewriter_filter_.reset(new internal::EventRewriterEventFilter); |
- AddPreTargetHandler(event_rewriter_filter_.get()); |
- |
- // UserActivityDetector passes events to observers, so let them get |
- // rewritten first. |
- user_activity_detector_.reset(new UserActivityDetector); |
- AddPreTargetHandler(user_activity_detector_.get()); |
- |
- overlay_filter_.reset(new internal::OverlayEventFilter); |
- AddPreTargetHandler(overlay_filter_.get()); |
- AddShellObserver(overlay_filter_.get()); |
- |
- input_method_filter_.reset(new views::corewm::InputMethodEventFilter( |
- root_window->GetAcceleratedWidget())); |
- AddPreTargetHandler(input_method_filter_.get()); |
- |
- accelerator_filter_.reset(new internal::AcceleratorFilter); |
- AddPreTargetHandler(accelerator_filter_.get()); |
- |
- event_transformation_handler_.reset(new internal::EventTransformationHandler); |
- AddPreTargetHandler(event_transformation_handler_.get()); |
- |
- system_gesture_filter_.reset(new internal::SystemGestureEventFilter); |
- AddPreTargetHandler(system_gesture_filter_.get()); |
- |
- keyboard_metrics_filter_.reset(new internal::KeyboardUMAEventFilter); |
- AddPreTargetHandler(keyboard_metrics_filter_.get()); |
- |
- // The keyboard system must be initialized before the RootWindowController is |
- // created. |
- if (keyboard::IsKeyboardEnabled()) |
- keyboard::InitializeKeyboard(); |
- |
- lock_state_controller_.reset(new LockStateController); |
- power_button_controller_.reset(new PowerButtonController( |
- lock_state_controller_.get())); |
- AddShellObserver(lock_state_controller_.get()); |
- |
- drag_drop_controller_.reset(new internal::DragDropController); |
- mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter()); |
- PrependPreTargetHandler(mouse_cursor_filter_.get()); |
- |
- // Create Controllers that may need root window. |
- // TODO(oshima): Move as many controllers before creating |
- // RootWindowController as possible. |
- visibility_controller_.reset(new AshVisibilityController); |
- user_action_client_.reset(delegate_->CreateUserActionClient()); |
- |
- magnification_controller_.reset( |
- MagnificationController::CreateInstance()); |
- mru_window_tracker_.reset(new MruWindowTracker(activation_client_)); |
- |
- partial_magnification_controller_.reset( |
- new PartialMagnificationController()); |
- |
- high_contrast_controller_.reset(new HighContrastController); |
- video_detector_.reset(new VideoDetector); |
- window_cycle_controller_.reset(new WindowCycleController()); |
- window_selector_controller_.reset(new WindowSelectorController()); |
- |
- tooltip_controller_.reset(new views::corewm::TooltipController( |
- gfx::SCREEN_TYPE_ALTERNATE)); |
- AddPreTargetHandler(tooltip_controller_.get()); |
- |
- event_client_.reset(new internal::EventClientImpl); |
- |
- // This controller needs to be set before SetupManagedWindowMode. |
- desktop_background_controller_.reset(new DesktopBackgroundController()); |
- user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate()); |
- |
- // StatusAreaWidget uses Shell's CapsLockDelegate. |
- caps_lock_delegate_.reset(delegate_->CreateCapsLockDelegate()); |
- |
- session_state_delegate_.reset(delegate_->CreateSessionStateDelegate()); |
- |
- if (!command_line->HasSwitch(views::corewm::switches::kNoDropShadows)) { |
- resize_shadow_controller_.reset(new internal::ResizeShadowController()); |
- shadow_controller_.reset( |
- new views::corewm::ShadowController(activation_client_)); |
- } |
- |
- // Create system_tray_notifier_ before the delegate. |
- system_tray_notifier_.reset(new ash::SystemTrayNotifier()); |
- |
- // Initialize system_tray_delegate_ before initializing StatusAreaWidget. |
- system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate()); |
- DCHECK(system_tray_delegate_.get()); |
- |
- internal::RootWindowController* root_window_controller = |
- new internal::RootWindowController(root_window); |
- InitRootWindowController(root_window_controller, |
- delegate_->IsFirstRunAfterBoot()); |
- |
- locale_notification_controller_.reset( |
- new internal::LocaleNotificationController); |
- |
- // Initialize system_tray_delegate_ after StatusAreaWidget is created. |
- system_tray_delegate_->Initialize(); |
- |
- display_controller_->InitSecondaryDisplays(); |
- |
- // Force Layout |
- root_window_controller->root_window_layout()->OnWindowResized(); |
- |
- // It needs to be created after OnWindowResized has been called, otherwise the |
- // widget will not paint when restoring after a browser crash. Also it needs |
- // to be created after InitSecondaryDisplays() to initialize the wallpapers in |
- // the correct size. |
- user_wallpaper_delegate_->InitializeWallpaper(); |
- |
- if (initially_hide_cursor_) |
- cursor_manager_.HideCursor(); |
- cursor_manager_.SetCursor(ui::kCursorPointer); |
- |
- if (!cursor_manager_.IsCursorVisible()) { |
- // Cursor might have been hidden by something other than chrome. |
- // Let the first mouse event show the cursor. |
- env_filter_->set_cursor_hidden_by_filter(true); |
- } |
- |
- // Set accelerator controller delegates. |
-#if defined(OS_CHROMEOS) |
- accelerator_controller_->SetBrightnessControlDelegate( |
- scoped_ptr<ash::BrightnessControlDelegate>( |
- new ash::system::BrightnessControllerChromeos).Pass()); |
-#endif |
- |
- // The compositor thread and main message loop have to be running in |
- // order to create mirror window. Run it after the main message loop |
- // is started. |
- base::MessageLoopForUI::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&internal::DisplayManager::CreateMirrorWindowIfAny, |
- base::Unretained(display_manager_.get()))); |
-} |
- |
-void Shell::ShowContextMenu(const gfx::Point& location_in_screen, |
- ui::MenuSourceType source_type) { |
- // No context menus if there is no session with an active user. |
- if (!session_state_delegate_->NumberOfLoggedInUsers()) |
- return; |
- // No context menus when screen is locked. |
- if (session_state_delegate_->IsScreenLocked()) |
- return; |
- |
- aura::RootWindow* root = |
- wm::GetRootWindowMatching(gfx::Rect(location_in_screen, gfx::Size())); |
- // TODO(oshima): The root and root window controller shouldn't be |
- // NULL even for the out-of-bounds |location_in_screen| (It should |
- // return the primary root). Investigate why/how this is |
- // happening. crbug.com/165214. |
- internal::RootWindowController* rwc = internal::GetRootWindowController(root); |
- CHECK(rwc) << "root=" << root |
- << ", location:" << location_in_screen.ToString(); |
- if (rwc) |
- rwc->ShowContextMenu(location_in_screen, source_type); |
-} |
- |
-void Shell::ToggleAppList(aura::Window* window) { |
- // If the context window is not given, show it on the target root window. |
- if (!window) |
- window = GetTargetRootWindow(); |
- if (!app_list_controller_) |
- app_list_controller_.reset(new internal::AppListController); |
- app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window); |
-} |
- |
-bool Shell::GetAppListTargetVisibility() const { |
- return app_list_controller_.get() && |
- app_list_controller_->GetTargetVisibility(); |
-} |
- |
-aura::Window* Shell::GetAppListWindow() { |
- return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL; |
-} |
- |
-bool Shell::IsSystemModalWindowOpen() const { |
- if (simulate_modal_window_open_for_testing_) |
- return true; |
- const std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( |
- internal::kShellWindowId_SystemModalContainer, NULL); |
- for (std::vector<aura::Window*>::const_iterator cit = containers.begin(); |
- cit != containers.end(); ++cit) { |
- for (aura::Window::Windows::const_iterator wit = (*cit)->children().begin(); |
- wit != (*cit)->children().end(); ++wit) { |
- if ((*wit)->GetProperty(aura::client::kModalKey) == |
- ui::MODAL_TYPE_SYSTEM && (*wit)->TargetVisibility()) { |
- return true; |
- } |
- } |
- } |
- return false; |
-} |
- |
-views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( |
- views::Widget* widget) { |
- // Use translucent-style window frames for dialogs. |
- CustomFrameViewAsh* frame_view = new CustomFrameViewAsh; |
- frame_view->Init(widget); |
- return frame_view; |
-} |
- |
-void Shell::RotateFocus(Direction direction) { |
- focus_cycler_->RotateFocus( |
- direction == FORWARD ? internal::FocusCycler::FORWARD : |
- internal::FocusCycler::BACKWARD); |
-} |
+void Shell::RotateFocus(Direction direction) { |
+ focus_cycler_->RotateFocus( |
+ direction == FORWARD ? internal::FocusCycler::FORWARD : |
+ internal::FocusCycler::BACKWARD); |
+} |
void Shell::SetDisplayWorkAreaInsets(Window* contains, |
const gfx::Insets& insets) { |
@@ -687,6 +338,11 @@ void Shell::SetDisplayWorkAreaInsets(Window* contains, |
} |
void Shell::OnLoginStateChanged(user::LoginStatus status) { |
+ if (status != user::LOGGED_IN_NONE) { |
+ // TODO(bshe): Primary root window controller may not be the controller to |
+ // attach virtual keyboard. See http://crbug.com/303429 |
+ InitKeyboard(GetPrimaryRootWindowController()); |
+ } |
FOR_EACH_OBSERVER(ShellObserver, observers_, OnLoginStateChanged(status)); |
} |
@@ -876,21 +532,392 @@ void Shell::DoInitialWorkspaceAnimation() { |
DoInitialAnimation(); |
} |
-void Shell::InitRootWindowController( |
- internal::RootWindowController* controller, |
- bool first_run_after_boot) { |
+//////////////////////////////////////////////////////////////////////////////// |
+// Shell, private: |
- aura::RootWindow* root_window = controller->root_window(); |
- DCHECK(activation_client_); |
- DCHECK(visibility_controller_.get()); |
- DCHECK(drag_drop_controller_.get()); |
- DCHECK(window_cycle_controller_.get()); |
+Shell::Shell(ShellDelegate* delegate) |
+ : screen_(new ScreenAsh), |
+ target_root_window_(NULL), |
+ scoped_target_root_window_(NULL), |
+ delegate_(delegate), |
+ window_positioner_(new WindowPositioner), |
+ activation_client_(NULL), |
+#if defined(OS_CHROMEOS) && defined(USE_X11) |
+ output_configurator_(new chromeos::OutputConfigurator()), |
+#endif // defined(OS_CHROMEOS) |
+ native_cursor_manager_(new AshNativeCursorManager), |
+ cursor_manager_(scoped_ptr<views::corewm::NativeCursorManager>( |
+ native_cursor_manager_)), |
+ browser_context_(NULL), |
+ simulate_modal_window_open_for_testing_(false), |
+ is_touch_hud_projection_enabled_(false) { |
+ DCHECK(delegate_.get()); |
+ display_manager_.reset(new internal::DisplayManager); |
- aura::client::SetFocusClient(root_window, focus_client_.get()); |
- input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); |
- aura::client::SetActivationClient(root_window, activation_client_); |
- views::corewm::FocusController* focus_controller = |
- static_cast<views::corewm::FocusController*>(activation_client_); |
+ ANNOTATE_LEAKING_OBJECT_PTR(screen_); // see crbug.com/156466 |
+ gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_); |
+ if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)) |
+ gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_); |
+ display_controller_.reset(new DisplayController); |
+#if defined(OS_CHROMEOS) && defined(USE_X11) |
+ bool is_panel_fitting_disabled = |
+ content::GpuDataManager::GetInstance()->IsFeatureBlacklisted( |
+ gpu::GPU_FEATURE_TYPE_PANEL_FITTING); |
+ |
+ output_configurator_->Init(!is_panel_fitting_disabled); |
+ |
+ base::MessagePumpX11::Current()->AddDispatcherForRootWindow( |
+ output_configurator()); |
+ // We can't do this with a root window listener because XI_HierarchyChanged |
+ // messages don't have a target window. |
+ base::MessagePumpX11::Current()->AddObserver(output_configurator()); |
+#endif // defined(OS_CHROMEOS) |
+ |
+#if defined(OS_CHROMEOS) |
+ internal::PowerStatus::Initialize(); |
+#endif |
+} |
+ |
+Shell::~Shell() { |
+ TRACE_EVENT0("shutdown", "ash::Shell::Destructor"); |
+ |
+ views::FocusManagerFactory::Install(NULL); |
+ |
+ // Remove the focus from any window. This will prevent overhead and side |
+ // effects (e.g. crashes) from changing focus during shutdown. |
+ // See bug crbug.com/134502. |
+ aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(NULL); |
+ |
+ // Please keep in same order as in Init() because it's easy to miss one. |
+ if (window_modality_controller_) |
+ window_modality_controller_.reset(); |
+ RemovePreTargetHandler(event_rewriter_filter_.get()); |
+ RemovePreTargetHandler(user_activity_detector_.get()); |
+ RemovePreTargetHandler(overlay_filter_.get()); |
+ RemovePreTargetHandler(input_method_filter_.get()); |
+ if (mouse_cursor_filter_) |
+ RemovePreTargetHandler(mouse_cursor_filter_.get()); |
+ RemovePreTargetHandler(system_gesture_filter_.get()); |
+ RemovePreTargetHandler(keyboard_metrics_filter_.get()); |
+ RemovePreTargetHandler(event_transformation_handler_.get()); |
+ RemovePreTargetHandler(accelerator_filter_.get()); |
+ |
+ // TooltipController is deleted with the Shell so removing its references. |
+ RemovePreTargetHandler(tooltip_controller_.get()); |
+ |
+ // AppList needs to be released before shelf layout manager, which is |
+ // destroyed with launcher container in the loop below. However, app list |
+ // container is now on top of launcher container and released after it. |
+ // TODO(xiyuan): Move it back when app list container is no longer needed. |
+ app_list_controller_.reset(); |
+ |
+ // Destroy SystemTrayDelegate before destroying the status area(s). |
+ system_tray_delegate_->Shutdown(); |
+ system_tray_delegate_.reset(); |
+ |
+ locale_notification_controller_.reset(); |
+ |
+ // Drag-and-drop must be canceled prior to close all windows. |
+ drag_drop_controller_.reset(); |
+ |
+ // Destroy all child windows including widgets. |
+ display_controller_->CloseChildWindows(); |
+ |
+ // Destroy SystemTrayNotifier after destroying SystemTray as TrayItems |
+ // needs to remove observers from it. |
+ system_tray_notifier_.reset(); |
+ |
+ // These need a valid Shell instance to clean up properly, so explicitly |
+ // delete them before invalidating the instance. |
+ // Alphabetical. TODO(oshima): sort. |
+ magnification_controller_.reset(); |
+ partial_magnification_controller_.reset(); |
+ resize_shadow_controller_.reset(); |
+ shadow_controller_.reset(); |
+ tooltip_controller_.reset(); |
+ event_client_.reset(); |
+ window_cycle_controller_.reset(); |
+ nested_dispatcher_controller_.reset(); |
+ user_action_client_.reset(); |
+ visibility_controller_.reset(); |
+ launcher_delegate_.reset(); |
+ launcher_model_.reset(); |
+ video_detector_.reset(); |
+ |
+ power_button_controller_.reset(); |
+ lock_state_controller_.reset(); |
+ mru_window_tracker_.reset(); |
+ |
+ resolution_notification_controller_.reset(); |
+ desktop_background_controller_.reset(); |
+ |
+ // This also deletes all RootWindows. Note that we invoke Shutdown() on |
+ // DisplayController before resetting |display_controller_|, since destruction |
+ // of its owned RootWindowControllers relies on the value. |
+ display_controller_->Shutdown(); |
+ display_controller_.reset(); |
+ screen_position_controller_.reset(); |
+ |
oshima
2013/10/04 16:50:17
maybe you should reset the controller before setti
bshe
2013/10/04 17:38:32
Done. keyboard_controller doesn't depend on shell
|
+#if defined(OS_CHROMEOS) && defined(USE_X11) |
+ if (display_change_observer_) |
+ output_configurator_->RemoveObserver(display_change_observer_.get()); |
+ if (output_configurator_animation_) |
+ output_configurator_->RemoveObserver(output_configurator_animation_.get()); |
+ if (display_error_observer_) |
+ output_configurator_->RemoveObserver(display_error_observer_.get()); |
+ base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow( |
+ output_configurator()); |
+ base::MessagePumpX11::Current()->RemoveObserver(output_configurator()); |
+ display_change_observer_.reset(); |
+#endif // defined(OS_CHROMEOS) |
+ |
+#if defined(OS_CHROMEOS) |
+ internal::PowerStatus::Shutdown(); |
+#endif |
+ |
+ DCHECK(instance_ == this); |
+ instance_ = NULL; |
+} |
+ |
+void Shell::Init() { |
+ CommandLine* command_line = CommandLine::ForCurrentProcess(); |
+ |
+ delegate_->PreInit(); |
+ bool display_initialized = false; |
+#if defined(OS_CHROMEOS) && defined(USE_X11) |
+ output_configurator_animation_.reset( |
+ new internal::OutputConfiguratorAnimation()); |
+ output_configurator_->AddObserver(output_configurator_animation_.get()); |
+ if (base::SysInfo::IsRunningOnChromeOS()) { |
+ display_change_observer_.reset(new internal::DisplayChangeObserver); |
+ // Register |display_change_observer_| first so that the rest of |
+ // observer gets invoked after the root windows are configured. |
+ output_configurator_->AddObserver(display_change_observer_.get()); |
+ display_error_observer_.reset(new internal::DisplayErrorObserver()); |
+ output_configurator_->AddObserver(display_error_observer_.get()); |
+ output_configurator_->set_state_controller(display_change_observer_.get()); |
+ if (!command_line->HasSwitch(ash::switches::kAshDisableSoftwareMirroring)) |
+ output_configurator_->set_mirroring_controller(display_manager_.get()); |
+ output_configurator_->Start( |
+ delegate_->IsFirstRunAfterBoot() ? kChromeOsBootColor : 0); |
+ display_initialized = true; |
+ } |
+#endif // defined(OS_CHROMEOS) && defined(USE_X11) |
+ if (!display_initialized) |
+ display_manager_->InitFromCommandLine(); |
+ |
+ // Install the custom factory first so that views::FocusManagers for Tray, |
+ // Launcher, and WallPaper could be created by the factory. |
+ views::FocusManagerFactory::Install(new AshFocusManagerFactory); |
+ |
+ // The WindowModalityController needs to be at the front of the input event |
+ // pretarget handler list to ensure that it processes input events when modal |
+ // windows are active. |
+ window_modality_controller_.reset( |
+ new views::corewm::WindowModalityController(this)); |
+ |
+ AddPreTargetHandler(this); |
+ |
+ env_filter_.reset(new views::corewm::CompoundEventFilter); |
+ AddPreTargetHandler(env_filter_.get()); |
+ |
+ // Env creates the compositor. Historically it seems to have been implicitly |
+ // initialized first by the ActivationController, but now that FocusController |
+ // no longer does this we need to do it explicitly. |
+ aura::Env::GetInstance(); |
+ views::corewm::FocusController* focus_controller = |
+ new views::corewm::FocusController(new wm::AshFocusRules); |
+ focus_client_.reset(focus_controller); |
+ activation_client_ = focus_controller; |
+ activation_client_->AddObserver(this); |
+ focus_cycler_.reset(new internal::FocusCycler()); |
+ |
+ screen_position_controller_.reset(new internal::ScreenPositionController); |
+ root_window_host_factory_.reset(delegate_->CreateRootWindowHostFactory()); |
+ |
+ display_controller_->Start(); |
+ display_controller_->InitPrimaryDisplay(); |
+ aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow(); |
+ target_root_window_ = root_window; |
+ |
+ resolution_notification_controller_.reset( |
+ new internal::ResolutionNotificationController); |
+ |
+ cursor_manager_.SetDisplay(DisplayController::GetPrimaryDisplay()); |
+ |
+ nested_dispatcher_controller_.reset(new NestedDispatcherController); |
+ accelerator_controller_.reset(new AcceleratorController); |
+ |
+ // The order in which event filters are added is significant. |
+ event_rewriter_filter_.reset(new internal::EventRewriterEventFilter); |
+ AddPreTargetHandler(event_rewriter_filter_.get()); |
+ |
+ // UserActivityDetector passes events to observers, so let them get |
+ // rewritten first. |
+ user_activity_detector_.reset(new UserActivityDetector); |
+ AddPreTargetHandler(user_activity_detector_.get()); |
+ |
+ overlay_filter_.reset(new internal::OverlayEventFilter); |
+ AddPreTargetHandler(overlay_filter_.get()); |
+ AddShellObserver(overlay_filter_.get()); |
+ |
+ input_method_filter_.reset(new views::corewm::InputMethodEventFilter( |
+ root_window->GetAcceleratedWidget())); |
+ AddPreTargetHandler(input_method_filter_.get()); |
+ |
+ accelerator_filter_.reset(new internal::AcceleratorFilter); |
+ AddPreTargetHandler(accelerator_filter_.get()); |
+ |
+ event_transformation_handler_.reset(new internal::EventTransformationHandler); |
+ AddPreTargetHandler(event_transformation_handler_.get()); |
+ |
+ system_gesture_filter_.reset(new internal::SystemGestureEventFilter); |
+ AddPreTargetHandler(system_gesture_filter_.get()); |
+ |
+ keyboard_metrics_filter_.reset(new internal::KeyboardUMAEventFilter); |
+ AddPreTargetHandler(keyboard_metrics_filter_.get()); |
+ |
+ // The keyboard system must be initialized before the RootWindowController is |
+ // created. |
+ if (keyboard::IsKeyboardEnabled()) |
+ keyboard::InitializeKeyboard(); |
+ |
+ lock_state_controller_.reset(new LockStateController); |
+ power_button_controller_.reset(new PowerButtonController( |
+ lock_state_controller_.get())); |
+ AddShellObserver(lock_state_controller_.get()); |
+ |
+ drag_drop_controller_.reset(new internal::DragDropController); |
+ mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter()); |
+ PrependPreTargetHandler(mouse_cursor_filter_.get()); |
+ |
+ // Create Controllers that may need root window. |
+ // TODO(oshima): Move as many controllers before creating |
+ // RootWindowController as possible. |
+ visibility_controller_.reset(new AshVisibilityController); |
+ user_action_client_.reset(delegate_->CreateUserActionClient()); |
+ |
+ magnification_controller_.reset( |
+ MagnificationController::CreateInstance()); |
+ mru_window_tracker_.reset(new MruWindowTracker(activation_client_)); |
+ |
+ partial_magnification_controller_.reset( |
+ new PartialMagnificationController()); |
+ |
+ high_contrast_controller_.reset(new HighContrastController); |
+ video_detector_.reset(new VideoDetector); |
+ window_cycle_controller_.reset(new WindowCycleController()); |
+ window_selector_controller_.reset(new WindowSelectorController()); |
+ |
+ tooltip_controller_.reset(new views::corewm::TooltipController( |
+ gfx::SCREEN_TYPE_ALTERNATE)); |
+ AddPreTargetHandler(tooltip_controller_.get()); |
+ |
+ event_client_.reset(new internal::EventClientImpl); |
+ |
+ // This controller needs to be set before SetupManagedWindowMode. |
+ desktop_background_controller_.reset(new DesktopBackgroundController()); |
+ user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate()); |
+ |
+ // StatusAreaWidget uses Shell's CapsLockDelegate. |
+ caps_lock_delegate_.reset(delegate_->CreateCapsLockDelegate()); |
+ |
+ session_state_delegate_.reset(delegate_->CreateSessionStateDelegate()); |
+ |
+ if (!command_line->HasSwitch(views::corewm::switches::kNoDropShadows)) { |
+ resize_shadow_controller_.reset(new internal::ResizeShadowController()); |
+ shadow_controller_.reset( |
+ new views::corewm::ShadowController(activation_client_)); |
+ } |
+ |
+ // Create system_tray_notifier_ before the delegate. |
+ system_tray_notifier_.reset(new ash::SystemTrayNotifier()); |
+ |
+ // Initialize system_tray_delegate_ before initializing StatusAreaWidget. |
+ system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate()); |
+ DCHECK(system_tray_delegate_.get()); |
+ |
+ internal::RootWindowController* root_window_controller = |
+ new internal::RootWindowController(root_window); |
+ InitRootWindowController(root_window_controller, |
+ delegate_->IsFirstRunAfterBoot()); |
+ InitKeyboard(root_window_controller); |
+ |
+ locale_notification_controller_.reset( |
+ new internal::LocaleNotificationController); |
+ |
+ // Initialize system_tray_delegate_ after StatusAreaWidget is created. |
+ system_tray_delegate_->Initialize(); |
+ |
+ display_controller_->InitSecondaryDisplays(); |
+ |
+ // Force Layout |
+ root_window_controller->root_window_layout()->OnWindowResized(); |
+ |
+ // It needs to be created after OnWindowResized has been called, otherwise the |
+ // widget will not paint when restoring after a browser crash. Also it needs |
+ // to be created after InitSecondaryDisplays() to initialize the wallpapers in |
+ // the correct size. |
+ user_wallpaper_delegate_->InitializeWallpaper(); |
+ |
+ if (initially_hide_cursor_) |
+ cursor_manager_.HideCursor(); |
+ cursor_manager_.SetCursor(ui::kCursorPointer); |
+ |
+ if (!cursor_manager_.IsCursorVisible()) { |
+ // Cursor might have been hidden by something other than chrome. |
+ // Let the first mouse event show the cursor. |
+ env_filter_->set_cursor_hidden_by_filter(true); |
+ } |
+ |
+ // Set accelerator controller delegates. |
+#if defined(OS_CHROMEOS) |
+ accelerator_controller_->SetBrightnessControlDelegate( |
+ scoped_ptr<ash::BrightnessControlDelegate>( |
+ new ash::system::BrightnessControllerChromeos).Pass()); |
+#endif |
+ |
+ // The compositor thread and main message loop have to be running in |
+ // order to create mirror window. Run it after the main message loop |
+ // is started. |
+ base::MessageLoopForUI::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&internal::DisplayManager::CreateMirrorWindowIfAny, |
+ base::Unretained(display_manager_.get()))); |
+} |
+ |
+void Shell::InitKeyboard(internal::RootWindowController* root) { |
+ if (keyboard::IsKeyboardEnabled()) { |
+ if (keyboard_controller_.get()) { |
+ RootWindowControllerList controllers = GetAllRootWindowControllers(); |
+ for (RootWindowControllerList::iterator iter = controllers.begin(); |
+ iter != controllers.end(); ++iter) { |
+ (*iter)->DeactivateKeyboard(keyboard_controller_.get()); |
+ } |
+ } |
+ keyboard::KeyboardControllerProxy* proxy = |
+ delegate_->CreateKeyboardControllerProxy(); |
+ keyboard_controller_.reset( |
+ new keyboard::KeyboardController(proxy)); |
+ root->ActivateKeyboard(keyboard_controller_.get()); |
+ } |
+} |
+ |
+void Shell::InitRootWindowController( |
+ internal::RootWindowController* controller, |
+ bool first_run_after_boot) { |
+ |
+ aura::RootWindow* root_window = controller->root_window(); |
+ DCHECK(activation_client_); |
+ DCHECK(visibility_controller_.get()); |
+ DCHECK(drag_drop_controller_.get()); |
+ DCHECK(window_cycle_controller_.get()); |
+ |
+ aura::client::SetFocusClient(root_window, focus_client_.get()); |
+ input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); |
+ aura::client::SetActivationClient(root_window, activation_client_); |
+ views::corewm::FocusController* focus_controller = |
+ static_cast<views::corewm::FocusController*>(activation_client_); |
root_window->AddPreTargetHandler(focus_controller); |
aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); |
aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); |
@@ -910,9 +937,6 @@ void Shell::InitRootWindowController( |
controller->Init(first_run_after_boot); |
} |
-//////////////////////////////////////////////////////////////////////////////// |
-// Shell, private: |
- |
bool Shell::CanWindowReceiveEvents(aura::Window* window) { |
RootWindowControllerList controllers = GetAllRootWindowControllers(); |
for (RootWindowControllerList::iterator iter = controllers.begin(); |