OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/mirror_window_controller.h" | 5 #include "ash/display/mirror_window_controller.h" |
6 | 6 |
7 #if defined(USE_X11) | 7 #if defined(USE_X11) |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 | 10 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 gfx::Size mirror_window_host_size; | 129 gfx::Size mirror_window_host_size; |
130 aura::Window* mirror_window = nullptr; | 130 aura::Window* mirror_window = nullptr; |
131 }; | 131 }; |
132 | 132 |
133 MirrorWindowController::MirroringHostInfo::MirroringHostInfo() { | 133 MirrorWindowController::MirroringHostInfo::MirroringHostInfo() { |
134 } | 134 } |
135 MirrorWindowController::MirroringHostInfo::~MirroringHostInfo() { | 135 MirrorWindowController::MirroringHostInfo::~MirroringHostInfo() { |
136 } | 136 } |
137 | 137 |
138 MirrorWindowController::MirrorWindowController() | 138 MirrorWindowController::MirrorWindowController() |
139 : screen_position_client_(new MirroringScreenPositionClient(this)) { | 139 : multi_display_mode_(DisplayManager::EXTENDED), |
| 140 screen_position_client_(new MirroringScreenPositionClient(this)) { |
140 } | 141 } |
141 | 142 |
142 MirrorWindowController::~MirrorWindowController() { | 143 MirrorWindowController::~MirrorWindowController() { |
143 // Make sure the root window gets deleted before cursor_window_delegate. | 144 // Make sure the root window gets deleted before cursor_window_delegate. |
144 Close(); | 145 Close(false); |
145 } | 146 } |
146 | 147 |
147 void MirrorWindowController::UpdateWindow( | 148 void MirrorWindowController::UpdateWindow( |
148 const std::vector<DisplayInfo>& display_info_list) { | 149 const std::vector<DisplayInfo>& display_info_list) { |
149 static int mirror_host_count = 0; | 150 static int mirror_host_count = 0; |
150 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 151 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
151 const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); | 152 const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); |
152 const DisplayInfo& source_display_info = | 153 const DisplayInfo& source_display_info = |
153 display_manager->GetDisplayInfo(primary.id()); | 154 display_manager->GetDisplayInfo(primary.id()); |
154 | 155 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 } | 241 } |
241 | 242 |
242 // Deleting WTHs for disconnected displays. | 243 // Deleting WTHs for disconnected displays. |
243 if (mirroring_host_info_map_.size() > display_info_list.size()) { | 244 if (mirroring_host_info_map_.size() > display_info_list.size()) { |
244 for (MirroringHostInfoMap::iterator iter = mirroring_host_info_map_.begin(); | 245 for (MirroringHostInfoMap::iterator iter = mirroring_host_info_map_.begin(); |
245 iter != mirroring_host_info_map_.end();) { | 246 iter != mirroring_host_info_map_.end();) { |
246 if (std::find_if(display_info_list.begin(), display_info_list.end(), | 247 if (std::find_if(display_info_list.begin(), display_info_list.end(), |
247 [iter](const DisplayInfo& info) { | 248 [iter](const DisplayInfo& info) { |
248 return info.id() == iter->first; | 249 return info.id() == iter->first; |
249 }) == display_info_list.end()) { | 250 }) == display_info_list.end()) { |
250 CloseAndDeleteHost(iter->second); | 251 CloseAndDeleteHost(iter->second, true); |
251 iter = mirroring_host_info_map_.erase(iter); | 252 iter = mirroring_host_info_map_.erase(iter); |
252 } else { | 253 } else { |
253 ++iter; | 254 ++iter; |
254 } | 255 } |
255 } | 256 } |
256 } | 257 } |
257 } | 258 } |
258 | 259 |
259 void MirrorWindowController::UpdateWindow() { | 260 void MirrorWindowController::UpdateWindow() { |
260 if (!mirroring_host_info_map_.size()) | 261 if (!mirroring_host_info_map_.size()) |
261 return; | 262 return; |
262 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 263 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
263 std::vector<DisplayInfo> display_info_list; | 264 std::vector<DisplayInfo> display_info_list; |
264 for (auto& pair : mirroring_host_info_map_) | 265 for (auto& pair : mirroring_host_info_map_) |
265 display_info_list.push_back(display_manager->GetDisplayInfo(pair.first)); | 266 display_info_list.push_back(display_manager->GetDisplayInfo(pair.first)); |
266 UpdateWindow(display_info_list); | 267 UpdateWindow(display_info_list); |
267 } | 268 } |
268 | 269 |
269 void MirrorWindowController::Close() { | 270 void MirrorWindowController::CloseIfNotNecessary() { |
270 for (auto& info : mirroring_host_info_map_) { | 271 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
271 CloseAndDeleteHost(info.second); | 272 |
272 } | 273 DisplayManager::MultiDisplayMode new_mode = |
| 274 display_manager->IsInUnifiedMode() |
| 275 ? DisplayManager::UNIFIED |
| 276 : (display_manager->IsInMirrorMode() ? DisplayManager::MIRRORING |
| 277 : DisplayManager::EXTENDED); |
| 278 if (multi_display_mode_ != new_mode) |
| 279 Close(true); |
| 280 multi_display_mode_ = new_mode; |
| 281 } |
| 282 |
| 283 void MirrorWindowController::Close(bool delay_host_deletion) { |
| 284 for (auto& info : mirroring_host_info_map_) |
| 285 CloseAndDeleteHost(info.second, delay_host_deletion); |
| 286 |
273 mirroring_host_info_map_.clear(); | 287 mirroring_host_info_map_.clear(); |
274 if (reflector_) { | 288 if (reflector_) { |
275 aura::Env::GetInstance()->context_factory()->RemoveReflector( | 289 aura::Env::GetInstance()->context_factory()->RemoveReflector( |
276 reflector_.get()); | 290 reflector_.get()); |
277 reflector_.reset(); | 291 reflector_.reset(); |
278 } | 292 } |
279 } | 293 } |
280 | 294 |
281 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { | 295 void MirrorWindowController::OnHostResized(const aura::WindowTreeHost* host) { |
282 for (auto& pair : mirroring_host_info_map_) { | 296 for (auto& pair : mirroring_host_info_map_) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 return mirroring_host_info_map_[id]->ash_host.get(); | 349 return mirroring_host_info_map_[id]->ash_host.get(); |
336 } | 350 } |
337 | 351 |
338 aura::Window::Windows MirrorWindowController::GetAllRootWindows() const { | 352 aura::Window::Windows MirrorWindowController::GetAllRootWindows() const { |
339 aura::Window::Windows root_windows; | 353 aura::Window::Windows root_windows; |
340 for (const auto& pair : mirroring_host_info_map_) | 354 for (const auto& pair : mirroring_host_info_map_) |
341 root_windows.push_back(pair.second->ash_host->AsWindowTreeHost()->window()); | 355 root_windows.push_back(pair.second->ash_host->AsWindowTreeHost()->window()); |
342 return root_windows; | 356 return root_windows; |
343 } | 357 } |
344 | 358 |
345 void MirrorWindowController::CloseAndDeleteHost(MirroringHostInfo* host_info) { | 359 void MirrorWindowController::CloseAndDeleteHost(MirroringHostInfo* host_info, |
| 360 bool delay_host_deletion) { |
346 aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); | 361 aura::WindowTreeHost* host = host_info->ash_host->AsWindowTreeHost(); |
347 | 362 |
348 aura::client::SetScreenPositionClient(host->window(), nullptr); | 363 aura::client::SetScreenPositionClient(host->window(), nullptr); |
349 | 364 |
350 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( | 365 NoneCaptureClient* capture_client = static_cast<NoneCaptureClient*>( |
351 aura::client::GetCaptureClient(host->window())); | 366 aura::client::GetCaptureClient(host->window())); |
352 aura::client::SetCaptureClient(host->window(), nullptr); | 367 aura::client::SetCaptureClient(host->window(), nullptr); |
353 delete capture_client; | 368 delete capture_client; |
354 | 369 |
355 host->RemoveObserver(Shell::GetInstance()->display_controller()); | 370 host->RemoveObserver(Shell::GetInstance()->display_controller()); |
356 host->RemoveObserver(this); | 371 host->RemoveObserver(this); |
357 host_info->ash_host->PrepareForShutdown(); | 372 host_info->ash_host->PrepareForShutdown(); |
358 reflector_->RemoveMirroringLayer(host_info->mirror_window->layer()); | 373 reflector_->RemoveMirroringLayer(host_info->mirror_window->layer()); |
359 | 374 |
360 delete host_info; | 375 // EventProcessor may be accessed after this call if the mirroring window |
| 376 // was deleted as a result of input event (e.g. shortcut), so don't delete |
| 377 // now. |
| 378 if (delay_host_deletion) |
| 379 base::MessageLoop::current()->DeleteSoon(FROM_HERE, host_info); |
| 380 else |
| 381 delete host_info; |
361 } | 382 } |
362 | 383 |
363 scoped_ptr<RootWindowTransformer> | 384 scoped_ptr<RootWindowTransformer> |
364 MirrorWindowController::CreateRootWindowTransformer() const { | 385 MirrorWindowController::CreateRootWindowTransformer() const { |
365 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | 386 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
366 const DisplayInfo& mirror_display_info = | 387 const DisplayInfo& mirror_display_info = |
367 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); | 388 display_manager->GetDisplayInfo(display_manager->mirroring_display_id()); |
368 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( | 389 const DisplayInfo& source_display_info = display_manager->GetDisplayInfo( |
369 Shell::GetScreen()->GetPrimaryDisplay().id()); | 390 Shell::GetScreen()->GetPrimaryDisplay().id()); |
370 DCHECK(display_manager->IsInMirrorMode()); | 391 DCHECK(display_manager->IsInMirrorMode()); |
371 return scoped_ptr<RootWindowTransformer>( | 392 return scoped_ptr<RootWindowTransformer>( |
372 CreateRootWindowTransformerForMirroredDisplay(source_display_info, | 393 CreateRootWindowTransformerForMirroredDisplay(source_display_info, |
373 mirror_display_info)); | 394 mirror_display_info)); |
374 } | 395 } |
375 | 396 |
376 } // namespace ash | 397 } // namespace ash |
OLD | NEW |