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. |
1089 // int64 mirroring_display_id = gfx::Display::kInvalidDisplayID; | |
1090 if (display_info_list->size() == 2) { | |
1091 switch (multi_display_mode_) { | |
1092 case MIRRORING: { | |
1093 bool zero_is_source = | |
1094 first_display_id_ == (*display_info_list)[0].id() || | |
1095 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); | |
1096 DCHECK_EQ(MIRRORING, multi_display_mode_); | |
1097 mirroring_display_id_ = | |
1098 (*display_info_list)[zero_is_source ? 1 : 0].id(); | |
1099 | |
1100 int64 display_id = mirroring_display_id_; | |
1101 auto iter = | |
1102 std::find_if(display_info_list->begin(), display_info_list->end(), | |
1103 [display_id](const DisplayInfo& info) { | |
1104 return info.id() == display_id; | |
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; | |
Jun Mukai
2015/04/26 23:45:08
I prefer to write
break;
}
order.
oshima
2015/04/27 17:48:38
Done.
| |
1115 case UNIFIED: { | |
1116 gfx::Rect unified_bounds; | |
1117 software_mirroring_display_list_.clear(); | |
1118 for (auto& info : *display_info_list) { | |
1119 InsertAndUpdateDisplayInfo(info); | |
1120 software_mirroring_display_list_.push_back( | |
1121 CreateDisplayFromDisplayInfoById(info.id())); | |
1122 gfx::Point origin(unified_bounds.right(), 0); | |
1123 unified_bounds.Union(gfx::Rect(origin, info.size_in_pixel())); | |
1124 } | |
1125 // first_display_id_ = kUnifiedDisplayId; | |
1126 DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); | |
1127 info.SetBounds(unified_bounds); | |
1128 display_info_list->clear(); | |
1129 display_info_list->push_back(info); | |
1130 } break; | |
1131 case EXTENDED: | |
1132 break; | |
1133 } | |
1134 } | |
1135 #if 0 | |
1136 // Use the internal display or 1st as the mirror source, then scale | |
1137 // the root window so that it matches the external display's | |
1138 // resolution. This is necessary in order for scaling to work while | |
1139 // mirrored. | |
1046 bool zero_is_source = | 1140 bool zero_is_source = |
1047 first_display_id_ == (*display_info_list)[0].id() || | 1141 first_display_id_ == (*display_info_list)[0].id() || |
1048 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); | 1142 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); |
1049 DCHECK_EQ(MIRRORING, second_display_mode_); | 1143 DCHECK_EQ(MIRRORING, multi_display_mode_); |
1050 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); | 1144 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); |
1051 int64 display_id = mirroring_display_id_; | 1145 int64 display_id = mirroring_display_id_; |
1052 auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), | 1146 auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), |
1053 [display_id](const DisplayInfo& info) { | 1147 [display_id](const DisplayInfo& info) { |
1054 return info.id() == display_id; | 1148 return info.id() == display_id; |
1055 }); | 1149 }); |
1056 DCHECK(iter != display_info_list->end()); | 1150 DCHECK(iter != display_info_list->end()); |
1057 DisplayInfo info = *iter; | 1151 DisplayInfo info = *iter; |
1058 info.SetOverscanInsets(gfx::Insets()); | 1152 info.SetOverscanInsets(gfx::Insets()); |
1059 InsertAndUpdateDisplayInfo(info); | 1153 InsertAndUpdateDisplayInfo(info); |
1060 software_mirroring_display_ = | 1154 software_mirroring_display_ = |
1061 CreateDisplayFromDisplayInfoById(mirroring_display_id_); | 1155 CreateDisplayFromDisplayInfoById(mirroring_display_id_); |
1062 display_info_list->erase(iter); | 1156 display_info_list->erase(iter); |
1157 #endif | |
oshima
2015/04/27 17:48:38
oops, I forgot to remove this. Removed.
| |
1063 } | 1158 } |
1064 | 1159 |
1065 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { | 1160 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
1066 auto iter = std::find_if( | 1161 auto iter = std::find_if( |
1067 active_display_list_.begin(), active_display_list_.end(), | 1162 active_display_list_.begin(), active_display_list_.end(), |
1068 [id](const gfx::Display& display) { return display.id() == id; }); | 1163 [id](const gfx::Display& display) { return display.id() == id; }); |
1069 if (iter != active_display_list_.end()) | 1164 if (iter != active_display_list_.end()) |
1070 return &(*iter); | 1165 return &(*iter); |
1071 DLOG(WARNING) << "Could not find display:" << id; | 1166 // TODO(oshima): This happens when a windows in unified desktop have |
1167 // been moved to normal window. Fix this. | |
1168 if (id != kUnifiedDisplayId) | |
1169 DLOG(WARNING) << "Could not find display:" << id; | |
1072 return NULL; | 1170 return NULL; |
1073 } | 1171 } |
1074 | 1172 |
1075 void DisplayManager::AddMirrorDisplayInfoIfAny( | 1173 void DisplayManager::AddMirrorDisplayInfoIfAny( |
1076 std::vector<DisplayInfo>* display_info_list) { | 1174 std::vector<DisplayInfo>* display_info_list) { |
1077 if (software_mirroring_enabled() && IsInMirrorMode()) | 1175 if (software_mirroring_enabled() && IsInMirrorMode()) |
1078 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); | 1176 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); |
1079 } | 1177 } |
1080 | 1178 |
1081 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { | 1179 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { |
(...skipping 13 matching lines...) Expand all Loading... | |
1095 #if defined(OS_CHROMEOS) | 1193 #if defined(OS_CHROMEOS) |
1096 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); | 1194 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); |
1097 if (color_profile != ui::COLOR_PROFILE_STANDARD) { | 1195 if (color_profile != ui::COLOR_PROFILE_STANDARD) { |
1098 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( | 1196 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( |
1099 display_info.id(), color_profile); | 1197 display_info.id(), color_profile); |
1100 } | 1198 } |
1101 #endif | 1199 #endif |
1102 } | 1200 } |
1103 | 1201 |
1104 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { | 1202 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { |
1105 DCHECK(display_info_.find(id) != display_info_.end()); | 1203 DCHECK(display_info_.find(id) != display_info_.end()) << "id=" << id; |
1106 const DisplayInfo& display_info = display_info_[id]; | 1204 const DisplayInfo& display_info = display_info_[id]; |
1107 | 1205 |
1108 gfx::Display new_display(display_info.id()); | 1206 gfx::Display new_display(display_info.id()); |
1109 gfx::Rect bounds_in_native(display_info.size_in_pixel()); | 1207 gfx::Rect bounds_in_native(display_info.size_in_pixel()); |
1110 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); | 1208 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); |
1111 | 1209 |
1112 // Simply set the origin to (0,0). The primary display's origin is | 1210 // 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 | 1211 // always (0,0) and the bounds of non-primary display(s) will be updated |
1114 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. | 1212 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. |
1115 new_display.SetScaleAndBounds( | 1213 new_display.SetScaleAndBounds( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1169 GetDisplayForId(displays->at(secondary_index).id()).bounds(); | 1267 GetDisplayForId(displays->at(secondary_index).id()).bounds(); |
1170 UpdateDisplayBoundsForLayout( | 1268 UpdateDisplayBoundsForLayout( |
1171 layout, displays->at(primary_index), &displays->at(secondary_index)); | 1269 layout, displays->at(primary_index), &displays->at(secondary_index)); |
1172 updated_indices->push_back(secondary_index); | 1270 updated_indices->push_back(secondary_index); |
1173 return bounds != displays->at(secondary_index).bounds(); | 1271 return bounds != displays->at(secondary_index).bounds(); |
1174 } | 1272 } |
1175 return false; | 1273 return false; |
1176 } | 1274 } |
1177 | 1275 |
1178 void DisplayManager::CreateMirrorWindowIfAny() { | 1276 void DisplayManager::CreateMirrorWindowIfAny() { |
1179 if (software_mirroring_display_.is_valid() && delegate_) { | 1277 if (software_mirroring_display_list_.empty() || !delegate_) |
1180 DisplayInfo display_info = GetDisplayInfo(software_mirroring_display_.id()); | 1278 return; |
1181 delegate_->CreateOrUpdateMirroringDisplay(display_info); | 1279 DisplayInfoList list; |
1182 } | 1280 for (auto& display : software_mirroring_display_list_) |
1281 list.push_back(GetDisplayInfo(display.id())); | |
1282 delegate_->CreateOrUpdateMirroringDisplay(list); | |
1183 } | 1283 } |
1184 | 1284 |
1185 // static | 1285 // static |
1186 void DisplayManager::UpdateDisplayBoundsForLayout( | 1286 void DisplayManager::UpdateDisplayBoundsForLayout( |
1187 const DisplayLayout& layout, | 1287 const DisplayLayout& layout, |
1188 const gfx::Display& primary_display, | 1288 const gfx::Display& primary_display, |
1189 gfx::Display* secondary_display) { | 1289 gfx::Display* secondary_display) { |
1190 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); | 1290 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); |
1191 | 1291 |
1192 const gfx::Rect& primary_bounds = primary_display.bounds(); | 1292 const gfx::Rect& primary_bounds = primary_display.bounds(); |
(...skipping 30 matching lines...) Expand all Loading... | |
1223 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 1323 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
1224 break; | 1324 break; |
1225 } | 1325 } |
1226 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 1326 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
1227 secondary_display->set_bounds( | 1327 secondary_display->set_bounds( |
1228 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1328 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
1229 secondary_display->UpdateWorkAreaFromInsets(insets); | 1329 secondary_display->UpdateWorkAreaFromInsets(insets); |
1230 } | 1330 } |
1231 | 1331 |
1232 void DisplayManager::RunPendingTasksForTest() { | 1332 void DisplayManager::RunPendingTasksForTest() { |
1233 if (software_mirroring_display_.is_valid()) | 1333 if (!software_mirroring_display_list_.empty()) |
1234 base::RunLoop().RunUntilIdle(); | 1334 base::RunLoop().RunUntilIdle(); |
1235 } | 1335 } |
1236 | 1336 |
1237 } // namespace ash | 1337 } // namespace ash |
OLD | NEW |