| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/display_controller.h" | 5 #include "ash/display/display_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "ash/ash_switches.h" | 11 #include "ash/ash_switches.h" |
| 12 #include "ash/display/display_layout_store.h" | 12 #include "ash/display/display_layout_store.h" |
| 13 #include "ash/display/display_manager.h" | 13 #include "ash/display/display_manager.h" |
| 14 #include "ash/display/mirror_window_controller.h" | 14 #include "ash/display/mirror_window_controller.h" |
| 15 #include "ash/display/root_window_transformers.h" | 15 #include "ash/display/root_window_transformers.h" |
| 16 #include "ash/display/virtual_keyboard_window_controller.h" | 16 #include "ash/display/virtual_keyboard_window_controller.h" |
| 17 #include "ash/host/root_window_host_factory.h" | 17 #include "ash/host/root_window_host_factory.h" |
| 18 #include "ash/root_window_controller.h" | 18 #include "ash/root_window_controller.h" |
| 19 #include "ash/root_window_settings.h" | 19 #include "ash/root_window_settings.h" |
| 20 #include "ash/screen_ash.h" | 20 #include "ash/screen_util.h" |
| 21 #include "ash/shell.h" | 21 #include "ash/shell.h" |
| 22 #include "ash/wm/coordinate_conversion.h" | 22 #include "ash/wm/coordinate_conversion.h" |
| 23 #include "base/command_line.h" | 23 #include "base/command_line.h" |
| 24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
| 25 #include "third_party/skia/include/utils/SkMatrix44.h" | |
| 26 #include "ui/aura/client/activation_client.h" | 25 #include "ui/aura/client/activation_client.h" |
| 27 #include "ui/aura/client/capture_client.h" | 26 #include "ui/aura/client/capture_client.h" |
| 28 #include "ui/aura/client/cursor_client.h" | |
| 29 #include "ui/aura/client/focus_client.h" | 27 #include "ui/aura/client/focus_client.h" |
| 30 #include "ui/aura/client/screen_position_client.h" | 28 #include "ui/aura/client/screen_position_client.h" |
| 31 #include "ui/aura/root_window.h" | 29 #include "ui/aura/root_window.h" |
| 32 #include "ui/aura/root_window_transformer.h" | 30 #include "ui/aura/root_window_transformer.h" |
| 33 #include "ui/aura/window.h" | 31 #include "ui/aura/window.h" |
| 34 #include "ui/aura/window_property.h" | 32 #include "ui/aura/window_property.h" |
| 35 #include "ui/aura/window_tracker.h" | 33 #include "ui/aura/window_tracker.h" |
| 36 #include "ui/compositor/compositor.h" | 34 #include "ui/compositor/compositor.h" |
| 37 #include "ui/compositor/dip_util.h" | |
| 38 #include "ui/gfx/display.h" | 35 #include "ui/gfx/display.h" |
| 39 #include "ui/gfx/screen.h" | 36 #include "ui/gfx/screen.h" |
| 40 | 37 |
| 41 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 42 #include "base/sys_info.h" | 39 #include "base/sys_info.h" |
| 43 #include "base/time/time.h" | 40 #include "base/time/time.h" |
| 44 #if defined(USE_X11) | 41 #if defined(USE_X11) |
| 45 #include "ash/display/output_configurator_animation.h" | 42 #include "ash/display/output_configurator_animation.h" |
| 46 #include "chromeos/display/output_configurator.h" | 43 #include "chromeos/display/output_configurator.h" |
| 47 #include "ui/base/x/x11_util.h" | 44 #include "ui/base/x/x11_util.h" |
| 48 #include "ui/gfx/x/x11_types.h" | 45 #include "ui/gfx/x/x11_types.h" |
| 49 | 46 |
| 50 // Including this at the bottom to avoid other | 47 // Including this at the bottom to avoid other |
| 51 // potential conflict with chrome headers. | 48 // potential conflict with chrome headers. |
| 52 #include <X11/extensions/Xrandr.h> | 49 #include <X11/extensions/Xrandr.h> |
| 53 #undef RootWindow | 50 #undef RootWindow |
| 54 #endif // defined(USE_X11) | 51 #endif // defined(USE_X11) |
| 55 #endif // defined(OS_CHROMEOS) | 52 #endif // defined(OS_CHROMEOS) |
| 56 | 53 |
| 57 namespace ash { | 54 namespace ash { |
| 58 namespace { | 55 namespace { |
| 59 | 56 |
| 60 // Primary display stored in global object as it can be | 57 // Primary display stored in global object as it can be |
| 61 // accessed after Shell is deleted. A separate display instance is created | 58 // accessed after Shell is deleted. A separate display instance is created |
| 62 // during the shutdown instead of always keeping two display instances | 59 // during the shutdown instead of always keeping two display instances |
| 63 // (one here and another one in display_manager) in sync, which is error prone. | 60 // (one here and another one in display_manager) in sync, which is error prone. |
| 64 int64 primary_display_id = gfx::Display::kInvalidDisplayID; | 61 int64 primary_display_id = gfx::Display::kInvalidDisplayID; |
| 65 gfx::Display* primary_display_for_shutdown = NULL; | |
| 66 // Keeps the number of displays during the shutdown after | |
| 67 // ash::Shell:: is deleted. | |
| 68 int num_displays_for_shutdown = -1; | |
| 69 | 62 |
| 70 // Specifies how long the display change should have been disabled | 63 // Specifies how long the display change should have been disabled |
| 71 // after each display change operations. | 64 // after each display change operations. |
| 72 // |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid | 65 // |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid |
| 73 // changing the settings while the system is still configurating | 66 // changing the settings while the system is still configurating |
| 74 // displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs| | 67 // displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs| |
| 75 // when the display change happens, so the actual timeout is much shorter. | 68 // when the display change happens, so the actual timeout is much shorter. |
| 76 const int64 kAfterDisplayChangeThrottleTimeoutMs = 500; | 69 const int64 kAfterDisplayChangeThrottleTimeoutMs = 500; |
| 77 const int64 kCycleDisplayThrottleTimeoutMs = 4000; | 70 const int64 kCycleDisplayThrottleTimeoutMs = 4000; |
| 78 const int64 kSwapDisplayThrottleTimeoutMs = 500; | 71 const int64 kSwapDisplayThrottleTimeoutMs = 500; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 new internal::VirtualKeyboardWindowController) { | 220 new internal::VirtualKeyboardWindowController) { |
| 228 #if defined(OS_CHROMEOS) | 221 #if defined(OS_CHROMEOS) |
| 229 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 222 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 230 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && | 223 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && |
| 231 base::SysInfo::IsRunningOnChromeOS()) | 224 base::SysInfo::IsRunningOnChromeOS()) |
| 232 limiter_.reset(new DisplayChangeLimiter); | 225 limiter_.reset(new DisplayChangeLimiter); |
| 233 #endif | 226 #endif |
| 234 // Reset primary display to make sure that tests don't use | 227 // Reset primary display to make sure that tests don't use |
| 235 // stale display info from previous tests. | 228 // stale display info from previous tests. |
| 236 primary_display_id = gfx::Display::kInvalidDisplayID; | 229 primary_display_id = gfx::Display::kInvalidDisplayID; |
| 237 delete primary_display_for_shutdown; | |
| 238 primary_display_for_shutdown = NULL; | |
| 239 num_displays_for_shutdown = -1; | |
| 240 } | 230 } |
| 241 | 231 |
| 242 DisplayController::~DisplayController() { | 232 DisplayController::~DisplayController() { |
| 243 DCHECK(primary_display_for_shutdown); | |
| 244 } | 233 } |
| 245 | 234 |
| 246 void DisplayController::Start() { | 235 void DisplayController::Start() { |
| 247 Shell::GetScreen()->AddObserver(this); | 236 Shell::GetScreen()->AddObserver(this); |
| 248 Shell::GetInstance()->display_manager()->set_delegate(this); | 237 Shell::GetInstance()->display_manager()->set_delegate(this); |
| 249 } | 238 } |
| 250 | 239 |
| 251 void DisplayController::Shutdown() { | 240 void DisplayController::Shutdown() { |
| 252 // Unset the display manager's delegate here because | 241 // Unset the display manager's delegate here because |
| 253 // DisplayManager outlives DisplayController. | 242 // DisplayManager outlives DisplayController. |
| 254 Shell::GetInstance()->display_manager()->set_delegate(NULL); | 243 Shell::GetInstance()->display_manager()->set_delegate(NULL); |
| 255 | 244 |
| 256 mirror_window_controller_.reset(); | 245 mirror_window_controller_.reset(); |
| 257 virtual_keyboard_window_controller_.reset(); | 246 virtual_keyboard_window_controller_.reset(); |
| 258 | 247 |
| 259 DCHECK(!primary_display_for_shutdown); | |
| 260 primary_display_for_shutdown = new gfx::Display( | |
| 261 GetDisplayManager()->GetDisplayForId(primary_display_id)); | |
| 262 num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); | |
| 263 | |
| 264 Shell::GetScreen()->RemoveObserver(this); | 248 Shell::GetScreen()->RemoveObserver(this); |
| 265 // Delete all root window controllers, which deletes root window | 249 // Delete all root window controllers, which deletes root window |
| 266 // from the last so that the primary root window gets deleted last. | 250 // from the last so that the primary root window gets deleted last. |
| 267 for (std::map<int64, aura::Window*>::const_reverse_iterator it = | 251 for (std::map<int64, aura::Window*>::const_reverse_iterator it = |
| 268 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { | 252 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { |
| 269 internal::RootWindowController* controller = | 253 internal::RootWindowController* controller = |
| 270 internal::GetRootWindowController(it->second); | 254 internal::GetRootWindowController(it->second); |
| 271 DCHECK(controller); | 255 DCHECK(controller); |
| 272 delete controller; | 256 delete controller; |
| 273 } | 257 } |
| 274 } | 258 } |
| 275 | 259 |
| 276 // static | |
| 277 const gfx::Display& DisplayController::GetPrimaryDisplay() { | |
| 278 DCHECK_NE(primary_display_id, gfx::Display::kInvalidDisplayID); | |
| 279 if (primary_display_for_shutdown) | |
| 280 return *primary_display_for_shutdown; | |
| 281 return GetDisplayManager()->GetDisplayForId(primary_display_id); | |
| 282 } | |
| 283 | |
| 284 // static | |
| 285 int DisplayController::GetNumDisplays() { | |
| 286 if (num_displays_for_shutdown >= 0) | |
| 287 return num_displays_for_shutdown; | |
| 288 return GetDisplayManager()->GetNumDisplays(); | |
| 289 } | |
| 290 | |
| 291 void DisplayController::InitPrimaryDisplay() { | 260 void DisplayController::InitPrimaryDisplay() { |
| 292 const gfx::Display& primary_candidate = | 261 const gfx::Display& primary_candidate = |
| 293 GetDisplayManager()->GetPrimaryDisplayCandidate(); | 262 GetDisplayManager()->GetPrimaryDisplayCandidate(); |
| 294 primary_display_id = primary_candidate.id(); | 263 primary_display_id = primary_candidate.id(); |
| 295 AddRootWindowForDisplay(primary_candidate); | 264 AddRootWindowForDisplay(primary_candidate); |
| 296 } | 265 } |
| 297 | 266 |
| 298 void DisplayController::InitSecondaryDisplays() { | 267 void DisplayController::InitSecondaryDisplays() { |
| 299 internal::DisplayManager* display_manager = GetDisplayManager(); | 268 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 300 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { | 269 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { |
| 301 const gfx::Display& display = display_manager->GetDisplayAt(i); | 270 const gfx::Display& display = display_manager->GetDisplayAt(i); |
| 302 if (primary_display_id != display.id()) { | 271 if (primary_display_id != display.id()) { |
| 303 aura::RootWindow* root = AddRootWindowForDisplay(display); | 272 aura::RootWindow* root = AddRootWindowForDisplay(display); |
| 304 internal::RootWindowController::CreateForSecondaryDisplay(root); | 273 internal::RootWindowController::CreateForSecondaryDisplay(root); |
| 305 } | 274 } |
| 306 } | 275 } |
| 307 UpdateHostWindowNames(); | 276 UpdateHostWindowNames(); |
| 308 } | 277 } |
| 309 | 278 |
| 310 void DisplayController::AddObserver(Observer* observer) { | 279 void DisplayController::AddObserver(Observer* observer) { |
| 311 observers_.AddObserver(observer); | 280 observers_.AddObserver(observer); |
| 312 } | 281 } |
| 313 | 282 |
| 314 void DisplayController::RemoveObserver(Observer* observer) { | 283 void DisplayController::RemoveObserver(Observer* observer) { |
| 315 observers_.RemoveObserver(observer); | 284 observers_.RemoveObserver(observer); |
| 316 } | 285 } |
| 317 | 286 |
| 287 // static |
| 288 int64 DisplayController::GetPrimaryDisplayId() { |
| 289 return primary_display_id; |
| 290 } |
| 291 |
| 318 aura::Window* DisplayController::GetPrimaryRootWindow() { | 292 aura::Window* DisplayController::GetPrimaryRootWindow() { |
| 319 DCHECK(!root_windows_.empty()); | 293 DCHECK(!root_windows_.empty()); |
| 320 return root_windows_[primary_display_id]; | 294 return root_windows_[primary_display_id]; |
| 321 } | 295 } |
| 322 | 296 |
| 323 aura::Window* DisplayController::GetRootWindowForDisplayId(int64 id) { | 297 aura::Window* DisplayController::GetRootWindowForDisplayId(int64 id) { |
| 324 return root_windows_[id]; | 298 return root_windows_[id]; |
| 325 } | 299 } |
| 326 | 300 |
| 327 void DisplayController::CloseChildWindows() { | 301 void DisplayController::CloseChildWindows() { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 378 |
| 405 if (Shell::GetScreen()->GetNumDisplays() > 1) { | 379 if (Shell::GetScreen()->GetNumDisplays() > 1) { |
| 406 #if defined(OS_CHROMEOS) && defined(USE_X11) | 380 #if defined(OS_CHROMEOS) && defined(USE_X11) |
| 407 internal::OutputConfiguratorAnimation* animation = | 381 internal::OutputConfiguratorAnimation* animation = |
| 408 Shell::GetInstance()->output_configurator_animation(); | 382 Shell::GetInstance()->output_configurator_animation(); |
| 409 if (animation) { | 383 if (animation) { |
| 410 animation->StartFadeOutAnimation(base::Bind( | 384 animation->StartFadeOutAnimation(base::Bind( |
| 411 &DisplayController::OnFadeOutForSwapDisplayFinished, | 385 &DisplayController::OnFadeOutForSwapDisplayFinished, |
| 412 base::Unretained(this))); | 386 base::Unretained(this))); |
| 413 } else { | 387 } else { |
| 414 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 388 SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); |
| 415 } | 389 } |
| 416 #else | 390 #else |
| 417 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 391 SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); |
| 418 #endif | 392 #endif |
| 419 } | 393 } |
| 420 } | 394 } |
| 421 | 395 |
| 422 void DisplayController::SetPrimaryDisplayId(int64 id) { | 396 void DisplayController::SetPrimaryDisplayId(int64 id) { |
| 423 DCHECK_NE(gfx::Display::kInvalidDisplayID, id); | 397 DCHECK_NE(gfx::Display::kInvalidDisplayID, id); |
| 424 if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id) | 398 if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id) |
| 425 return; | 399 return; |
| 426 | 400 |
| 427 const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id); | 401 const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 447 return; | 421 return; |
| 448 } | 422 } |
| 449 | 423 |
| 450 aura::Window* non_primary_root = root_windows_[new_primary_display.id()]; | 424 aura::Window* non_primary_root = root_windows_[new_primary_display.id()]; |
| 451 LOG_IF(ERROR, !non_primary_root) | 425 LOG_IF(ERROR, !non_primary_root) |
| 452 << "Unknown display is requested in SetPrimaryDisplay: id=" | 426 << "Unknown display is requested in SetPrimaryDisplay: id=" |
| 453 << new_primary_display.id(); | 427 << new_primary_display.id(); |
| 454 if (!non_primary_root) | 428 if (!non_primary_root) |
| 455 return; | 429 return; |
| 456 | 430 |
| 457 gfx::Display old_primary_display = GetPrimaryDisplay(); | 431 gfx::Display old_primary_display = Shell::GetScreen()->GetPrimaryDisplay(); |
| 458 | 432 |
| 459 // Swap root windows between current and new primary display. | 433 // Swap root windows between current and new primary display. |
| 460 aura::Window* primary_root = root_windows_[primary_display_id]; | 434 aura::Window* primary_root = root_windows_[primary_display_id]; |
| 461 DCHECK(primary_root); | 435 DCHECK(primary_root); |
| 462 DCHECK_NE(primary_root, non_primary_root); | 436 DCHECK_NE(primary_root, non_primary_root); |
| 463 | 437 |
| 464 root_windows_[new_primary_display.id()] = primary_root; | 438 root_windows_[new_primary_display.id()] = primary_root; |
| 465 internal::GetRootWindowSettings(primary_root)->display_id = | 439 internal::GetRootWindowSettings(primary_root)->display_id = |
| 466 new_primary_display.id(); | 440 new_primary_display.id(); |
| 467 | 441 |
| 468 root_windows_[old_primary_display.id()] = non_primary_root; | 442 root_windows_[old_primary_display.id()] = non_primary_root; |
| 469 internal::GetRootWindowSettings(non_primary_root)->display_id = | 443 internal::GetRootWindowSettings(non_primary_root)->display_id = |
| 470 old_primary_display.id(); | 444 old_primary_display.id(); |
| 471 | 445 |
| 472 primary_display_id = new_primary_display.id(); | 446 primary_display_id = new_primary_display.id(); |
| 473 GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( | 447 GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( |
| 474 display_manager->GetCurrentDisplayIdPair(), primary_display_id); | 448 display_manager->GetCurrentDisplayIdPair(), primary_display_id); |
| 475 | 449 |
| 476 UpdateWorkAreaOfDisplayNearestWindow( | 450 UpdateWorkAreaOfDisplayNearestWindow( |
| 477 primary_root, old_primary_display.GetWorkAreaInsets()); | 451 primary_root, old_primary_display.GetWorkAreaInsets()); |
| 478 UpdateWorkAreaOfDisplayNearestWindow( | 452 UpdateWorkAreaOfDisplayNearestWindow( |
| 479 non_primary_root, new_primary_display.GetWorkAreaInsets()); | 453 non_primary_root, new_primary_display.GetWorkAreaInsets()); |
| 480 | 454 |
| 481 // Update the dispay manager with new display info. | 455 // Update the dispay manager with new display info. |
| 482 std::vector<internal::DisplayInfo> display_info_list; | 456 std::vector<internal::DisplayInfo> display_info_list; |
| 483 display_info_list.push_back(display_manager->GetDisplayInfo( | 457 display_info_list.push_back(display_manager->GetDisplayInfo( |
| 484 primary_display_id)); | 458 primary_display_id)); |
| 485 display_info_list.push_back(display_manager->GetDisplayInfo( | 459 display_info_list.push_back(display_manager->GetDisplayInfo( |
| 486 ScreenAsh::GetSecondaryDisplay().id())); | 460 ScreenUtil::GetSecondaryDisplay().id())); |
| 487 GetDisplayManager()->set_force_bounds_changed(true); | 461 GetDisplayManager()->set_force_bounds_changed(true); |
| 488 GetDisplayManager()->UpdateDisplays(display_info_list); | 462 GetDisplayManager()->UpdateDisplays(display_info_list); |
| 489 GetDisplayManager()->set_force_bounds_changed(false); | 463 GetDisplayManager()->set_force_bounds_changed(false); |
| 490 } | 464 } |
| 491 | 465 |
| 492 void DisplayController::EnsurePointerInDisplays() { | 466 void DisplayController::EnsurePointerInDisplays() { |
| 493 // If the mouse is currently on a display in native location, | 467 // If the mouse is currently on a display in native location, |
| 494 // use the same native location. Otherwise find the display closest | 468 // use the same native location. Otherwise find the display closest |
| 495 // to the current cursor location in screen coordinates. | 469 // to the current cursor location in screen coordinates. |
| 496 | 470 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 bool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( | 513 bool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( |
| 540 const aura::Window* window, | 514 const aura::Window* window, |
| 541 const gfx::Insets& insets) { | 515 const gfx::Insets& insets) { |
| 542 const aura::Window* root_window = window->GetRootWindow(); | 516 const aura::Window* root_window = window->GetRootWindow(); |
| 543 int64 id = internal::GetRootWindowSettings(root_window)->display_id; | 517 int64 id = internal::GetRootWindowSettings(root_window)->display_id; |
| 544 // if id is |kInvaildDisplayID|, it's being deleted. | 518 // if id is |kInvaildDisplayID|, it's being deleted. |
| 545 DCHECK(id != gfx::Display::kInvalidDisplayID); | 519 DCHECK(id != gfx::Display::kInvalidDisplayID); |
| 546 return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); | 520 return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); |
| 547 } | 521 } |
| 548 | 522 |
| 549 const gfx::Display& DisplayController::GetDisplayNearestWindow( | |
| 550 const aura::Window* window) const { | |
| 551 if (!window) | |
| 552 return GetPrimaryDisplay(); | |
| 553 const aura::Window* root_window = window->GetRootWindow(); | |
| 554 if (!root_window) | |
| 555 return GetPrimaryDisplay(); | |
| 556 int64 id = internal::GetRootWindowSettings(root_window)->display_id; | |
| 557 // if id is |kInvaildDisplayID|, it's being deleted. | |
| 558 DCHECK(id != gfx::Display::kInvalidDisplayID); | |
| 559 | |
| 560 internal::DisplayManager* display_manager = GetDisplayManager(); | |
| 561 // RootWindow needs Display to determine its device scale factor | |
| 562 // for non desktop display. | |
| 563 if (display_manager->non_desktop_display().id() == id) | |
| 564 return display_manager->non_desktop_display(); | |
| 565 return display_manager->GetDisplayForId(id); | |
| 566 } | |
| 567 | |
| 568 const gfx::Display& DisplayController::GetDisplayNearestPoint( | |
| 569 const gfx::Point& point) const { | |
| 570 const gfx::Display& display = | |
| 571 GetDisplayManager()->FindDisplayContainingPoint(point); | |
| 572 if (display.is_valid()) | |
| 573 return display; | |
| 574 | |
| 575 // Fallback to the display that has the shortest Manhattan distance from | |
| 576 // the |point|. This is correct in the only areas that matter, namely in the | |
| 577 // corners between the physical screens. | |
| 578 int min_distance = INT_MAX; | |
| 579 const gfx::Display* nearest_display = NULL; | |
| 580 for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { | |
| 581 const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); | |
| 582 int distance = display.bounds().ManhattanDistanceToPoint(point); | |
| 583 if (distance < min_distance) { | |
| 584 min_distance = distance; | |
| 585 nearest_display = &display; | |
| 586 } | |
| 587 } | |
| 588 // There should always be at least one display that is less than INT_MAX away. | |
| 589 DCHECK(nearest_display); | |
| 590 return *nearest_display; | |
| 591 } | |
| 592 | |
| 593 const gfx::Display& DisplayController::GetDisplayMatching( | |
| 594 const gfx::Rect& rect) const { | |
| 595 if (rect.IsEmpty()) | |
| 596 return GetDisplayNearestPoint(rect.origin()); | |
| 597 | |
| 598 int max_area = 0; | |
| 599 const gfx::Display* matching = NULL; | |
| 600 for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { | |
| 601 const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); | |
| 602 gfx::Rect intersect = gfx::IntersectRects(display.bounds(), rect); | |
| 603 int area = intersect.width() * intersect.height(); | |
| 604 if (area > max_area) { | |
| 605 max_area = area; | |
| 606 matching = &display; | |
| 607 } | |
| 608 } | |
| 609 // Fallback to the primary display if there is no matching display. | |
| 610 return matching ? *matching : GetPrimaryDisplay(); | |
| 611 } | |
| 612 | |
| 613 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { | 523 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { |
| 614 const internal::DisplayInfo& display_info = | 524 const internal::DisplayInfo& display_info = |
| 615 GetDisplayManager()->GetDisplayInfo(display.id()); | 525 GetDisplayManager()->GetDisplayInfo(display.id()); |
| 616 DCHECK(!display_info.bounds_in_native().IsEmpty()); | 526 DCHECK(!display_info.bounds_in_native().IsEmpty()); |
| 617 aura::WindowEventDispatcher* dispatcher = | 527 aura::WindowEventDispatcher* dispatcher = |
| 618 root_windows_[display.id()]->GetDispatcher(); | 528 root_windows_[display.id()]->GetDispatcher(); |
| 619 dispatcher->host()->SetBounds(display_info.bounds_in_native()); | 529 dispatcher->host()->SetBounds(display_info.bounds_in_native()); |
| 620 SetDisplayPropertiesOnHostWindow(dispatcher, display); | 530 SetDisplayPropertiesOnHostWindow(dispatcher, display); |
| 621 } | 531 } |
| 622 | 532 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 // root to the other display. | 565 // root to the other display. |
| 656 if (primary_display_id == display.id()) { | 566 if (primary_display_id == display.id()) { |
| 657 // Temporarily store the primary root window in | 567 // Temporarily store the primary root window in |
| 658 // |primary_root_window_for_replace_| when replacing the display. | 568 // |primary_root_window_for_replace_| when replacing the display. |
| 659 if (root_windows_.size() == 0) { | 569 if (root_windows_.size() == 0) { |
| 660 primary_display_id = gfx::Display::kInvalidDisplayID; | 570 primary_display_id = gfx::Display::kInvalidDisplayID; |
| 661 primary_root_window_for_replace_ = root_to_delete; | 571 primary_root_window_for_replace_ = root_to_delete; |
| 662 return; | 572 return; |
| 663 } | 573 } |
| 664 DCHECK_EQ(1U, root_windows_.size()); | 574 DCHECK_EQ(1U, root_windows_.size()); |
| 665 primary_display_id = ScreenAsh::GetSecondaryDisplay().id(); | 575 primary_display_id = ScreenUtil::GetSecondaryDisplay().id(); |
| 666 aura::Window* primary_root = root_to_delete; | 576 aura::Window* primary_root = root_to_delete; |
| 667 | 577 |
| 668 // Delete the other root instead. | 578 // Delete the other root instead. |
| 669 root_to_delete = root_windows_[primary_display_id]; | 579 root_to_delete = root_windows_[primary_display_id]; |
| 670 internal::GetRootWindowSettings(root_to_delete)->display_id = display.id(); | 580 internal::GetRootWindowSettings(root_to_delete)->display_id = display.id(); |
| 671 | 581 |
| 672 // Setup primary root. | 582 // Setup primary root. |
| 673 root_windows_[primary_display_id] = primary_root; | 583 root_windows_[primary_display_id] = primary_root; |
| 674 internal::GetRootWindowSettings(primary_root)->display_id = | 584 internal::GetRootWindowSettings(primary_root)->display_id = |
| 675 primary_display_id; | 585 primary_display_id; |
| 676 | 586 |
| 677 OnDisplayBoundsChanged( | 587 OnDisplayBoundsChanged( |
| 678 GetDisplayManager()->GetDisplayForId(primary_display_id)); | 588 GetDisplayManager()->GetDisplayForId(primary_display_id)); |
| 679 } | 589 } |
| 680 internal::RootWindowController* controller = | 590 internal::RootWindowController* controller = |
| 681 internal::GetRootWindowController(root_to_delete); | 591 internal::GetRootWindowController(root_to_delete); |
| 682 DCHECK(controller); | 592 DCHECK(controller); |
| 683 controller->MoveWindowsTo(GetPrimaryRootWindow()); | 593 controller->MoveWindowsTo(GetPrimaryRootWindow()); |
| 684 // Delete most of root window related objects, but don't delete | 594 // Delete most of root window related objects, but don't delete |
| 685 // root window itself yet because the stack may be using it. | 595 // root window itself yet because the stack may be using it. |
| 686 controller->Shutdown(); | 596 controller->Shutdown(); |
| 687 base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller); | 597 base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller); |
| 688 } | 598 } |
| 689 | 599 |
| 690 void DisplayController::OnWindowTreeHostResized(const aura::RootWindow* root) { | 600 void DisplayController::OnWindowTreeHostResized(const aura::RootWindow* root) { |
| 601 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( |
| 602 const_cast<aura::Window*>(root->window())); |
| 603 |
| 691 internal::DisplayManager* display_manager = GetDisplayManager(); | 604 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 692 gfx::Display display = GetDisplayNearestWindow(root->window()); | |
| 693 if (display_manager->UpdateDisplayBounds( | 605 if (display_manager->UpdateDisplayBounds( |
| 694 display.id(), | 606 display.id(), |
| 695 root->host()->GetBounds())) { | 607 root->host()->GetBounds())) { |
| 696 mirror_window_controller_->UpdateWindow(); | 608 mirror_window_controller_->UpdateWindow(); |
| 697 } | 609 } |
| 698 } | 610 } |
| 699 | 611 |
| 700 void DisplayController::CreateOrUpdateNonDesktopDisplay( | 612 void DisplayController::CreateOrUpdateNonDesktopDisplay( |
| 701 const internal::DisplayInfo& info) { | 613 const internal::DisplayInfo& info) { |
| 702 switch (GetDisplayManager()->second_display_mode()) { | 614 switch (GetDisplayManager()->second_display_mode()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 714 } | 626 } |
| 715 | 627 |
| 716 void DisplayController::CloseNonDesktopDisplay() { | 628 void DisplayController::CloseNonDesktopDisplay() { |
| 717 mirror_window_controller_->Close(); | 629 mirror_window_controller_->Close(); |
| 718 virtual_keyboard_window_controller_->Close(); | 630 virtual_keyboard_window_controller_->Close(); |
| 719 } | 631 } |
| 720 | 632 |
| 721 void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { | 633 void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { |
| 722 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); | 634 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); |
| 723 focus_activation_store_->Store(clear_focus); | 635 focus_activation_store_->Store(clear_focus); |
| 724 | 636 gfx::Screen* screen = Shell::GetScreen(); |
| 725 gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); | 637 gfx::Point point_in_screen = screen->GetCursorScreenPoint(); |
| 726 gfx::Display display = GetDisplayNearestPoint(point_in_screen); | 638 gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); |
| 727 aura::Window* root_window = GetRootWindowForDisplayId(display.id()); | 639 aura::Window* root_window = GetRootWindowForDisplayId(display.id()); |
| 728 | 640 |
| 729 aura::client::ScreenPositionClient* client = | 641 aura::client::ScreenPositionClient* client = |
| 730 aura::client::GetScreenPositionClient(root_window); | 642 aura::client::GetScreenPositionClient(root_window); |
| 731 client->ConvertPointFromScreen(root_window, &point_in_screen); | 643 client->ConvertPointFromScreen(root_window, &point_in_screen); |
| 732 root_window->GetDispatcher()->host()->ConvertPointToNativeScreen( | 644 root_window->GetDispatcher()->host()->ConvertPointToNativeScreen( |
| 733 &point_in_screen); | 645 &point_in_screen); |
| 734 cursor_location_in_native_coords_for_restore_ = point_in_screen; | 646 cursor_location_in_native_coords_for_restore_ = point_in_screen; |
| 735 } | 647 } |
| 736 | 648 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 749 | 661 |
| 750 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { | 662 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { |
| 751 int64 primary_id = layout.primary_id; | 663 int64 primary_id = layout.primary_id; |
| 752 SetPrimaryDisplayId( | 664 SetPrimaryDisplayId( |
| 753 primary_id == gfx::Display::kInvalidDisplayID ? | 665 primary_id == gfx::Display::kInvalidDisplayID ? |
| 754 pair.first : primary_id); | 666 pair.first : primary_id); |
| 755 // Update the primary_id in case the above call is | 667 // Update the primary_id in case the above call is |
| 756 // ignored. Happens when a) default layout's primary id | 668 // ignored. Happens when a) default layout's primary id |
| 757 // doesn't exist, or b) the primary_id has already been | 669 // doesn't exist, or b) the primary_id has already been |
| 758 // set to the same and didn't update it. | 670 // set to the same and didn't update it. |
| 759 layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); | 671 layout_store->UpdatePrimaryDisplayId( |
| 672 pair, Shell::GetScreen()->GetPrimaryDisplay().id()); |
| 760 } | 673 } |
| 761 } | 674 } |
| 762 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); | 675 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); |
| 763 UpdateHostWindowNames(); | 676 UpdateHostWindowNames(); |
| 764 EnsurePointerInDisplays(); | 677 EnsurePointerInDisplays(); |
| 765 } | 678 } |
| 766 | 679 |
| 767 aura::RootWindow* DisplayController::AddRootWindowForDisplay( | 680 aura::RootWindow* DisplayController::AddRootWindowForDisplay( |
| 768 const gfx::Display& display) { | 681 const gfx::Display& display) { |
| 769 static int root_window_count = 0; | 682 static int root_window_count = 0; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 792 CommandLine::ForCurrentProcess()->HasSwitch( | 705 CommandLine::ForCurrentProcess()->HasSwitch( |
| 793 switches::kAshConstrainPointerToRoot); | 706 switches::kAshConstrainPointerToRoot); |
| 794 if (base::SysInfo::IsRunningOnChromeOS() || force_constrain_pointer_to_root) | 707 if (base::SysInfo::IsRunningOnChromeOS() || force_constrain_pointer_to_root) |
| 795 root_window->host()->ConfineCursorToRootWindow(); | 708 root_window->host()->ConfineCursorToRootWindow(); |
| 796 #endif | 709 #endif |
| 797 return root_window; | 710 return root_window; |
| 798 } | 711 } |
| 799 | 712 |
| 800 void DisplayController::OnFadeOutForSwapDisplayFinished() { | 713 void DisplayController::OnFadeOutForSwapDisplayFinished() { |
| 801 #if defined(OS_CHROMEOS) && defined(USE_X11) | 714 #if defined(OS_CHROMEOS) && defined(USE_X11) |
| 802 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 715 SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); |
| 803 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); | 716 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); |
| 804 #endif | 717 #endif |
| 805 } | 718 } |
| 806 | 719 |
| 807 void DisplayController::UpdateHostWindowNames() { | 720 void DisplayController::UpdateHostWindowNames() { |
| 808 #if defined(USE_X11) | 721 #if defined(USE_X11) |
| 809 // crbug.com/120229 - set the window title for the primary dislpay | 722 // crbug.com/120229 - set the window title for the primary dislpay |
| 810 // to "aura_root_0" so gtalk can find the primary root window to broadcast. | 723 // to "aura_root_0" so gtalk can find the primary root window to broadcast. |
| 811 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. | 724 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. |
| 812 aura::Window* primary = Shell::GetPrimaryRootWindow(); | 725 aura::Window* primary = Shell::GetPrimaryRootWindow(); |
| 813 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 726 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 814 for (size_t i = 0; i < root_windows.size(); ++i) { | 727 for (size_t i = 0; i < root_windows.size(); ++i) { |
| 815 std::string name = | 728 std::string name = |
| 816 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; | 729 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; |
| 817 gfx::AcceleratedWidget xwindow = | 730 gfx::AcceleratedWidget xwindow = |
| 818 root_windows[i]->GetDispatcher()->host()->GetAcceleratedWidget(); | 731 root_windows[i]->GetDispatcher()->host()->GetAcceleratedWidget(); |
| 819 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); | 732 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); |
| 820 } | 733 } |
| 821 #endif | 734 #endif |
| 822 } | 735 } |
| 823 | 736 |
| 824 } // namespace ash | 737 } // namespace ash |
| OLD | NEW |