summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-15 07:38:23 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-15 07:38:23 +0000
commitbe65be36422183ca14c6e61bdcca8b79eb36c668 (patch)
tree37ba9417fdf52544c6f0e4195136e6a8457ea5f5 /ash
parent56c2ee9abf440e57c3b133c625067743f237c324 (diff)
downloadchromium_src-be65be36422183ca14c6e61bdcca8b79eb36c668.zip
chromium_src-be65be36422183ca14c6e61bdcca8b79eb36c668.tar.gz
chromium_src-be65be36422183ca14c6e61bdcca8b79eb36c668.tar.bz2
Add Extended Desktop mode behind --ash-extended-desktop flag.
A lot of stuff still doesn't work but you can create and use a window on 2nd display. MonitorController now owns all root windows. BUG=123160 TEST=see http://codereview.chromium.org/10536187/ Review URL: https://chromiumcodereview.appspot.com/10535149 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142350 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/accelerators/accelerator_controller.cc4
-rw-r--r--ash/accelerators/accelerator_table.cc1
-rw-r--r--ash/ash_switches.cc6
-rw-r--r--ash/ash_switches.h2
-rw-r--r--ash/desktop_background/desktop_background_controller.cc61
-rw-r--r--ash/monitor/monitor_controller.cc138
-rw-r--r--ash/monitor/monitor_controller.h45
-rw-r--r--ash/monitor/multi_monitor_manager.cc7
-rw-r--r--ash/shell.cc125
-rw-r--r--ash/shell.h25
-rw-r--r--ash/wm/workspace/workspace_manager.cc3
11 files changed, 285 insertions, 132 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 6233651..63f9fab 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -343,9 +343,7 @@ bool AcceleratorController::PerformAction(int action,
return HandleRestoreTab();
case TAKE_SCREENSHOT:
if (screenshot_delegate_.get()) {
- std::vector<aura::RootWindow*> root_windows;
- ash::Shell::GetInstance()->monitor_controller()->GetAllRootWindows(
- &root_windows);
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
for (size_t i = 0; i < root_windows.size(); ++i)
screenshot_delegate_->HandleTakeScreenshot(root_windows[i]);
}
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 9d31ea2..ecba2c9 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -111,6 +111,7 @@ const AcceleratorData kAcceleratorData[] = {
{ true, ui::VKEY_W, ui::EF_ALT_DOWN, CYCLE_FORWARD_MRU },
{ true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU },
{ true, ui::VKEY_F4, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, MONITOR_CYCLE },
+ { true, ui::VKEY_F4, ui::EF_SHIFT_DOWN, MONITOR_ADD_REMOVE },
{ true, ui::VKEY_HOME, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
MONITOR_TOGGLE_SCALE },
#endif
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index baf4a7b..b34f135 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -14,6 +14,9 @@ const char kAppListShowAppsOnly[] = "app-list-show-apps-only";
// Enables the Oak tree viewer.
const char kAshEnableOak[] = "ash-enable-oak";
+// Enable extended desktop.
+const char kAshExtendedDesktop[] = "ash-extended-desktop";
+
// Use Ash notifications.
const char kAshNotify[] = "ash-notify";
@@ -23,9 +26,6 @@ const char kAshTouchHud[] = "ash-touch-hud";
// If present animations are disabled.
const char kAshWindowAnimationsDisabled[] = "ash-window-animations-disabled";
-// Enable extended desktop.
-const char kAuraExtendedDesktop[] = "ash-extended-desktop";
-
// Use Google-style dialog box frames.
const char kAuraGoogleDialogFrames[] = "aura-google-dialog-frames";
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index f42801a..2b4896e 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -18,10 +18,10 @@ namespace switches {
// Please keep alphabetized.
ASH_EXPORT extern const char kAppListShowAppsOnly[];
ASH_EXPORT extern const char kAshEnableOak[];
+ASH_EXPORT extern const char kAshExtendedDesktop[];
ASH_EXPORT extern const char kAshNotify[];
ASH_EXPORT extern const char kAshTouchHud[];
ASH_EXPORT extern const char kAshWindowAnimationsDisabled[];
-ASH_EXPORT extern const char kAuraExtendedDesktop[];
ASH_EXPORT extern const char kAuraGoogleDialogFrames[];
ASH_EXPORT extern const char kAuraLegacyPowerButton[];
ASH_EXPORT extern const char kAuraNoShadows[];
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc
index 380c659..a25b768 100644
--- a/ash/desktop_background/desktop_background_controller.cc
+++ b/ash/desktop_background/desktop_background_controller.cc
@@ -124,10 +124,14 @@ void DesktopBackgroundController::SetDefaultWallpaper(int index) {
void DesktopBackgroundController::SetCustomWallpaper(
const gfx::ImageSkia& wallpaper,
WallpaperLayout layout) {
- aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
- GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL);
- internal::CreateDesktopBackground(wallpaper, layout, root_window);
- desktop_background_mode_ = BACKGROUND_IMAGE;
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ aura::RootWindow* root_window = *iter;
+ GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL);
+ internal::CreateDesktopBackground(wallpaper, layout, root_window);
+ desktop_background_mode_ = BACKGROUND_IMAGE;
+ }
}
void DesktopBackgroundController::CancelPendingWallpaperOperation() {
@@ -145,28 +149,36 @@ void DesktopBackgroundController::SetDesktopBackgroundSolidColorMode(
// TODO(derat): Remove this in favor of having the compositor only clear the
// viewport when there are regions not covered by a layer:
// http://crbug.com/113445
- ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
- background_layer->SetColor(color);
- aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
- Shell::GetContainer(
- root_window,
- internal::kShellWindowId_DesktopBackgroundContainer)->
- layer()->Add(background_layer);
- GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(
- background_layer);
- GetRootWindowLayoutManager(root_window)->SetBackgroundWidget(NULL);
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ ui::Layer* background_layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
+ background_layer->SetColor(color);
+ aura::RootWindow* root_window = *iter;
+ Shell::GetContainer(
+ root_window,
+ internal::kShellWindowId_DesktopBackgroundContainer)->
+ layer()->Add(background_layer);
+ GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(
+ background_layer);
+ GetRootWindowLayoutManager(root_window)->SetBackgroundWidget(NULL);
+ }
desktop_background_mode_ = BACKGROUND_SOLID_COLOR;
}
void DesktopBackgroundController::SetDesktopBackgroundImageMode(
scoped_refptr<WallpaperOperation> wo) {
- aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
- GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL);
- if (wo->wallpaper()) {
- internal::CreateDesktopBackground(
- *wo->wallpaper(), wo->wallpaper_layout(), root_window);
- desktop_background_mode_ = BACKGROUND_IMAGE;
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ aura::RootWindow* root_window = *iter;
+ GetRootWindowLayoutManager(root_window)->SetBackgroundLayer(NULL);
+ if (wo->wallpaper()) {
+ internal::CreateDesktopBackground(
+ *wo->wallpaper(), wo->wallpaper_layout(), root_window);
+ }
}
+ desktop_background_mode_ = BACKGROUND_IMAGE;
}
void DesktopBackgroundController::OnWallpaperLoadCompleted(
@@ -179,9 +191,12 @@ void DesktopBackgroundController::OnWallpaperLoadCompleted(
}
void DesktopBackgroundController::CreateEmptyWallpaper() {
- gfx::ImageSkia dummy;
- internal::CreateDesktopBackground(
- dummy, CENTER, Shell::GetPrimaryRootWindow());
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter) {
+ gfx::ImageSkia dummy;
+ internal::CreateDesktopBackground(dummy, CENTER, *iter);
+ }
desktop_background_mode_ = BACKGROUND_IMAGE;
}
diff --git a/ash/monitor/monitor_controller.cc b/ash/monitor/monitor_controller.cc
index 8269947..d224b94 100644
--- a/ash/monitor/monitor_controller.cc
+++ b/ash/monitor/monitor_controller.cc
@@ -6,7 +6,9 @@
#include "ash/ash_switches.h"
#include "ash/monitor/multi_monitor_manager.h"
+#include "ash/root_window_controller.h"
#include "ash/shell.h"
+#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
@@ -15,31 +17,102 @@
namespace ash {
namespace internal {
+namespace {
+bool extended_desktop_enabled = false;
+}
MonitorController::MonitorController()
: secondary_display_layout_(RIGHT) {
aura::Env::GetInstance()->monitor_manager()->AddObserver(this);
- Init();
}
MonitorController::~MonitorController() {
aura::Env::GetInstance()->monitor_manager()->RemoveObserver(this);
- // Remove the root first.
- int monitor_id = Shell::GetPrimaryRootWindow()->GetProperty(kMonitorIdKey);
- DCHECK(monitor_id >= 0);
- root_windows_.erase(monitor_id);
- STLDeleteContainerPairSecondPointers(
- root_windows_.begin(), root_windows_.end());
+ // Delete all root window controllers, which deletes root window
+ // from the last so that the primary root window gets deleted last.
+ for (std::map<int, aura::RootWindow*>::const_reverse_iterator it =
+ root_windows_.rbegin(); it != root_windows_.rend(); ++it) {
+ internal::RootWindowController* controller =
+ wm::GetRootWindowController(it->second);
+ // RootWindow may not have RootWindowController in non
+ // extended desktop mode.
+ if (controller)
+ delete controller;
+ else
+ delete it->second;
+ }
+}
+
+void MonitorController::InitPrimaryDisplay() {
+ aura::MonitorManager* monitor_manager =
+ aura::Env::GetInstance()->monitor_manager();
+ const gfx::Display& display = monitor_manager->GetMonitorAt(0);
+ DCHECK_EQ(0, display.id());
+ aura::RootWindow* root =
+ monitor_manager->CreateRootWindowForMonitor(display);
+ root_windows_[display.id()] = root;
+ if (aura::MonitorManager::use_fullscreen_host_window() &&
+ !IsExtendedDesktopEnabled()) {
+ root->ConfineCursorToWindow();
+ }
+ root->SetHostBounds(display.bounds_in_pixel());
+}
+
+void MonitorController::InitSecondaryDisplays() {
+ aura::MonitorManager* monitor_manager =
+ aura::Env::GetInstance()->monitor_manager();
+ for (size_t i = 1; i < monitor_manager->GetNumMonitors(); ++i) {
+ const gfx::Display& display = monitor_manager->GetMonitorAt(i);
+ aura::RootWindow* root =
+ monitor_manager->CreateRootWindowForMonitor(display);
+ root_windows_[display.id()] = root;
+ Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root);
+ }
+}
+
+aura::RootWindow* MonitorController::GetPrimaryRootWindow() {
+ DCHECK(!root_windows_.empty());
+ return root_windows_[0];
+}
+
+void MonitorController::CloseChildWindows() {
+ for (std::map<int, aura::RootWindow*>::const_iterator it =
+ root_windows_.begin(); it != root_windows_.end(); ++it) {
+ aura::RootWindow* root_window = it->second;
+ internal::RootWindowController* controller =
+ wm::GetRootWindowController(root_window);
+ if (controller) {
+ controller->CloseChildWindows();
+ } else {
+ while (!root_window->children().empty()) {
+ aura::Window* child = root_window->children()[0];
+ delete child;
+ }
+ }
+ }
}
-void MonitorController::GetAllRootWindows(
- std::vector<aura::RootWindow*>* windows) {
- DCHECK(windows);
- windows->clear();
+std::vector<aura::RootWindow*> MonitorController::GetAllRootWindows() {
+ std::vector<aura::RootWindow*> windows;
+ for (std::map<int, aura::RootWindow*>::const_iterator it =
+ root_windows_.begin(); it != root_windows_.end(); ++it) {
+ if (wm::GetRootWindowController(it->second))
+ windows.push_back(it->second);
+ }
+ return windows;
+}
+std::vector<internal::RootWindowController*>
+MonitorController::GetAllRootWindowControllers() {
+ std::vector<internal::RootWindowController*> controllers;
for (std::map<int, aura::RootWindow*>::const_iterator it =
- root_windows_.begin(); it != root_windows_.end(); ++it)
- windows->push_back(it->second);
+ root_windows_.begin(); it != root_windows_.end(); ++it) {
+ internal::RootWindowController* controller =
+ wm::GetRootWindowController(it->second);
+ if (controller)
+ controllers.push_back(controller);
+ }
+ return controllers;
}
void MonitorController::SetSecondaryDisplayLayout(
@@ -47,12 +120,6 @@ void MonitorController::SetSecondaryDisplayLayout(
secondary_display_layout_ = layout;
}
-bool MonitorController::IsExtendedDesktopEnabled(){
- static bool enabled = CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAuraExtendedDesktop);
- return enabled;
-}
-
void MonitorController::OnDisplayBoundsChanged(const gfx::Display& display) {
root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel());
}
@@ -78,26 +145,25 @@ void MonitorController::OnDisplayRemoved(const gfx::Display& display) {
// is deleted by the Shell.
if (root != Shell::GetPrimaryRootWindow()) {
root_windows_.erase(display.id());
- delete root;
+ internal::RootWindowController* controller =
+ wm::GetRootWindowController(root);
+ if (controller)
+ delete controller;
+ else
+ delete root;
}
}
-void MonitorController::Init() {
- aura::MonitorManager* monitor_manager =
- aura::Env::GetInstance()->monitor_manager();
- for (size_t i = 0; i < monitor_manager->GetNumMonitors(); ++i) {
- const gfx::Display& display = monitor_manager->GetMonitorAt(i);
- if (i == 0) {
- // Primary monitor
- root_windows_[display.id()] = Shell::GetPrimaryRootWindow();
- Shell::GetPrimaryRootWindow()->SetHostBounds(display.bounds_in_pixel());
- } else {
- aura::RootWindow* root =
- monitor_manager->CreateRootWindowForMonitor(display);
- root_windows_[display.id()] = root;
- Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root);
- }
- }
+// static
+bool MonitorController::IsExtendedDesktopEnabled(){
+ return extended_desktop_enabled ||
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAshExtendedDesktop);
+}
+
+// static
+void MonitorController::SetExtendedDesktopEnabled(bool enabled) {
+ extended_desktop_enabled = enabled;
}
} // namespace internal
diff --git a/ash/monitor/monitor_controller.h b/ash/monitor/monitor_controller.h
index d61f5ab..f5e24cd 100644
--- a/ash/monitor/monitor_controller.h
+++ b/ash/monitor/monitor_controller.h
@@ -21,14 +21,13 @@ class RootWindow;
namespace ash {
namespace internal {
+class RootWindowController;
-// MonitorController creates and maintains RootWindows for each
-// attached monitor, keeping them in sync with monitor configuration changes.
+// MonitorController owns and maintains RootWindows for each attached
+// display, keeping them in sync with display configuration changes.
+// TODO(oshima): Rename MonitorXXX to DisplayXXX.
class MonitorController : public aura::DisplayObserver {
public:
- MonitorController();
- virtual ~MonitorController();
-
// Layout options where the secondary monitor should be positioned.
enum SecondaryDisplayLayout {
TOP,
@@ -37,26 +36,48 @@ class MonitorController : public aura::DisplayObserver {
LEFT
};
- // Gets all of the root windows.
- void GetAllRootWindows(std::vector<aura::RootWindow*>* windows);
+ MonitorController();
+ virtual ~MonitorController();
+
+ // Initializes primary display.
+ void InitPrimaryDisplay();
+
+ // Initialize secondary display. This is separated because in non
+ // extended desktop mode, this creates background widgets, which
+ // requires other controllers.
+ void InitSecondaryDisplays();
+
+ // Returns the root window for primary display.
+ aura::RootWindow* GetPrimaryRootWindow();
+
+ // Closes all child windows in the all root windows.
+ void CloseChildWindows();
+
+ // Returns all root windows. In non extended desktop mode, this
+ // returns the primary root window only.
+ std::vector<aura::RootWindow*> GetAllRootWindows();
+
+ // Returns all oot window controllers. In non extended desktop
+ // mode, this return a RootWindowController for the primary root window only.
+ std::vector<internal::RootWindowController*> GetAllRootWindowControllers();
SecondaryDisplayLayout secondary_display_layout() const {
return secondary_display_layout_;
}
void SetSecondaryDisplayLayout(SecondaryDisplayLayout layout);
- // Is extended desktop enabled?
- bool IsExtendedDesktopEnabled();
-
// aura::DisplayObserver overrides:
virtual void OnDisplayBoundsChanged(
const gfx::Display& display) OVERRIDE;
virtual void OnDisplayAdded(const gfx::Display& display) OVERRIDE;
virtual void OnDisplayRemoved(const gfx::Display& display) OVERRIDE;
- private:
- void Init();
+ // Is extended desktop enabled?
+ static bool IsExtendedDesktopEnabled();
+ // Change the extended desktop mode. Used for testing.
+ static void SetExtendedDesktopEnabled(bool enabled);
+ private:
std::map<int, aura::RootWindow*> root_windows_;
SecondaryDisplayLayout secondary_display_layout_;
diff --git a/ash/monitor/multi_monitor_manager.cc b/ash/monitor/multi_monitor_manager.cc
index 8538eb7..e36cf01 100644
--- a/ash/monitor/multi_monitor_manager.cc
+++ b/ash/monitor/multi_monitor_manager.cc
@@ -94,6 +94,9 @@ void MultiMonitorManager::OnNativeMonitorsChanged(
const gfx::Display& new_display = new_displays[i];
displays_.push_back(gfx::Display(new_display.id()));
gfx::Display& display = displays_.back();
+ // Force the primary display's ID to be 0.
+ if (i == 0)
+ display.set_id(0);
display.SetScaleAndBounds(new_display.device_scale_factor(),
new_display.bounds_in_pixel());
NotifyDisplayAdded(display);
@@ -180,8 +183,10 @@ void MultiMonitorManager::Init() {
iter != parts.end(); ++iter) {
displays_.push_back(CreateMonitorFromSpec(*iter));
}
- if (displays_.empty())
+ if (displays_.empty()) {
displays_.push_back(CreateMonitorFromSpec("" /* default */));
+ displays_.back().set_id(0);
+ }
}
void MultiMonitorManager::AddRemoveMonitorImpl() {
diff --git a/ash/shell.cc b/ash/shell.cc
index 3070679..f889182 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -166,6 +166,7 @@ internal::WorkspaceController* Shell::TestApi::workspace_controller() {
Shell::Shell(ShellDelegate* delegate)
: screen_(new ScreenAsh),
+ active_root_window_(NULL),
env_filter_(NULL),
delegate_(delegate),
#if defined(OS_CHROMEOS)
@@ -215,17 +216,14 @@ Shell::~Shell() {
// TODO(xiyuan): Move it back when app list container is no longer needed.
app_list_controller_.reset();
- // Destroy secondary monitor's widgets before all the windows are destroyed.
- monitor_controller_.reset();
-
- root_window_controller_->CloseChildWindows();
+ // Destroy all child windows including widgets.
+ monitor_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();
magnification_controller_.reset();
- monitor_controller_.reset();
power_button_controller_.reset();
resize_shadow_controller_.reset();
shadow_controller_.reset();
@@ -236,7 +234,8 @@ Shell::~Shell() {
user_action_client_.reset();
visibility_controller_.reset();
- root_window_controller_.reset();
+ // This also deletes all RootWindows.
+ monitor_controller_.reset();
// Launcher widget has a InputMethodBridge that references to
// input_method_filter_'s input_method_. So explicitly release launcher_
@@ -289,12 +288,18 @@ void Shell::DeleteInstance() {
// static
internal::RootWindowController* Shell::GetPrimaryRootWindowController() {
- return GetInstance()->root_window_controller_.get();
+ return wm::GetRootWindowController(GetPrimaryRootWindow());
+}
+
+// static
+Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() {
+ return Shell::GetInstance()->monitor_controller()->
+ GetAllRootWindowControllers();
}
// static
aura::RootWindow* Shell::GetPrimaryRootWindow() {
- return GetPrimaryRootWindowController()->root_window();
+ return GetInstance()->monitor_controller()->GetPrimaryRootWindow();
}
// static
@@ -309,6 +314,12 @@ aura::RootWindow* Shell::GetRootWindowAt(const gfx::Point& point) {
}
// static
+Shell::RootWindowList Shell::GetAllRootWindows() {
+ return Shell::GetInstance()->monitor_controller()->
+ GetAllRootWindows();
+}
+
+// static
aura::Window* Shell::GetContainer(aura::RootWindow* root_window,
int container_id) {
return root_window->GetChildById(container_id);
@@ -334,11 +345,16 @@ void Shell::Init() {
aura::Env::GetInstance()->SetEventFilter(env_filter_);
aura::Env::GetInstance()->cursor_manager()->set_delegate(this);
- aura::RootWindow* root_window =
- aura::MonitorManager::CreateRootWindowForPrimaryMonitor();
- active_root_window_ = root_window;
+
focus_manager_.reset(new aura::FocusManager);
+ activation_controller_.reset(
+ new internal::ActivationController(focus_manager_.get()));
+
+ monitor_controller_.reset(new internal::MonitorController);
+ monitor_controller_->InitPrimaryDisplay();
+ aura::RootWindow* root_window = monitor_controller_->GetPrimaryRootWindow();
+ active_root_window_ = root_window;
#if !defined(OS_MACOSX)
nested_dispatcher_controller_.reset(new NestedDispatcherController);
@@ -375,9 +391,6 @@ void Shell::Init() {
slow_animation_filter_.reset(new internal::SlowAnimationEventFilter);
AddEnvEventFilter(slow_animation_filter_.get());
- activation_controller_.reset(
- new internal::ActivationController(focus_manager_.get()));
-
capture_controller_.reset(new internal::CaptureController);
CommandLine* command_line = CommandLine::ForCurrentProcess();
@@ -386,10 +399,9 @@ void Shell::Init() {
touch_observer_hud_.reset(new internal::TouchObserverHUD);
AddEnvEventFilter(touch_observer_hud_.get());
}
-
- root_window_controller_.reset(
- new internal::RootWindowController(root_window));
- root_window_controller_->CreateContainers();
+ internal::RootWindowController* root_window_controller =
+ new internal::RootWindowController(root_window);
+ root_window_controller->CreateContainers();
// Create Controllers that may need root window.
// TODO(oshima): Move as many controllers before creating
@@ -409,9 +421,8 @@ void Shell::Init() {
high_contrast_controller_.reset(new HighContrastController);
video_detector_.reset(new VideoDetector);
window_cycle_controller_.reset(new WindowCycleController);
- monitor_controller_.reset(new internal::MonitorController);
- InitRootWindow(root_window);
+ InitRootWindowController(root_window_controller);
// Initialize Primary RootWindow specific items.
status_area_widget_ = new internal::StatusAreaWidget();
@@ -428,7 +439,7 @@ void Shell::Init() {
if (!user_wallpaper_delegate_.get())
user_wallpaper_delegate_.reset(new DummyUserWallpaperDelegate());
- InitLayoutManagersForPrimaryDisplay(root_window_controller_.get());
+ InitLayoutManagersForPrimaryDisplay(root_window_controller);
if (!command_line->HasSwitch(switches::kAuraNoShadows)) {
resize_shadow_controller_.reset(new internal::ResizeShadowController());
@@ -439,7 +450,7 @@ void Shell::Init() {
CreateLauncher();
// Force Layout
- root_window_controller_->root_window_layout()->OnWindowResized();
+ 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.
@@ -448,6 +459,8 @@ void Shell::Init() {
power_button_controller_.reset(new PowerButtonController);
AddShellObserver(power_button_controller_.get());
+ monitor_controller_->InitSecondaryDisplays();
+
if (initially_hide_cursor_)
aura::Env::GetInstance()->cursor_manager()->ShowCursor(false);
}
@@ -587,7 +600,10 @@ ShelfAlignment Shell::GetShelfAlignment() {
}
void Shell::SetDimming(bool should_dim) {
- GetPrimaryRootWindowController()->screen_dimmer()->SetDimming(should_dim);
+ RootWindowControllerList controllers = GetAllRootWindowControllers();
+ for (RootWindowControllerList::iterator iter = controllers.begin();
+ iter != controllers.end(); ++iter)
+ (*iter)->screen_dimmer()->SetDimming(should_dim);
}
SystemTrayDelegate* Shell::tray_delegate() {
@@ -605,22 +621,34 @@ int Shell::GetGridSize() const {
void Shell::InitRootWindowForSecondaryMonitor(aura::RootWindow* root) {
root->set_focus_manager(focus_manager_.get());
- root->SetFocusWhenShown(false);
- root->SetLayoutManager(new internal::RootWindowLayoutManager(root));
- aura::Window* container = new aura::Window(NULL);
- container->SetName("SecondaryMonitorContainer");
- container->Init(ui::LAYER_NOT_DRAWN);
- root->AddChild(container);
- container->SetLayoutManager(new internal::BaseLayoutManager(root));
- CreateSecondaryMonitorWidget(container);
- container->Show();
- root->layout_manager()->OnWindowResized();
- root->ShowRootWindow();
-
- aura::client::SetCaptureClient(root, capture_controller_.get());
-}
-
-void Shell::InitRootWindow(aura::RootWindow* root_window) {
+ if (internal::MonitorController::IsExtendedDesktopEnabled()) {
+ internal::RootWindowController* controller =
+ new internal::RootWindowController(root);
+ controller->CreateContainers();
+ InitRootWindowController(controller);
+ controller->root_window_layout()->OnWindowResized();
+ root->ShowRootWindow();
+ // Activate new root for testing.
+ active_root_window_ = root;
+ } else {
+ root->SetFocusWhenShown(false);
+ root->SetLayoutManager(new internal::RootWindowLayoutManager(root));
+ aura::Window* container = new aura::Window(NULL);
+ container->SetName("SecondaryMonitorContainer");
+ container->Init(ui::LAYER_NOT_DRAWN);
+ root->AddChild(container);
+ container->SetLayoutManager(new internal::BaseLayoutManager(root));
+ CreateSecondaryMonitorWidget(container);
+ container->Show();
+ root->layout_manager()->OnWindowResized();
+ root->ShowRootWindow();
+ aura::client::SetCaptureClient(root, capture_controller_.get());
+ }
+}
+
+void Shell::InitRootWindowController(
+ internal::RootWindowController* controller) {
+ aura::RootWindow* root_window = controller->root_window();
DCHECK(activation_controller_.get());
DCHECK(visibility_controller_.get());
DCHECK(drag_drop_controller_.get());
@@ -642,7 +670,7 @@ void Shell::InitRootWindow(aura::RootWindow* root_window) {
aura::client::SetUserActionClient(root_window, user_action_client_.get());
root_window->SetCursor(ui::kCursorPointer);
- root_window_controller_->InitLayoutManagers();
+ controller->InitLayoutManagers();
}
////////////////////////////////////////////////////////////////////////////////
@@ -686,17 +714,24 @@ void Shell::InitLayoutManagersForPrimaryDisplay(
}
void Shell::DisableWorkspaceGridLayout() {
- GetPrimaryRootWindowController()->
- workspace_controller()->workspace_manager()->set_grid_size(0);
+ RootWindowControllerList controllers = GetAllRootWindowControllers();
+ for (RootWindowControllerList::iterator iter = controllers.begin();
+ iter != controllers.end(); ++iter)
+ (*iter)->workspace_controller()->workspace_manager()->set_grid_size(0);
}
void Shell::SetCursor(gfx::NativeCursor cursor) {
- // TODO(oshima): set cursor to all root windows.
- GetPrimaryRootWindow()->SetCursor(cursor);
+ RootWindowList root_windows = GetAllRootWindows();
+ for (RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter)
+ (*iter)->SetCursor(cursor);
}
void Shell::ShowCursor(bool visible) {
- GetPrimaryRootWindow()->ShowCursor(visible);
+ RootWindowList root_windows = GetAllRootWindows();
+ for (RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter)
+ (*iter)->ShowCursor(visible);
}
} // namespace ash
diff --git a/ash/shell.h b/ash/shell.h
index daa17f0..cf0ec17 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -110,6 +110,9 @@ class WorkspaceController;
// takes ownership of the Shell.
class ASH_EXPORT Shell : aura::CursorDelegate {
public:
+ typedef std::vector<aura::RootWindow*> RootWindowList;
+ typedef std::vector<internal::RootWindowController*> RootWindowControllerList;
+
enum Direction {
FORWARD,
BACKWARD
@@ -146,21 +149,29 @@ class ASH_EXPORT Shell : aura::CursorDelegate {
// Returns the root window controller for the primary root window.
static internal::RootWindowController* GetPrimaryRootWindowController();
- // Gets the primary RootWindow. The primary RootWindow is the one
+ // Returns all root window controllers. In non extended desktop
+ // mode, this return a RootWindowController for the primary root window only.
+ static RootWindowControllerList GetAllRootWindowControllers();
+
+ // Returns the primary RootWindow. The primary RootWindow is the one
// that has a launcher.
static aura::RootWindow* GetPrimaryRootWindow();
- // Gets the active RootWindow. The active RootWindow is the one that
+ // Returns the active RootWindow. The active RootWindow is the one that
// contains the current active window as a decendant child. The active
// RootWindow remains the same even when the active window becomes NULL,
// until the another window who has a different root window becomes active.
static aura::RootWindow* GetActiveRootWindow();
- // Gets the RootWindow at |point| in the virtual screen coordinates.
+ // Returns the RootWindow at |point| in the virtual screen coordinates.
// Returns NULL if the root window does not exist at the given
// point.
static aura::RootWindow* GetRootWindowAt(const gfx::Point& point);
+ // Returns all root windows. In non extended desktop mode, this
+ // returns the primary root window only.
+ static RootWindowList GetAllRootWindows();
+
static aura::Window* GetContainer(aura::RootWindow* root_window,
int container_id);
@@ -330,7 +341,7 @@ class ASH_EXPORT Shell : aura::CursorDelegate {
browser_context_ = browser_context;
}
- // Initialize the root window to be used for a secondary monitor.
+ // Initializes the root window to be used for a secondary monitor.
void InitRootWindowForSecondaryMonitor(aura::RootWindow* root);
#if defined(OS_CHROMEOS)
@@ -351,8 +362,9 @@ class ASH_EXPORT Shell : aura::CursorDelegate {
void Init();
- // Initiailze the root window so that it can host browser windows.
- void InitRootWindow(aura::RootWindow* root);
+ // Initializes the root window and root window controller so that it
+ // can host browser windows.
+ void InitRootWindowController(internal::RootWindowController* root);
// Initializes the layout managers and event filters specific for
// primary display.
@@ -372,7 +384,6 @@ class ASH_EXPORT Shell : aura::CursorDelegate {
// when the screen is initially created.
static bool initially_hide_cursor_;
- scoped_ptr<internal::RootWindowController> root_window_controller_;
ScreenAsh* screen_;
// Active root window. Never become NULL.
diff --git a/ash/wm/workspace/workspace_manager.cc b/ash/wm/workspace/workspace_manager.cc
index c50fc84..1eccfe6 100644
--- a/ash/wm/workspace/workspace_manager.cc
+++ b/ash/wm/workspace/workspace_manager.cc
@@ -133,7 +133,8 @@ void WorkspaceManager::SetActiveWorkspaceByWindow(aura::Window* window) {
}
void WorkspaceManager::UpdateShelfVisibility() {
- shelf_->UpdateVisibilityState();
+ if (shelf_)
+ shelf_->UpdateVisibilityState();
}
WorkspaceManager::WindowState WorkspaceManager::GetWindowState() {