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 |