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

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

Issue 657583003: Chrome OS: Ash support for >=3 displays. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add unit test for 3 displays. Fix nits. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/display/display_manager.h" 5 #include "ash/display/display_manager.h"
6 6
7 #include <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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698