| Index: ash/monitor/multi_monitor_manager.cc
|
| diff --git a/ash/monitor/multi_monitor_manager.cc b/ash/monitor/multi_monitor_manager.cc
|
| index a6a30f958a8268cd05039bb851c51f966a083fda..8ed2de9be05718c1ce4593dacf59e7ff2db0cbf6 100644
|
| --- a/ash/monitor/multi_monitor_manager.cc
|
| +++ b/ash/monitor/multi_monitor_manager.cc
|
| @@ -22,6 +22,15 @@ DECLARE_WINDOW_PROPERTY_TYPE(aura::Monitor*);
|
|
|
| namespace ash {
|
| namespace internal {
|
| +namespace {
|
| +
|
| +aura::Monitor* Copy(aura::Monitor* m) {
|
| + aura::Monitor* monitor = new aura::Monitor;
|
| + monitor->set_bounds(m->bounds());
|
| + return monitor;
|
| +}
|
| +
|
| +} // namespace
|
|
|
| DEFINE_WINDOW_PROPERTY_KEY(aura::Monitor*, kMonitorKey, NULL);
|
|
|
| @@ -36,17 +45,57 @@ MultiMonitorManager::MultiMonitorManager() {
|
| }
|
|
|
| MultiMonitorManager::~MultiMonitorManager() {
|
| - STLDeleteContainerPointers(monitors_.begin(), monitors_.end());
|
| + // All monitors must have been deleted when monitor manager is deleted.
|
| + CHECK(!monitors_.size());
|
| }
|
|
|
| -void MultiMonitorManager::OnNativeMonitorResized(const gfx::Size& size) {
|
| - // TODO(oshima): Update monitors using xrandr and notify observers
|
| - // Just update the primary for now.
|
| - if (use_fullscreen_host_window()) {
|
| - Monitor* monitor =
|
| - aura::Env::GetInstance()->monitor_manager()->GetMonitorAt(0);
|
| - monitor->set_size(size);
|
| - NotifyBoundsChanged(monitor);
|
| +// static
|
| +void MultiMonitorManager::AddRemoveMonitor() {
|
| + MultiMonitorManager* manager = static_cast<MultiMonitorManager*>(
|
| + aura::Env::GetInstance()->monitor_manager());
|
| + manager->AddRemoveMonitorImpl();
|
| +}
|
| +
|
| +void MultiMonitorManager::CycleMonitor() {
|
| + MultiMonitorManager* manager = static_cast<MultiMonitorManager*>(
|
| + aura::Env::GetInstance()->monitor_manager());
|
| + manager->CycleMonitorImpl();
|
| +}
|
| +
|
| +void MultiMonitorManager::OnNativeMonitorsChanged(
|
| + const std::vector<const aura::Monitor*>& new_monitors) {
|
| + size_t min = std::min(monitors_.size(), new_monitors.size());
|
| +
|
| + // For m19, we only care about 1st monitor as primary, and
|
| + // don't differentiate the rest of monitors as all secondary
|
| + // monitors have the same content.
|
| + // TODO(oshima): Fix this so that we can differentiate outputs
|
| + // and keep a content on one monitor stays on the same monitor
|
| + // when a monitor is added or removed.
|
| + for (size_t i = 0; i < min; ++i) {
|
| + Monitor* current_monitor = monitors_[i];
|
| + const Monitor* new_monitor = new_monitors[i];
|
| + if (current_monitor->bounds() != new_monitor->bounds()) {
|
| + current_monitor->set_bounds(new_monitor->bounds());
|
| + NotifyBoundsChanged(current_monitor);
|
| + }
|
| + }
|
| +
|
| + if (monitors_.size() < new_monitors.size()) {
|
| + // New monitors added
|
| + for (size_t i = min; i < new_monitors.size(); ++i) {
|
| + Monitor* monitor = new Monitor();
|
| + monitor->set_bounds(new_monitors[i]->bounds());
|
| + monitors_.push_back(monitor);
|
| + NotifyMonitorAdded(monitor);
|
| + }
|
| + } else {
|
| + // Monitors are removed.
|
| + while (monitors_.size() > new_monitors.size()) {
|
| + Monitor* monitor = monitors_.back();
|
| + // Monitor object is deleted in OnWindowDestroying.
|
| + NotifyMonitorRemoved(monitor);
|
| + }
|
| }
|
| }
|
|
|
| @@ -54,6 +103,7 @@ RootWindow* MultiMonitorManager::CreateRootWindowForMonitor(
|
| Monitor* monitor) {
|
| RootWindow* root_window = new RootWindow(monitor->bounds());
|
| root_window->AddObserver(this);
|
| + root_window->AddRootWindowObserver(this);
|
| root_window->SetProperty(kMonitorKey, monitor);
|
| return root_window;
|
| }
|
| @@ -89,22 +139,28 @@ Monitor* MultiMonitorManager::GetMonitorNearestWindow(const Window* window) {
|
| return const_cast<Monitor*>(manager->GetMonitorNearestWindow(window));
|
| }
|
|
|
| -void MultiMonitorManager::OnWindowBoundsChanged(
|
| - Window* window, const gfx::Rect& bounds) {
|
| +void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root,
|
| + const gfx::Size& old_size) {
|
| if (!use_fullscreen_host_window()) {
|
| - Monitor* monitor = window->GetProperty(kMonitorKey);
|
| - monitor->set_size(bounds.size());
|
| + Monitor* monitor = root->GetProperty(kMonitorKey);
|
| + monitor->set_size(root->GetHostSize());
|
| NotifyBoundsChanged(monitor);
|
| }
|
| }
|
|
|
| void MultiMonitorManager::OnWindowDestroying(Window* window) {
|
| + RootWindow* root = static_cast<RootWindow*>(window);
|
| + root->RemoveObserver(this);
|
| + // Don't remove RootWindowObserver because the observer list in
|
| + // RootWindowObserver class has already been destroyed by this time.
|
| +
|
| Monitor* monitor = window->GetProperty(kMonitorKey);
|
| monitors_.erase(std::find(monitors_.begin(), monitors_.end(), monitor));
|
| delete monitor;
|
| }
|
|
|
| void MultiMonitorManager::Init() {
|
| + // TODO(oshima): Move this logic to MonitorChangeObserver.
|
| const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
| switches::kAuraHostWindowSize);
|
| vector<string> parts;
|
| @@ -117,5 +173,36 @@ void MultiMonitorManager::Init() {
|
| monitors_.push_back(CreateMonitorFromSpec("" /* default */));
|
| }
|
|
|
| +void MultiMonitorManager::AddRemoveMonitorImpl() {
|
| + std::vector<const Monitor*> new_monitors;
|
| + if (monitors_.size() > 1) {
|
| + // Remove if there is more than one monitor.
|
| + int count = monitors_.size() - 1;
|
| + for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter)
|
| + new_monitors.push_back(Copy(*iter));
|
| + } else {
|
| + // Add if there is only one monitor.
|
| + new_monitors.push_back(Copy(monitors_[0]));
|
| + aura::Monitor* extra_monitor = new Monitor;
|
| + extra_monitor->set_bounds(gfx::Rect(100, 100, 1440, 800));
|
| + new_monitors.push_back(extra_monitor);
|
| + }
|
| + if (new_monitors.size())
|
| + OnNativeMonitorsChanged(new_monitors);
|
| + STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end());
|
| +}
|
| +
|
| +void MultiMonitorManager::CycleMonitorImpl() {
|
| + if (monitors_.size() > 1) {
|
| + std::vector<const Monitor*> new_monitors;
|
| + for (Monitors::const_iterator iter = monitors_.begin() + 1;
|
| + iter != monitors_.end(); ++iter)
|
| + new_monitors.push_back(Copy(*iter));
|
| + new_monitors.push_back(Copy(monitors_.front()));
|
| + OnNativeMonitorsChanged(new_monitors);
|
| + STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end());
|
| + }
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace ash
|
|
|