Chromium Code Reviews| Index: ash/display/mirror_window_controller.cc |
| diff --git a/ash/display/mirror_window_controller.cc b/ash/display/mirror_window_controller.cc |
| index c7e5acf0e1ce2f6961b9d767e42cb2a2ab23c967..e0a1412b300bd783ea7e5d0e3eec2e65e751666b 100644 |
| --- a/ash/display/mirror_window_controller.cc |
| +++ b/ash/display/mirror_window_controller.cc |
| @@ -76,6 +76,11 @@ class NoneCaptureClient : public aura::client::CaptureClient { |
| } // namespace |
| +MirrorWindowController::MirroringHostInfo::MirroringHostInfo() { |
| +} |
| +MirrorWindowController::MirroringHostInfo::~MirroringHostInfo() { |
| +} |
| + |
| MirrorWindowController::MirrorWindowController() {} |
| MirrorWindowController::~MirrorWindowController() { |
| @@ -83,93 +88,182 @@ MirrorWindowController::~MirrorWindowController() { |
| Close(); |
| } |
| -void MirrorWindowController::UpdateWindow(const DisplayInfo& display_info) { |
| +void MirrorWindowController::UpdateWindow( |
| + const std::vector<DisplayInfo>& display_info_list) { |
| static int mirror_host_count = 0; |
| - if (!ash_host_.get()) { |
| - AshWindowTreeHostInitParams init_params; |
| - init_params.initial_bounds = display_info.bounds_in_native(); |
| - ash_host_.reset(AshWindowTreeHost::Create(init_params)); |
| - aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); |
| - host->window()->SetName( |
| - base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++)); |
| - host->compositor()->SetBackgroundColor(SK_ColorBLACK); |
| - // No need to remove the observer because the DisplayController outlives the |
| - // host. |
| - host->AddObserver(Shell::GetInstance()->display_controller()); |
| - host->AddObserver(this); |
| - // TODO(oshima): TouchHUD is using idkey. |
| - InitRootWindowSettings(host->window())->display_id = display_info.id(); |
| - host->InitHost(); |
| + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| + const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); |
| + const DisplayInfo& source_display_info = |
| + display_manager->GetDisplayInfo(primary.id()); |
| + |
| + gfx::Point mirroring_origin; |
| + for (const DisplayInfo& display_info : display_info_list) { |
| + if (mirroring_host_info_map_.find(display_info.id()) == |
| + mirroring_host_info_map_.end()) { |
| + AshWindowTreeHostInitParams init_params; |
| + init_params.initial_bounds = display_info.bounds_in_native(); |
| + MirroringHostInfo* host_info = new MirroringHostInfo; |
| + host_info->ash_host.reset(AshWindowTreeHost::Create(init_params)); |
| + mirroring_host_info_map_[display_info.id()] = host_info; |
| + |
| + aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
| + host->window()->SetName( |
| + base::StringPrintf("MirrorRootWindow-%d", mirror_host_count++)); |
| + host->compositor()->SetBackgroundColor(SK_ColorBLACK); |
| + // No need to remove the observer because the DisplayController outlives |
| + // the |
| + // host. |
| + host->AddObserver(Shell::GetInstance()->display_controller()); |
| + host->AddObserver(this); |
| + // TODO(oshima): TouchHUD is using idkey. |
| + InitRootWindowSettings(host->window())->display_id = display_info.id(); |
| + host->InitHost(); |
| #if defined(USE_X11) |
| - DisableInput(host->GetAcceleratedWidget()); |
| + if (display_manager->multi_display_mode() != DisplayManager::UNIFIED) |
| + DisableInput(host->GetAcceleratedWidget()); |
| #endif |
| - aura::client::SetCaptureClient(host->window(), new NoneCaptureClient()); |
| - host->Show(); |
| - |
| - // TODO(oshima): Start mirroring. |
| - aura::Window* mirror_window = new aura::Window(NULL); |
| - mirror_window->Init(ui::LAYER_SOLID_COLOR); |
| - host->window()->AddChild(mirror_window); |
| - mirror_window->SetBounds(host->window()->bounds()); |
| - mirror_window->Show(); |
| - reflector_ = aura::Env::GetInstance()->context_factory()->CreateReflector( |
| - Shell::GetPrimaryRootWindow()->GetHost()->compositor(), |
| - mirror_window->layer()); |
| - } else { |
| - aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); |
| - GetRootWindowSettings(host->window())->display_id = display_info.id(); |
| - host->SetBounds(display_info.bounds_in_native()); |
| +#if defined(OS_CHROMEOS) |
| + if (display_manager->multi_display_mode() == DisplayManager::UNIFIED) { |
| + host_info->ash_host->ConfineCursorToRootWindow(); |
| + AshWindowTreeHost* unified_ash_host = |
| + Shell::GetInstance() |
| + ->display_controller() |
| + ->GetAshWindowTreeHostForDisplayId( |
| + Shell::GetScreen()->GetPrimaryDisplay().id()); |
| + unified_ash_host->RegisterMirroringHost(host_info->ash_host.get()); |
| + } |
| +#endif |
| + |
| + aura::client::SetCaptureClient(host->window(), new NoneCaptureClient()); |
| + host->Show(); |
| + |
| + aura::Window* mirror_window = host_info->mirror_window = |
| + new aura::Window(nullptr); |
| + mirror_window->Init(ui::LAYER_SOLID_COLOR); |
| + host->window()->AddChild(mirror_window); |
| + mirror_window->SetBounds(host->window()->bounds()); |
| + mirror_window->Show(); |
| + if (reflector_) { |
| + // TODO(oshima): Enable this once reflect change is landed. |
| + // reflector_->AddMirroringLayer(mirror_window->layer()); |
| + } else { |
| + reflector_ = |
| + aura::Env::GetInstance()->context_factory()->CreateReflector( |
| + Shell::GetPrimaryRootWindow()->GetHost()->compositor(), |
| + mirror_window->layer()); |
| + } |
| + } else { |
| + aura::WindowTreeHost* host = mirroring_host_info_map_[display_info.id()] |
| + ->ash_host->AsWindowTreeHost(); |
| + GetRootWindowSettings(host->window())->display_id = display_info.id(); |
| + host->SetBounds(display_info.bounds_in_native()); |
| + } |
| + |
| + AshWindowTreeHost* mirroring_ash_host = |
| + mirroring_host_info_map_[display_info.id()]->ash_host.get(); |
| + switch (display_manager->multi_display_mode()) { |
| + case DisplayManager::MIRRORING: { |
| + scoped_ptr<RootWindowTransformer> transformer( |
| + CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
| + display_info)); |
| + mirroring_ash_host->SetRootWindowTransformer(transformer.Pass()); |
| + } break; |
|
Jun Mukai
2015/04/27 18:23:39
style nit: break; } ?
oshima
2015/04/27 20:30:55
Done.
|
| + case DisplayManager::UNIFIED: { |
| + gfx::Display display; |
| + display.SetScaleAndBounds( |
| + 1.0f, gfx::Rect(mirroring_origin, |
| + display_info.bounds_in_native().size())); |
| + mirroring_origin.SetPoint(display.bounds().right(), 0); |
| + scoped_ptr<RootWindowTransformer> transformer( |
| + CreateRootWindowTransformerForUnifiedDesktop(primary.bounds(), |
| + display)); |
| + mirroring_ash_host->SetRootWindowTransformer(transformer.Pass()); |
| + } break; |
| + case DisplayManager::EXTENDED: |
| + NOTREACHED(); |
| + } |
| } |
| - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| - const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
| - Shell::GetScreen()->GetPrimaryDisplay().id()); |
| - DCHECK(display_manager->IsInMirrorMode()); |
| - scoped_ptr<RootWindowTransformer> transformer( |
| - CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
| - display_info)); |
| - ash_host_->SetRootWindowTransformer(transformer.Pass()); |
| + // Deleting WTHs for disconnected displays. |
| + if (mirroring_host_info_map_.size() > display_info_list.size()) { |
| + for (MirroringHostInfoMap::iterator iter = mirroring_host_info_map_.begin(); |
| + iter != mirroring_host_info_map_.end();) { |
| + if (std::find_if(display_info_list.begin(), display_info_list.end(), |
| + [iter](const DisplayInfo& info) { |
| + return info.id() == iter->first; |
| + }) == display_info_list.end()) { |
| + CloseHost(iter->second); |
| + iter = mirroring_host_info_map_.erase(iter); |
| + } else { |
| + ++iter; |
| + } |
| + } |
| + } |
| } |
| void MirrorWindowController::UpdateWindow() { |
| - if (ash_host_.get()) { |
| - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| - const DisplayInfo& mirror_display_info = display_manager->GetDisplayInfo( |
| - display_manager->mirroring_display_id()); |
| - UpdateWindow(mirror_display_info); |
| - } |
| + if (!mirroring_host_info_map_.size()) |
| + return; |
| + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| + std::vector<DisplayInfo> display_info_list; |
| + for (auto& pair : mirroring_host_info_map_) |
| + display_info_list.push_back(display_manager->GetDisplayInfo(pair.first)); |
| + UpdateWindow(display_info_list); |
| } |
| void MirrorWindowController::Close() { |
| - if (ash_host_.get()) { |
| - aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); |
| + for (auto& info : mirroring_host_info_map_) { |
| + CloseHost(info.second); |
| + } |
| + mirroring_host_info_map_.clear(); |
| + if (reflector_) { |
| aura::Env::GetInstance()->context_factory()->RemoveReflector( |
| reflector_.get()); |
| - reflector_ = nullptr; |
| - NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
| - aura::client::GetCaptureClient(host->window())); |
| - aura::client::SetCaptureClient(host->window(), NULL); |
| - delete capture_client; |
| - |
| - host->RemoveObserver(Shell::GetInstance()->display_controller()); |
| - host->RemoveObserver(this); |
| - ash_host_.reset(); |
| + reflector_.reset(); |
| } |
| } |
| void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { |
| - if (mirror_window_host_size_ == host->GetBounds().size()) |
| - return; |
| - mirror_window_host_size_ = host->GetBounds().size(); |
| - reflector_->OnMirroringCompositorResized(); |
| - ash_host_->SetRootWindowTransformer(CreateRootWindowTransformer().Pass()); |
| - Shell::GetInstance()->display_controller()->cursor_window_controller()-> |
| - UpdateLocation(); |
| + for (auto& pair : mirroring_host_info_map_) { |
| + MirroringHostInfo* info = pair.second; |
| + if (info->ash_host->AsWindowTreeHost() == host) { |
| + if (info->mirror_window_host_size == host->GetBounds().size()) |
| + return; |
| + info->mirror_window_host_size = host->GetBounds().size(); |
| + reflector_->OnMirroringCompositorResized(); |
| + info->ash_host->SetRootWindowTransformer( |
| + CreateRootWindowTransformer().Pass()); |
| + Shell::GetInstance() |
| + ->display_controller() |
| + ->cursor_window_controller() |
| + ->UpdateLocation(); |
| + return; |
| + } |
| + } |
| } |
| aura::Window* MirrorWindowController::GetWindow() { |
| - return ash_host_.get() ? ash_host_->AsWindowTreeHost()->window() : NULL; |
| + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| + if (display_manager->multi_display_mode() != DisplayManager::MIRRORING || |
| + mirroring_host_info_map_.size() == 0) |
| + return nullptr; |
| + return mirroring_host_info_map_.begin() |
| + ->second->ash_host->AsWindowTreeHost() |
| + ->window(); |
| +} |
| + |
| +void MirrorWindowController::CloseHost(MirroringHostInfo* host_info) { |
| + aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
| + NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
| + aura::client::GetCaptureClient(host->window())); |
| + aura::client::SetCaptureClient(host->window(), NULL); |
| + delete capture_client; |
| + |
| + host->RemoveObserver(Shell::GetInstance()->display_controller()); |
| + host->RemoveObserver(this); |
| + // reflector_->RemoveMirroringLayer(host_info->mirror_window->layer()); |
| + delete host_info; |
| } |
| scoped_ptr<RootWindowTransformer> |