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; |
+ 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> |