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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { | 295 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { |
296 if (IsMirrored()) { | 296 if (IsMirrored()) { |
297 if (software_mirroring_enabled()) { | 297 if (software_mirroring_enabled()) { |
298 CHECK_EQ(2u, num_connected_displays()); | 298 CHECK_EQ(2u, num_connected_displays()); |
299 // This comment is to make it easy to distinguish the crash | 299 // This comment is to make it easy to distinguish the crash |
300 // between two checks. | 300 // between two checks. |
301 CHECK_EQ(1u, displays_.size()); | 301 CHECK_EQ(1u, displays_.size()); |
302 } | 302 } |
303 return std::make_pair(displays_[0].id(), mirrored_display_id_); | 303 return std::make_pair(displays_[0].id(), mirrored_display_id_); |
304 } else { | 304 } else { |
305 CHECK_GE(2u, displays_.size()); | 305 CHECK_LE(2u, displays_.size()); |
306 int64 id_at_zero = displays_[0].id(); | 306 int64 id_at_zero = displays_[0].id(); |
307 if (id_at_zero == gfx::Display::InternalDisplayId() || | 307 if (id_at_zero == gfx::Display::InternalDisplayId() || |
308 id_at_zero == first_display_id()) { | 308 id_at_zero == first_display_id()) { |
309 return std::make_pair(id_at_zero, displays_[1].id()); | 309 return std::make_pair(id_at_zero, displays_[1].id()); |
310 } else { | 310 } else { |
311 return std::make_pair(displays_[1].id(), id_at_zero); | 311 return std::make_pair(displays_[1].id(), id_at_zero); |
312 } | 312 } |
313 } | 313 } |
314 } | 314 } |
315 | 315 |
316 void DisplayManager::SetLayoutForCurrentDisplays( | 316 void DisplayManager::SetLayoutForCurrentDisplays( |
317 const DisplayLayout& layout_relative_to_primary) { | 317 const DisplayLayout& layout_relative_to_primary) { |
318 DCHECK_EQ(2U, GetNumDisplays()); | 318 if (GetNumDisplays() != 2) |
319 if (GetNumDisplays() < 2) | |
320 return; | 319 return; |
321 const gfx::Display& primary = screen_->GetPrimaryDisplay(); | 320 const gfx::Display& primary = screen_->GetPrimaryDisplay(); |
322 const DisplayIdPair pair = GetCurrentDisplayIdPair(); | 321 const DisplayIdPair pair = GetCurrentDisplayIdPair(); |
323 // Invert if the primary was swapped. | 322 // Invert if the primary was swapped. |
324 DisplayLayout to_set = pair.first == primary.id() ? | 323 DisplayLayout to_set = pair.first == primary.id() ? |
325 layout_relative_to_primary : layout_relative_to_primary.Invert(); | 324 layout_relative_to_primary : layout_relative_to_primary.Invert(); |
326 | 325 |
327 DisplayLayout current_layout = | 326 DisplayLayout current_layout = |
328 layout_store_->GetRegisteredDisplayLayout(pair); | 327 layout_store_->GetRegisteredDisplayLayout(pair); |
329 if (to_set.position != current_layout.position || | 328 if (to_set.position != current_layout.position || |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 // is possible there is no need to update |displays_| and we early out | 859 // is possible there is no need to update |displays_| and we early out |
861 // here. But we still want to run the PostDisplayConfigurationChange() | 860 // here. But we still want to run the PostDisplayConfigurationChange() |
862 // cause there are some clients need to act on this, e.g. | 861 // cause there are some clients need to act on this, e.g. |
863 // TouchTransformerController needs to adjust the TouchTransformer when | 862 // TouchTransformerController needs to adjust the TouchTransformer when |
864 // switching from dual displays to single display. | 863 // switching from dual displays to single display. |
865 if (delegate_) | 864 if (delegate_) |
866 delegate_->PostDisplayConfigurationChange(); | 865 delegate_->PostDisplayConfigurationChange(); |
867 return; | 866 return; |
868 } | 867 } |
869 | 868 |
870 size_t updated_index; | 869 std::vector<size_t> updated_indices; |
871 if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) && | 870 if (UpdateNonPrimaryDisplayBoundsForLayout(&new_displays, &updated_indices)) { |
872 std::find(added_display_indices.begin(), | 871 for (std::vector<size_t>::iterator it = updated_indices.begin(); |
873 added_display_indices.end(), | 872 it != updated_indices.end(); ++it) { |
874 updated_index) == added_display_indices.end()) { | 873 size_t updated_index = *it; |
875 uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS | | 874 if (std::find(added_display_indices.begin(), |
876 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA; | 875 added_display_indices.end(), |
877 if (display_changes.find(updated_index) != display_changes.end()) | 876 updated_index) == added_display_indices.end()) { |
878 metrics |= display_changes[updated_index]; | 877 uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS | |
| 878 gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA; |
| 879 if (display_changes.find(updated_index) != display_changes.end()) |
| 880 metrics |= display_changes[updated_index]; |
879 | 881 |
880 display_changes[updated_index] = metrics; | 882 display_changes[updated_index] = metrics; |
| 883 } |
| 884 } |
881 } | 885 } |
882 | 886 |
883 displays_ = new_displays; | 887 displays_ = new_displays; |
884 | 888 |
885 base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); | 889 base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); |
886 | 890 |
887 // Temporarily add displays to be removed because display object | 891 // Temporarily add displays to be removed because display object |
888 // being removed are accessed during shutting down the root. | 892 // being removed are accessed during shutting down the root. |
889 displays_.insert(displays_.end(), removed_displays.begin(), | 893 displays_.insert(displays_.end(), removed_displays.begin(), |
890 removed_displays.end()); | 894 removed_displays.end()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 if (has_mirroring_display && delegate_) | 958 if (has_mirroring_display && delegate_) |
955 CreateMirrorWindowAsyncIfAny(); | 959 CreateMirrorWindowAsyncIfAny(); |
956 } | 960 } |
957 | 961 |
958 const gfx::Display& DisplayManager::GetDisplayAt(size_t index) const { | 962 const gfx::Display& DisplayManager::GetDisplayAt(size_t index) const { |
959 DCHECK_LT(index, displays_.size()); | 963 DCHECK_LT(index, displays_.size()); |
960 return displays_[index]; | 964 return displays_[index]; |
961 } | 965 } |
962 | 966 |
963 const gfx::Display& DisplayManager::GetPrimaryDisplayCandidate() const { | 967 const gfx::Display& DisplayManager::GetPrimaryDisplayCandidate() const { |
964 if (GetNumDisplays() == 1) | 968 if (GetNumDisplays() != 2) |
965 return displays_[0]; | 969 return displays_[0]; |
966 DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout( | 970 DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout( |
967 GetCurrentDisplayIdPair()); | 971 GetCurrentDisplayIdPair()); |
968 return GetDisplayForId(layout.primary_id); | 972 return GetDisplayForId(layout.primary_id); |
969 } | 973 } |
970 | 974 |
971 size_t DisplayManager::GetNumDisplays() const { | 975 size_t DisplayManager::GetNumDisplays() const { |
972 return displays_.size(); | 976 return displays_.size(); |
973 } | 977 } |
974 | 978 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 | 1168 |
1165 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { | 1169 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { |
1166 DCHECK(display_info_.find(id) != display_info_.end()); | 1170 DCHECK(display_info_.find(id) != display_info_.end()); |
1167 const DisplayInfo& display_info = display_info_[id]; | 1171 const DisplayInfo& display_info = display_info_[id]; |
1168 | 1172 |
1169 gfx::Display new_display(display_info.id()); | 1173 gfx::Display new_display(display_info.id()); |
1170 gfx::Rect bounds_in_native(display_info.size_in_pixel()); | 1174 gfx::Rect bounds_in_native(display_info.size_in_pixel()); |
1171 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); | 1175 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); |
1172 | 1176 |
1173 // Simply set the origin to (0,0). The primary display's origin is | 1177 // Simply set the origin to (0,0). The primary display's origin is |
1174 // always (0,0) and the secondary display's bounds will be updated | 1178 // always (0,0) and the bounds of non-primary display(s) will be updated |
1175 // in |UpdateSecondaryDisplayBoundsForLayout| called in |UpdateDisplay|. | 1179 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. |
1176 new_display.SetScaleAndBounds( | 1180 new_display.SetScaleAndBounds( |
1177 device_scale_factor, gfx::Rect(bounds_in_native.size())); | 1181 device_scale_factor, gfx::Rect(bounds_in_native.size())); |
1178 new_display.set_rotation(display_info.rotation()); | 1182 new_display.set_rotation(display_info.rotation()); |
1179 new_display.set_touch_support(display_info.touch_support()); | 1183 new_display.set_touch_support(display_info.touch_support()); |
1180 return new_display; | 1184 return new_display; |
1181 } | 1185 } |
1182 | 1186 |
1183 bool DisplayManager::UpdateSecondaryDisplayBoundsForLayout( | 1187 bool DisplayManager::UpdateNonPrimaryDisplayBoundsForLayout( |
1184 DisplayList* displays, | 1188 DisplayList* displays, |
1185 size_t* updated_index) const { | 1189 std::vector<size_t>* updated_indices) const { |
1186 if (displays->size() != 2U) | 1190 |
| 1191 if (displays->size() < 2U) |
1187 return false; | 1192 return false; |
1188 | 1193 |
| 1194 if (displays->size() > 2U) { |
| 1195 // For more than 2 displays, always use horizontal layout. |
| 1196 int x_offset = displays->at(0).bounds().width(); |
| 1197 for (size_t i = 1; i < displays->size(); ++i) { |
| 1198 gfx::Display& display = displays->at(i); |
| 1199 const gfx::Rect& bounds = display.bounds(); |
| 1200 gfx::Point origin = gfx::Point(x_offset, 0); |
| 1201 gfx::Insets insets = display.GetWorkAreaInsets(); |
| 1202 display.set_bounds(gfx::Rect(origin, bounds.size())); |
| 1203 display.UpdateWorkAreaFromInsets(insets); |
| 1204 x_offset += bounds.width(); |
| 1205 updated_indices->push_back(i); |
| 1206 } |
| 1207 return true; |
| 1208 } |
| 1209 |
1189 int64 id_at_zero = displays->at(0).id(); | 1210 int64 id_at_zero = displays->at(0).id(); |
1190 DisplayIdPair pair = | 1211 DisplayIdPair pair = |
1191 (id_at_zero == first_display_id_ || | 1212 (id_at_zero == first_display_id_ || |
1192 id_at_zero == gfx::Display::InternalDisplayId()) ? | 1213 id_at_zero == gfx::Display::InternalDisplayId()) ? |
1193 std::make_pair(id_at_zero, displays->at(1).id()) : | 1214 std::make_pair(id_at_zero, displays->at(1).id()) : |
1194 std::make_pair(displays->at(1).id(), id_at_zero); | 1215 std::make_pair(displays->at(1).id(), id_at_zero); |
1195 DisplayLayout layout = | 1216 DisplayLayout layout = |
1196 layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); | 1217 layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); |
1197 | 1218 |
1198 // Ignore if a user has a old format (should be extremely rare) | 1219 // Ignore if a user has a old format (should be extremely rare) |
1199 // and this will be replaced with DCHECK. | 1220 // and this will be replaced with DCHECK. |
1200 if (layout.primary_id != gfx::Display::kInvalidDisplayID) { | 1221 if (layout.primary_id != gfx::Display::kInvalidDisplayID) { |
1201 size_t primary_index, secondary_index; | 1222 size_t primary_index, secondary_index; |
1202 if (displays->at(0).id() == layout.primary_id) { | 1223 if (displays->at(0).id() == layout.primary_id) { |
1203 primary_index = 0; | 1224 primary_index = 0; |
1204 secondary_index = 1; | 1225 secondary_index = 1; |
1205 } else { | 1226 } else { |
1206 primary_index = 1; | 1227 primary_index = 1; |
1207 secondary_index = 0; | 1228 secondary_index = 0; |
1208 } | 1229 } |
1209 // This function may be called before the secondary display is | 1230 // This function may be called before the secondary display is |
1210 // registered. The bounds is empty in that case and will | 1231 // registered. The bounds is empty in that case and will |
1211 // return true. | 1232 // return true. |
1212 gfx::Rect bounds = | 1233 gfx::Rect bounds = |
1213 GetDisplayForId(displays->at(secondary_index).id()).bounds(); | 1234 GetDisplayForId(displays->at(secondary_index).id()).bounds(); |
1214 UpdateDisplayBoundsForLayout( | 1235 UpdateDisplayBoundsForLayout( |
1215 layout, displays->at(primary_index), &displays->at(secondary_index)); | 1236 layout, displays->at(primary_index), &displays->at(secondary_index)); |
1216 *updated_index = secondary_index; | 1237 updated_indices->push_back(secondary_index); |
1217 return bounds != displays->at(secondary_index).bounds(); | 1238 return bounds != displays->at(secondary_index).bounds(); |
1218 } | 1239 } |
1219 return false; | 1240 return false; |
1220 } | 1241 } |
1221 | 1242 |
1222 void DisplayManager::CreateMirrorWindowIfAny() { | 1243 void DisplayManager::CreateMirrorWindowIfAny() { |
1223 if (HasSoftwareMirroringDisplay() && delegate_) { | 1244 if (HasSoftwareMirroringDisplay() && delegate_) { |
1224 DisplayInfo display_info = GetDisplayInfo(mirroring_display_.id()); | 1245 DisplayInfo display_info = GetDisplayInfo(mirroring_display_.id()); |
1225 delegate_->CreateOrUpdateMirroringDisplay(display_info); | 1246 delegate_->CreateOrUpdateMirroringDisplay(display_info); |
1226 } | 1247 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 1293 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
1273 break; | 1294 break; |
1274 } | 1295 } |
1275 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 1296 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
1276 secondary_display->set_bounds( | 1297 secondary_display->set_bounds( |
1277 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1298 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
1278 secondary_display->UpdateWorkAreaFromInsets(insets); | 1299 secondary_display->UpdateWorkAreaFromInsets(insets); |
1279 } | 1300 } |
1280 | 1301 |
1281 } // namespace ash | 1302 } // namespace ash |
OLD | NEW |