Index: ash/shell.cc |
diff --git a/ash/shell.cc b/ash/shell.cc |
index 630629809a45113ba27e2822c5010c67ec674378..307067921038bd45e78a3740aa9381b584d6c280 100644 |
--- a/ash/shell.cc |
+++ b/ash/shell.cc |
@@ -20,6 +20,7 @@ |
#include "ash/monitor/monitor_controller.h" |
#include "ash/monitor/multi_monitor_manager.h" |
#include "ash/monitor/secondary_monitor_view.h" |
+#include "ash/root_window_controller.h" |
#include "ash/screen_ash.h" |
#include "ash/shell_context_menu.h" |
#include "ash/shell_delegate.h" |
@@ -106,135 +107,6 @@ namespace { |
using aura::Window; |
using views::Widget; |
-// Creates a new window for use as a container. |
-aura::Window* CreateContainer(int window_id, |
- const char* name, |
- aura::Window* parent) { |
- aura::Window* container = new aura::Window(NULL); |
- container->set_id(window_id); |
- container->SetName(name); |
- container->Init(ui::LAYER_NOT_DRAWN); |
- parent->AddChild(container); |
- if (window_id != internal::kShellWindowId_UnparentedControlContainer) |
- container->Show(); |
- return container; |
-} |
- |
-// Creates each of the special window containers that holds windows of various |
-// types in the shell UI. |
-void CreateSpecialContainers(aura::RootWindow* root_window) { |
- // These containers are just used by PowerButtonController to animate groups |
- // of containers simultaneously without messing up the current transformations |
- // on those containers. These are direct children of the root window; all of |
- // the other containers are their children. |
- aura::Window* non_lock_screen_containers = CreateContainer( |
- internal::kShellWindowId_NonLockScreenContainersContainer, |
- "NonLockScreenContainersContainer", |
- root_window); |
- aura::Window* lock_screen_containers = CreateContainer( |
- internal::kShellWindowId_LockScreenContainersContainer, |
- "LockScreenContainersContainer", |
- root_window); |
- aura::Window* lock_screen_related_containers = CreateContainer( |
- internal::kShellWindowId_LockScreenRelatedContainersContainer, |
- "LockScreenRelatedContainersContainer", |
- root_window); |
- |
- CreateContainer(internal::kShellWindowId_UnparentedControlContainer, |
- "UnparentedControlContainer", |
- non_lock_screen_containers); |
- |
- aura::Window* desktop_background_containers = CreateContainer( |
- internal::kShellWindowId_DesktopBackgroundContainer, |
- "DesktopBackgroundContainer", |
- non_lock_screen_containers); |
- SetChildWindowVisibilityChangesAnimated(desktop_background_containers); |
- |
- aura::Window* default_container = CreateContainer( |
- internal::kShellWindowId_DefaultContainer, |
- "DefaultContainer", |
- non_lock_screen_containers); |
- default_container->SetEventFilter( |
- new ToplevelWindowEventFilter(default_container)); |
- SetChildWindowVisibilityChangesAnimated(default_container); |
- |
- aura::Window* always_on_top_container = CreateContainer( |
- internal::kShellWindowId_AlwaysOnTopContainer, |
- "AlwaysOnTopContainer", |
- non_lock_screen_containers); |
- always_on_top_container->SetEventFilter( |
- new ToplevelWindowEventFilter(always_on_top_container)); |
- SetChildWindowVisibilityChangesAnimated(always_on_top_container); |
- |
- CreateContainer(internal::kShellWindowId_PanelContainer, |
- "PanelContainer", |
- non_lock_screen_containers); |
- |
- CreateContainer(internal::kShellWindowId_LauncherContainer, |
- "LauncherContainer", |
- non_lock_screen_containers); |
- |
- CreateContainer(internal::kShellWindowId_AppListContainer, |
- "AppListContainer", |
- non_lock_screen_containers); |
- |
- aura::Window* modal_container = CreateContainer( |
- internal::kShellWindowId_SystemModalContainer, |
- "SystemModalContainer", |
- non_lock_screen_containers); |
- modal_container->SetEventFilter( |
- new ToplevelWindowEventFilter(modal_container)); |
- modal_container->SetLayoutManager( |
- new internal::SystemModalContainerLayoutManager(modal_container)); |
- SetChildWindowVisibilityChangesAnimated(modal_container); |
- |
- // TODO(beng): Figure out if we can make this use |
- // SystemModalContainerEventFilter instead of stops_event_propagation. |
- aura::Window* lock_container = CreateContainer( |
- internal::kShellWindowId_LockScreenContainer, |
- "LockScreenContainer", |
- lock_screen_containers); |
- lock_container->SetLayoutManager( |
- new internal::BaseLayoutManager(root_window)); |
- // TODO(beng): stopsevents |
- |
- aura::Window* lock_modal_container = CreateContainer( |
- internal::kShellWindowId_LockSystemModalContainer, |
- "LockSystemModalContainer", |
- lock_screen_containers); |
- lock_modal_container->SetEventFilter( |
- new ToplevelWindowEventFilter(lock_modal_container)); |
- lock_modal_container->SetLayoutManager( |
- new internal::SystemModalContainerLayoutManager(lock_modal_container)); |
- SetChildWindowVisibilityChangesAnimated(lock_modal_container); |
- |
- CreateContainer(internal::kShellWindowId_StatusContainer, |
- "StatusContainer", |
- lock_screen_related_containers); |
- |
- aura::Window* settings_bubble_container = CreateContainer( |
- internal::kShellWindowId_SettingBubbleContainer, |
- "SettingBubbleContainer", |
- lock_screen_related_containers); |
- SetChildWindowVisibilityChangesAnimated(settings_bubble_container); |
- |
- aura::Window* menu_container = CreateContainer( |
- internal::kShellWindowId_MenuContainer, |
- "MenuContainer", |
- lock_screen_related_containers); |
- SetChildWindowVisibilityChangesAnimated(menu_container); |
- |
- aura::Window* drag_drop_container = CreateContainer( |
- internal::kShellWindowId_DragImageAndTooltipContainer, |
- "DragImageAndTooltipContainer", |
- lock_screen_related_containers); |
- SetChildWindowVisibilityChangesAnimated(drag_drop_container); |
- |
- CreateContainer(internal::kShellWindowId_OverlayContainer, |
- "OverlayContainer", |
- lock_screen_related_containers); |
-} |
- |
// This dummy class is used for shell unit tests. We dont have chrome delegate |
// in these tests. |
class DummyUserWallpaperDelegate : public UserWallpaperDelegate { |
@@ -272,7 +144,7 @@ bool Shell::initially_hide_cursor_ = false; |
Shell::TestApi::TestApi(Shell* shell) : shell_(shell) {} |
internal::RootWindowLayoutManager* Shell::TestApi::root_window_layout() { |
- return shell_->root_window_layout_; |
+ return shell_->GetPrimaryRootWindowController()->root_window_layout(); |
} |
aura::shared::InputMethodEventFilter* |
@@ -286,15 +158,14 @@ internal::SystemGestureEventFilter* |
} |
internal::WorkspaceController* Shell::TestApi::workspace_controller() { |
- return shell_->workspace_controller_.get(); |
+ return shell_->GetPrimaryRootWindowController()->workspace_controller(); |
} |
//////////////////////////////////////////////////////////////////////////////// |
// Shell, public: |
Shell::Shell(ShellDelegate* delegate) |
- : root_window_(aura::MonitorManager::CreateRootWindowForPrimaryMonitor()), |
- screen_(new ScreenAsh), |
+ : screen_(new ScreenAsh), |
env_filter_(NULL), |
delegate_(delegate), |
#if defined(OS_CHROMEOS) |
@@ -302,7 +173,6 @@ Shell::Shell(ShellDelegate* delegate) |
#endif // defined(OS_CHROMEOS) |
shelf_(NULL), |
panel_layout_manager_(NULL), |
- root_window_layout_(NULL), |
status_area_widget_(NULL), |
browser_context_(NULL) { |
gfx::Screen::SetInstance(screen_); |
@@ -333,20 +203,8 @@ Shell::~Shell() { |
if (touch_observer_hud_.get()) |
RemoveEnvEventFilter(touch_observer_hud_.get()); |
- // Close background widget now so that the focus manager of the |
- // widget gets deleted in the final message loop run. |
- root_window_layout_->SetBackgroundWidget(NULL); |
- |
- aura::RootWindow* root_window = GetPrimaryRootWindow(); |
- |
// TooltipController is deleted with the Shell so removing its references. |
RemoveEnvEventFilter(tooltip_controller_.get()); |
- aura::client::SetTooltipClient(root_window, NULL); |
- tooltip_controller_.reset(); |
- |
- // Make sure we delete WorkspaceController before launcher is |
- // deleted as it has a reference to launcher model. |
- workspace_controller_.reset(); |
// The status area needs to be shut down before the windows are destroyed. |
status_area_widget_->Shutdown(); |
@@ -360,35 +218,26 @@ Shell::~Shell() { |
// Destroy secondary monitor's widgets before all the windows are destroyed. |
monitor_controller_.reset(); |
- // Delete containers now so that child windows does not access |
- // observers when they are destructed. |
- while (!root_window->children().empty()) { |
- aura::Window* child = root_window->children()[0]; |
- delete child; |
- } |
+ root_window_controller_->CloseChildWindows(); |
// These need a valid Shell instance to clean up properly, so explicitly |
// delete them before invalidating the instance. |
// Alphabetical. |
drag_drop_controller_.reset(); |
- event_client_.reset(); |
magnification_controller_.reset(); |
monitor_controller_.reset(); |
power_button_controller_.reset(); |
resize_shadow_controller_.reset(); |
- screen_dimmer_.reset(); |
shadow_controller_.reset(); |
tooltip_controller_.reset(); |
window_cycle_controller_.reset(); |
- aura::client::SetCaptureClient(root_window, NULL); |
capture_controller_.reset(); |
- aura::client::SetDispatcherClient(root_window, NULL); |
nested_dispatcher_controller_.reset(); |
- aura::client::SetUserActionClient(root_window, NULL); |
user_action_client_.reset(); |
- aura::client::SetVisibilityClient(root_window, NULL); |
visibility_controller_.reset(); |
+ root_window_controller_.reset(); |
+ |
// Launcher widget has a InputMethodBridge that references to |
// input_method_filter_'s input_method_. So explicitly release launcher_ |
// before input_method_filter_. And this needs to be after we delete all |
@@ -398,7 +247,6 @@ Shell::~Shell() { |
// Delete the activation controller after other controllers and launcher |
// because they might have registered ActivationChangeObserver. |
- aura::client::SetActivationClient(root_window, NULL); |
activation_controller_.reset(); |
DCHECK(instance_ == this); |
@@ -440,8 +288,13 @@ void Shell::DeleteInstance() { |
} |
// static |
+internal::RootWindowController* Shell::GetPrimaryRootWindowController() { |
+ return GetInstance()->root_window_controller_.get(); |
+} |
+ |
+// static |
aura::RootWindow* Shell::GetPrimaryRootWindow() { |
- return GetInstance()->root_window_.get(); |
+ return GetPrimaryRootWindowController()->root_window(); |
} |
// static |
@@ -481,17 +334,14 @@ void Shell::Init() { |
aura::Env::GetInstance()->SetEventFilter(env_filter_); |
aura::Env::GetInstance()->cursor_manager()->set_delegate(this); |
- |
- aura::RootWindow* root_window = GetPrimaryRootWindow(); |
+ aura::RootWindow* root_window = |
+ aura::MonitorManager::CreateRootWindowForPrimaryMonitor(); |
active_root_window_ = root_window; |
focus_manager_.reset(new aura::FocusManager); |
- root_window_->set_focus_manager(focus_manager_.get()); |
#if !defined(OS_MACOSX) |
nested_dispatcher_controller_.reset(new NestedDispatcherController); |
- aura::client::SetDispatcherClient(root_window, |
- nested_dispatcher_controller_.get()); |
accelerator_controller_.reset(new AcceleratorController); |
#endif |
shell_context_menu_.reset(new internal::ShellContextMenu); |
@@ -512,7 +362,6 @@ void Shell::Init() { |
DCHECK_EQ(3U, GetEnvEventFilterCount()); |
input_method_filter_.reset(new aura::shared::InputMethodEventFilter()); |
- input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); |
AddEnvEventFilter(input_method_filter_.get()); |
#if !defined(OS_MACOSX) |
@@ -526,18 +375,10 @@ void Shell::Init() { |
slow_animation_filter_.reset(new internal::SlowAnimationEventFilter); |
AddEnvEventFilter(slow_animation_filter_.get()); |
- root_window->SetCursor(ui::kCursorPointer); |
- if (initially_hide_cursor_) |
- aura::Env::GetInstance()->cursor_manager()->ShowCursor(false); |
- |
activation_controller_.reset( |
new internal::ActivationController(focus_manager_.get())); |
- aura::client::SetActivationClient(root_window, activation_controller_.get()); |
capture_controller_.reset(new internal::CaptureController); |
- aura::client::SetCaptureClient(root_window, capture_controller_.get()); |
- |
- CreateSpecialContainers(root_window); |
CommandLine* command_line = CommandLine::ForCurrentProcess(); |
@@ -546,17 +387,40 @@ void Shell::Init() { |
AddEnvEventFilter(touch_observer_hud_.get()); |
} |
+ root_window_controller_.reset( |
+ new internal::RootWindowController(root_window)); |
+ root_window_controller_->CreateContainers(); |
+ |
+ // Create Controllers that may need root window. |
+ // TODO(oshima): Move as many controllers before creating |
+ // RootWindowController as possible. |
stacking_controller_.reset(new internal::StackingController); |
+ visibility_controller_.reset(new internal::VisibilityController); |
+ drag_drop_controller_.reset(new internal::DragDropController); |
+ tooltip_controller_.reset(new internal::TooltipController( |
+ drag_drop_controller_.get())); |
+ if (delegate_.get()) |
+ user_action_client_.reset(delegate_->CreateUserActionClient()); |
+ window_modality_controller_.reset(new internal::WindowModalityController); |
+ AddEnvEventFilter(window_modality_controller_.get()); |
+ AddEnvEventFilter(tooltip_controller_.get()); |
- root_window_layout_ = new internal::RootWindowLayoutManager(root_window); |
- root_window->SetLayoutManager(root_window_layout_); |
+ magnification_controller_.reset(new internal::MagnificationController); |
+ high_contrast_controller_.reset(new HighContrastController); |
+ video_detector_.reset(new VideoDetector); |
+ window_cycle_controller_.reset(new WindowCycleController); |
+ monitor_controller_.reset(new internal::MonitorController); |
- event_client_.reset(new internal::EventClientImpl(root_window)); |
+ InitRootWindow(root_window); |
+ // Initialize Primary RootWindow specific items. |
status_area_widget_ = new internal::StatusAreaWidget(); |
status_area_widget_->CreateTrayViews(delegate_.get()); |
status_area_widget_->Show(); |
+ focus_cycler_.reset(new internal::FocusCycler()); |
+ focus_cycler_->AddWidget(status_area_widget_); |
+ |
// This controller needs to be set before SetupManagedWindowMode. |
desktop_background_controller_.reset(new DesktopBackgroundController()); |
if (delegate_.get()) |
@@ -564,54 +428,28 @@ void Shell::Init() { |
if (!user_wallpaper_delegate_.get()) |
user_wallpaper_delegate_.reset(new DummyUserWallpaperDelegate()); |
- if (delegate_.get()) |
- user_action_client_.reset(delegate_->CreateUserActionClient()); |
- if (user_action_client_.get()) |
- aura::client::SetUserActionClient(root_window, user_action_client_.get()); |
- |
- InitLayoutManagers(); |
+ InitLayoutManagersForPrimaryDisplay(root_window_controller_.get()); |
if (!command_line->HasSwitch(switches::kAuraNoShadows)) { |
resize_shadow_controller_.reset(new internal::ResizeShadowController()); |
shadow_controller_.reset(new internal::ShadowController()); |
} |
- focus_cycler_.reset(new internal::FocusCycler()); |
- focus_cycler_->AddWidget(status_area_widget_); |
- |
if (!delegate_.get() || delegate_->IsUserLoggedIn()) |
CreateLauncher(); |
- // Force a layout. |
- root_window->layout_manager()->OnWindowResized(); |
+ // 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. |
user_wallpaper_delegate_->InitializeWallpaper(); |
- window_modality_controller_.reset(new internal::WindowModalityController); |
- AddEnvEventFilter(window_modality_controller_.get()); |
- |
- visibility_controller_.reset(new internal::VisibilityController); |
- aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); |
- |
- drag_drop_controller_.reset(new internal::DragDropController); |
- aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); |
- |
- tooltip_controller_.reset( |
- new internal::TooltipController(drag_drop_controller_.get())); |
- aura::client::SetTooltipClient(root_window, tooltip_controller_.get()); |
- |
- AddEnvEventFilter(tooltip_controller_.get()); |
- |
- magnification_controller_.reset(new internal::MagnificationController); |
- high_contrast_controller_.reset(new HighContrastController); |
power_button_controller_.reset(new PowerButtonController); |
AddShellObserver(power_button_controller_.get()); |
- video_detector_.reset(new VideoDetector); |
- window_cycle_controller_.reset(new WindowCycleController); |
- monitor_controller_.reset(new internal::MonitorController); |
- screen_dimmer_.reset(new internal::ScreenDimmer(root_window)); |
+ |
+ if (initially_hide_cursor_) |
+ aura::Env::GetInstance()->cursor_manager()->ShowCursor(false); |
} |
void Shell::AddEnvEventFilter(aura::EventFilter* filter) { |
@@ -704,9 +542,9 @@ void Shell::CreateLauncher() { |
if (launcher_.get()) |
return; |
- aura::Window* default_container = GetContainer( |
- GetPrimaryRootWindow(), |
- internal::kShellWindowId_DefaultContainer); |
+ aura::Window* default_container = |
+ GetPrimaryRootWindowController()-> |
+ GetContainer(internal::kShellWindowId_DefaultContainer); |
launcher_.reset(new Launcher(default_container)); |
launcher_->SetFocusCycler(focus_cycler_.get()); |
@@ -748,6 +586,10 @@ ShelfAlignment Shell::GetShelfAlignment() { |
return shelf_->alignment(); |
} |
+void Shell::SetDimming(bool should_dim) { |
+ GetPrimaryRootWindowController()->screen_dimmer()->SetDimming(should_dim); |
+} |
+ |
SystemTrayDelegate* Shell::tray_delegate() { |
return status_area_widget_->system_tray_delegate(); |
} |
@@ -757,11 +599,8 @@ SystemTray* Shell::system_tray() { |
} |
int Shell::GetGridSize() const { |
- return workspace_controller_->workspace_manager()->grid_size(); |
-} |
- |
-bool Shell::IsInMaximizedMode() const { |
- return workspace_controller_->workspace_manager()->IsInMaximizedMode(); |
+ return GetPrimaryRootWindowController()->workspace_controller()-> |
+ workspace_manager()->grid_size(); |
} |
void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) { |
@@ -781,41 +620,55 @@ void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) { |
aura::client::SetCaptureClient(root, capture_controller_.get()); |
} |
+void Shell::InitRootWindow(aura::RootWindow* root_window) { |
+ DCHECK(activation_controller_.get()); |
+ DCHECK(visibility_controller_.get()); |
+ DCHECK(drag_drop_controller_.get()); |
+ DCHECK(capture_controller_.get()); |
+ |
+ root_window->set_focus_manager(focus_manager_.get()); |
+ input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); |
+ aura::client::SetActivationClient(root_window, activation_controller_.get()); |
+ aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); |
+ aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); |
+ aura::client::SetTooltipClient(root_window, tooltip_controller_.get()); |
+ aura::client::SetCaptureClient(root_window, capture_controller_.get()); |
+ |
+ if (nested_dispatcher_controller_.get()) { |
+ aura::client::SetDispatcherClient(root_window, |
+ nested_dispatcher_controller_.get()); |
+ } |
+ if (user_action_client_.get()) |
+ aura::client::SetUserActionClient(root_window, user_action_client_.get()); |
+ |
+ root_window->SetCursor(ui::kCursorPointer); |
+ root_window_controller_->InitLayoutManagers(); |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// Shell, private: |
-void Shell::InitLayoutManagers() { |
- DCHECK(root_window_layout_); |
+void Shell::InitLayoutManagersForPrimaryDisplay( |
+ internal::RootWindowController* controller) { |
DCHECK(status_area_widget_); |
internal::ShelfLayoutManager* shelf_layout_manager = |
new internal::ShelfLayoutManager(status_area_widget_); |
- GetContainer( |
- GetPrimaryRootWindow(), |
- internal::kShellWindowId_LauncherContainer)-> |
+ controller->GetContainer(internal::kShellWindowId_LauncherContainer)-> |
SetLayoutManager(shelf_layout_manager); |
shelf_ = shelf_layout_manager; |
internal::StatusAreaLayoutManager* status_area_layout_manager = |
new internal::StatusAreaLayoutManager(shelf_layout_manager); |
- GetContainer(GetPrimaryRootWindow(), |
- internal::kShellWindowId_StatusContainer)-> |
+ controller->GetContainer(internal::kShellWindowId_StatusContainer)-> |
SetLayoutManager(status_area_layout_manager); |
- aura::Window* default_container = GetContainer( |
- GetPrimaryRootWindow(), internal::kShellWindowId_DefaultContainer); |
- // Workspace manager has its own layout managers. |
- workspace_controller_.reset( |
- new internal::WorkspaceController(default_container)); |
- workspace_controller_->workspace_manager()->set_shelf(shelf_layout_manager); |
shelf_layout_manager->set_workspace_manager( |
- workspace_controller_->workspace_manager()); |
+ controller->workspace_controller()->workspace_manager()); |
- aura::Window* always_on_top_container = GetContainer( |
- GetPrimaryRootWindow(), internal::kShellWindowId_AlwaysOnTopContainer); |
- always_on_top_container->SetLayoutManager( |
- new internal::BaseLayoutManager( |
- always_on_top_container->GetRootWindow())); |
+ // TODO(oshima): Support multiple displays. |
+ controller->workspace_controller()->workspace_manager()-> |
+ set_shelf(shelf()); |
// Create Panel layout manager |
if (CommandLine::ForCurrentProcess()-> |
@@ -833,8 +686,8 @@ void Shell::InitLayoutManagers() { |
} |
void Shell::DisableWorkspaceGridLayout() { |
- if (workspace_controller_.get()) |
- workspace_controller_->workspace_manager()->set_grid_size(0); |
+ GetPrimaryRootWindowController()-> |
+ workspace_controller()->workspace_manager()->set_grid_size(0); |
} |
void Shell::SetCursor(gfx::NativeCursor cursor) { |