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