| 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/display/multi_display_manager.h" | 5 #include "ash/display/multi_display_manager.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "ash/display/display_controller.h" | 10 #include "ash/display/display_controller.h" |
| 11 #include "ash/shell.h" |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/string_split.h" | 14 #include "base/string_split.h" |
| 14 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
| 15 #include "ui/aura/aura_switches.h" | 16 #include "ui/aura/aura_switches.h" |
| 16 #include "ui/aura/env.h" | 17 #include "ui/aura/env.h" |
| 17 #include "ui/aura/root_window.h" | 18 #include "ui/aura/root_window.h" |
| 18 #include "ui/aura/root_window_host.h" | 19 #include "ui/aura/root_window_host.h" |
| 19 #include "ui/aura/window_property.h" | 20 #include "ui/aura/window_property.h" |
| 20 #include "ui/gfx/display.h" | 21 #include "ui/gfx/display.h" |
| 22 #include "ui/gfx/screen.h" |
| 21 #include "ui/gfx/rect.h" | 23 #include "ui/gfx/rect.h" |
| 22 | 24 |
| 23 #if defined(USE_X11) | 25 #if defined(USE_X11) |
| 24 #include "ui/base/x/x11_util.h" | 26 #include "ui/base/x/x11_util.h" |
| 25 #endif | 27 #endif |
| 26 | 28 |
| 27 #if defined(OS_CHROMEOS) | 29 #if defined(OS_CHROMEOS) |
| 28 #include "base/chromeos/chromeos_version.h" | 30 #include "base/chromeos/chromeos_version.h" |
| 29 #include "chromeos/display/output_configurator.h" | 31 #include "chromeos/display/output_configurator.h" |
| 30 #endif | 32 #endif |
| 31 | 33 |
| 32 DECLARE_WINDOW_PROPERTY_TYPE(int64); | 34 DECLARE_WINDOW_PROPERTY_TYPE(int64); |
| 35 typedef std::vector<gfx::Display> DisplayList; |
| 33 | 36 |
| 34 namespace ash { | 37 namespace ash { |
| 35 namespace internal { | 38 namespace internal { |
| 36 namespace { | 39 namespace { |
| 37 | 40 |
| 41 struct DisplaySortFunctor { |
| 42 bool operator()(const gfx::Display& a, const gfx::Display& b) { |
| 43 return a.id() < b.id(); |
| 44 } |
| 45 }; |
| 46 |
| 38 gfx::Display& GetInvalidDisplay() { | 47 gfx::Display& GetInvalidDisplay() { |
| 39 static gfx::Display* invalid_display = new gfx::Display(); | 48 static gfx::Display* invalid_display = new gfx::Display(); |
| 40 return *invalid_display; | 49 return *invalid_display; |
| 41 } | 50 } |
| 42 | 51 |
| 52 #if defined(OS_CHROMEOS) |
| 53 int64 GetDisplayIdForOutput(XID output) { |
| 54 uint16 manufacturer_id = 0; |
| 55 uint32 serial_number = 0; |
| 56 ui::GetOutputDeviceData( |
| 57 output, &manufacturer_id, &serial_number, NULL); |
| 58 return gfx::Display::GetID(manufacturer_id, serial_number); |
| 59 } |
| 60 #endif |
| 61 |
| 43 } // namespace | 62 } // namespace |
| 44 | 63 |
| 45 using aura::RootWindow; | 64 using aura::RootWindow; |
| 46 using aura::Window; | 65 using aura::Window; |
| 47 using std::string; | 66 using std::string; |
| 48 using std::vector; | 67 using std::vector; |
| 49 | 68 |
| 50 DEFINE_WINDOW_PROPERTY_KEY(int64, kDisplayIdKey, | 69 DEFINE_WINDOW_PROPERTY_KEY(int64, kDisplayIdKey, |
| 51 gfx::Display::kInvalidDisplayID); | 70 gfx::Display::kInvalidDisplayID); |
| 52 | 71 |
| 53 MultiDisplayManager::MultiDisplayManager() : | 72 MultiDisplayManager::MultiDisplayManager() : |
| 54 internal_display_id_(gfx::Display::kInvalidDisplayID) { | 73 internal_display_id_(gfx::Display::kInvalidDisplayID), |
| 74 force_bounds_changed_(false) { |
| 55 Init(); | 75 Init(); |
| 56 } | 76 } |
| 57 | 77 |
| 58 MultiDisplayManager::~MultiDisplayManager() { | 78 MultiDisplayManager::~MultiDisplayManager() { |
| 59 } | 79 } |
| 60 | 80 |
| 61 // static | 81 // static |
| 62 void MultiDisplayManager::CycleDisplay() { | 82 void MultiDisplayManager::CycleDisplay() { |
| 63 MultiDisplayManager* manager = static_cast<MultiDisplayManager*>( | 83 MultiDisplayManager* manager = static_cast<MultiDisplayManager*>( |
| 64 aura::Env::GetInstance()->display_manager()); | 84 aura::Env::GetInstance()->display_manager()); |
| 65 manager->CycleDisplayImpl(); | 85 manager->CycleDisplayImpl(); |
| 66 } | 86 } |
| 67 | 87 |
| 68 // static | 88 // static |
| 69 void MultiDisplayManager::ToggleDisplayScale() { | 89 void MultiDisplayManager::ToggleDisplayScale() { |
| 70 MultiDisplayManager* manager = static_cast<MultiDisplayManager*>( | 90 MultiDisplayManager* manager = static_cast<MultiDisplayManager*>( |
| 71 aura::Env::GetInstance()->display_manager()); | 91 aura::Env::GetInstance()->display_manager()); |
| 72 manager->ScaleDisplayImpl(); | 92 manager->ScaleDisplayImpl(); |
| 73 } | 93 } |
| 74 | 94 |
| 75 void MultiDisplayManager::InitInternalDisplayInfo() { | 95 bool MultiDisplayManager::IsActiveDisplay(const gfx::Display& display) const { |
| 76 #if defined(OS_CHROMEOS) | 96 for (DisplayList::const_iterator iter = displays_.begin(); |
| 77 if (!base::chromeos::IsRunningOnChromeOS()) | 97 iter != displays_.end(); ++iter) { |
| 78 return; | 98 if ((*iter).id() == display.id()) |
| 79 std::vector<XID> outputs; | 99 return true; |
| 80 ui::GetOutputDeviceHandles(&outputs); | |
| 81 std::vector<std::string> output_names = ui::GetOutputNames(outputs); | |
| 82 for (size_t i = 0; i < output_names.size(); ++i) { | |
| 83 if (chromeos::OutputConfigurator::IsInternalOutputName( | |
| 84 output_names[i])) { | |
| 85 XID internal_output = outputs[i]; | |
| 86 uint16 manufacturer_id = 0; | |
| 87 uint32 serial_number = 0; | |
| 88 ui::GetOutputDeviceData( | |
| 89 internal_output, &manufacturer_id, &serial_number, NULL); | |
| 90 internal_display_id_ = | |
| 91 gfx::Display::GetID(manufacturer_id, serial_number); | |
| 92 return; | |
| 93 } | |
| 94 } | 100 } |
| 95 #endif | 101 return false; |
| 96 } | 102 } |
| 97 | 103 |
| 98 bool MultiDisplayManager::HasInternalDisplay() const { | 104 bool MultiDisplayManager::HasInternalDisplay() const { |
| 99 return internal_display_id_ != gfx::Display::kInvalidDisplayID; | 105 return internal_display_id_ != gfx::Display::kInvalidDisplayID; |
| 100 } | 106 } |
| 101 | 107 |
| 108 bool MultiDisplayManager::IsInternalDisplayId(int64 id) const { |
| 109 return internal_display_id_ == id; |
| 110 } |
| 111 |
| 102 bool MultiDisplayManager::UpdateWorkAreaOfDisplayNearestWindow( | 112 bool MultiDisplayManager::UpdateWorkAreaOfDisplayNearestWindow( |
| 103 const aura::Window* window, | 113 const aura::Window* window, |
| 104 const gfx::Insets& insets) { | 114 const gfx::Insets& insets) { |
| 105 const RootWindow* root = window->GetRootWindow(); | 115 const RootWindow* root = window->GetRootWindow(); |
| 106 gfx::Display& display = FindDisplayForRootWindow(root); | 116 gfx::Display& display = FindDisplayForRootWindow(root); |
| 107 gfx::Rect old_work_area = display.work_area(); | 117 gfx::Rect old_work_area = display.work_area(); |
| 108 display.UpdateWorkAreaFromInsets(insets); | 118 display.UpdateWorkAreaFromInsets(insets); |
| 109 return old_work_area != display.work_area(); | 119 return old_work_area != display.work_area(); |
| 110 } | 120 } |
| 111 | 121 |
| 112 const gfx::Display& MultiDisplayManager::FindDisplayContainingPoint( | 122 const gfx::Display& MultiDisplayManager::FindDisplayContainingPoint( |
| 113 const gfx::Point& point_in_screen) const { | 123 const gfx::Point& point_in_screen) const { |
| 114 for (std::vector<gfx::Display>::const_iterator iter = displays_.begin(); | 124 for (DisplayList::const_iterator iter = displays_.begin(); |
| 115 iter != displays_.end(); ++iter) { | 125 iter != displays_.end(); ++iter) { |
| 116 const gfx::Display& display = *iter; | 126 const gfx::Display& display = *iter; |
| 117 if (display.bounds().Contains(point_in_screen)) | 127 if (display.bounds().Contains(point_in_screen)) |
| 118 return display; | 128 return display; |
| 119 } | 129 } |
| 120 return GetInvalidDisplay(); | 130 return GetInvalidDisplay(); |
| 121 } | 131 } |
| 122 | 132 |
| 123 void MultiDisplayManager::OnNativeDisplaysChanged( | 133 void MultiDisplayManager::OnNativeDisplaysChanged( |
| 124 const std::vector<gfx::Display>& updated_displays) { | 134 const std::vector<gfx::Display>& updated_displays) { |
| 125 if (updated_displays.size() == 0) { | 135 if (updated_displays.empty()) { |
| 126 // Don't update the displays when all displays are disconnected. | 136 // Don't update the displays when all displays are disconnected. |
| 127 // This happens when: | 137 // This happens when: |
| 128 // - the device is idle and powerd requested to turn off all displays. | 138 // - the device is idle and powerd requested to turn off all displays. |
| 129 // - the device is suspended. (kernel turns off all displays) | 139 // - the device is suspended. (kernel turns off all displays) |
| 130 // - the internal display's brightness is set to 0 and no external | 140 // - the internal display's brightness is set to 0 and no external |
| 131 // display is connected. | 141 // display is connected. |
| 132 // - the internal display's brightness is 0 and external display is | 142 // - the internal display's brightness is 0 and external display is |
| 133 // disconnected. | 143 // disconnected. |
| 134 // The display will be updated when one of displays is turned on, and the | 144 // The display will be updated when one of displays is turned on, and the |
| 135 // display list will be updated correctly. | 145 // display list will be updated correctly. |
| 136 return; | 146 return; |
| 137 } | 147 } |
| 138 std::vector<gfx::Display> new_displays; | 148 DisplayList new_displays = updated_displays; |
| 139 if (internal_display_id_ != gfx::Display::kInvalidDisplayID) { | 149 if (internal_display_id_ != gfx::Display::kInvalidDisplayID) { |
| 140 bool internal_display_connected = false; | 150 bool internal_display_connected = false; |
| 141 for (Displays::const_iterator iter = updated_displays.begin(); | 151 for (DisplayList::const_iterator iter = updated_displays.begin(); |
| 142 iter != updated_displays.end(); ++iter) { | 152 iter != updated_displays.end(); ++iter) { |
| 143 if ((*iter).id() == internal_display_id_) { | 153 if ((*iter).id() == internal_display_id_) { |
| 144 internal_display_connected = true; | 154 internal_display_connected = true; |
| 145 // Update the internal display cache. | 155 // Update the internal display cache. |
| 146 internal_display_.reset(new gfx::Display); | 156 internal_display_.reset(new gfx::Display); |
| 147 *internal_display_.get() = *iter; | 157 *internal_display_.get() = *iter; |
| 148 break; | 158 break; |
| 149 } | 159 } |
| 150 } | 160 } |
| 151 // If the internal display wasn't connected, use the cached value. | 161 // If the internal display wasn't connected, use the cached value. |
| 152 if (!internal_display_connected) | 162 if (!internal_display_connected) { |
| 163 // Internal display may be reported as disconnect during startup time. |
| 164 if (!internal_display_.get()) { |
| 165 internal_display_.reset(new gfx::Display(internal_display_id_, |
| 166 gfx::Rect(800, 600))); |
| 167 } |
| 153 new_displays.push_back(*internal_display_.get()); | 168 new_displays.push_back(*internal_display_.get()); |
| 154 new_displays.insert( | 169 } |
| 155 new_displays.end(), updated_displays.begin(), updated_displays.end()); | |
| 156 } else { | 170 } else { |
| 157 new_displays = updated_displays; | 171 new_displays = updated_displays; |
| 158 } | 172 } |
| 159 | 173 |
| 160 size_t min = std::min(displays_.size(), new_displays.size()); | 174 std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor()); |
| 175 std::sort(new_displays.begin(), new_displays.end(), DisplaySortFunctor()); |
| 176 DisplayList removed_displays; |
| 177 std::vector<size_t> changed_display_indices; |
| 178 std::vector<size_t> added_display_indices; |
| 179 gfx::Display current_primary; |
| 180 if (Shell::HasInstance()) |
| 181 current_primary = gfx::Screen::GetPrimaryDisplay(); |
| 161 | 182 |
| 162 // TODO(oshima): Fix this so that we can differentiate outputs | 183 for (DisplayList::iterator curr_iter = displays_.begin(), |
| 163 // and keep a content on one display stays on the same display | 184 new_iter = new_displays.begin(); |
| 164 // when a display is added or removed. | 185 curr_iter != displays_.end() || new_iter != new_displays.end();) { |
| 165 for (size_t i = 0; i < min; ++i) { | 186 if (curr_iter == displays_.end()) { |
| 166 gfx::Display& current_display = displays_[i]; | 187 // more displays in new list. |
| 167 const gfx::Display& new_display = new_displays[i]; | 188 added_display_indices.push_back(new_iter - new_displays.begin()); |
| 168 if (current_display.bounds_in_pixel() != new_display.bounds_in_pixel() || | 189 ++new_iter; |
| 169 current_display.device_scale_factor() != | 190 } else if (new_iter == new_displays.end()) { |
| 170 new_display.device_scale_factor()) { | 191 // more displays in current list. |
| 171 current_display.SetScaleAndBounds(new_display.device_scale_factor(), | 192 removed_displays.push_back(*curr_iter); |
| 172 new_display.bounds_in_pixel()); | 193 ++curr_iter; |
| 173 NotifyBoundsChanged(current_display); | 194 } else if ((*curr_iter).id() == (*new_iter).id()) { |
| 195 const gfx::Display& current_display = *curr_iter; |
| 196 gfx::Display& new_display = *new_iter; |
| 197 if (force_bounds_changed_ || |
| 198 current_display.bounds_in_pixel() != new_display.bounds_in_pixel() || |
| 199 current_display.device_scale_factor() != |
| 200 new_display.device_scale_factor()) { |
| 201 changed_display_indices.push_back(new_iter - new_displays.begin()); |
| 202 } |
| 203 // TODO(oshima): This is ugly. Simplify these operations. |
| 204 new_display.SetScaleAndBounds( |
| 205 new_display.device_scale_factor(), |
| 206 new_display.bounds_in_pixel()); |
| 207 // If the display is primary, then simpy use 0,0. Otherwise, |
| 208 // use the origin currently used. |
| 209 if ((*new_iter).id() != current_primary.id()) { |
| 210 new_display.set_bounds(gfx::Rect(current_display.bounds().origin(), |
| 211 new_display.bounds().size())); |
| 212 } |
| 213 new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); |
| 214 ++curr_iter; |
| 215 ++new_iter; |
| 216 } else if ((*curr_iter).id() < (*new_iter).id()) { |
| 217 // more displays in current list between ids, which means it is deleted. |
| 218 removed_displays.push_back(*curr_iter); |
| 219 ++curr_iter; |
| 220 } else { |
| 221 // more displays in new list between ids, which means it is added. |
| 222 added_display_indices.push_back(new_iter - new_displays.begin()); |
| 223 ++new_iter; |
| 174 } | 224 } |
| 175 } | 225 } |
| 226 displays_ = new_displays; |
| 227 // Temporarily add displays to be removed because display object |
| 228 // being removed are accessed during shutting down the root. |
| 229 displays_.insert(displays_.end(), removed_displays.begin(), |
| 230 removed_displays.end()); |
| 231 for (std::vector<size_t>::iterator iter = changed_display_indices.begin(); |
| 232 iter != changed_display_indices.end(); ++iter) { |
| 233 NotifyBoundsChanged(displays_[*iter]); |
| 234 } |
| 235 for (std::vector<size_t>::iterator iter = added_display_indices.begin(); |
| 236 iter != added_display_indices.end(); ++iter) { |
| 237 NotifyDisplayAdded(displays_[*iter]); |
| 238 } |
| 176 | 239 |
| 177 if (displays_.size() < new_displays.size()) { | 240 for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); |
| 178 // New displays added | 241 iter != removed_displays.rend(); ++iter) { |
| 179 for (size_t i = min; i < new_displays.size(); ++i) { | 242 NotifyDisplayRemoved(displays_.back()); |
| 180 const gfx::Display& new_display = new_displays[i]; | 243 displays_.pop_back(); |
| 181 displays_.push_back(gfx::Display(new_display.id())); | |
| 182 gfx::Display& display = displays_.back(); | |
| 183 display.SetScaleAndBounds(new_display.device_scale_factor(), | |
| 184 new_display.bounds_in_pixel()); | |
| 185 NotifyDisplayAdded(display); | |
| 186 } | |
| 187 } else { | |
| 188 // Displays are removed. We keep the display for the primary | |
| 189 // display (at index 0) because it needs the display information | |
| 190 // even if it doesn't exit. | |
| 191 while (displays_.size() > new_displays.size() && displays_.size() > 1) { | |
| 192 Displays::reverse_iterator iter = displays_.rbegin(); | |
| 193 NotifyDisplayRemoved(*iter); | |
| 194 displays_.erase(iter.base() - 1); | |
| 195 } | |
| 196 } | 244 } |
| 197 } | 245 } |
| 198 | 246 |
| 199 RootWindow* MultiDisplayManager::CreateRootWindowForDisplay( | 247 RootWindow* MultiDisplayManager::CreateRootWindowForDisplay( |
| 200 const gfx::Display& display) { | 248 const gfx::Display& display) { |
| 201 RootWindow* root_window = | 249 RootWindow* root_window = |
| 202 new RootWindow(RootWindow::CreateParams(display.bounds_in_pixel())); | 250 new RootWindow(RootWindow::CreateParams(display.bounds_in_pixel())); |
| 203 // No need to remove RootWindowObserver because | 251 // No need to remove RootWindowObserver because |
| 204 // the DisplayManager object outlives RootWindow objects. | 252 // the DisplayManager object outlives RootWindow objects. |
| 205 root_window->AddRootWindowObserver(this); | 253 root_window->AddRootWindowObserver(this); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 int area = intersect.width() * intersect.height(); | 295 int area = intersect.width() * intersect.height(); |
| 248 if (area > max) { | 296 if (area > max) { |
| 249 max = area; | 297 max = area; |
| 250 matching = &(*iter); | 298 matching = &(*iter); |
| 251 } | 299 } |
| 252 } | 300 } |
| 253 // Fallback to the primary display if there is no matching display. | 301 // Fallback to the primary display if there is no matching display. |
| 254 return matching ? *matching : displays_[0]; | 302 return matching ? *matching : displays_[0]; |
| 255 } | 303 } |
| 256 | 304 |
| 257 std::string MultiDisplayManager::GetDisplayNameAt(size_t index) { | 305 std::string MultiDisplayManager::GetDisplayNameFor( |
| 306 const gfx::Display& display) { |
| 258 #if defined(USE_X11) | 307 #if defined(USE_X11) |
| 259 gfx::Display* display = GetDisplayAt(index); | |
| 260 std::vector<XID> outputs; | 308 std::vector<XID> outputs; |
| 261 if (display && display->id() != gfx::Display::kInvalidDisplayID && | 309 if (display.id() != gfx::Display::kInvalidDisplayID && |
| 262 ui::GetOutputDeviceHandles(&outputs)) { | 310 ui::GetOutputDeviceHandles(&outputs)) { |
| 263 for (size_t i = 0; i < outputs.size(); ++i) { | 311 for (size_t i = 0; i < outputs.size(); ++i) { |
| 264 uint16 manufacturer_id = 0; | 312 uint16 manufacturer_id = 0; |
| 265 uint32 serial_number = 0; | 313 uint32 serial_number = 0; |
| 266 std::string name; | 314 std::string name; |
| 267 if (ui::GetOutputDeviceData( | 315 if (ui::GetOutputDeviceData( |
| 268 outputs[i], &manufacturer_id, &serial_number, &name) && | 316 outputs[i], &manufacturer_id, &serial_number, &name) && |
| 269 display->id() == | 317 display.id() == |
| 270 gfx::Display::GetID(manufacturer_id, serial_number)) { | 318 gfx::Display::GetID(manufacturer_id, serial_number)) { |
| 271 return name; | 319 return name; |
| 272 } | 320 } |
| 273 } | 321 } |
| 274 } | 322 } |
| 275 #endif | 323 #endif |
| 276 | 324 return base::StringPrintf("Display %d", static_cast<int>(display.id())); |
| 277 return base::StringPrintf("Display %d", static_cast<int>(index + 1)); | |
| 278 } | 325 } |
| 279 | 326 |
| 280 void MultiDisplayManager::OnRootWindowResized(const aura::RootWindow* root, | 327 void MultiDisplayManager::OnRootWindowResized(const aura::RootWindow* root, |
| 281 const gfx::Size& old_size) { | 328 const gfx::Size& old_size) { |
| 282 if (!use_fullscreen_host_window()) { | 329 if (!use_fullscreen_host_window()) { |
| 283 gfx::Display& display = FindDisplayForRootWindow(root); | 330 gfx::Display& display = FindDisplayForRootWindow(root); |
| 284 if (display.size() != root->GetHostSize()) { | 331 if (display.size() != root->GetHostSize()) { |
| 285 display.SetSize(root->GetHostSize()); | 332 display.SetSize(root->GetHostSize()); |
| 286 NotifyBoundsChanged(display); | 333 NotifyBoundsChanged(display); |
| 287 } | 334 } |
| 288 } | 335 } |
| 289 } | 336 } |
| 290 | 337 |
| 291 void MultiDisplayManager::Init() { | 338 void MultiDisplayManager::Init() { |
| 339 #if defined(OS_CHROMEOS) |
| 340 if (base::chromeos::IsRunningOnChromeOS()) { |
| 341 std::vector<XID> outputs; |
| 342 ui::GetOutputDeviceHandles(&outputs); |
| 343 std::vector<std::string> output_names = ui::GetOutputNames(outputs); |
| 344 for (size_t i = 0; i < output_names.size(); ++i) { |
| 345 if (chromeos::OutputConfigurator::IsInternalOutputName( |
| 346 output_names[i])) { |
| 347 internal_display_id_ = GetDisplayIdForOutput(outputs[i]); |
| 348 break; |
| 349 } |
| 350 } |
| 351 } |
| 352 #endif |
| 353 |
| 292 // TODO(oshima): Move this logic to DisplayChangeObserver. | 354 // TODO(oshima): Move this logic to DisplayChangeObserver. |
| 293 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 355 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 294 switches::kAuraHostWindowSize); | 356 switches::kAuraHostWindowSize); |
| 295 vector<string> parts; | 357 vector<string> parts; |
| 296 base::SplitString(size_str, ',', &parts); | 358 base::SplitString(size_str, ',', &parts); |
| 297 for (vector<string>::const_iterator iter = parts.begin(); | 359 for (vector<string>::const_iterator iter = parts.begin(); |
| 298 iter != parts.end(); ++iter) { | 360 iter != parts.end(); ++iter) { |
| 299 AddDisplayFromSpec(*iter); | 361 AddDisplayFromSpec(*iter); |
| 300 } | 362 } |
| 301 if (displays_.empty()) | 363 if (displays_.empty()) |
| 302 AddDisplayFromSpec(std::string() /* default */); | 364 AddDisplayFromSpec(std::string() /* default */); |
| 303 } | 365 } |
| 304 | 366 |
| 305 void MultiDisplayManager::CycleDisplayImpl() { | 367 void MultiDisplayManager::CycleDisplayImpl() { |
| 306 std::vector<gfx::Display> new_displays; | 368 std::vector<gfx::Display> new_displays; |
| 307 if (displays_.size() > 1) { | 369 if (displays_.size() > 1) { |
| 308 // Remove if there is more than one display. | 370 // Remove if there is more than one display. |
| 309 int count = displays_.size() - 1; | 371 int count = displays_.size() - 1; |
| 310 for (Displays::const_iterator iter = displays_.begin(); count-- > 0; ++iter) | 372 for (DisplayList::const_iterator iter = displays_.begin(); |
| 373 count-- > 0; ++iter) { |
| 311 new_displays.push_back(*iter); | 374 new_displays.push_back(*iter); |
| 375 } |
| 312 } else { | 376 } else { |
| 313 // Add if there is only one display. | 377 // Add if there is only one display. |
| 314 new_displays.push_back(displays_[0]); | 378 new_displays.push_back(displays_[0]); |
| 315 new_displays.push_back(CreateDisplayFromSpec("100+200-500x400")); | 379 new_displays.push_back(CreateDisplayFromSpec("100+200-500x400")); |
| 316 } | 380 } |
| 317 if (new_displays.size()) | 381 if (new_displays.size()) |
| 318 OnNativeDisplaysChanged(new_displays); | 382 OnNativeDisplaysChanged(new_displays); |
| 319 } | 383 } |
| 320 | 384 |
| 321 void MultiDisplayManager::ScaleDisplayImpl() { | 385 void MultiDisplayManager::ScaleDisplayImpl() { |
| 322 if (displays_.size() > 0) { | 386 if (displays_.size() > 0) { |
| 323 std::vector<gfx::Display> new_displays; | 387 std::vector<gfx::Display> new_displays; |
| 324 for (Displays::const_iterator iter = displays_.begin(); | 388 for (DisplayList::const_iterator iter = displays_.begin(); |
| 325 iter != displays_.end(); ++iter) { | 389 iter != displays_.end(); ++iter) { |
| 326 gfx::Display display = *iter; | 390 gfx::Display display = *iter; |
| 327 float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; | 391 float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; |
| 328 display.SetScaleAndBounds( | 392 display.SetScaleAndBounds( |
| 329 factor, gfx::Rect(display.bounds_in_pixel().origin(), | 393 factor, gfx::Rect(display.bounds_in_pixel().origin(), |
| 330 display.size().Scale(factor))); | 394 display.size().Scale(factor))); |
| 331 new_displays.push_back(display); | 395 new_displays.push_back(display); |
| 332 } | 396 } |
| 333 OnNativeDisplaysChanged(new_displays); | 397 OnNativeDisplaysChanged(new_displays); |
| 334 } | 398 } |
| 335 } | 399 } |
| 336 | 400 |
| 337 gfx::Display& MultiDisplayManager::FindDisplayForRootWindow( | 401 gfx::Display& MultiDisplayManager::FindDisplayForRootWindow( |
| 338 const aura::RootWindow* root_window) { | 402 const aura::RootWindow* root_window) { |
| 339 int64 id = root_window->GetProperty(kDisplayIdKey); | 403 int64 id = root_window->GetProperty(kDisplayIdKey); |
| 340 // if id is |kInvaildDisplayID|, it's being deleted. | 404 // if id is |kInvaildDisplayID|, it's being deleted. |
| 341 DCHECK(id != gfx::Display::kInvalidDisplayID); | 405 DCHECK(id != gfx::Display::kInvalidDisplayID); |
| 342 for (Displays::iterator iter = displays_.begin(); | 406 return FindDisplayForId(id); |
| 407 } |
| 408 |
| 409 gfx::Display& MultiDisplayManager::FindDisplayForId(int64 id) { |
| 410 for (DisplayList::iterator iter = displays_.begin(); |
| 343 iter != displays_.end(); ++iter) { | 411 iter != displays_.end(); ++iter) { |
| 344 if ((*iter).id() == id) | 412 if ((*iter).id() == id) |
| 345 return *iter; | 413 return *iter; |
| 346 } | 414 } |
| 347 DLOG(FATAL) << "Could not find display by id:" << id; | 415 DLOG(FATAL) << "Could not find display:" << id; |
| 348 return GetInvalidDisplay(); | 416 return GetInvalidDisplay(); |
| 349 } | 417 } |
| 350 | 418 |
| 351 void MultiDisplayManager::AddDisplayFromSpec(const std::string& spec) { | 419 void MultiDisplayManager::AddDisplayFromSpec(const std::string& spec) { |
| 352 gfx::Display display = CreateDisplayFromSpec(spec); | 420 gfx::Display display = CreateDisplayFromSpec(spec); |
| 353 | 421 |
| 354 const gfx::Insets insets = display.GetWorkAreaInsets(); | 422 const gfx::Insets insets = display.GetWorkAreaInsets(); |
| 355 const gfx::Rect& native_bounds = display.bounds_in_pixel(); | 423 const gfx::Rect& native_bounds = display.bounds_in_pixel(); |
| 356 display.SetScaleAndBounds(display.device_scale_factor(), native_bounds); | 424 display.SetScaleAndBounds(display.device_scale_factor(), native_bounds); |
| 357 display.UpdateWorkAreaFromInsets(insets); | 425 display.UpdateWorkAreaFromInsets(insets); |
| 358 displays_.push_back(display); | 426 displays_.push_back(display); |
| 359 } | 427 } |
| 360 | 428 |
| 361 int64 MultiDisplayManager::EnableInternalDisplayForTest() { | 429 int64 MultiDisplayManager::SetFirstDisplayAsInternalDisplayForTest() { |
| 362 const int64 kInternalDisplayIdForTest = 9999; | 430 internal_display_id_ = displays_[0].id(); |
| 363 internal_display_id_ = kInternalDisplayIdForTest; | 431 internal_display_.reset(new gfx::Display); |
| 364 internal_display_.reset(new gfx::Display(internal_display_id_, | 432 *internal_display_ = displays_[0]; |
| 365 gfx::Rect(800, 600))); | 433 return internal_display_id_; |
| 366 return kInternalDisplayIdForTest; | 434 } |
| 435 |
| 436 void MultiDisplayManager::SetDisplayIdsForTest(DisplayList* to_update) const { |
| 437 DisplayList::iterator iter_to_update = to_update->begin(); |
| 438 DisplayList::const_iterator iter = displays_.begin(); |
| 439 for (; iter != displays_.end() && iter_to_update != to_update->end(); |
| 440 ++iter, ++iter_to_update) { |
| 441 (*iter_to_update).set_id((*iter).id()); |
| 442 } |
| 367 } | 443 } |
| 368 | 444 |
| 369 } // namespace internal | 445 } // namespace internal |
| 370 } // namespace ash | 446 } // namespace ash |
| OLD | NEW |