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

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

Powered by Google App Engine
This is Rietveld 408576698