| 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 |