Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: ash/display/display_manager.cc

Issue 15367003: Create a mirror window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: win fix Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698