| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/monitor/multi_monitor_manager.h" | 5 #include "ash/monitor/multi_monitor_manager.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/string_split.h" | 12 #include "base/string_split.h" |
| 13 #include "ui/aura/aura_switches.h" | 13 #include "ui/aura/aura_switches.h" |
| 14 #include "ui/aura/env.h" | 14 #include "ui/aura/env.h" |
| 15 #include "ui/aura/monitor.h" | |
| 16 #include "ui/aura/root_window.h" | 15 #include "ui/aura/root_window.h" |
| 17 #include "ui/aura/root_window_host.h" | 16 #include "ui/aura/root_window_host.h" |
| 17 #include "ui/aura/window_property.h" |
| 18 #include "ui/gfx/monitor.h" |
| 18 #include "ui/gfx/rect.h" | 19 #include "ui/gfx/rect.h" |
| 19 #include "ui/aura/window_property.h" | |
| 20 | 20 |
| 21 DECLARE_WINDOW_PROPERTY_TYPE(aura::Monitor*); | 21 DECLARE_WINDOW_PROPERTY_TYPE(gfx::Monitor*); |
| 22 | 22 |
| 23 namespace ash { | 23 namespace ash { |
| 24 namespace internal { | 24 namespace internal { |
| 25 namespace { | |
| 26 | 25 |
| 27 aura::Monitor* Copy(aura::Monitor* m) { | 26 using aura::RootWindow; |
| 28 aura::Monitor* monitor = new aura::Monitor; | 27 using aura::Window; |
| 29 monitor->set_bounds(m->bounds()); | 28 using gfx::Monitor; |
| 30 return monitor; | |
| 31 } | |
| 32 | |
| 33 } // namespace | |
| 34 | |
| 35 DEFINE_WINDOW_PROPERTY_KEY(aura::Monitor*, kMonitorKey, NULL); | |
| 36 | |
| 37 using std::string; | 29 using std::string; |
| 38 using std::vector; | 30 using std::vector; |
| 39 using aura::Monitor; | 31 |
| 40 using aura::RootWindow; | 32 DEFINE_WINDOW_PROPERTY_KEY(Monitor*, kMonitorKey, NULL); |
| 41 using aura::Window; | |
| 42 | 33 |
| 43 MultiMonitorManager::MultiMonitorManager() { | 34 MultiMonitorManager::MultiMonitorManager() { |
| 44 Init(); | 35 Init(); |
| 45 } | 36 } |
| 46 | 37 |
| 47 MultiMonitorManager::~MultiMonitorManager() { | 38 MultiMonitorManager::~MultiMonitorManager() { |
| 48 STLDeleteContainerPointers(monitors_.begin(), monitors_.end()); | 39 STLDeleteContainerPointers(monitors_.begin(), monitors_.end()); |
| 49 } | 40 } |
| 50 | 41 |
| 51 // static | 42 // static |
| 52 void MultiMonitorManager::AddRemoveMonitor() { | 43 void MultiMonitorManager::AddRemoveMonitor() { |
| 53 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( | 44 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( |
| 54 aura::Env::GetInstance()->monitor_manager()); | 45 aura::Env::GetInstance()->monitor_manager()); |
| 55 manager->AddRemoveMonitorImpl(); | 46 manager->AddRemoveMonitorImpl(); |
| 56 } | 47 } |
| 57 | 48 |
| 58 void MultiMonitorManager::CycleMonitor() { | 49 void MultiMonitorManager::CycleMonitor() { |
| 59 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( | 50 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( |
| 60 aura::Env::GetInstance()->monitor_manager()); | 51 aura::Env::GetInstance()->monitor_manager()); |
| 61 manager->CycleMonitorImpl(); | 52 manager->CycleMonitorImpl(); |
| 62 } | 53 } |
| 63 | 54 |
| 64 void MultiMonitorManager::OnNativeMonitorsChanged( | 55 void MultiMonitorManager::OnNativeMonitorsChanged( |
| 65 const std::vector<const aura::Monitor*>& new_monitors) { | 56 const std::vector<const Monitor*>& new_monitors) { |
| 66 size_t min = std::min(monitors_.size(), new_monitors.size()); | 57 size_t min = std::min(monitors_.size(), new_monitors.size()); |
| 67 | 58 |
| 68 // For m19, we only care about 1st monitor as primary, and | 59 // For m19, we only care about 1st monitor as primary, and |
| 69 // don't differentiate the rest of monitors as all secondary | 60 // don't differentiate the rest of monitors as all secondary |
| 70 // monitors have the same content. | 61 // monitors have the same content. |
| 71 // TODO(oshima): Fix this so that we can differentiate outputs | 62 // TODO(oshima): Fix this so that we can differentiate outputs |
| 72 // and keep a content on one monitor stays on the same monitor | 63 // and keep a content on one monitor stays on the same monitor |
| 73 // when a monitor is added or removed. | 64 // when a monitor is added or removed. |
| 74 for (size_t i = 0; i < min; ++i) { | 65 for (size_t i = 0; i < min; ++i) { |
| 75 Monitor* current_monitor = monitors_[i]; | 66 Monitor* current_monitor = monitors_[i]; |
| 76 const Monitor* new_monitor = new_monitors[i]; | 67 const Monitor* new_monitor = new_monitors[i]; |
| 77 if (current_monitor->bounds() != new_monitor->bounds()) { | 68 if (current_monitor->bounds() != new_monitor->bounds()) { |
| 78 current_monitor->set_bounds(new_monitor->bounds()); | 69 current_monitor->SetBoundsAndUpdateWorkArea(new_monitor->bounds()); |
| 79 NotifyBoundsChanged(current_monitor); | 70 NotifyBoundsChanged(current_monitor); |
| 80 } | 71 } |
| 81 } | 72 } |
| 82 | 73 |
| 83 if (monitors_.size() < new_monitors.size()) { | 74 if (monitors_.size() < new_monitors.size()) { |
| 84 // New monitors added | 75 // New monitors added |
| 85 for (size_t i = min; i < new_monitors.size(); ++i) { | 76 for (size_t i = min; i < new_monitors.size(); ++i) { |
| 86 Monitor* monitor = new Monitor(); | 77 Monitor* monitor = new Monitor(); |
| 87 monitor->set_bounds(new_monitors[i]->bounds()); | 78 monitor->SetBoundsAndUpdateWorkArea(new_monitors[i]->bounds()); |
| 79 |
| 88 monitors_.push_back(monitor); | 80 monitors_.push_back(monitor); |
| 89 NotifyMonitorAdded(monitor); | 81 NotifyMonitorAdded(monitor); |
| 90 } | 82 } |
| 91 } else { | 83 } else { |
| 92 // Monitors are removed. We keep the monitor for the primary | 84 // Monitors are removed. We keep the monitor for the primary |
| 93 // monitor (at index 0) because it needs the monitor information | 85 // monitor (at index 0) because it needs the monitor information |
| 94 // even if it doesn't exit. | 86 // even if it doesn't exit. |
| 95 while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) { | 87 while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) { |
| 96 Monitor* monitor = monitors_.back(); | 88 Monitor* monitor = monitors_.back(); |
| 97 NotifyMonitorRemoved(monitor); | 89 NotifyMonitorRemoved(monitor); |
| 98 monitors_.erase(std::find(monitors_.begin(), monitors_.end(), monitor)); | 90 monitors_.erase(std::find(monitors_.begin(), monitors_.end(), monitor)); |
| 99 delete monitor; | 91 delete monitor; |
| 100 } | 92 } |
| 101 } | 93 } |
| 102 } | 94 } |
| 103 | 95 |
| 104 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( | 96 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( |
| 105 Monitor* monitor) { | 97 Monitor* monitor) { |
| 106 RootWindow* root_window = new RootWindow(monitor->bounds()); | 98 RootWindow* root_window = new RootWindow(monitor->bounds()); |
| 107 // No need to remove RootWindowObserver because | 99 // No need to remove RootWindowObserver because |
| 108 // the MonitorManager object outlives RootWindow objects. | 100 // the MonitorManager object outlives RootWindow objects. |
| 109 root_window->AddRootWindowObserver(this); | 101 root_window->AddRootWindowObserver(this); |
| 110 root_window->SetProperty(kMonitorKey, monitor); | 102 root_window->SetProperty(kMonitorKey, monitor); |
| 111 return root_window; | 103 return root_window; |
| 112 } | 104 } |
| 113 | 105 |
| 106 Monitor* MultiMonitorManager::GetMonitorAt(size_t index) { |
| 107 return index < monitors_.size() ? monitors_[index] : NULL; |
| 108 } |
| 109 |
| 110 size_t MultiMonitorManager::GetNumMonitors() const { |
| 111 return monitors_.size(); |
| 112 } |
| 113 |
| 114 const Monitor* MultiMonitorManager::GetMonitorNearestWindow( | 114 const Monitor* MultiMonitorManager::GetMonitorNearestWindow( |
| 115 const Window* window) const { | 115 const Window* window) const { |
| 116 if (!window) { | 116 if (!window) { |
| 117 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); | 117 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); |
| 118 return manager->GetMonitorAt(0); | 118 return manager->GetMonitorAt(0); |
| 119 } | 119 } |
| 120 const RootWindow* root = window->GetRootWindow(); | 120 const RootWindow* root = window->GetRootWindow(); |
| 121 return root ? root->GetProperty(kMonitorKey) : NULL; | 121 return root ? root->GetProperty(kMonitorKey) : NULL; |
| 122 } | 122 } |
| 123 | 123 |
| 124 Monitor* MultiMonitorManager::GetMonitorNearestWindow( |
| 125 const Window* window) { |
| 126 const MonitorManager* manager = this; |
| 127 return const_cast<Monitor*>( |
| 128 manager->GetMonitorNearestWindow(window)); |
| 129 } |
| 130 |
| 124 const Monitor* MultiMonitorManager::GetMonitorNearestPoint( | 131 const Monitor* MultiMonitorManager::GetMonitorNearestPoint( |
| 125 const gfx::Point& point) const { | 132 const gfx::Point& point) const { |
| 126 // TODO(oshima): For m19, mouse is constrained within | 133 // TODO(oshima): For m19, mouse is constrained within |
| 127 // the primary window. | 134 // the primary window. |
| 128 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); | 135 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); |
| 129 return manager->GetMonitorAt(0); | 136 return manager->GetMonitorAt(0); |
| 130 } | 137 } |
| 131 | 138 |
| 132 Monitor* MultiMonitorManager::GetMonitorAt(size_t index) { | |
| 133 return index < monitors_.size() ? monitors_[index] : NULL; | |
| 134 } | |
| 135 | |
| 136 size_t MultiMonitorManager::GetNumMonitors() const { | |
| 137 return monitors_.size(); | |
| 138 } | |
| 139 | |
| 140 Monitor* MultiMonitorManager::GetMonitorNearestWindow(const Window* window) { | |
| 141 const MonitorManager* manager = this; | |
| 142 return const_cast<Monitor*>(manager->GetMonitorNearestWindow(window)); | |
| 143 } | |
| 144 | |
| 145 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, | 139 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, |
| 146 const gfx::Size& old_size) { | 140 const gfx::Size& old_size) { |
| 147 if (!use_fullscreen_host_window()) { | 141 if (!use_fullscreen_host_window()) { |
| 148 Monitor* monitor = root->GetProperty(kMonitorKey); | 142 Monitor* monitor = root->GetProperty(kMonitorKey); |
| 149 monitor->set_size(root->GetHostSize()); | 143 monitor->SetSizeAndUpdateWorkArea(root->GetHostSize()); |
| 150 NotifyBoundsChanged(monitor); | 144 NotifyBoundsChanged(monitor); |
| 151 } | 145 } |
| 152 } | 146 } |
| 153 | 147 |
| 154 void MultiMonitorManager::Init() { | 148 void MultiMonitorManager::Init() { |
| 155 // TODO(oshima): Move this logic to MonitorChangeObserver. | 149 // TODO(oshima): Move this logic to MonitorChangeObserver. |
| 156 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 150 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 157 switches::kAuraHostWindowSize); | 151 switches::kAuraHostWindowSize); |
| 158 vector<string> parts; | 152 vector<string> parts; |
| 159 base::SplitString(size_str, ',', &parts); | 153 base::SplitString(size_str, ',', &parts); |
| 160 for (vector<string>::const_iterator iter = parts.begin(); | 154 for (vector<string>::const_iterator iter = parts.begin(); |
| 161 iter != parts.end(); ++iter) { | 155 iter != parts.end(); ++iter) { |
| 162 monitors_.push_back(CreateMonitorFromSpec(*iter)); | 156 monitors_.push_back(CreateMonitorFromSpec(*iter)); |
| 163 } | 157 } |
| 164 if (monitors_.empty()) | 158 if (monitors_.empty()) |
| 165 monitors_.push_back(CreateMonitorFromSpec("" /* default */)); | 159 monitors_.push_back(CreateMonitorFromSpec("" /* default */)); |
| 166 } | 160 } |
| 167 | 161 |
| 168 void MultiMonitorManager::AddRemoveMonitorImpl() { | 162 void MultiMonitorManager::AddRemoveMonitorImpl() { |
| 169 std::vector<const Monitor*> new_monitors; | 163 std::vector<const Monitor*> new_monitors; |
| 170 if (monitors_.size() > 1) { | 164 if (monitors_.size() > 1) { |
| 171 // Remove if there is more than one monitor. | 165 // Remove if there is more than one monitor. |
| 172 int count = monitors_.size() - 1; | 166 int count = monitors_.size() - 1; |
| 173 for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter) | 167 for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter) |
| 174 new_monitors.push_back(Copy(*iter)); | 168 new_monitors.push_back(new Monitor(**iter)); |
| 175 } else { | 169 } else { |
| 176 // Add if there is only one monitor. | 170 // Add if there is only one monitor. |
| 177 new_monitors.push_back(Copy(monitors_[0])); | 171 new_monitors.push_back(new Monitor(*monitors_[0])); |
| 178 aura::Monitor* extra_monitor = new Monitor; | 172 Monitor* extra_monitor = new Monitor; |
| 179 extra_monitor->set_bounds(gfx::Rect(100, 100, 1440, 800)); | 173 extra_monitor->set_bounds(gfx::Rect(100, 100, 1440, 800)); |
| 180 new_monitors.push_back(extra_monitor); | 174 new_monitors.push_back(extra_monitor); |
| 181 } | 175 } |
| 182 if (new_monitors.size()) | 176 if (new_monitors.size()) |
| 183 OnNativeMonitorsChanged(new_monitors); | 177 OnNativeMonitorsChanged(new_monitors); |
| 184 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); | 178 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); |
| 185 } | 179 } |
| 186 | 180 |
| 187 void MultiMonitorManager::CycleMonitorImpl() { | 181 void MultiMonitorManager::CycleMonitorImpl() { |
| 188 if (monitors_.size() > 1) { | 182 if (monitors_.size() > 1) { |
| 189 std::vector<const Monitor*> new_monitors; | 183 std::vector<const Monitor*> new_monitors; |
| 190 for (Monitors::const_iterator iter = monitors_.begin() + 1; | 184 for (Monitors::const_iterator iter = monitors_.begin() + 1; |
| 191 iter != monitors_.end(); ++iter) | 185 iter != monitors_.end(); ++iter) |
| 192 new_monitors.push_back(Copy(*iter)); | 186 new_monitors.push_back(new Monitor(**iter)); |
| 193 new_monitors.push_back(Copy(monitors_.front())); | 187 new_monitors.push_back(new Monitor(*monitors_.front())); |
| 194 OnNativeMonitorsChanged(new_monitors); | 188 OnNativeMonitorsChanged(new_monitors); |
| 195 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); | 189 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end()); |
| 196 } | 190 } |
| 197 } | 191 } |
| 198 | 192 |
| 199 } // namespace internal | 193 } // namespace internal |
| 200 } // namespace ash | 194 } // namespace ash |
| OLD | NEW |