Chromium Code Reviews| 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 <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "base/strings/string_number_conversions.h" | 30 #include "base/strings/string_number_conversions.h" |
| 31 #include "base/strings/string_split.h" | 31 #include "base/strings/string_split.h" |
| 32 #include "base/strings/stringprintf.h" | 32 #include "base/strings/stringprintf.h" |
| 33 #include "base/strings/utf_string_conversions.h" | 33 #include "base/strings/utf_string_conversions.h" |
| 34 #include "base/threading/thread_task_runner_handle.h" | 34 #include "base/threading/thread_task_runner_handle.h" |
| 35 #include "grit/ash_strings.h" | 35 #include "grit/ash_strings.h" |
| 36 #include "ui/base/l10n/l10n_util.h" | 36 #include "ui/base/l10n/l10n_util.h" |
| 37 #include "ui/display/display.h" | 37 #include "ui/display/display.h" |
| 38 #include "ui/display/display_observer.h" | 38 #include "ui/display/display_observer.h" |
| 39 #include "ui/display/manager/display_layout_store.h" | 39 #include "ui/display/manager/display_layout_store.h" |
| 40 #include "ui/display/manager/display_manager_utilities.h" | |
| 40 #include "ui/display/manager/managed_display_info.h" | 41 #include "ui/display/manager/managed_display_info.h" |
| 41 #include "ui/display/screen.h" | 42 #include "ui/display/screen.h" |
| 42 #include "ui/gfx/font_render_params.h" | 43 #include "ui/gfx/font_render_params.h" |
| 43 #include "ui/gfx/geometry/rect.h" | 44 #include "ui/gfx/geometry/rect.h" |
| 44 #include "ui/gfx/geometry/size_conversions.h" | 45 #include "ui/gfx/geometry/size_conversions.h" |
| 45 | 46 |
| 46 #if defined(USE_X11) | 47 #if defined(USE_X11) |
| 47 #include "ui/base/x/x11_util.h" // nogncheck | 48 #include "ui/base/x/x11_util.h" // nogncheck |
| 48 #endif | 49 #endif |
| 49 | 50 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 62 // We need to keep this in order for unittests to tell if | 63 // We need to keep this in order for unittests to tell if |
| 63 // the object in display::Screen::GetScreenByType is for shutdown. | 64 // the object in display::Screen::GetScreenByType is for shutdown. |
| 64 display::Screen* screen_for_shutdown = nullptr; | 65 display::Screen* screen_for_shutdown = nullptr; |
| 65 | 66 |
| 66 // The number of pixels to overlap between the primary and secondary displays, | 67 // The number of pixels to overlap between the primary and secondary displays, |
| 67 // in case that the offset value is too large. | 68 // in case that the offset value is too large. |
| 68 const int kMinimumOverlapForInvalidOffset = 100; | 69 const int kMinimumOverlapForInvalidOffset = 100; |
| 69 | 70 |
| 70 struct DisplaySortFunctor { | 71 struct DisplaySortFunctor { |
| 71 bool operator()(const display::Display& a, const display::Display& b) { | 72 bool operator()(const display::Display& a, const display::Display& b) { |
| 72 return CompareDisplayIds(a.id(), b.id()); | 73 return ui::CompareDisplayIds(a.id(), b.id()); |
| 73 } | 74 } |
| 74 }; | 75 }; |
| 75 | 76 |
| 76 struct DisplayInfoSortFunctor { | 77 struct DisplayInfoSortFunctor { |
| 77 bool operator()(const ui::ManagedDisplayInfo& a, | 78 bool operator()(const ui::ManagedDisplayInfo& a, |
| 78 const ui::ManagedDisplayInfo& b) { | 79 const ui::ManagedDisplayInfo& b) { |
| 79 return CompareDisplayIds(a.id(), b.id()); | 80 return ui::CompareDisplayIds(a.id(), b.id()); |
| 80 } | 81 } |
| 81 }; | 82 }; |
| 82 | 83 |
| 83 display::Display& GetInvalidDisplay() { | 84 display::Display& GetInvalidDisplay() { |
| 84 static display::Display* invalid_display = new display::Display(); | 85 static display::Display* invalid_display = new display::Display(); |
| 85 return *invalid_display; | 86 return *invalid_display; |
| 86 } | 87 } |
| 87 | 88 |
| 88 ui::ManagedDisplayInfo::ManagedDisplayModeList::const_iterator FindDisplayMode( | 89 ui::ManagedDisplayInfo::ManagedDisplayModeList::const_iterator FindDisplayMode( |
| 89 const ui::ManagedDisplayInfo& info, | 90 const ui::ManagedDisplayInfo& info, |
| 90 const scoped_refptr<ui::ManagedDisplayMode>& target_mode) { | 91 const scoped_refptr<ui::ManagedDisplayMode>& target_mode) { |
| 91 const ui::ManagedDisplayInfo::ManagedDisplayModeList& modes = | 92 const ui::ManagedDisplayInfo::ManagedDisplayModeList& modes = |
| 92 info.display_modes(); | 93 info.display_modes(); |
| 93 return std::find_if( | 94 return std::find_if( |
| 94 modes.begin(), modes.end(), | 95 modes.begin(), modes.end(), |
| 95 [target_mode](const scoped_refptr<ui::ManagedDisplayMode>& mode) { | 96 [target_mode](const scoped_refptr<ui::ManagedDisplayMode>& mode) { |
| 96 return target_mode->IsEquivalent(mode); | 97 return target_mode->IsEquivalent(mode); |
| 97 }); | 98 }); |
| 98 } | 99 } |
| 99 | 100 |
| 100 void SetInternalManagedDisplayModeList(ui::ManagedDisplayInfo* info) { | 101 void SetInternalManagedDisplayModeList(ui::ManagedDisplayInfo* info) { |
| 101 scoped_refptr<ui::ManagedDisplayMode> native_mode = | 102 scoped_refptr<ui::ManagedDisplayMode> native_mode = |
| 102 new ui::ManagedDisplayMode(info->bounds_in_native().size(), | 103 new ui::ManagedDisplayMode(info->bounds_in_native().size(), |
| 103 0.0 /* refresh_rate */, false /* interlaced */, | 104 0.0 /* refresh_rate */, false /* interlaced */, |
| 104 false /* native_mode */, 1.0 /* ui_scale */, | 105 false /* native_mode */, 1.0 /* ui_scale */, |
| 105 info->device_scale_factor()); | 106 info->device_scale_factor()); |
| 106 info->SetManagedDisplayModes( | 107 info->SetManagedDisplayModes( |
| 107 CreateInternalManagedDisplayModeList(native_mode)); | 108 ui::CreateInternalManagedDisplayModeList(native_mode)); |
| 108 } | 109 } |
| 109 | 110 |
| 110 void MaybeInitInternalDisplay(ui::ManagedDisplayInfo* info) { | 111 void MaybeInitInternalDisplay(ui::ManagedDisplayInfo* info) { |
| 111 int64_t id = info->id(); | 112 int64_t id = info->id(); |
| 112 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 113 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 113 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) { | 114 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) { |
| 114 display::Display::SetInternalDisplayId(id); | 115 display::Display::SetInternalDisplayId(id); |
| 115 SetInternalManagedDisplayModeList(info); | 116 SetInternalManagedDisplayModeList(info); |
| 116 } | 117 } |
| 117 } | 118 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 } | 220 } |
| 220 LOG(ERROR) << "DisplayLayout is requested for single display"; | 221 LOG(ERROR) << "DisplayLayout is requested for single display"; |
| 221 // On release build, just fallback to default instead of blowing up. | 222 // On release build, just fallback to default instead of blowing up. |
| 222 static display::DisplayLayout layout; | 223 static display::DisplayLayout layout; |
| 223 layout.primary_id = active_display_list_[0].id(); | 224 layout.primary_id = active_display_list_[0].id(); |
| 224 return layout; | 225 return layout; |
| 225 } | 226 } |
| 226 | 227 |
| 227 display::DisplayIdList DisplayManager::GetCurrentDisplayIdList() const { | 228 display::DisplayIdList DisplayManager::GetCurrentDisplayIdList() const { |
| 228 if (IsInUnifiedMode()) { | 229 if (IsInUnifiedMode()) { |
| 229 return CreateDisplayIdList(software_mirroring_display_list_); | 230 return ui::CreateDisplayIdList(software_mirroring_display_list_); |
| 230 } else if (IsInMirrorMode()) { | 231 } else if (IsInMirrorMode()) { |
| 231 if (software_mirroring_enabled()) { | 232 if (software_mirroring_enabled()) { |
| 232 CHECK_EQ(2u, num_connected_displays()); | 233 CHECK_EQ(2u, num_connected_displays()); |
| 233 // This comment is to make it easy to distinguish the crash | 234 // This comment is to make it easy to distinguish the crash |
| 234 // between two checks. | 235 // between two checks. |
| 235 CHECK_EQ(1u, active_display_list_.size()); | 236 CHECK_EQ(1u, active_display_list_.size()); |
| 236 } | 237 } |
| 237 int64_t ids[] = {active_display_list_[0].id(), mirroring_display_id_}; | 238 int64_t ids[] = {active_display_list_[0].id(), mirroring_display_id_}; |
| 238 return ash::GenerateDisplayIdList(std::begin(ids), std::end(ids)); | 239 return ui::GenerateDisplayIdList(std::begin(ids), std::end(ids)); |
| 239 } else { | 240 } else { |
| 240 CHECK_LE(2u, active_display_list_.size()); | 241 CHECK_LE(2u, active_display_list_.size()); |
| 241 return CreateDisplayIdList(active_display_list_); | 242 return ui::CreateDisplayIdList(active_display_list_); |
| 242 } | 243 } |
| 243 } | 244 } |
| 244 | 245 |
| 245 void DisplayManager::SetLayoutForCurrentDisplays( | 246 void DisplayManager::SetLayoutForCurrentDisplays( |
| 246 std::unique_ptr<display::DisplayLayout> layout) { | 247 std::unique_ptr<display::DisplayLayout> layout) { |
| 247 if (GetNumDisplays() == 1) | 248 if (GetNumDisplays() == 1) |
| 248 return; | 249 return; |
| 249 const display::DisplayIdList list = GetCurrentDisplayIdList(); | 250 const display::DisplayIdList list = GetCurrentDisplayIdList(); |
| 250 | 251 |
| 251 DCHECK(display::DisplayLayout::Validate(list, *layout)); | 252 DCHECK(display::DisplayLayout::Validate(list, *layout)); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 276 } | 277 } |
| 277 | 278 |
| 278 const display::Display& DisplayManager::GetDisplayForId(int64_t id) const { | 279 const display::Display& DisplayManager::GetDisplayForId(int64_t id) const { |
| 279 display::Display* display = | 280 display::Display* display = |
| 280 const_cast<DisplayManager*>(this)->FindDisplayForId(id); | 281 const_cast<DisplayManager*>(this)->FindDisplayForId(id); |
| 281 return display ? *display : GetInvalidDisplay(); | 282 return display ? *display : GetInvalidDisplay(); |
| 282 } | 283 } |
| 283 | 284 |
| 284 const display::Display& DisplayManager::FindDisplayContainingPoint( | 285 const display::Display& DisplayManager::FindDisplayContainingPoint( |
| 285 const gfx::Point& point_in_screen) const { | 286 const gfx::Point& point_in_screen) const { |
| 286 int index = | 287 int index = ui::FindDisplayIndexContainingPoint(active_display_list_, |
| 287 FindDisplayIndexContainingPoint(active_display_list_, point_in_screen); | 288 point_in_screen); |
| 288 return index < 0 ? GetInvalidDisplay() : active_display_list_[index]; | 289 return index < 0 ? GetInvalidDisplay() : active_display_list_[index]; |
| 289 } | 290 } |
| 290 | 291 |
| 291 bool DisplayManager::UpdateWorkAreaOfDisplay(int64_t display_id, | 292 bool DisplayManager::UpdateWorkAreaOfDisplay(int64_t display_id, |
| 292 const gfx::Insets& insets) { | 293 const gfx::Insets& insets) { |
| 293 display::Display* display = FindDisplayForId(display_id); | 294 display::Display* display = FindDisplayForId(display_id); |
| 294 DCHECK(display); | 295 DCHECK(display); |
| 295 gfx::Rect old_work_area = display->work_area(); | 296 gfx::Rect old_work_area = display->work_area(); |
| 296 display->UpdateWorkAreaFromInsets(insets); | 297 display->UpdateWorkAreaFromInsets(insets); |
| 297 bool workarea_changed = old_work_area != display->work_area(); | 298 bool workarea_changed = old_work_area != display->work_area(); |
| (...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 | 1087 |
| 1087 void DisplayManager::UpdateInternalManagedDisplayModeListForTest() { | 1088 void DisplayManager::UpdateInternalManagedDisplayModeListForTest() { |
| 1088 if (!display::Display::HasInternalDisplay() || | 1089 if (!display::Display::HasInternalDisplay() || |
| 1089 display_info_.count(display::Display::InternalDisplayId()) == 0) | 1090 display_info_.count(display::Display::InternalDisplayId()) == 0) |
| 1090 return; | 1091 return; |
| 1091 ui::ManagedDisplayInfo* info = | 1092 ui::ManagedDisplayInfo* info = |
| 1092 &display_info_[display::Display::InternalDisplayId()]; | 1093 &display_info_[display::Display::InternalDisplayId()]; |
| 1093 SetInternalManagedDisplayModeList(info); | 1094 SetInternalManagedDisplayModeList(info); |
| 1094 } | 1095 } |
| 1095 | 1096 |
| 1097 bool DisplayManager::ZoomInternalDisplay(bool up) { | |
| 1098 int64_t display_id = | |
| 1099 IsInUnifiedMode() ? kUnifiedDisplayId : GetDisplayIdForUIScaling(); | |
| 1100 const ui::ManagedDisplayInfo& display_info = GetDisplayInfo(display_id); | |
| 1101 | |
| 1102 scoped_refptr<ui::ManagedDisplayMode> mode; | |
| 1103 if (IsInUnifiedMode()) { | |
| 1104 mode = GetDisplayModeForNextResolution(display_info, up); | |
| 1105 } else { | |
| 1106 if (!IsActiveDisplayId(display_info.id()) || | |
| 1107 !display::Display::IsInternalDisplayId(display_info.id())) { | |
| 1108 return false; | |
| 1109 } | |
| 1110 mode = GetDisplayModeForNextUIScale(display_info, up); | |
| 1111 } | |
| 1112 | |
| 1113 if (!mode) | |
| 1114 return false; | |
| 1115 return SetDisplayMode(display_id, mode); | |
|
oshima
2016/08/26 21:55:59
nit:
return mode ? SetDisplayMode() : false;
rjkroege
2016/08/30 19:11:06
Done.
| |
| 1116 } | |
| 1117 | |
| 1118 void DisplayManager::ResetInternalDisplayZoom() { | |
| 1119 if (IsInUnifiedMode()) { | |
| 1120 const ui::ManagedDisplayInfo& display_info = | |
| 1121 GetDisplayInfo(DisplayManager::kUnifiedDisplayId); | |
| 1122 const ui::ManagedDisplayInfo::ManagedDisplayModeList& modes = | |
| 1123 display_info.display_modes(); | |
| 1124 auto iter = | |
| 1125 std::find_if(modes.begin(), modes.end(), | |
| 1126 [](const scoped_refptr<ui::ManagedDisplayMode>& mode) { | |
| 1127 return mode->native(); | |
| 1128 }); | |
| 1129 SetDisplayMode(kUnifiedDisplayId, *iter); | |
| 1130 } else { | |
| 1131 SetDisplayUIScale(GetDisplayIdForUIScaling(), 1.0f); | |
| 1132 } | |
| 1133 } | |
| 1134 | |
| 1096 void DisplayManager::CreateSoftwareMirroringDisplayInfo( | 1135 void DisplayManager::CreateSoftwareMirroringDisplayInfo( |
| 1097 DisplayInfoList* display_info_list) { | 1136 DisplayInfoList* display_info_list) { |
| 1098 // Use the internal display or 1st as the mirror source, then scale | 1137 // Use the internal display or 1st as the mirror source, then scale |
| 1099 // the root window so that it matches the external display's | 1138 // the root window so that it matches the external display's |
| 1100 // resolution. This is necessary in order for scaling to work while | 1139 // resolution. This is necessary in order for scaling to work while |
| 1101 // mirrored. | 1140 // mirrored. |
| 1102 switch (multi_display_mode_) { | 1141 switch (multi_display_mode_) { |
| 1103 case MIRRORING: { | 1142 case MIRRORING: { |
| 1104 if (display_info_list->size() != 2) | 1143 if (display_info_list->size() != 2) |
| 1105 return; | 1144 return; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1324 } | 1363 } |
| 1325 | 1364 |
| 1326 void DisplayManager::UpdateNonPrimaryDisplayBoundsForLayout( | 1365 void DisplayManager::UpdateNonPrimaryDisplayBoundsForLayout( |
| 1327 display::DisplayList* display_list, | 1366 display::DisplayList* display_list, |
| 1328 std::vector<size_t>* updated_indices) { | 1367 std::vector<size_t>* updated_indices) { |
| 1329 if (display_list->size() == 1u) | 1368 if (display_list->size() == 1u) |
| 1330 return; | 1369 return; |
| 1331 | 1370 |
| 1332 const display::DisplayLayout& layout = | 1371 const display::DisplayLayout& layout = |
| 1333 layout_store_->GetRegisteredDisplayLayout( | 1372 layout_store_->GetRegisteredDisplayLayout( |
| 1334 CreateDisplayIdList(*display_list)); | 1373 ui::CreateDisplayIdList(*display_list)); |
| 1335 | 1374 |
| 1336 // Ignore if a user has a old format (should be extremely rare) | 1375 // Ignore if a user has a old format (should be extremely rare) |
| 1337 // and this will be replaced with DCHECK. | 1376 // and this will be replaced with DCHECK. |
| 1338 if (layout.primary_id == display::Display::kInvalidDisplayID) | 1377 if (layout.primary_id == display::Display::kInvalidDisplayID) |
| 1339 return; | 1378 return; |
| 1340 | 1379 |
| 1341 // display_list does not have translation set, so ApplyDisplayLayout cannot | 1380 // display_list does not have translation set, so ApplyDisplayLayout cannot |
| 1342 // provide accurate change information. We'll find the changes after the call. | 1381 // provide accurate change information. We'll find the changes after the call. |
| 1343 ApplyDisplayLayout(layout, display_list, nullptr); | 1382 ApplyDisplayLayout(layout, display_list, nullptr); |
| 1344 size_t num_displays = display_list->size(); | 1383 size_t num_displays = display_list->size(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1366 layout.ApplyToDisplayList(display_list, updated_ids, | 1405 layout.ApplyToDisplayList(display_list, updated_ids, |
| 1367 kMinimumOverlapForInvalidOffset); | 1406 kMinimumOverlapForInvalidOffset); |
| 1368 } | 1407 } |
| 1369 | 1408 |
| 1370 void DisplayManager::RunPendingTasksForTest() { | 1409 void DisplayManager::RunPendingTasksForTest() { |
| 1371 if (!software_mirroring_display_list_.empty()) | 1410 if (!software_mirroring_display_list_.empty()) |
| 1372 base::RunLoop().RunUntilIdle(); | 1411 base::RunLoop().RunUntilIdle(); |
| 1373 } | 1412 } |
| 1374 | 1413 |
| 1375 } // namespace ash | 1414 } // namespace ash |
| OLD | NEW |