| 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/root_window.h" | 15 #include "ui/aura/root_window.h" |
| 16 #include "ui/aura/root_window_host.h" | 16 #include "ui/aura/root_window_host.h" |
| 17 #include "ui/aura/window_property.h" | 17 #include "ui/aura/window_property.h" |
| 18 #include "ui/gfx/monitor.h" | 18 #include "ui/gfx/display.h" |
| 19 #include "ui/gfx/rect.h" | 19 #include "ui/gfx/rect.h" |
| 20 | 20 |
| 21 DECLARE_WINDOW_PROPERTY_TYPE(int); | 21 DECLARE_WINDOW_PROPERTY_TYPE(int); |
| 22 | 22 |
| 23 namespace ash { | 23 namespace ash { |
| 24 namespace internal { | 24 namespace internal { |
| 25 namespace { | 25 namespace { |
| 26 gfx::Monitor& GetInvalidMonitor() { | 26 |
| 27 static gfx::Monitor* invalid_monitor = new gfx::Monitor(); | 27 gfx::Display& GetInvalidDisplay() { |
| 28 return *invalid_monitor; | 28 static gfx::Display* invalid_display = new gfx::Display(); |
| 29 return *invalid_display; |
| 29 } | 30 } |
| 31 |
| 30 } // namespace | 32 } // namespace |
| 31 | 33 |
| 32 using aura::RootWindow; | 34 using aura::RootWindow; |
| 33 using aura::Window; | 35 using aura::Window; |
| 34 using gfx::Monitor; | |
| 35 using std::string; | 36 using std::string; |
| 36 using std::vector; | 37 using std::vector; |
| 37 | 38 |
| 38 DEFINE_WINDOW_PROPERTY_KEY(int, kMonitorIdKey, -1); | 39 DEFINE_WINDOW_PROPERTY_KEY(int, kMonitorIdKey, -1); |
| 39 | 40 |
| 40 MultiMonitorManager::MultiMonitorManager() { | 41 MultiMonitorManager::MultiMonitorManager() { |
| 41 Init(); | 42 Init(); |
| 42 } | 43 } |
| 43 | 44 |
| 44 MultiMonitorManager::~MultiMonitorManager() { | 45 MultiMonitorManager::~MultiMonitorManager() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 57 manager->CycleMonitorImpl(); | 58 manager->CycleMonitorImpl(); |
| 58 } | 59 } |
| 59 | 60 |
| 60 void MultiMonitorManager::ToggleMonitorScale() { | 61 void MultiMonitorManager::ToggleMonitorScale() { |
| 61 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( | 62 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( |
| 62 aura::Env::GetInstance()->monitor_manager()); | 63 aura::Env::GetInstance()->monitor_manager()); |
| 63 manager->ScaleMonitorImpl(); | 64 manager->ScaleMonitorImpl(); |
| 64 } | 65 } |
| 65 | 66 |
| 66 void MultiMonitorManager::OnNativeMonitorsChanged( | 67 void MultiMonitorManager::OnNativeMonitorsChanged( |
| 67 const std::vector<Monitor>& new_monitors) { | 68 const std::vector<gfx::Display>& new_displays) { |
| 68 size_t min = std::min(monitors_.size(), new_monitors.size()); | 69 size_t min = std::min(displays_.size(), new_displays.size()); |
| 69 | 70 |
| 70 // For m19, we only care about 1st monitor as primary, and | 71 // For m19, we only care about 1st monitor as primary, and |
| 71 // don't differentiate the rest of monitors as all secondary | 72 // don't differentiate the rest of monitors as all secondary |
| 72 // monitors have the same content. ID for primary monitor stays the same | 73 // monitors have the same content. ID for primary monitor stays the same |
| 73 // because we never remove it, we don't update IDs for other monitors | 74 // because we never remove it, we don't update IDs for other monitors |
| 74 // , for now, because they're the same. | 75 // , for now, because they're the same. |
| 75 // TODO(oshima): Fix this so that we can differentiate outputs | 76 // TODO(oshima): Fix this so that we can differentiate outputs |
| 76 // and keep a content on one monitor stays on the same monitor | 77 // and keep a content on one monitor stays on the same monitor |
| 77 // when a monitor is added or removed. | 78 // when a monitor is added or removed. |
| 78 for (size_t i = 0; i < min; ++i) { | 79 for (size_t i = 0; i < min; ++i) { |
| 79 Monitor& current_monitor = monitors_[i]; | 80 gfx::Display& current_display = displays_[i]; |
| 80 const Monitor& new_monitor = new_monitors[i]; | 81 const gfx::Display& new_display = new_displays[i]; |
| 81 if (current_monitor.bounds_in_pixel() != new_monitor.bounds_in_pixel()) { | 82 if (current_display.bounds_in_pixel() != new_display.bounds_in_pixel()) { |
| 82 current_monitor.SetScaleAndBounds(new_monitor.device_scale_factor(), | 83 current_display.SetScaleAndBounds(new_display.device_scale_factor(), |
| 83 new_monitor.bounds_in_pixel()); | 84 new_display.bounds_in_pixel()); |
| 84 NotifyBoundsChanged(current_monitor); | 85 NotifyBoundsChanged(current_display); |
| 85 } | 86 } |
| 86 } | 87 } |
| 87 | 88 |
| 88 if (monitors_.size() < new_monitors.size()) { | 89 if (displays_.size() < new_displays.size()) { |
| 89 // New monitors added | 90 // New monitors added |
| 90 for (size_t i = min; i < new_monitors.size(); ++i) { | 91 for (size_t i = min; i < new_displays.size(); ++i) { |
| 91 const gfx::Monitor& new_monitor = new_monitors[i]; | 92 const gfx::Display& new_display = new_displays[i]; |
| 92 monitors_.push_back(Monitor(new_monitor.id())); | 93 displays_.push_back(gfx::Display(new_display.id())); |
| 93 gfx::Monitor& monitor = monitors_.back(); | 94 gfx::Display& display = displays_.back(); |
| 94 monitor.SetScaleAndBounds(new_monitor.device_scale_factor(), | 95 display.SetScaleAndBounds(new_display.device_scale_factor(), |
| 95 new_monitor.bounds_in_pixel()); | 96 new_display.bounds_in_pixel()); |
| 96 NotifyMonitorAdded(monitor); | 97 NotifyDisplayAdded(display); |
| 97 } | 98 } |
| 98 } else { | 99 } else { |
| 99 // Monitors are removed. We keep the monitor for the primary | 100 // Monitors are removed. We keep the monitor for the primary |
| 100 // monitor (at index 0) because it needs the monitor information | 101 // monitor (at index 0) because it needs the monitor information |
| 101 // even if it doesn't exit. | 102 // even if it doesn't exit. |
| 102 while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) { | 103 while (displays_.size() > new_displays.size() && displays_.size() > 1) { |
| 103 Monitors::reverse_iterator iter = monitors_.rbegin(); | 104 Displays::reverse_iterator iter = displays_.rbegin(); |
| 104 NotifyMonitorRemoved(*iter); | 105 NotifyDisplayRemoved(*iter); |
| 105 monitors_.erase(iter.base() - 1); | 106 displays_.erase(iter.base() - 1); |
| 106 } | 107 } |
| 107 } | 108 } |
| 108 } | 109 } |
| 109 | 110 |
| 110 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( | 111 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( |
| 111 const Monitor& monitor) { | 112 const gfx::Display& display) { |
| 112 RootWindow* root_window = new RootWindow(monitor.bounds_in_pixel()); | 113 RootWindow* root_window = new RootWindow(display.bounds_in_pixel()); |
| 113 // No need to remove RootWindowObserver because | 114 // No need to remove RootWindowObserver because |
| 114 // the MonitorManager object outlives RootWindow objects. | 115 // the MonitorManager object outlives RootWindow objects. |
| 115 root_window->AddRootWindowObserver(this); | 116 root_window->AddRootWindowObserver(this); |
| 116 root_window->SetProperty(kMonitorIdKey, monitor.id()); | 117 root_window->SetProperty(kMonitorIdKey, display.id()); |
| 117 root_window->Init(); | 118 root_window->Init(); |
| 118 return root_window; | 119 return root_window; |
| 119 } | 120 } |
| 120 | 121 |
| 121 const Monitor& MultiMonitorManager::GetMonitorAt(size_t index) { | 122 const gfx::Display& MultiMonitorManager::GetMonitorAt(size_t index) { |
| 122 return index < monitors_.size() ? monitors_[index] : GetInvalidMonitor(); | 123 return index < displays_.size() ? displays_[index] : GetInvalidDisplay(); |
| 123 } | 124 } |
| 124 | 125 |
| 125 size_t MultiMonitorManager::GetNumMonitors() const { | 126 size_t MultiMonitorManager::GetNumMonitors() const { |
| 126 return monitors_.size(); | 127 return displays_.size(); |
| 127 } | 128 } |
| 128 | 129 |
| 129 const Monitor& MultiMonitorManager::GetMonitorNearestWindow( | 130 const gfx::Display& MultiMonitorManager::GetMonitorNearestWindow( |
| 130 const Window* window) const { | 131 const Window* window) const { |
| 131 if (!window) { | 132 if (!window) { |
| 132 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); | 133 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); |
| 133 return manager->GetMonitorAt(0); | 134 return manager->GetMonitorAt(0); |
| 134 } | 135 } |
| 135 const RootWindow* root = window->GetRootWindow(); | 136 const RootWindow* root = window->GetRootWindow(); |
| 136 MultiMonitorManager* that = const_cast<MultiMonitorManager*>(this); | 137 MultiMonitorManager* that = const_cast<MultiMonitorManager*>(this); |
| 137 return root ? | 138 return root ? |
| 138 that->FindMonitorById(root->GetProperty(kMonitorIdKey)) : | 139 that->FindDisplayById(root->GetProperty(kMonitorIdKey)) : |
| 139 GetInvalidMonitor(); | 140 GetInvalidDisplay(); |
| 140 } | 141 } |
| 141 | 142 |
| 142 const Monitor& MultiMonitorManager::GetMonitorNearestPoint( | 143 const gfx::Display& MultiMonitorManager::GetMonitorNearestPoint( |
| 143 const gfx::Point& point) const { | 144 const gfx::Point& point) const { |
| 144 // TODO(oshima): For m19, mouse is constrained within | 145 // TODO(oshima): For m19, mouse is constrained within |
| 145 // the primary window. | 146 // the primary window. |
| 146 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); | 147 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); |
| 147 return manager->GetMonitorAt(0); | 148 return manager->GetMonitorAt(0); |
| 148 } | 149 } |
| 149 | 150 |
| 150 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, | 151 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, |
| 151 const gfx::Size& old_size) { | 152 const gfx::Size& old_size) { |
| 152 if (!use_fullscreen_host_window()) { | 153 if (!use_fullscreen_host_window()) { |
| 153 int monitor_id = root->GetProperty(kMonitorIdKey); | 154 int monitor_id = root->GetProperty(kMonitorIdKey); |
| 154 Monitor& monitor = FindMonitorById(monitor_id); | 155 gfx::Display& display = FindDisplayById(monitor_id); |
| 155 monitor.SetSize(root->GetHostSize()); | 156 display.SetSize(root->GetHostSize()); |
| 156 NotifyBoundsChanged(monitor); | 157 NotifyBoundsChanged(display); |
| 157 } | 158 } |
| 158 } | 159 } |
| 159 | 160 |
| 160 bool MultiMonitorManager::UpdateWorkAreaOfMonitorNearestWindow( | 161 bool MultiMonitorManager::UpdateWorkAreaOfMonitorNearestWindow( |
| 161 const aura::Window* window, | 162 const aura::Window* window, |
| 162 const gfx::Insets& insets) { | 163 const gfx::Insets& insets) { |
| 163 const RootWindow* root = window->GetRootWindow(); | 164 const RootWindow* root = window->GetRootWindow(); |
| 164 Monitor& monitor = FindMonitorById(root->GetProperty(kMonitorIdKey)); | 165 gfx::Display& display = FindDisplayById(root->GetProperty(kMonitorIdKey)); |
| 165 gfx::Rect old_work_area = monitor.work_area(); | 166 gfx::Rect old_work_area = display.work_area(); |
| 166 monitor.UpdateWorkAreaFromInsets(insets); | 167 display.UpdateWorkAreaFromInsets(insets); |
| 167 return old_work_area != monitor.work_area(); | 168 return old_work_area != display.work_area(); |
| 168 } | 169 } |
| 169 | 170 |
| 170 void MultiMonitorManager::Init() { | 171 void MultiMonitorManager::Init() { |
| 171 // TODO(oshima): Move this logic to MonitorChangeObserver. | 172 // TODO(oshima): Move this logic to MonitorChangeObserver. |
| 172 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 173 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 173 switches::kAuraHostWindowSize); | 174 switches::kAuraHostWindowSize); |
| 174 vector<string> parts; | 175 vector<string> parts; |
| 175 base::SplitString(size_str, ',', &parts); | 176 base::SplitString(size_str, ',', &parts); |
| 176 for (vector<string>::const_iterator iter = parts.begin(); | 177 for (vector<string>::const_iterator iter = parts.begin(); |
| 177 iter != parts.end(); ++iter) { | 178 iter != parts.end(); ++iter) { |
| 178 monitors_.push_back(CreateMonitorFromSpec(*iter)); | 179 displays_.push_back(CreateMonitorFromSpec(*iter)); |
| 179 } | 180 } |
| 180 if (monitors_.empty()) | 181 if (displays_.empty()) |
| 181 monitors_.push_back(CreateMonitorFromSpec("" /* default */)); | 182 displays_.push_back(CreateMonitorFromSpec("" /* default */)); |
| 182 } | 183 } |
| 183 | 184 |
| 184 void MultiMonitorManager::AddRemoveMonitorImpl() { | 185 void MultiMonitorManager::AddRemoveMonitorImpl() { |
| 185 std::vector<Monitor> new_monitors; | 186 std::vector<gfx::Display> new_displays; |
| 186 if (monitors_.size() > 1) { | 187 if (displays_.size() > 1) { |
| 187 // Remove if there is more than one monitor. | 188 // Remove if there is more than one display. |
| 188 int count = monitors_.size() - 1; | 189 int count = displays_.size() - 1; |
| 189 for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter) | 190 for (Displays::const_iterator iter = displays_.begin(); count-- > 0; ++iter) |
| 190 new_monitors.push_back(*iter); | 191 new_displays.push_back(*iter); |
| 191 } else { | 192 } else { |
| 192 // Add if there is only one monitor. | 193 // Add if there is only one display. |
| 193 new_monitors.push_back(monitors_[0]); | 194 new_displays.push_back(displays_[0]); |
| 194 new_monitors.push_back(CreateMonitorFromSpec("50+50-1280x768")); | 195 new_displays.push_back(CreateMonitorFromSpec("50+50-1280x768")); |
| 195 } | 196 } |
| 196 if (new_monitors.size()) | 197 if (new_displays.size()) |
| 197 OnNativeMonitorsChanged(new_monitors); | 198 OnNativeMonitorsChanged(new_displays); |
| 198 } | 199 } |
| 199 | 200 |
| 200 void MultiMonitorManager::CycleMonitorImpl() { | 201 void MultiMonitorManager::CycleMonitorImpl() { |
| 201 if (monitors_.size() > 1) { | 202 if (displays_.size() > 1) { |
| 202 std::vector<Monitor> new_monitors; | 203 std::vector<gfx::Display> new_displays; |
| 203 for (Monitors::const_iterator iter = monitors_.begin() + 1; | 204 for (Displays::const_iterator iter = displays_.begin() + 1; |
| 204 iter != monitors_.end(); ++iter) { | 205 iter != displays_.end(); ++iter) { |
| 205 gfx::Monitor monitor = *iter; | 206 gfx::Display display = *iter; |
| 206 new_monitors.push_back(monitor); | 207 new_displays.push_back(display); |
| 207 } | 208 } |
| 208 new_monitors.push_back(monitors_.front()); | 209 new_displays.push_back(displays_.front()); |
| 209 OnNativeMonitorsChanged(new_monitors); | 210 OnNativeMonitorsChanged(new_displays); |
| 210 } | 211 } |
| 211 } | 212 } |
| 212 | 213 |
| 213 void MultiMonitorManager::ScaleMonitorImpl() { | 214 void MultiMonitorManager::ScaleMonitorImpl() { |
| 214 if (monitors_.size() > 0) { | 215 if (displays_.size() > 0) { |
| 215 std::vector<Monitor> new_monitors; | 216 std::vector<gfx::Display> new_displays; |
| 216 for (Monitors::const_iterator iter = monitors_.begin(); | 217 for (Displays::const_iterator iter = displays_.begin(); |
| 217 iter != monitors_.end(); ++iter) { | 218 iter != displays_.end(); ++iter) { |
| 218 gfx::Monitor monitor = *iter; | 219 gfx::Display display = *iter; |
| 219 float factor = monitor.device_scale_factor() == 1.0f ? 2.0f : 1.0f; | 220 float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; |
| 220 monitor.SetScaleAndBounds( | 221 display.SetScaleAndBounds( |
| 221 factor, gfx::Rect(monitor.bounds_in_pixel().origin(), | 222 factor, gfx::Rect(display.bounds_in_pixel().origin(), |
| 222 monitor.size().Scale(factor))); | 223 display.size().Scale(factor))); |
| 223 new_monitors.push_back(monitor); | 224 new_displays.push_back(display); |
| 224 } | 225 } |
| 225 OnNativeMonitorsChanged(new_monitors); | 226 OnNativeMonitorsChanged(new_displays); |
| 226 } | 227 } |
| 227 } | 228 } |
| 228 | 229 |
| 229 gfx::Monitor& MultiMonitorManager::FindMonitorById(int id) { | 230 gfx::Display& MultiMonitorManager::FindDisplayById(int id) { |
| 230 for (Monitors::iterator iter = monitors_.begin(); | 231 for (Displays::iterator iter = displays_.begin(); |
| 231 iter != monitors_.end(); ++iter) { | 232 iter != displays_.end(); ++iter) { |
| 232 if ((*iter).id() == id) | 233 if ((*iter).id() == id) |
| 233 return *iter; | 234 return *iter; |
| 234 } | 235 } |
| 235 DLOG(FATAL) << "Could not find monitor by id:" << id; | 236 DLOG(FATAL) << "Could not find display by id:" << id; |
| 236 return GetInvalidMonitor(); | 237 return GetInvalidDisplay(); |
| 237 } | 238 } |
| 238 | 239 |
| 239 } // namespace internal | 240 } // namespace internal |
| 240 } // namespace ash | 241 } // namespace ash |
| OLD | NEW |