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 |