Chromium Code Reviews| 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/display_manager.h" | 5 #include "ash/display/display_manager.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "ash/ash_switches.h" | 12 #include "ash/ash_switches.h" |
| 13 #include "ash/display/display_controller.h" | 13 #include "ash/display/display_controller.h" |
| 14 #include "ash/display/mirror_window_controller.h" | |
| 14 #include "ash/screen_ash.h" | 15 #include "ash/screen_ash.h" |
| 15 #include "ash/shell.h" | 16 #include "ash/shell.h" |
| 16 #include "base/auto_reset.h" | 17 #include "base/auto_reset.h" |
| 17 #include "base/command_line.h" | 18 #include "base/command_line.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 20 #include "base/stringprintf.h" | 21 #include "base/stringprintf.h" |
| 21 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_split.h" | 23 #include "base/strings/string_split.h" |
| 23 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 24 #include "grit/ash_strings.h" | 25 #include "grit/ash_strings.h" |
| 25 #include "ui/aura/client/screen_position_client.h" | 26 #include "ui/aura/client/screen_position_client.h" |
| 26 #include "ui/aura/env.h" | 27 #include "ui/aura/env.h" |
| 27 #include "ui/aura/root_window.h" | 28 #include "ui/aura/root_window.h" |
| 28 #include "ui/aura/root_window_host.h" | 29 #include "ui/aura/root_window_host.h" |
| 29 #include "ui/aura/window_property.h" | 30 #include "ui/aura/window_property.h" |
| 30 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
| 31 #include "ui/gfx/display.h" | 32 #include "ui/gfx/display.h" |
| 32 #include "ui/gfx/rect.h" | 33 #include "ui/gfx/rect.h" |
| 33 #include "ui/gfx/screen.h" | 34 #include "ui/gfx/screen.h" |
| 34 #include "ui/gfx/size_conversions.h" | 35 #include "ui/gfx/size_conversions.h" |
| 35 | 36 |
| 36 #if defined(USE_X11) | 37 #if defined(USE_X11) |
| 37 #include "ui/base/x/x11_util.h" | 38 #include "ui/base/x/x11_util.h" |
| 38 #endif | 39 #endif |
| 39 | 40 |
| 40 #if defined(OS_CHROMEOS) | 41 #if defined(OS_CHROMEOS) |
| 42 #include "ash/display/output_configurator_animation.h" | |
| 41 #include "base/chromeos/chromeos_version.h" | 43 #include "base/chromeos/chromeos_version.h" |
| 42 #include "chromeos/display/output_configurator.h" | 44 #include "chromeos/display/output_configurator.h" |
| 43 #endif | 45 #endif |
| 44 | 46 |
| 45 #if defined(OS_WIN) | 47 #if defined(OS_WIN) |
| 46 #include "base/win/windows_version.h" | 48 #include "base/win/windows_version.h" |
| 47 #include "ui/aura/remote_root_window_host_win.h" | 49 #include "ui/aura/remote_root_window_host_win.h" |
| 48 #endif | 50 #endif |
| 49 | 51 |
| 50 DECLARE_WINDOW_PROPERTY_TYPE(int64); | 52 DECLARE_WINDOW_PROPERTY_TYPE(int64); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 #endif | 112 #endif |
| 111 } | 113 } |
| 112 return ret; | 114 return ret; |
| 113 } | 115 } |
| 114 | 116 |
| 115 gfx::Display& GetInvalidDisplay() { | 117 gfx::Display& GetInvalidDisplay() { |
| 116 static gfx::Display* invalid_display = new gfx::Display(); | 118 static gfx::Display* invalid_display = new gfx::Display(); |
| 117 return *invalid_display; | 119 return *invalid_display; |
| 118 } | 120 } |
| 119 | 121 |
| 122 // Used to either create or close the mirror window | |
| 123 // after all displays and associated RootWidows are | |
| 124 // configured in UpdateDisplay. | |
| 125 class MirrorWindowUpdater { | |
| 126 public: | |
| 127 virtual ~MirrorWindowUpdater() {} | |
| 128 }; | |
| 129 | |
| 130 class MirrorWindowCreater : public MirrorWindowUpdater { | |
|
James Cook
2013/05/21 08:07:41
nit: either Creator or Builder
oshima
2013/05/21 14:41:50
Done.
| |
| 131 public: | |
| 132 explicit MirrorWindowCreater(const DisplayInfo& display_info) | |
| 133 : display_info_(display_info) { | |
| 134 } | |
| 135 | |
| 136 virtual ~MirrorWindowCreater() { | |
| 137 Shell::GetInstance()->mirror_window_controller()-> | |
| 138 UpdateWindow(display_info_); | |
| 139 } | |
| 140 | |
| 141 private: | |
| 142 const DisplayInfo display_info_; | |
| 143 DISALLOW_COPY_AND_ASSIGN(MirrorWindowCreater); | |
| 144 }; | |
| 145 | |
| 146 class MirrorWindowCloser : public MirrorWindowUpdater { | |
| 147 public: | |
| 148 MirrorWindowCloser() {} | |
| 149 virtual ~MirrorWindowCloser() { | |
| 150 Shell::GetInstance()->mirror_window_controller()->Close(); | |
| 151 } | |
| 152 | |
| 153 private: | |
| 154 DISALLOW_COPY_AND_ASSIGN(MirrorWindowCloser); | |
| 155 }; | |
| 156 | |
| 120 } // namespace | 157 } // namespace |
| 121 | 158 |
| 122 using aura::RootWindow; | 159 using aura::RootWindow; |
| 123 using aura::Window; | 160 using aura::Window; |
| 124 using std::string; | 161 using std::string; |
| 125 using std::vector; | 162 using std::vector; |
| 126 | 163 |
| 127 DEFINE_WINDOW_PROPERTY_KEY(int64, kDisplayIdKey, | 164 DEFINE_WINDOW_PROPERTY_KEY(int64, kDisplayIdKey, |
| 128 gfx::Display::kInvalidDisplayID); | 165 gfx::Display::kInvalidDisplayID); |
| 129 | 166 |
| 130 DisplayManager::DisplayManager() | 167 DisplayManager::DisplayManager() |
| 131 : first_display_id_(gfx::Display::kInvalidDisplayID), | 168 : first_display_id_(gfx::Display::kInvalidDisplayID), |
| 132 mirrored_display_id_(gfx::Display::kInvalidDisplayID), | |
| 133 num_connected_displays_(0), | 169 num_connected_displays_(0), |
| 134 force_bounds_changed_(false), | 170 force_bounds_changed_(false), |
| 135 change_display_upon_host_resize_(false) { | 171 change_display_upon_host_resize_(false), |
| 172 software_mirroring_enabled_(false) { | |
| 136 #if defined(OS_CHROMEOS) | 173 #if defined(OS_CHROMEOS) |
| 137 change_display_upon_host_resize_ = !base::chromeos::IsRunningOnChromeOS(); | 174 change_display_upon_host_resize_ = !base::chromeos::IsRunningOnChromeOS(); |
| 138 #endif | 175 #endif |
| 139 Init(); | 176 Init(); |
| 140 } | 177 } |
| 141 | 178 |
| 142 DisplayManager::~DisplayManager() { | 179 DisplayManager::~DisplayManager() { |
| 143 } | 180 } |
| 144 | 181 |
| 145 // static | 182 // static |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 if (updated_displays.size() == 1) { | 365 if (updated_displays.size() == 1) { |
| 329 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); | 366 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); |
| 330 } else { | 367 } else { |
| 331 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() | 368 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() |
| 332 << ") [0]=" << updated_displays[0].ToString() | 369 << ") [0]=" << updated_displays[0].ToString() |
| 333 << ", [1]=" << updated_displays[1].ToString(); | 370 << ", [1]=" << updated_displays[1].ToString(); |
| 334 } | 371 } |
| 335 | 372 |
| 336 bool internal_display_connected = false; | 373 bool internal_display_connected = false; |
| 337 num_connected_displays_ = updated_displays.size(); | 374 num_connected_displays_ = updated_displays.size(); |
| 338 mirrored_display_id_ = gfx::Display::kInvalidDisplayID; | 375 mirrored_display_ = gfx::Display(); |
| 339 DisplayInfoList new_display_info_list; | 376 DisplayInfoList new_display_info_list; |
| 340 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); | 377 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); |
| 341 iter != updated_displays.end(); | 378 iter != updated_displays.end(); |
| 342 ++iter) { | 379 ++iter) { |
| 343 if (!internal_display_connected) | 380 if (!internal_display_connected) |
| 344 internal_display_connected = IsInternalDisplayId(iter->id()); | 381 internal_display_connected = IsInternalDisplayId(iter->id()); |
| 345 // Mirrored monitors have the same y coordinates. | 382 // Mirrored monitors have the same y coordinates. |
| 346 int y = iter->bounds_in_pixel().y(); | 383 int y = iter->bounds_in_pixel().y(); |
| 347 if (y_coords.find(y) != y_coords.end()) { | 384 if (y_coords.find(y) != y_coords.end()) { |
| 348 InsertAndUpdateDisplayInfo(*iter); | 385 InsertAndUpdateDisplayInfo(*iter); |
| 349 mirrored_display_id_ = iter->id(); | 386 mirrored_display_ = CreateDisplayFromDisplayInfoById(iter->id()); |
| 350 } else { | 387 } else { |
| 351 y_coords.insert(y); | 388 y_coords.insert(y); |
| 352 new_display_info_list.push_back(*iter); | 389 new_display_info_list.push_back(*iter); |
| 353 } | 390 } |
| 354 } | 391 } |
| 355 if (HasInternalDisplay() && | 392 if (HasInternalDisplay() && |
| 356 !internal_display_connected && | 393 !internal_display_connected && |
| 357 display_info_.find(gfx::Display::InternalDisplayId()) == | 394 display_info_.find(gfx::Display::InternalDisplayId()) == |
| 358 display_info_.end()) { | 395 display_info_.end()) { |
| 359 DisplayInfo internal_display_info( | 396 DisplayInfo internal_display_info( |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 385 DisplayList removed_displays; | 422 DisplayList removed_displays; |
| 386 std::vector<size_t> changed_display_indices; | 423 std::vector<size_t> changed_display_indices; |
| 387 std::vector<size_t> added_display_indices; | 424 std::vector<size_t> added_display_indices; |
| 388 | 425 |
| 389 DisplayList::iterator curr_iter = displays_.begin(); | 426 DisplayList::iterator curr_iter = displays_.begin(); |
| 390 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); | 427 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); |
| 391 | 428 |
| 392 DisplayList new_displays; | 429 DisplayList new_displays; |
| 393 bool update_mouse_location = false; | 430 bool update_mouse_location = false; |
| 394 | 431 |
| 432 scoped_ptr<MirrorWindowUpdater> mirror_window_updater; | |
| 433 // TODO(oshima): We may want to use external as the source. | |
| 434 int mirrored_display_id = gfx::Display::kInvalidDisplayID; | |
| 435 if (software_mirroring_enabled_ && updated_display_info_list.size() == 2) | |
| 436 mirrored_display_id = updated_display_info_list[1].id(); | |
| 437 | |
| 395 while (curr_iter != displays_.end() || | 438 while (curr_iter != displays_.end() || |
| 396 new_info_iter != new_display_info_list.end()) { | 439 new_info_iter != new_display_info_list.end()) { |
| 440 if (new_info_iter != new_display_info_list.end() && | |
| 441 mirrored_display_id == new_info_iter->id()) { | |
| 442 InsertAndUpdateDisplayInfo(*new_info_iter); | |
| 443 mirrored_display_ = CreateDisplayFromDisplayInfoById(new_info_iter->id()); | |
| 444 mirror_window_updater.reset( | |
| 445 new MirrorWindowCreater(display_info_[new_info_iter->id()])); | |
|
James Cook
2013/05/21 08:07:41
Does this need to choose the higher resolution mon
oshima
2013/05/21 14:41:50
Considering the typical usage, I think this should
| |
| 446 ++new_info_iter; | |
| 447 // Remove existing external dispaly if it is going to be mirrored. | |
| 448 if (curr_iter != displays_.end() && | |
| 449 curr_iter->id() == mirrored_display_id) { | |
| 450 removed_displays.push_back(*curr_iter); | |
| 451 ++curr_iter; | |
| 452 } | |
| 453 update_mouse_location = true; | |
| 454 continue; | |
| 455 } | |
| 456 | |
| 397 if (curr_iter == displays_.end()) { | 457 if (curr_iter == displays_.end()) { |
| 398 // more displays in new list. | 458 // more displays in new list. |
| 399 added_display_indices.push_back(new_displays.size()); | 459 added_display_indices.push_back(new_displays.size()); |
| 400 InsertAndUpdateDisplayInfo(*new_info_iter); | 460 InsertAndUpdateDisplayInfo(*new_info_iter); |
| 401 new_displays.push_back( | 461 new_displays.push_back( |
| 402 CreateDisplayFromDisplayInfoById(new_info_iter->id())); | 462 CreateDisplayFromDisplayInfoById(new_info_iter->id())); |
| 403 ++new_info_iter; | 463 ++new_info_iter; |
| 404 } else if (new_info_iter == new_display_info_list.end()) { | 464 } else if (new_info_iter == new_display_info_list.end()) { |
| 405 // more displays in current list. | 465 // more displays in current list. |
| 406 removed_displays.push_back(*curr_iter); | 466 removed_displays.push_back(*curr_iter); |
| 407 ++curr_iter; | 467 ++curr_iter; |
| 408 update_mouse_location = true; | 468 update_mouse_location = true; |
| 409 } else if (curr_iter->id() == new_info_iter->id()) { | 469 } else if (curr_iter->id() == new_info_iter->id()) { |
| 410 const gfx::Display& current_display = *curr_iter; | 470 const gfx::Display& current_display = *curr_iter; |
| 411 // Copy the info because |CreateDisplayFromInfo| updates the instance. | 471 // Copy the info because |CreateDisplayFromInfo| updates the instance. |
| 412 const DisplayInfo current_display_info = | 472 const DisplayInfo current_display_info = |
| 413 GetDisplayInfo(current_display.id()); | 473 GetDisplayInfo(current_display.id()); |
| 414 InsertAndUpdateDisplayInfo(*new_info_iter); | 474 InsertAndUpdateDisplayInfo(*new_info_iter); |
| 415 gfx::Display new_display = | 475 gfx::Display new_display = |
| 416 CreateDisplayFromDisplayInfoById(new_info_iter->id()); | 476 CreateDisplayFromDisplayInfoById(new_info_iter->id()); |
| 417 const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id()); | 477 const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id()); |
| 418 | 478 |
| 419 bool host_window_bounds_changed = | 479 bool host_window_bounds_changed = |
| 420 current_display_info.bounds_in_pixel() != | 480 current_display_info.bounds_in_pixel() != |
| 421 new_display_info.bounds_in_pixel(); | 481 new_display_info.bounds_in_pixel(); |
| 422 | 482 |
| 423 // TODO(oshima): Rotating square dislay doesn't work as the size | |
| 424 // won't change. This doesn't cause a problem now as there is no | |
| 425 // such display. This will be fixed by comparing the rotation as | |
| 426 // well when the rotation variable is added to gfx::Display. | |
| 427 if (force_bounds_changed_ || | 483 if (force_bounds_changed_ || |
| 428 host_window_bounds_changed || | 484 host_window_bounds_changed || |
| 429 (current_display.device_scale_factor() != | 485 (current_display.device_scale_factor() != |
| 430 new_display.device_scale_factor()) || | 486 new_display.device_scale_factor()) || |
| 431 (current_display_info.size_in_pixel() != | 487 (current_display_info.size_in_pixel() != |
| 432 new_display.GetSizeInPixel())) { | 488 new_display.GetSizeInPixel()) || |
| 489 (current_display.rotation() != new_display.rotation())) { | |
| 433 | 490 |
| 434 // Don't update mouse location if the display size has | 491 // Don't update mouse location if the display size has |
| 435 // changed due to rotation or zooming. | 492 // changed due to rotation or zooming. |
| 436 if (host_window_bounds_changed) | 493 if (host_window_bounds_changed) |
| 437 update_mouse_location = true; | 494 update_mouse_location = true; |
| 438 | 495 |
| 439 changed_display_indices.push_back(new_displays.size()); | 496 changed_display_indices.push_back(new_displays.size()); |
| 440 } | 497 } |
| 441 | 498 |
| 442 new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); | 499 new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); |
| 443 new_displays.push_back(new_display); | 500 new_displays.push_back(new_display); |
| 444 ++curr_iter; | 501 ++curr_iter; |
| 445 ++new_info_iter; | 502 ++new_info_iter; |
| 446 } else if (curr_iter->id() < new_info_iter->id()) { | 503 } else if (curr_iter->id() < new_info_iter->id()) { |
| 447 // more displays in current list between ids, which means it is deleted. | 504 // more displays in current list between ids, which means it is deleted. |
| 448 removed_displays.push_back(*curr_iter); | 505 removed_displays.push_back(*curr_iter); |
| 449 ++curr_iter; | 506 ++curr_iter; |
| 450 update_mouse_location = true; | 507 update_mouse_location = true; |
| 451 } else { | 508 } else { |
| 452 // more displays in new list between ids, which means it is added. | 509 // more displays in new list between ids, which means it is added. |
| 453 added_display_indices.push_back(new_displays.size()); | 510 added_display_indices.push_back(new_displays.size()); |
| 454 InsertAndUpdateDisplayInfo(*new_info_iter); | 511 InsertAndUpdateDisplayInfo(*new_info_iter); |
| 455 new_displays.push_back( | 512 new_displays.push_back( |
| 456 CreateDisplayFromDisplayInfoById(new_info_iter->id())); | 513 CreateDisplayFromDisplayInfoById(new_info_iter->id())); |
| 457 ++new_info_iter; | 514 ++new_info_iter; |
| 458 } | 515 } |
| 459 } | 516 } |
| 460 | 517 |
| 518 // Try to close mirror window unless mirror window is necessary. | |
| 519 if (!mirror_window_updater.get()) | |
| 520 mirror_window_updater.reset(new MirrorWindowCloser); | |
| 521 | |
| 461 // Do not update |displays_| if there's nothing to be updated. Without this, | 522 // Do not update |displays_| if there's nothing to be updated. Without this, |
| 462 // it will not update the display layout, which causes the bug | 523 // it will not update the display layout, which causes the bug |
| 463 // http://crbug.com/155948. | 524 // http://crbug.com/155948. |
| 464 if (changed_display_indices.empty() && added_display_indices.empty() && | 525 if (changed_display_indices.empty() && added_display_indices.empty() && |
| 465 removed_displays.empty()) { | 526 removed_displays.empty()) { |
| 466 return; | 527 return; |
| 467 } | 528 } |
| 468 | 529 |
| 469 DisplayController* display_controller = | 530 DisplayController* display_controller = |
| 470 Shell::GetInstance()->display_controller(); | 531 Shell::GetInstance()->display_controller(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 } | 593 } |
| 533 #endif | 594 #endif |
| 534 return primary_candidate; | 595 return primary_candidate; |
| 535 } | 596 } |
| 536 | 597 |
| 537 size_t DisplayManager::GetNumDisplays() const { | 598 size_t DisplayManager::GetNumDisplays() const { |
| 538 return displays_.size(); | 599 return displays_.size(); |
| 539 } | 600 } |
| 540 | 601 |
| 541 bool DisplayManager::IsMirrored() const { | 602 bool DisplayManager::IsMirrored() const { |
| 542 return mirrored_display_id_ != gfx::Display::kInvalidDisplayID; | 603 return mirrored_display_.id() != gfx::Display::kInvalidDisplayID; |
| 543 } | 604 } |
| 544 | 605 |
| 545 const gfx::Display& DisplayManager::GetDisplayNearestWindow( | 606 const gfx::Display& DisplayManager::GetDisplayNearestWindow( |
| 546 const Window* window) const { | 607 const Window* window) const { |
| 547 if (!window) | 608 if (!window) |
| 548 return DisplayController::GetPrimaryDisplay(); | 609 return DisplayController::GetPrimaryDisplay(); |
| 549 const RootWindow* root = window->GetRootWindow(); | 610 const RootWindow* root = window->GetRootWindow(); |
| 550 DisplayManager* manager = const_cast<DisplayManager*>(this); | 611 DisplayManager* manager = const_cast<DisplayManager*>(this); |
| 551 return root ? | 612 return root ? |
| 552 manager->FindDisplayForRootWindow(root) : | 613 manager->FindDisplayForRootWindow(root) : |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 if (id == gfx::Display::kInvalidDisplayID) | 654 if (id == gfx::Display::kInvalidDisplayID) |
| 594 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); | 655 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| 595 | 656 |
| 596 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); | 657 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); |
| 597 if (iter != display_info_.end() && !iter->second.name().empty()) | 658 if (iter != display_info_.end() && !iter->second.name().empty()) |
| 598 return iter->second.name(); | 659 return iter->second.name(); |
| 599 | 660 |
| 600 return base::StringPrintf("Display %d", static_cast<int>(id)); | 661 return base::StringPrintf("Display %d", static_cast<int>(id)); |
| 601 } | 662 } |
| 602 | 663 |
| 603 void DisplayManager::OnRootWindowResized(const aura::RootWindow* root, | |
| 604 const gfx::Size& old_size) { | |
| 605 if (change_display_upon_host_resize_) { | |
| 606 gfx::Display& display = FindDisplayForRootWindow(root); | |
| 607 gfx::Size old_display_size_in_pixel = display.GetSizeInPixel(); | |
| 608 display_info_[display.id()].SetBounds( | |
| 609 gfx::Rect(root->GetHostOrigin(), root->GetHostSize())); | |
| 610 const gfx::Size& new_root_size = root->bounds().size(); | |
| 611 if (old_size != new_root_size) { | |
| 612 display.SetSize(display_info_[display.id()].size_in_pixel()); | |
| 613 Shell::GetInstance()->screen()->NotifyBoundsChanged(display); | |
| 614 } | |
| 615 } | |
| 616 } | |
| 617 | |
| 618 void DisplayManager::SetMirrorMode(bool mirrored) { | 664 void DisplayManager::SetMirrorMode(bool mirrored) { |
| 619 if (num_connected_displays() <= 1) | 665 if (num_connected_displays() <= 1) |
| 620 return; | 666 return; |
| 621 | 667 |
| 622 #if defined(OS_CHROMEOS) | 668 #if defined(OS_CHROMEOS) |
| 623 if (base::chromeos::IsRunningOnChromeOS()) { | 669 if (base::chromeos::IsRunningOnChromeOS()) { |
| 624 chromeos::OutputState new_state = mirrored ? | 670 chromeos::OutputState new_state = mirrored ? |
| 625 chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED; | 671 chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED; |
| 626 Shell::GetInstance()->output_configurator()->SetDisplayMode(new_state); | 672 Shell::GetInstance()->output_configurator()->SetDisplayMode(new_state); |
| 627 } else { | 673 } else { |
| 628 // TODO(oshima): Compositor based mirroring. | 674 SetSoftwareMirroring(mirrored); |
| 675 DisplayInfoList display_info_list; | |
| 676 int count = 0; | |
| 677 for (std::map<int64, DisplayInfo>::const_iterator iter = | |
| 678 display_info_.begin(); | |
| 679 count < 2; ++iter, ++count) { | |
| 680 display_info_list.push_back(GetDisplayInfo(iter->second.id())); | |
| 681 } | |
| 682 UpdateDisplays(display_info_list); | |
| 683 if (Shell::GetInstance()->output_configurator_animation()) { | |
| 684 Shell::GetInstance()->output_configurator_animation()-> | |
| 685 StartFadeInAnimation(); | |
| 686 } | |
| 629 } | 687 } |
| 630 #endif | 688 #endif |
| 631 } | 689 } |
| 632 | 690 |
| 633 void DisplayManager::AddRemoveDisplay() { | 691 void DisplayManager::AddRemoveDisplay() { |
| 634 DCHECK(!displays_.empty()); | 692 DCHECK(!displays_.empty()); |
| 635 std::vector<DisplayInfo> new_display_info_list; | 693 std::vector<DisplayInfo> new_display_info_list; |
| 636 new_display_info_list.push_back( | 694 new_display_info_list.push_back( |
| 637 GetDisplayInfo(DisplayController::GetPrimaryDisplay().id())); | 695 GetDisplayInfo(DisplayController::GetPrimaryDisplay().id())); |
| 638 // Add if there is only one display. | 696 // Add if there is only one display connected. |
| 639 if (displays_.size() == 1) { | 697 if (num_connected_displays() == 1) { |
| 640 // Layout the 2nd display below the primary as with the real device. | 698 // Layout the 2nd display below the primary as with the real device. |
| 641 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); | 699 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); |
| 642 gfx::Rect host_bounds = | 700 gfx::Rect host_bounds = |
| 643 gfx::Rect(primary->GetHostOrigin(), primary->GetHostSize()); | 701 gfx::Rect(primary->GetHostOrigin(), primary->GetHostSize()); |
| 644 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( | 702 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( |
| 645 base::StringPrintf( | 703 base::StringPrintf( |
| 646 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); | 704 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); |
| 647 } | 705 } |
| 648 num_connected_displays_ = new_display_info_list.size(); | 706 num_connected_displays_ = new_display_info_list.size(); |
| 649 UpdateDisplays(new_display_info_list); | 707 UpdateDisplays(new_display_info_list); |
| 650 } | 708 } |
| 651 | 709 |
| 652 void DisplayManager::ToggleDisplayScaleFactor() { | 710 void DisplayManager::ToggleDisplayScaleFactor() { |
| 653 DCHECK(!displays_.empty()); | 711 DCHECK(!displays_.empty()); |
| 654 std::vector<DisplayInfo> new_display_info_list; | 712 std::vector<DisplayInfo> new_display_info_list; |
| 655 for (DisplayList::const_iterator iter = displays_.begin(); | 713 for (DisplayList::const_iterator iter = displays_.begin(); |
| 656 iter != displays_.end(); ++iter) { | 714 iter != displays_.end(); ++iter) { |
| 657 DisplayInfo display_info = GetDisplayInfo(iter->id()); | 715 DisplayInfo display_info = GetDisplayInfo(iter->id()); |
| 658 display_info.set_device_scale_factor( | 716 display_info.set_device_scale_factor( |
| 659 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); | 717 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); |
| 660 new_display_info_list.push_back(display_info); | 718 new_display_info_list.push_back(display_info); |
| 661 } | 719 } |
| 662 UpdateDisplays(new_display_info_list); | 720 UpdateDisplays(new_display_info_list); |
| 663 } | 721 } |
| 664 | 722 |
| 723 void DisplayManager::OnRootWindowResized(const aura::RootWindow* root, | |
| 724 const gfx::Size& old_size) { | |
| 725 if (change_display_upon_host_resize_) { | |
| 726 gfx::Display& display = FindDisplayForRootWindow(root); | |
| 727 gfx::Size old_display_size_in_pixel = display.GetSizeInPixel(); | |
| 728 display_info_[display.id()].SetBounds( | |
| 729 gfx::Rect(root->GetHostOrigin(), root->GetHostSize())); | |
| 730 const gfx::Size& new_root_size = root->bounds().size(); | |
| 731 if (old_size != new_root_size) { | |
| 732 display.SetSize(display_info_[display.id()].size_in_pixel()); | |
| 733 Shell::GetInstance()->screen()->NotifyBoundsChanged(display); | |
| 734 } | |
| 735 } | |
| 736 } | |
| 737 | |
| 738 void DisplayManager::SetSoftwareMirroring(bool enabled) { | |
| 739 software_mirroring_enabled_ = enabled; | |
| 740 mirrored_display_ = gfx::Display(); | |
| 741 } | |
| 742 | |
| 665 int64 DisplayManager::GetDisplayIdForUIScaling() const { | 743 int64 DisplayManager::GetDisplayIdForUIScaling() const { |
| 666 // UI Scaling is effective only on internal display. | 744 // UI Scaling is effective only on internal display. |
| 667 int64 display_id = gfx::Display::InternalDisplayId(); | 745 int64 display_id = gfx::Display::InternalDisplayId(); |
| 668 #if defined(OS_WIN) | 746 #if defined(OS_WIN) |
| 669 display_id = first_display_id(); | 747 display_id = first_display_id(); |
| 670 #endif | 748 #endif |
| 671 return display_id; | 749 return display_id; |
| 672 } | 750 } |
| 673 | 751 |
| 674 void DisplayManager::Init() { | 752 void DisplayManager::Init() { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 686 first_display_id_ = displays_[0].id(); | 764 first_display_id_ = displays_[0].id(); |
| 687 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 765 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 688 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) | 766 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) |
| 689 gfx::Display::SetInternalDisplayId(first_display_id_); | 767 gfx::Display::SetInternalDisplayId(first_display_id_); |
| 690 num_connected_displays_ = displays_.size(); | 768 num_connected_displays_ = displays_.size(); |
| 691 } | 769 } |
| 692 | 770 |
| 693 gfx::Display& DisplayManager::FindDisplayForRootWindow( | 771 gfx::Display& DisplayManager::FindDisplayForRootWindow( |
| 694 const aura::RootWindow* root_window) { | 772 const aura::RootWindow* root_window) { |
| 695 int64 id = root_window->GetProperty(kDisplayIdKey); | 773 int64 id = root_window->GetProperty(kDisplayIdKey); |
| 774 // RootWindow needs Display to determine it's device scale factor. | |
| 775 // TODO(oshima): We don't need full display info for mirror | |
| 776 // window. Refactor so that RootWindow doesn't use it. | |
| 777 if (mirrored_display_.id() == id) | |
| 778 return mirrored_display_; | |
| 779 | |
| 696 // if id is |kInvaildDisplayID|, it's being deleted. | 780 // if id is |kInvaildDisplayID|, it's being deleted. |
| 697 DCHECK(id != gfx::Display::kInvalidDisplayID); | 781 DCHECK(id != gfx::Display::kInvalidDisplayID); |
| 698 gfx::Display& display = FindDisplayForId(id); | 782 gfx::Display& display = FindDisplayForId(id); |
| 699 DCHECK(display.is_valid()); | 783 DCHECK(display.is_valid()); |
| 700 return display; | 784 return display; |
| 701 } | 785 } |
| 702 | 786 |
| 703 gfx::Display& DisplayManager::FindDisplayForId(int64 id) { | 787 gfx::Display& DisplayManager::FindDisplayForId(int64 id) { |
| 704 for (DisplayList::iterator iter = displays_.begin(); | 788 for (DisplayList::iterator iter = displays_.begin(); |
| 705 iter != displays_.end(); ++iter) { | 789 iter != displays_.end(); ++iter) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 // always (0,0) and the secondary display's bounds will be updated | 824 // always (0,0) and the secondary display's bounds will be updated |
| 741 // by |DisplayController::UpdateDisplayBoundsForLayout|. | 825 // by |DisplayController::UpdateDisplayBoundsForLayout|. |
| 742 new_display.SetScaleAndBounds( | 826 new_display.SetScaleAndBounds( |
| 743 display_info.device_scale_factor(), gfx::Rect(bounds_in_pixel.size())); | 827 display_info.device_scale_factor(), gfx::Rect(bounds_in_pixel.size())); |
| 744 new_display.set_rotation(display_info.rotation()); | 828 new_display.set_rotation(display_info.rotation()); |
| 745 return new_display; | 829 return new_display; |
| 746 } | 830 } |
| 747 | 831 |
| 748 } // namespace internal | 832 } // namespace internal |
| 749 } // namespace ash | 833 } // namespace ash |
| OLD | NEW |