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 <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 #if defined(OS_CHROMEOS) | 43 #if defined(OS_CHROMEOS) |
44 #include "ash/display/display_configurator_animation.h" | 44 #include "ash/display/display_configurator_animation.h" |
45 #include "base/sys_info.h" | 45 #include "base/sys_info.h" |
46 #endif | 46 #endif |
47 | 47 |
48 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
49 #include "base/win/windows_version.h" | 49 #include "base/win/windows_version.h" |
50 #endif | 50 #endif |
51 | 51 |
| 52 #include "base/debug/stack_trace.h" |
| 53 |
52 namespace ash { | 54 namespace ash { |
53 typedef std::vector<gfx::Display> DisplayList; | 55 typedef std::vector<gfx::Display> DisplayList; |
54 typedef std::vector<DisplayInfo> DisplayInfoList; | 56 typedef std::vector<DisplayInfo> DisplayInfoList; |
55 | 57 |
56 namespace { | 58 namespace { |
57 | 59 |
58 // We need to keep this in order for unittests to tell if | 60 // We need to keep this in order for unittests to tell if |
59 // the object in gfx::Screen::GetScreenByType is for shutdown. | 61 // the object in gfx::Screen::GetScreenByType is for shutdown. |
60 gfx::Screen* screen_for_shutdown = NULL; | 62 gfx::Screen* screen_for_shutdown = NULL; |
61 | 63 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 | 110 |
109 bool IsInternalDisplayId(int64 id) { | 111 bool IsInternalDisplayId(int64 id) { |
110 return gfx::Display::InternalDisplayId() == id; | 112 return gfx::Display::InternalDisplayId() == id; |
111 } | 113 } |
112 | 114 |
113 } // namespace | 115 } // namespace |
114 | 116 |
115 using std::string; | 117 using std::string; |
116 using std::vector; | 118 using std::vector; |
117 | 119 |
| 120 // static |
| 121 int64 DisplayManager::kUnifiedDisplayId = -10; |
| 122 |
118 DisplayManager::DisplayManager() | 123 DisplayManager::DisplayManager() |
119 : delegate_(NULL), | 124 : delegate_(NULL), |
120 screen_(new ScreenAsh), | 125 screen_(new ScreenAsh), |
121 layout_store_(new DisplayLayoutStore), | 126 layout_store_(new DisplayLayoutStore), |
122 first_display_id_(gfx::Display::kInvalidDisplayID), | 127 first_display_id_(gfx::Display::kInvalidDisplayID), |
123 num_connected_displays_(0), | 128 num_connected_displays_(0), |
124 force_bounds_changed_(false), | 129 force_bounds_changed_(false), |
125 change_display_upon_host_resize_(false), | 130 change_display_upon_host_resize_(false), |
126 second_display_mode_(EXTENDED), | 131 multi_display_mode_(EXTENDED), |
| 132 default_multi_display_mode_(EXTENDED), |
127 mirroring_display_id_(gfx::Display::kInvalidDisplayID), | 133 mirroring_display_id_(gfx::Display::kInvalidDisplayID), |
128 registered_internal_display_rotation_lock_(false), | 134 registered_internal_display_rotation_lock_(false), |
129 registered_internal_display_rotation_(gfx::Display::ROTATE_0), | 135 registered_internal_display_rotation_(gfx::Display::ROTATE_0), |
130 weak_ptr_factory_(this) { | 136 weak_ptr_factory_(this) { |
131 #if defined(OS_CHROMEOS) | 137 #if defined(OS_CHROMEOS) |
132 // Enable only on the device so that DisplayManagerFontTest passes. | 138 // Enable only on the device so that DisplayManagerFontTest passes. |
133 if (base::SysInfo::IsRunningOnChromeOS()) | 139 if (base::SysInfo::IsRunningOnChromeOS()) |
134 DisplayInfo::SetUse125DSFForUIScaling(true); | 140 DisplayInfo::SetUse125DSFForUIScaling(true); |
135 | 141 |
| 142 if (switches::UnifiedDesktopEnabled()) |
| 143 multi_display_mode_ = default_multi_display_mode_ = UNIFIED; |
| 144 |
136 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); | 145 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); |
137 #endif | 146 #endif |
138 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); | 147 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); |
139 gfx::Screen* current_native = | 148 gfx::Screen* current_native = |
140 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); | 149 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); |
141 // If there is no native, or the native was for shutdown, | 150 // If there is no native, or the native was for shutdown, |
142 // use ash's screen. | 151 // use ash's screen. |
143 if (!current_native || | 152 if (!current_native || |
144 current_native == screen_for_shutdown) { | 153 current_native == screen_for_shutdown) { |
145 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); | 154 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); |
(...skipping 17 matching lines...) Expand all Loading... |
163 vector<string> parts; | 172 vector<string> parts; |
164 base::SplitString(size_str, ',', &parts); | 173 base::SplitString(size_str, ',', &parts); |
165 for (vector<string>::const_iterator iter = parts.begin(); | 174 for (vector<string>::const_iterator iter = parts.begin(); |
166 iter != parts.end(); ++iter) { | 175 iter != parts.end(); ++iter) { |
167 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); | 176 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); |
168 info_list.back().set_native(true); | 177 info_list.back().set_native(true); |
169 } | 178 } |
170 MaybeInitInternalDisplay(&info_list[0]); | 179 MaybeInitInternalDisplay(&info_list[0]); |
171 if (info_list.size() > 1 && | 180 if (info_list.size() > 1 && |
172 command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { | 181 command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { |
173 SetSecondDisplayMode(MIRRORING); | 182 SetMultiDisplayMode(MIRRORING); |
174 } | 183 } |
175 OnNativeDisplaysChanged(info_list); | 184 OnNativeDisplaysChanged(info_list); |
176 return true; | 185 return true; |
177 } | 186 } |
178 | 187 |
179 void DisplayManager::InitDefaultDisplay() { | 188 void DisplayManager::InitDefaultDisplay() { |
180 DisplayInfoList info_list; | 189 DisplayInfoList info_list; |
181 info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); | 190 info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); |
182 info_list.back().set_native(true); | 191 info_list.back().set_native(true); |
183 MaybeInitInternalDisplay(&info_list[0]); | 192 MaybeInitInternalDisplay(&info_list[0]); |
(...skipping 28 matching lines...) Expand all Loading... |
212 } | 221 } |
213 NOTREACHED() << "DisplayLayout is requested for single display"; | 222 NOTREACHED() << "DisplayLayout is requested for single display"; |
214 // On release build, just fallback to default instead of blowing up. | 223 // On release build, just fallback to default instead of blowing up. |
215 DisplayLayout layout = | 224 DisplayLayout layout = |
216 layout_store_->default_display_layout(); | 225 layout_store_->default_display_layout(); |
217 layout.primary_id = active_display_list_[0].id(); | 226 layout.primary_id = active_display_list_[0].id(); |
218 return layout; | 227 return layout; |
219 } | 228 } |
220 | 229 |
221 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { | 230 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { |
222 if (IsInMirrorMode()) { | 231 if (IsInUnifiedMode()) { |
| 232 return std::make_pair(software_mirroring_display_list_[0].id(), |
| 233 software_mirroring_display_list_[1].id()); |
| 234 } else if (IsInMirrorMode()) { |
223 if (software_mirroring_enabled()) { | 235 if (software_mirroring_enabled()) { |
224 CHECK_EQ(2u, num_connected_displays()); | 236 CHECK_EQ(2u, num_connected_displays()); |
225 // This comment is to make it easy to distinguish the crash | 237 // This comment is to make it easy to distinguish the crash |
226 // between two checks. | 238 // between two checks. |
227 CHECK_EQ(1u, active_display_list_.size()); | 239 CHECK_EQ(1u, active_display_list_.size()); |
228 } | 240 } |
229 return std::make_pair(active_display_list_[0].id(), mirroring_display_id_); | 241 return std::make_pair(active_display_list_[0].id(), mirroring_display_id_); |
230 } else { | 242 } else { |
231 CHECK_LE(2u, active_display_list_.size()); | 243 CHECK_LE(2u, active_display_list_.size()); |
232 int64 id_at_zero = active_display_list_[0].id(); | 244 int64 id_at_zero = active_display_list_[0].id(); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); | 598 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); |
587 } else { | 599 } else { |
588 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() | 600 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() |
589 << ") [0]=" << updated_displays[0].ToString() | 601 << ") [0]=" << updated_displays[0].ToString() |
590 << ", [1]=" << updated_displays[1].ToString(); | 602 << ", [1]=" << updated_displays[1].ToString(); |
591 } | 603 } |
592 | 604 |
593 bool internal_display_connected = false; | 605 bool internal_display_connected = false; |
594 num_connected_displays_ = updated_displays.size(); | 606 num_connected_displays_ = updated_displays.size(); |
595 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 607 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
596 software_mirroring_display_ = gfx::Display(); | 608 software_mirroring_display_list_.clear(); |
597 DisplayInfoList new_display_info_list; | 609 DisplayInfoList new_display_info_list; |
598 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); | 610 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); |
599 iter != updated_displays.end(); | 611 iter != updated_displays.end(); |
600 ++iter) { | 612 ++iter) { |
601 if (!internal_display_connected) | 613 if (!internal_display_connected) |
602 internal_display_connected = IsInternalDisplayId(iter->id()); | 614 internal_display_connected = IsInternalDisplayId(iter->id()); |
603 // Mirrored monitors have the same origins. | 615 // Mirrored monitors have the same origins. |
604 gfx::Point origin = iter->bounds_in_native().origin(); | 616 gfx::Point origin = iter->bounds_in_native().origin(); |
605 if (origins.find(origin) != origins.end()) { | 617 if (origins.find(origin) != origins.end()) { |
606 InsertAndUpdateDisplayInfo(*iter); | 618 InsertAndUpdateDisplayInfo(*iter); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 std::sort(active_display_list_.begin(), active_display_list_.end(), | 673 std::sort(active_display_list_.begin(), active_display_list_.end(), |
662 DisplaySortFunctor()); | 674 DisplaySortFunctor()); |
663 std::sort(new_display_info_list.begin(), | 675 std::sort(new_display_info_list.begin(), |
664 new_display_info_list.end(), | 676 new_display_info_list.end(), |
665 DisplayInfoSortFunctor()); | 677 DisplayInfoSortFunctor()); |
666 // Close the mirroring window if any here to avoid creating two compositor on | 678 // Close the mirroring window if any here to avoid creating two compositor on |
667 // one display. | 679 // one display. |
668 if (delegate_) | 680 if (delegate_) |
669 delegate_->CloseMirroringDisplay(); | 681 delegate_->CloseMirroringDisplay(); |
670 | 682 |
671 if (second_display_mode_ == MIRRORING && new_display_info_list.size() == 2) | 683 CreateSoftwareMirroringDisplay(&new_display_info_list); |
672 CreateSoftwareMirroringDisplay(&new_display_info_list); | |
673 | 684 |
674 DisplayList new_displays; | 685 DisplayList new_displays; |
675 DisplayList removed_displays; | 686 DisplayList removed_displays; |
676 std::map<size_t, uint32_t> display_changes; | 687 std::map<size_t, uint32_t> display_changes; |
677 std::vector<size_t> added_display_indices; | 688 std::vector<size_t> added_display_indices; |
678 | 689 |
679 DisplayList::iterator curr_iter = active_display_list_.begin(); | 690 DisplayList::iterator curr_iter = active_display_list_.begin(); |
680 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); | 691 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); |
681 | 692 |
682 while (curr_iter != active_display_list_.end() || | 693 while (curr_iter != active_display_list_.end() || |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 } | 874 } |
864 | 875 |
865 size_t DisplayManager::GetNumDisplays() const { | 876 size_t DisplayManager::GetNumDisplays() const { |
866 return active_display_list_.size(); | 877 return active_display_list_.size(); |
867 } | 878 } |
868 | 879 |
869 bool DisplayManager::IsInMirrorMode() const { | 880 bool DisplayManager::IsInMirrorMode() const { |
870 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; | 881 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; |
871 } | 882 } |
872 | 883 |
| 884 bool DisplayManager::IsInUnifiedMode() const { |
| 885 return multi_display_mode_ == UNIFIED && |
| 886 !software_mirroring_display_list_.empty(); |
| 887 } |
| 888 |
873 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { | 889 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { |
874 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); | 890 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); |
875 | 891 |
876 std::map<int64, DisplayInfo>::const_iterator iter = | 892 std::map<int64, DisplayInfo>::const_iterator iter = |
877 display_info_.find(display_id); | 893 display_info_.find(display_id); |
878 CHECK(iter != display_info_.end()) << display_id; | 894 CHECK(iter != display_info_.end()) << display_id; |
879 return iter->second; | 895 return iter->second; |
880 } | 896 } |
881 | 897 |
| 898 const gfx::Display DisplayManager::GetMirroringDisplayById( |
| 899 int64 display_id) const { |
| 900 auto iter = std::find_if(software_mirroring_display_list_.begin(), |
| 901 software_mirroring_display_list_.end(), |
| 902 [display_id](const gfx::Display& display) { |
| 903 return display.id() == display_id; |
| 904 }); |
| 905 return iter == software_mirroring_display_list_.end() ? gfx::Display() |
| 906 : *iter; |
| 907 } |
| 908 |
882 std::string DisplayManager::GetDisplayNameForId(int64 id) { | 909 std::string DisplayManager::GetDisplayNameForId(int64 id) { |
883 if (id == gfx::Display::kInvalidDisplayID) | 910 if (id == gfx::Display::kInvalidDisplayID) |
884 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); | 911 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
885 | 912 |
886 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); | 913 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); |
887 if (iter != display_info_.end() && !iter->second.name().empty()) | 914 if (iter != display_info_.end() && !iter->second.name().empty()) |
888 return iter->second.name(); | 915 return iter->second.name(); |
889 | 916 |
890 return base::StringPrintf("Display %d", static_cast<int>(id)); | 917 return base::StringPrintf("Display %d", static_cast<int>(id)); |
891 } | 918 } |
892 | 919 |
893 int64 DisplayManager::GetDisplayIdForUIScaling() const { | 920 int64 DisplayManager::GetDisplayIdForUIScaling() const { |
894 // UI Scaling is effective only on internal display. | 921 // UI Scaling is effective only on internal display. |
895 int64 display_id = gfx::Display::InternalDisplayId(); | 922 int64 display_id = gfx::Display::InternalDisplayId(); |
896 #if defined(OS_WIN) | 923 #if defined(OS_WIN) |
897 display_id = first_display_id(); | 924 display_id = first_display_id(); |
898 #endif | 925 #endif |
899 return display_id; | 926 return display_id; |
900 } | 927 } |
901 | 928 |
902 void DisplayManager::SetMirrorMode(bool mirrored) { | 929 void DisplayManager::SetMirrorMode(bool mirror) { |
| 930 #if defined(OS_CHROMEOS) |
903 if (num_connected_displays() <= 1) | 931 if (num_connected_displays() <= 1) |
904 return; | 932 return; |
905 | 933 |
906 #if defined(OS_CHROMEOS) | |
907 if (base::SysInfo::IsRunningOnChromeOS()) { | 934 if (base::SysInfo::IsRunningOnChromeOS()) { |
908 ui::MultipleDisplayState new_state = | 935 ui::MultipleDisplayState new_state = |
909 mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR : | 936 mirror ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR |
910 ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; | 937 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
911 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); | 938 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); |
912 return; | 939 return; |
913 } | 940 } |
914 #endif | 941 |
915 // This is fallback path to emulate mirroroing on desktop. | 942 // This is fallback path to emulate mirroroing on desktop. |
916 SetSecondDisplayMode(mirrored ? MIRRORING : EXTENDED); | |
917 DisplayInfoList display_info_list; | 943 DisplayInfoList display_info_list; |
918 int count = 0; | 944 for (DisplayList::const_iterator iter = active_display_list_.begin(); |
919 for (std::map<int64, DisplayInfo>::const_iterator iter = | 945 (display_info_list.size() < 2 && iter != active_display_list_.end()); |
920 display_info_.begin(); | 946 ++iter) { |
921 count < 2; ++iter, ++count) { | 947 if (iter->id() == kUnifiedDisplayId) |
922 display_info_list.push_back(GetDisplayInfo(iter->second.id())); | 948 continue; |
| 949 display_info_list.push_back(GetDisplayInfo(iter->id())); |
923 } | 950 } |
| 951 for (auto iter = software_mirroring_display_list_.begin(); |
| 952 (display_info_list.size() < 2 && |
| 953 iter != software_mirroring_display_list_.end()); |
| 954 ++iter) { |
| 955 display_info_list.push_back(GetDisplayInfo(iter->id())); |
| 956 } |
| 957 |
| 958 SetSoftwareMirroring(mirror); |
924 UpdateDisplays(display_info_list); | 959 UpdateDisplays(display_info_list); |
925 #if defined(OS_CHROMEOS) | |
926 if (Shell::GetInstance()->display_configurator_animation()) { | 960 if (Shell::GetInstance()->display_configurator_animation()) { |
927 Shell::GetInstance()->display_configurator_animation()-> | 961 Shell::GetInstance()->display_configurator_animation()-> |
928 StartFadeInAnimation(); | 962 StartFadeInAnimation(); |
929 } | 963 } |
930 #endif | 964 #endif |
931 } | 965 } |
932 | 966 |
933 void DisplayManager::AddRemoveDisplay() { | 967 void DisplayManager::AddRemoveDisplay() { |
934 DCHECK(!active_display_list_.empty()); | 968 DCHECK(!active_display_list_.empty()); |
935 std::vector<DisplayInfo> new_display_info_list; | 969 std::vector<DisplayInfo> new_display_info_list; |
936 const DisplayInfo& first_display = | 970 const DisplayInfo& first_display = |
937 GetDisplayInfo(active_display_list_[0].id()); | 971 IsInUnifiedMode() |
| 972 ? GetDisplayInfo(software_mirroring_display_list_[0].id()) |
| 973 : GetDisplayInfo(active_display_list_[0].id()); |
938 new_display_info_list.push_back(first_display); | 974 new_display_info_list.push_back(first_display); |
939 // Add if there is only one display connected. | 975 // Add if there is only one display connected. |
940 if (num_connected_displays() == 1) { | 976 if (num_connected_displays() == 1) { |
941 // Layout the 2nd display below the primary as with the real device. | 977 // Layout the 2nd display below the primary as with the real device. |
942 gfx::Rect host_bounds = first_display.bounds_in_native(); | 978 gfx::Rect host_bounds = first_display.bounds_in_native(); |
943 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( | 979 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( |
944 base::StringPrintf( | 980 base::StringPrintf( |
945 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); | 981 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); |
946 } | 982 } |
947 num_connected_displays_ = new_display_info_list.size(); | 983 num_connected_displays_ = new_display_info_list.size(); |
948 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 984 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
949 software_mirroring_display_ = gfx::Display(); | 985 software_mirroring_display_list_.clear(); |
950 UpdateDisplays(new_display_info_list); | 986 UpdateDisplays(new_display_info_list); |
951 } | 987 } |
952 | 988 |
953 void DisplayManager::ToggleDisplayScaleFactor() { | 989 void DisplayManager::ToggleDisplayScaleFactor() { |
954 DCHECK(!active_display_list_.empty()); | 990 DCHECK(!active_display_list_.empty()); |
955 std::vector<DisplayInfo> new_display_info_list; | 991 std::vector<DisplayInfo> new_display_info_list; |
956 for (DisplayList::const_iterator iter = active_display_list_.begin(); | 992 for (DisplayList::const_iterator iter = active_display_list_.begin(); |
957 iter != active_display_list_.end(); ++iter) { | 993 iter != active_display_list_.end(); ++iter) { |
958 DisplayInfo display_info = GetDisplayInfo(iter->id()); | 994 DisplayInfo display_info = GetDisplayInfo(iter->id()); |
959 display_info.set_device_scale_factor( | 995 display_info.set_device_scale_factor( |
960 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); | 996 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); |
961 new_display_info_list.push_back(display_info); | 997 new_display_info_list.push_back(display_info); |
962 } | 998 } |
963 AddMirrorDisplayInfoIfAny(&new_display_info_list); | 999 AddMirrorDisplayInfoIfAny(&new_display_info_list); |
964 UpdateDisplays(new_display_info_list); | 1000 UpdateDisplays(new_display_info_list); |
965 } | 1001 } |
966 | 1002 |
967 #if defined(OS_CHROMEOS) | 1003 #if defined(OS_CHROMEOS) |
968 void DisplayManager::SetSoftwareMirroring(bool enabled) { | 1004 void DisplayManager::SetSoftwareMirroring(bool enabled) { |
969 SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED); | 1005 SetMultiDisplayMode(enabled ? MIRRORING : default_multi_display_mode_); |
970 } | 1006 } |
971 | 1007 |
972 bool DisplayManager::SoftwareMirroringEnabled() const { | 1008 bool DisplayManager::SoftwareMirroringEnabled() const { |
973 return software_mirroring_enabled(); | 1009 return software_mirroring_enabled(); |
974 } | 1010 } |
975 #endif | 1011 #endif |
976 | 1012 |
977 void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) { | 1013 void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { |
978 second_display_mode_ = mode; | 1014 multi_display_mode_ = mode; |
979 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 1015 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
980 software_mirroring_display_ = gfx::Display(); | 1016 software_mirroring_display_list_.clear(); |
| 1017 } |
| 1018 |
| 1019 void DisplayManager::SetDefaultMultiDisplayMode(MultiDisplayMode mode) { |
| 1020 // TODO(oshima): Remove this constrain. |
| 1021 DCHECK_EQ(default_multi_display_mode_, EXTENDED); |
| 1022 DCHECK_EQ(mode, UNIFIED); |
| 1023 default_multi_display_mode_ = mode; |
981 } | 1024 } |
982 | 1025 |
983 bool DisplayManager::UpdateDisplayBounds(int64 display_id, | 1026 bool DisplayManager::UpdateDisplayBounds(int64 display_id, |
984 const gfx::Rect& new_bounds) { | 1027 const gfx::Rect& new_bounds) { |
985 if (change_display_upon_host_resize_) { | 1028 if (change_display_upon_host_resize_) { |
986 display_info_[display_id].SetBounds(new_bounds); | 1029 display_info_[display_id].SetBounds(new_bounds); |
987 // Don't notify observers if the mirrored window has changed. | 1030 // Don't notify observers if the mirrored window has changed. |
988 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) | 1031 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) |
989 return false; | 1032 return false; |
990 gfx::Display* display = FindDisplayForId(display_id); | 1033 gfx::Display* display = FindDisplayForId(display_id); |
991 display->SetSize(display_info_[display_id].size_in_pixel()); | 1034 display->SetSize(display_info_[display_id].size_in_pixel()); |
992 screen_->NotifyMetricsChanged(*display, | 1035 screen_->NotifyMetricsChanged(*display, |
993 gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS); | 1036 gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS); |
994 return true; | 1037 return true; |
995 } | 1038 } |
996 return false; | 1039 return false; |
997 } | 1040 } |
998 | 1041 |
999 void DisplayManager::CreateMirrorWindowAsyncIfAny() { | 1042 void DisplayManager::CreateMirrorWindowAsyncIfAny() { |
1000 // Do not post a task if the software mirroring doesn't exist, or | 1043 // Do not post a task if the software mirroring doesn't exist, or |
1001 // during initialization when compositor's init task isn't posted yet. | 1044 // during initialization when compositor's init task isn't posted yet. |
1002 // ash::Shell::Init() will call this after the compositor is initialized. | 1045 // ash::Shell::Init() will call this after the compositor is initialized. |
1003 if (!software_mirroring_display_.is_valid() || !delegate_) | 1046 if (software_mirroring_display_list_.empty() || !delegate_) |
1004 return; | 1047 return; |
1005 base::MessageLoopForUI::current()->PostTask( | 1048 base::MessageLoopForUI::current()->PostTask( |
1006 FROM_HERE, | 1049 FROM_HERE, |
1007 base::Bind(&DisplayManager::CreateMirrorWindowIfAny, | 1050 base::Bind(&DisplayManager::CreateMirrorWindowIfAny, |
1008 weak_ptr_factory_.GetWeakPtr())); | 1051 weak_ptr_factory_.GetWeakPtr())); |
1009 } | 1052 } |
1010 | 1053 |
1011 scoped_ptr<MouseWarpController> DisplayManager::CreateMouseWarpController( | 1054 scoped_ptr<MouseWarpController> DisplayManager::CreateMouseWarpController( |
1012 aura::Window* drag_source) const { | 1055 aura::Window* drag_source) const { |
1013 // Extra check for |num_connected_displays()| is for SystemDisplayApiTest | 1056 // Extra check for |num_connected_displays()| is for SystemDisplayApiTest |
(...skipping 22 matching lines...) Expand all Loading... |
1036 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()]; | 1079 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()]; |
1037 SetInternalDisplayModeList(info); | 1080 SetInternalDisplayModeList(info); |
1038 } | 1081 } |
1039 | 1082 |
1040 void DisplayManager::CreateSoftwareMirroringDisplay( | 1083 void DisplayManager::CreateSoftwareMirroringDisplay( |
1041 DisplayInfoList* display_info_list) { | 1084 DisplayInfoList* display_info_list) { |
1042 // Use the internal display or 1st as the mirror source, then scale | 1085 // Use the internal display or 1st as the mirror source, then scale |
1043 // the root window so that it matches the external display's | 1086 // the root window so that it matches the external display's |
1044 // resolution. This is necessary in order for scaling to work while | 1087 // resolution. This is necessary in order for scaling to work while |
1045 // mirrored. | 1088 // mirrored. |
1046 bool zero_is_source = | 1089 // int64 mirroring_display_id = gfx::Display::kInvalidDisplayID; |
1047 first_display_id_ == (*display_info_list)[0].id() || | 1090 if (display_info_list->size() == 2) { |
1048 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); | 1091 switch (multi_display_mode_) { |
1049 DCHECK_EQ(MIRRORING, second_display_mode_); | 1092 case MIRRORING: { |
1050 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); | 1093 bool zero_is_source = |
1051 int64 display_id = mirroring_display_id_; | 1094 first_display_id_ == (*display_info_list)[0].id() || |
1052 auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), | 1095 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); |
1053 [display_id](const DisplayInfo& info) { | 1096 DCHECK_EQ(MIRRORING, multi_display_mode_); |
1054 return info.id() == display_id; | 1097 mirroring_display_id_ = |
1055 }); | 1098 (*display_info_list)[zero_is_source ? 1 : 0].id(); |
1056 DCHECK(iter != display_info_list->end()); | 1099 |
1057 DisplayInfo info = *iter; | 1100 int64 display_id = mirroring_display_id_; |
1058 info.SetOverscanInsets(gfx::Insets()); | 1101 auto iter = |
1059 InsertAndUpdateDisplayInfo(info); | 1102 std::find_if(display_info_list->begin(), display_info_list->end(), |
1060 software_mirroring_display_ = | 1103 [display_id](const DisplayInfo& info) { |
1061 CreateDisplayFromDisplayInfoById(mirroring_display_id_); | 1104 return info.id() == display_id; |
1062 display_info_list->erase(iter); | 1105 }); |
| 1106 DCHECK(iter != display_info_list->end()); |
| 1107 |
| 1108 DisplayInfo info = *iter; |
| 1109 info.SetOverscanInsets(gfx::Insets()); |
| 1110 InsertAndUpdateDisplayInfo(info); |
| 1111 software_mirroring_display_list_.push_back( |
| 1112 CreateDisplayFromDisplayInfoById(mirroring_display_id_)); |
| 1113 display_info_list->erase(iter); |
| 1114 break; |
| 1115 } |
| 1116 case UNIFIED: { |
| 1117 // TODO(oshima): Suport displays that have different heights. |
| 1118 gfx::Rect unified_bounds; |
| 1119 software_mirroring_display_list_.clear(); |
| 1120 for (auto& info : *display_info_list) { |
| 1121 InsertAndUpdateDisplayInfo(info); |
| 1122 software_mirroring_display_list_.push_back( |
| 1123 CreateDisplayFromDisplayInfoById(info.id())); |
| 1124 gfx::Point origin(unified_bounds.right(), 0); |
| 1125 unified_bounds.Union(gfx::Rect(origin, info.size_in_pixel())); |
| 1126 } |
| 1127 DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); |
| 1128 info.SetBounds(unified_bounds); |
| 1129 display_info_list->clear(); |
| 1130 display_info_list->push_back(info); |
| 1131 break; |
| 1132 } |
| 1133 case EXTENDED: |
| 1134 break; |
| 1135 } |
| 1136 } |
1063 } | 1137 } |
1064 | 1138 |
1065 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { | 1139 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
1066 auto iter = std::find_if( | 1140 auto iter = std::find_if( |
1067 active_display_list_.begin(), active_display_list_.end(), | 1141 active_display_list_.begin(), active_display_list_.end(), |
1068 [id](const gfx::Display& display) { return display.id() == id; }); | 1142 [id](const gfx::Display& display) { return display.id() == id; }); |
1069 if (iter != active_display_list_.end()) | 1143 if (iter != active_display_list_.end()) |
1070 return &(*iter); | 1144 return &(*iter); |
1071 DLOG(WARNING) << "Could not find display:" << id; | 1145 // TODO(oshima): This happens when a windows in unified desktop have |
| 1146 // been moved to normal window. Fix this. |
| 1147 if (id != kUnifiedDisplayId) |
| 1148 DLOG(WARNING) << "Could not find display:" << id; |
1072 return NULL; | 1149 return NULL; |
1073 } | 1150 } |
1074 | 1151 |
1075 void DisplayManager::AddMirrorDisplayInfoIfAny( | 1152 void DisplayManager::AddMirrorDisplayInfoIfAny( |
1076 std::vector<DisplayInfo>* display_info_list) { | 1153 std::vector<DisplayInfo>* display_info_list) { |
1077 if (software_mirroring_enabled() && IsInMirrorMode()) | 1154 if (software_mirroring_enabled() && IsInMirrorMode()) |
1078 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); | 1155 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); |
1079 } | 1156 } |
1080 | 1157 |
1081 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { | 1158 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { |
(...skipping 13 matching lines...) Expand all Loading... |
1095 #if defined(OS_CHROMEOS) | 1172 #if defined(OS_CHROMEOS) |
1096 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); | 1173 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); |
1097 if (color_profile != ui::COLOR_PROFILE_STANDARD) { | 1174 if (color_profile != ui::COLOR_PROFILE_STANDARD) { |
1098 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( | 1175 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( |
1099 display_info.id(), color_profile); | 1176 display_info.id(), color_profile); |
1100 } | 1177 } |
1101 #endif | 1178 #endif |
1102 } | 1179 } |
1103 | 1180 |
1104 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { | 1181 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { |
1105 DCHECK(display_info_.find(id) != display_info_.end()); | 1182 DCHECK(display_info_.find(id) != display_info_.end()) << "id=" << id; |
1106 const DisplayInfo& display_info = display_info_[id]; | 1183 const DisplayInfo& display_info = display_info_[id]; |
1107 | 1184 |
1108 gfx::Display new_display(display_info.id()); | 1185 gfx::Display new_display(display_info.id()); |
1109 gfx::Rect bounds_in_native(display_info.size_in_pixel()); | 1186 gfx::Rect bounds_in_native(display_info.size_in_pixel()); |
1110 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); | 1187 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); |
1111 | 1188 |
1112 // Simply set the origin to (0,0). The primary display's origin is | 1189 // Simply set the origin to (0,0). The primary display's origin is |
1113 // always (0,0) and the bounds of non-primary display(s) will be updated | 1190 // always (0,0) and the bounds of non-primary display(s) will be updated |
1114 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. | 1191 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. |
1115 new_display.SetScaleAndBounds( | 1192 new_display.SetScaleAndBounds( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 GetDisplayForId(displays->at(secondary_index).id()).bounds(); | 1246 GetDisplayForId(displays->at(secondary_index).id()).bounds(); |
1170 UpdateDisplayBoundsForLayout( | 1247 UpdateDisplayBoundsForLayout( |
1171 layout, displays->at(primary_index), &displays->at(secondary_index)); | 1248 layout, displays->at(primary_index), &displays->at(secondary_index)); |
1172 updated_indices->push_back(secondary_index); | 1249 updated_indices->push_back(secondary_index); |
1173 return bounds != displays->at(secondary_index).bounds(); | 1250 return bounds != displays->at(secondary_index).bounds(); |
1174 } | 1251 } |
1175 return false; | 1252 return false; |
1176 } | 1253 } |
1177 | 1254 |
1178 void DisplayManager::CreateMirrorWindowIfAny() { | 1255 void DisplayManager::CreateMirrorWindowIfAny() { |
1179 if (software_mirroring_display_.is_valid() && delegate_) { | 1256 if (software_mirroring_display_list_.empty() || !delegate_) |
1180 DisplayInfo display_info = GetDisplayInfo(software_mirroring_display_.id()); | 1257 return; |
1181 delegate_->CreateOrUpdateMirroringDisplay(display_info); | 1258 DisplayInfoList list; |
1182 } | 1259 for (auto& display : software_mirroring_display_list_) |
| 1260 list.push_back(GetDisplayInfo(display.id())); |
| 1261 delegate_->CreateOrUpdateMirroringDisplay(list); |
1183 } | 1262 } |
1184 | 1263 |
1185 // static | 1264 // static |
1186 void DisplayManager::UpdateDisplayBoundsForLayout( | 1265 void DisplayManager::UpdateDisplayBoundsForLayout( |
1187 const DisplayLayout& layout, | 1266 const DisplayLayout& layout, |
1188 const gfx::Display& primary_display, | 1267 const gfx::Display& primary_display, |
1189 gfx::Display* secondary_display) { | 1268 gfx::Display* secondary_display) { |
1190 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); | 1269 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); |
1191 | 1270 |
1192 const gfx::Rect& primary_bounds = primary_display.bounds(); | 1271 const gfx::Rect& primary_bounds = primary_display.bounds(); |
(...skipping 30 matching lines...) Expand all Loading... |
1223 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 1302 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
1224 break; | 1303 break; |
1225 } | 1304 } |
1226 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 1305 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
1227 secondary_display->set_bounds( | 1306 secondary_display->set_bounds( |
1228 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1307 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
1229 secondary_display->UpdateWorkAreaFromInsets(insets); | 1308 secondary_display->UpdateWorkAreaFromInsets(insets); |
1230 } | 1309 } |
1231 | 1310 |
1232 void DisplayManager::RunPendingTasksForTest() { | 1311 void DisplayManager::RunPendingTasksForTest() { |
1233 if (software_mirroring_display_.is_valid()) | 1312 if (!software_mirroring_display_list_.empty()) |
1234 base::RunLoop().RunUntilIdle(); | 1313 base::RunLoop().RunUntilIdle(); |
1235 } | 1314 } |
1236 | 1315 |
1237 } // namespace ash | 1316 } // namespace ash |
OLD | NEW |