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