Chromium Code Reviews| Index: ash/display/display_manager.cc |
| diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc |
| index f4f344f6519de81e0027673e226f77f4539ec0f5..faefb9af245c27402da0b7016fde55e9c604de6f 100644 |
| --- a/ash/display/display_manager.cc |
| +++ b/ash/display/display_manager.cc |
| @@ -49,6 +49,8 @@ |
| #include "base/win/windows_version.h" |
| #endif |
| +#include "base/debug/stack_trace.h" |
| + |
| namespace ash { |
| typedef std::vector<gfx::Display> DisplayList; |
| typedef std::vector<DisplayInfo> DisplayInfoList; |
| @@ -115,6 +117,9 @@ bool IsInternalDisplayId(int64 id) { |
| using std::string; |
| using std::vector; |
| +// static |
| +int64 DisplayManager::kUnifiedDisplayId = -10; |
| + |
| DisplayManager::DisplayManager() |
| : delegate_(NULL), |
| screen_(new ScreenAsh), |
| @@ -123,7 +128,8 @@ DisplayManager::DisplayManager() |
| num_connected_displays_(0), |
| force_bounds_changed_(false), |
| change_display_upon_host_resize_(false), |
| - second_display_mode_(EXTENDED), |
| + multi_display_mode_(EXTENDED), |
| + default_multi_display_mode_(EXTENDED), |
| mirroring_display_id_(gfx::Display::kInvalidDisplayID), |
| registered_internal_display_rotation_lock_(false), |
| registered_internal_display_rotation_(gfx::Display::ROTATE_0), |
| @@ -133,6 +139,9 @@ DisplayManager::DisplayManager() |
| if (base::SysInfo::IsRunningOnChromeOS()) |
| DisplayInfo::SetUse125DSFForUIScaling(true); |
| + if (switches::UnifiedDesktopEnabled()) |
| + multi_display_mode_ = default_multi_display_mode_ = UNIFIED; |
| + |
| change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); |
| #endif |
| gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); |
| @@ -170,7 +179,7 @@ bool DisplayManager::InitFromCommandLine() { |
| MaybeInitInternalDisplay(&info_list[0]); |
| if (info_list.size() > 1 && |
| command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { |
| - SetSecondDisplayMode(MIRRORING); |
| + SetMultiDisplayMode(MIRRORING); |
| } |
| OnNativeDisplaysChanged(info_list); |
| return true; |
| @@ -219,7 +228,10 @@ DisplayLayout DisplayManager::GetCurrentDisplayLayout() { |
| } |
| DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { |
| - if (IsInMirrorMode()) { |
| + if (IsInUnifiedMode()) { |
| + return std::make_pair(software_mirroring_display_list_[0].id(), |
| + software_mirroring_display_list_[1].id()); |
| + } else if (IsInMirrorMode()) { |
| if (software_mirroring_enabled()) { |
| CHECK_EQ(2u, num_connected_displays()); |
| // This comment is to make it easy to distinguish the crash |
| @@ -593,7 +605,7 @@ void DisplayManager::OnNativeDisplaysChanged( |
| bool internal_display_connected = false; |
| num_connected_displays_ = updated_displays.size(); |
| mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| - software_mirroring_display_ = gfx::Display(); |
| + software_mirroring_display_list_.clear(); |
| DisplayInfoList new_display_info_list; |
| for (DisplayInfoList::const_iterator iter = updated_displays.begin(); |
| iter != updated_displays.end(); |
| @@ -668,8 +680,7 @@ void DisplayManager::UpdateDisplays( |
| if (delegate_) |
| delegate_->CloseMirroringDisplay(); |
| - if (second_display_mode_ == MIRRORING && new_display_info_list.size() == 2) |
| - CreateSoftwareMirroringDisplay(&new_display_info_list); |
| + CreateSoftwareMirroringDisplay(&new_display_info_list); |
| DisplayList new_displays; |
| DisplayList removed_displays; |
| @@ -870,6 +881,11 @@ bool DisplayManager::IsInMirrorMode() const { |
| return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; |
| } |
| +bool DisplayManager::IsInUnifiedMode() const { |
| + return multi_display_mode_ == UNIFIED && |
| + !software_mirroring_display_list_.empty(); |
| +} |
| + |
| const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { |
| DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); |
| @@ -879,6 +895,17 @@ const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { |
| return iter->second; |
| } |
| +const gfx::Display DisplayManager::GetMirroringDisplayById( |
| + int64 display_id) const { |
| + auto iter = std::find_if(software_mirroring_display_list_.begin(), |
| + software_mirroring_display_list_.end(), |
| + [display_id](const gfx::Display& display) { |
| + return display.id() == display_id; |
| + }); |
| + return iter == software_mirroring_display_list_.end() ? gfx::Display() |
| + : *iter; |
| +} |
| + |
| std::string DisplayManager::GetDisplayNameForId(int64 id) { |
| if (id == gfx::Display::kInvalidDisplayID) |
| return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| @@ -899,30 +926,37 @@ int64 DisplayManager::GetDisplayIdForUIScaling() const { |
| return display_id; |
| } |
| -void DisplayManager::SetMirrorMode(bool mirrored) { |
| +void DisplayManager::SetMirrorMode(bool mirror) { |
| +#if defined(OS_CHROMEOS) |
| if (num_connected_displays() <= 1) |
| return; |
| -#if defined(OS_CHROMEOS) |
| if (base::SysInfo::IsRunningOnChromeOS()) { |
| ui::MultipleDisplayState new_state = |
| - mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR : |
| - ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| + mirror ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR |
| + : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); |
| return; |
| } |
| -#endif |
| + |
| // This is fallback path to emulate mirroroing on desktop. |
| - SetSecondDisplayMode(mirrored ? MIRRORING : EXTENDED); |
| DisplayInfoList display_info_list; |
| - int count = 0; |
| - for (std::map<int64, DisplayInfo>::const_iterator iter = |
| - display_info_.begin(); |
| - count < 2; ++iter, ++count) { |
| - display_info_list.push_back(GetDisplayInfo(iter->second.id())); |
| + for (DisplayList::const_iterator iter = active_display_list_.begin(); |
| + (display_info_list.size() < 2 && iter != active_display_list_.end()); |
| + ++iter) { |
| + if (iter->id() == kUnifiedDisplayId) |
| + continue; |
| + display_info_list.push_back(GetDisplayInfo(iter->id())); |
| } |
| + for (auto iter = software_mirroring_display_list_.begin(); |
| + (display_info_list.size() < 2 && |
| + iter != software_mirroring_display_list_.end()); |
| + ++iter) { |
| + display_info_list.push_back(GetDisplayInfo(iter->id())); |
| + } |
| + |
| + SetSoftwareMirroring(mirror); |
| UpdateDisplays(display_info_list); |
| -#if defined(OS_CHROMEOS) |
| if (Shell::GetInstance()->display_configurator_animation()) { |
| Shell::GetInstance()->display_configurator_animation()-> |
| StartFadeInAnimation(); |
| @@ -934,7 +968,9 @@ void DisplayManager::AddRemoveDisplay() { |
| DCHECK(!active_display_list_.empty()); |
| std::vector<DisplayInfo> new_display_info_list; |
| const DisplayInfo& first_display = |
| - GetDisplayInfo(active_display_list_[0].id()); |
| + IsInUnifiedMode() |
| + ? GetDisplayInfo(software_mirroring_display_list_[0].id()) |
| + : GetDisplayInfo(active_display_list_[0].id()); |
| new_display_info_list.push_back(first_display); |
| // Add if there is only one display connected. |
| if (num_connected_displays() == 1) { |
| @@ -946,7 +982,7 @@ void DisplayManager::AddRemoveDisplay() { |
| } |
| num_connected_displays_ = new_display_info_list.size(); |
| mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| - software_mirroring_display_ = gfx::Display(); |
| + software_mirroring_display_list_.clear(); |
| UpdateDisplays(new_display_info_list); |
| } |
| @@ -966,7 +1002,7 @@ void DisplayManager::ToggleDisplayScaleFactor() { |
| #if defined(OS_CHROMEOS) |
| void DisplayManager::SetSoftwareMirroring(bool enabled) { |
| - SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED); |
| + SetMultiDisplayMode(enabled ? MIRRORING : default_multi_display_mode_); |
| } |
| bool DisplayManager::SoftwareMirroringEnabled() const { |
| @@ -974,10 +1010,17 @@ bool DisplayManager::SoftwareMirroringEnabled() const { |
| } |
| #endif |
| -void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) { |
| - second_display_mode_ = mode; |
| +void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { |
| + multi_display_mode_ = mode; |
| mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| - software_mirroring_display_ = gfx::Display(); |
| + software_mirroring_display_list_.clear(); |
| +} |
| + |
| +void DisplayManager::SetDefaultMultiDisplayMode(MultiDisplayMode mode) { |
| + // TODO(oshima): Remove this constrain. |
| + DCHECK_EQ(default_multi_display_mode_, EXTENDED); |
| + DCHECK_EQ(mode, UNIFIED); |
| + default_multi_display_mode_ = mode; |
| } |
| bool DisplayManager::UpdateDisplayBounds(int64 display_id, |
| @@ -1000,7 +1043,7 @@ void DisplayManager::CreateMirrorWindowAsyncIfAny() { |
| // Do not post a task if the software mirroring doesn't exist, or |
| // during initialization when compositor's init task isn't posted yet. |
| // ash::Shell::Init() will call this after the compositor is initialized. |
| - if (!software_mirroring_display_.is_valid() || !delegate_) |
| + if (software_mirroring_display_list_.empty() || !delegate_) |
| return; |
| base::MessageLoopForUI::current()->PostTask( |
| FROM_HERE, |
| @@ -1043,10 +1086,61 @@ void DisplayManager::CreateSoftwareMirroringDisplay( |
| // the root window so that it matches the external display's |
| // resolution. This is necessary in order for scaling to work while |
| // mirrored. |
| + // int64 mirroring_display_id = gfx::Display::kInvalidDisplayID; |
| + if (display_info_list->size() == 2) { |
| + switch (multi_display_mode_) { |
| + case MIRRORING: { |
| + bool zero_is_source = |
| + first_display_id_ == (*display_info_list)[0].id() || |
| + gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); |
| + DCHECK_EQ(MIRRORING, multi_display_mode_); |
| + mirroring_display_id_ = |
| + (*display_info_list)[zero_is_source ? 1 : 0].id(); |
| + |
| + int64 display_id = mirroring_display_id_; |
| + auto iter = |
| + std::find_if(display_info_list->begin(), display_info_list->end(), |
| + [display_id](const DisplayInfo& info) { |
| + return info.id() == display_id; |
| + }); |
| + DCHECK(iter != display_info_list->end()); |
| + |
| + DisplayInfo info = *iter; |
| + info.SetOverscanInsets(gfx::Insets()); |
| + InsertAndUpdateDisplayInfo(info); |
| + software_mirroring_display_list_.push_back( |
| + CreateDisplayFromDisplayInfoById(mirroring_display_id_)); |
| + display_info_list->erase(iter); |
| + } break; |
|
Jun Mukai
2015/04/26 23:45:08
I prefer to write
break;
}
order.
oshima
2015/04/27 17:48:38
Done.
|
| + case UNIFIED: { |
| + gfx::Rect unified_bounds; |
| + software_mirroring_display_list_.clear(); |
| + for (auto& info : *display_info_list) { |
| + InsertAndUpdateDisplayInfo(info); |
| + software_mirroring_display_list_.push_back( |
| + CreateDisplayFromDisplayInfoById(info.id())); |
| + gfx::Point origin(unified_bounds.right(), 0); |
| + unified_bounds.Union(gfx::Rect(origin, info.size_in_pixel())); |
| + } |
| + // first_display_id_ = kUnifiedDisplayId; |
| + DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); |
| + info.SetBounds(unified_bounds); |
| + display_info_list->clear(); |
| + display_info_list->push_back(info); |
| + } break; |
| + case EXTENDED: |
| + break; |
| + } |
| + } |
| +#if 0 |
| + // Use the internal display or 1st as the mirror source, then scale |
| + // the root window so that it matches the external display's |
| + // resolution. This is necessary in order for scaling to work while |
| + // mirrored. |
| bool zero_is_source = |
| first_display_id_ == (*display_info_list)[0].id() || |
| gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); |
| - DCHECK_EQ(MIRRORING, second_display_mode_); |
| + DCHECK_EQ(MIRRORING, multi_display_mode_); |
| mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); |
| int64 display_id = mirroring_display_id_; |
| auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), |
| @@ -1060,6 +1154,7 @@ void DisplayManager::CreateSoftwareMirroringDisplay( |
| software_mirroring_display_ = |
| CreateDisplayFromDisplayInfoById(mirroring_display_id_); |
| display_info_list->erase(iter); |
| +#endif |
|
oshima
2015/04/27 17:48:38
oops, I forgot to remove this. Removed.
|
| } |
| gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
| @@ -1068,7 +1163,10 @@ gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
| [id](const gfx::Display& display) { return display.id() == id; }); |
| if (iter != active_display_list_.end()) |
| return &(*iter); |
| - DLOG(WARNING) << "Could not find display:" << id; |
| + // TODO(oshima): This happens when a windows in unified desktop have |
| + // been moved to normal window. Fix this. |
| + if (id != kUnifiedDisplayId) |
| + DLOG(WARNING) << "Could not find display:" << id; |
| return NULL; |
| } |
| @@ -1102,7 +1200,7 @@ void DisplayManager::OnDisplayInfoUpdated(const DisplayInfo& display_info) { |
| } |
| gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { |
| - DCHECK(display_info_.find(id) != display_info_.end()); |
| + DCHECK(display_info_.find(id) != display_info_.end()) << "id=" << id; |
| const DisplayInfo& display_info = display_info_[id]; |
| gfx::Display new_display(display_info.id()); |
| @@ -1176,10 +1274,12 @@ bool DisplayManager::UpdateNonPrimaryDisplayBoundsForLayout( |
| } |
| void DisplayManager::CreateMirrorWindowIfAny() { |
| - if (software_mirroring_display_.is_valid() && delegate_) { |
| - DisplayInfo display_info = GetDisplayInfo(software_mirroring_display_.id()); |
| - delegate_->CreateOrUpdateMirroringDisplay(display_info); |
| - } |
| + if (software_mirroring_display_list_.empty() || !delegate_) |
| + return; |
| + DisplayInfoList list; |
| + for (auto& display : software_mirroring_display_list_) |
| + list.push_back(GetDisplayInfo(display.id())); |
| + delegate_->CreateOrUpdateMirroringDisplay(list); |
| } |
| // static |
| @@ -1230,7 +1330,7 @@ void DisplayManager::UpdateDisplayBoundsForLayout( |
| } |
| void DisplayManager::RunPendingTasksForTest() { |
| - if (software_mirroring_display_.is_valid()) |
| + if (!software_mirroring_display_list_.empty()) |
| base::RunLoop().RunUntilIdle(); |
| } |