Chromium Code Reviews| 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_manager.h" | 13 #include "ash/display/display_manager.h" |
| 13 #include "ash/display/root_window_transformers.h" | 14 #include "ash/display/root_window_transformers.h" |
| 14 #include "ash/host/root_window_host_factory.h" | 15 #include "ash/host/root_window_host_factory.h" |
| 15 #include "ash/root_window_controller.h" | 16 #include "ash/root_window_controller.h" |
| 16 #include "ash/screen_ash.h" | 17 #include "ash/screen_ash.h" |
| 17 #include "ash/shell.h" | 18 #include "ash/shell.h" |
| 18 #include "ash/wm/coordinate_conversion.h" | 19 #include "ash/wm/coordinate_conversion.h" |
| 19 #include "ash/wm/property_util.h" | 20 #include "ash/wm/property_util.h" |
| 20 #include "ash/wm/window_util.h" | 21 #include "ash/wm/window_util.h" |
| 21 #include "base/command_line.h" | 22 #include "base/command_line.h" |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 DisplayController::DisplayController() | 217 DisplayController::DisplayController() |
| 217 : primary_root_window_for_replace_(NULL), | 218 : primary_root_window_for_replace_(NULL), |
| 218 in_bootstrap_(true), | 219 in_bootstrap_(true), |
| 219 focus_activation_store_(new internal::FocusActivationStore()) { | 220 focus_activation_store_(new internal::FocusActivationStore()) { |
| 220 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 221 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 221 #if defined(OS_CHROMEOS) | 222 #if defined(OS_CHROMEOS) |
| 222 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && | 223 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && |
| 223 base::chromeos::IsRunningOnChromeOS()) | 224 base::chromeos::IsRunningOnChromeOS()) |
| 224 limiter_.reset(new DisplayChangeLimiter); | 225 limiter_.reset(new DisplayChangeLimiter); |
| 225 #endif | 226 #endif |
| 226 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { | |
| 227 std::string value = command_line->GetSwitchValueASCII( | |
| 228 switches::kAshSecondaryDisplayLayout); | |
| 229 char layout; | |
| 230 int offset = 0; | |
| 231 if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) { | |
| 232 if (layout == 't') | |
| 233 default_display_layout_.position = DisplayLayout::TOP; | |
| 234 else if (layout == 'b') | |
| 235 default_display_layout_.position = DisplayLayout::BOTTOM; | |
| 236 else if (layout == 'r') | |
| 237 default_display_layout_.position = DisplayLayout::RIGHT; | |
| 238 else if (layout == 'l') | |
| 239 default_display_layout_.position = DisplayLayout::LEFT; | |
| 240 default_display_layout_.offset = offset; | |
| 241 } | |
| 242 } | |
| 243 // Reset primary display to make sure that tests don't use | 227 // Reset primary display to make sure that tests don't use |
| 244 // stale display info from previous tests. | 228 // stale display info from previous tests. |
| 245 primary_display_id = gfx::Display::kInvalidDisplayID; | 229 primary_display_id = gfx::Display::kInvalidDisplayID; |
| 246 delete primary_display_for_shutdown; | 230 delete primary_display_for_shutdown; |
| 247 primary_display_for_shutdown = NULL; | 231 primary_display_for_shutdown = NULL; |
| 248 num_displays_for_shutdown = -1; | 232 num_displays_for_shutdown = -1; |
| 249 } | 233 } |
| 250 | 234 |
| 251 DisplayController::~DisplayController() { | 235 DisplayController::~DisplayController() { |
| 252 DCHECK(primary_display_for_shutdown); | 236 DCHECK(primary_display_for_shutdown); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 for (std::map<int64, aura::RootWindow*>::const_iterator it = | 366 for (std::map<int64, aura::RootWindow*>::const_iterator it = |
| 383 root_windows_.begin(); it != root_windows_.end(); ++it) { | 367 root_windows_.begin(); it != root_windows_.end(); ++it) { |
| 384 internal::RootWindowController* controller = | 368 internal::RootWindowController* controller = |
| 385 GetRootWindowController(it->second); | 369 GetRootWindowController(it->second); |
| 386 if (controller) | 370 if (controller) |
| 387 controllers.push_back(controller); | 371 controllers.push_back(controller); |
| 388 } | 372 } |
| 389 return controllers; | 373 return controllers; |
| 390 } | 374 } |
| 391 | 375 |
| 392 void DisplayController::SetDefaultDisplayLayout(const DisplayLayout& layout) { | |
| 393 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 394 if (!command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) | |
| 395 default_display_layout_ = layout; | |
| 396 } | |
| 397 | |
| 398 void DisplayController::RegisterLayoutForDisplayIdPair( | |
| 399 int64 id1, | |
| 400 int64 id2, | |
| 401 const DisplayLayout& layout) { | |
| 402 RegisterLayoutForDisplayIdPairInternal(id1, id2, layout, true); | |
| 403 } | |
| 404 | |
| 405 void DisplayController::SetLayoutForCurrentDisplays( | 376 void DisplayController::SetLayoutForCurrentDisplays( |
| 406 const DisplayLayout& layout_relative_to_primary) { | 377 const DisplayLayout& layout_relative_to_primary) { |
| 407 DCHECK_EQ(2U, GetDisplayManager()->GetNumDisplays()); | 378 DCHECK_EQ(2U, GetDisplayManager()->GetNumDisplays()); |
| 408 if (GetDisplayManager()->GetNumDisplays() < 2) | 379 if (GetDisplayManager()->GetNumDisplays() < 2) |
| 409 return; | 380 return; |
| 410 const gfx::Display& primary = GetPrimaryDisplay(); | 381 const gfx::Display& primary = GetPrimaryDisplay(); |
| 411 const DisplayIdPair pair = GetCurrentDisplayIdPair(); | 382 const DisplayIdPair pair = GetCurrentDisplayIdPair(); |
| 412 // Invert if the primary was swapped. | 383 // Invert if the primary was swapped. |
| 413 DisplayLayout to_set = pair.first == primary.id() ? | 384 DisplayLayout to_set = pair.first == primary.id() ? |
| 414 layout_relative_to_primary : layout_relative_to_primary.Invert(); | 385 layout_relative_to_primary : layout_relative_to_primary.Invert(); |
| 415 | 386 |
| 416 const DisplayLayout& current_layout = paired_layouts_[pair]; | 387 internal::DisplayLayoutStore* layout_store = |
| 388 GetDisplayManager()->layout_store(); | |
| 389 DisplayLayout current_layout = | |
| 390 layout_store->GetRegisteredDisplayLayout(pair); | |
| 417 if (to_set.position != current_layout.position || | 391 if (to_set.position != current_layout.position || |
| 418 to_set.offset != current_layout.offset) { | 392 to_set.offset != current_layout.offset) { |
| 419 to_set.primary_id = primary.id(); | 393 to_set.primary_id = primary.id(); |
| 420 paired_layouts_[pair] = to_set; | 394 layout_store->RegisterLayoutForDisplayIdPair( |
| 395 pair.first, pair.second, to_set); | |
| 421 NotifyDisplayConfigurationChanging(); | 396 NotifyDisplayConfigurationChanging(); |
| 422 // TODO(oshima): Call UpdateDisplays instead. | 397 // TODO(oshima): Call UpdateDisplays instead. |
| 423 UpdateDisplayBoundsForLayout(); | 398 UpdateDisplayBoundsForLayout(); |
| 424 NotifyDisplayConfigurationChanged(); | 399 NotifyDisplayConfigurationChanged(); |
| 425 } | 400 } |
| 426 } | 401 } |
| 427 | 402 |
| 428 DisplayLayout DisplayController::GetCurrentDisplayLayout() { | 403 DisplayLayout DisplayController::GetCurrentDisplayLayout() { |
| 429 DCHECK_EQ(2U, GetDisplayManager()->num_connected_displays()); | 404 DCHECK_EQ(2U, GetDisplayManager()->num_connected_displays()); |
| 430 // Invert if the primary was swapped. | 405 // Invert if the primary was swapped. |
| 431 if (GetDisplayManager()->num_connected_displays() > 1) { | 406 if (GetDisplayManager()->num_connected_displays() > 1) { |
| 432 DisplayIdPair pair = GetCurrentDisplayIdPair(); | 407 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
| 433 return ComputeDisplayLayoutForDisplayIdPair(pair); | 408 return GetDisplayManager()->layout_store()-> |
| 409 ComputeDisplayLayoutForDisplayIdPair(pair); | |
| 434 } | 410 } |
| 435 // On release build, just fallback to default instead of blowing up. | 411 // On release build, just fallback to default instead of blowing up. |
| 436 DisplayLayout layout = default_display_layout_; | 412 DisplayLayout layout = |
| 413 GetDisplayManager()->layout_store()->default_display_layout(); | |
| 437 layout.primary_id = primary_display_id; | 414 layout.primary_id = primary_display_id; |
|
Jun Mukai
2013/07/09 16:54:17
can't we move this setting primary_display_id logi
oshima
2013/07/09 17:27:58
store doesn't know about the current primary (only
| |
| 438 return layout; | 415 return layout; |
| 439 } | 416 } |
| 440 | 417 |
| 441 DisplayIdPair DisplayController::GetCurrentDisplayIdPair() const { | 418 DisplayIdPair DisplayController::GetCurrentDisplayIdPair() const { |
| 442 internal::DisplayManager* display_manager = GetDisplayManager(); | 419 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 443 const gfx::Display& primary = GetPrimaryDisplay(); | 420 const gfx::Display& primary = GetPrimaryDisplay(); |
| 444 if (display_manager->IsMirrored()) { | 421 if (display_manager->IsMirrored()) { |
| 445 return std::make_pair(primary.id(), | 422 return std::make_pair(primary.id(), |
| 446 display_manager->mirrored_display().id()); | 423 display_manager->mirrored_display().id()); |
| 447 } | 424 } |
| 448 | 425 |
| 449 const gfx::Display& secondary = ScreenAsh::GetSecondaryDisplay(); | 426 const gfx::Display& secondary = ScreenAsh::GetSecondaryDisplay(); |
| 450 if (primary.IsInternal() || | 427 if (primary.IsInternal() || |
| 451 GetDisplayManager()->first_display_id() == primary.id()) { | 428 GetDisplayManager()->first_display_id() == primary.id()) { |
| 452 return std::make_pair(primary.id(), secondary.id()); | 429 return std::make_pair(primary.id(), secondary.id()); |
| 453 } else { | 430 } else { |
| 454 // Display has been Swapped. | 431 // Display has been Swapped. |
| 455 return std::make_pair(secondary.id(), primary.id()); | 432 return std::make_pair(secondary.id(), primary.id()); |
| 456 } | 433 } |
| 457 } | 434 } |
| 458 | 435 |
| 459 DisplayLayout DisplayController::GetRegisteredDisplayLayout( | |
| 460 const DisplayIdPair& pair) { | |
| 461 std::map<DisplayIdPair, DisplayLayout>::const_iterator iter = | |
| 462 paired_layouts_.find(pair); | |
| 463 return | |
| 464 iter != paired_layouts_.end() ? iter->second : CreateDisplayLayout(pair); | |
| 465 } | |
| 466 | |
| 467 void DisplayController::ToggleMirrorMode() { | 436 void DisplayController::ToggleMirrorMode() { |
| 468 internal::DisplayManager* display_manager = GetDisplayManager(); | 437 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 469 if (display_manager->num_connected_displays() <= 1) | 438 if (display_manager->num_connected_displays() <= 1) |
| 470 return; | 439 return; |
| 471 | 440 |
| 472 if (limiter_) { | 441 if (limiter_) { |
| 473 if (limiter_->IsThrottled()) | 442 if (limiter_->IsThrottled()) |
| 474 return; | 443 return; |
| 475 limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); | 444 limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); |
| 476 } | 445 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 DCHECK_NE(primary_root, non_primary_root); | 521 DCHECK_NE(primary_root, non_primary_root); |
| 553 | 522 |
| 554 root_windows_[new_primary_display.id()] = primary_root; | 523 root_windows_[new_primary_display.id()] = primary_root; |
| 555 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); | 524 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); |
| 556 | 525 |
| 557 root_windows_[old_primary_display.id()] = non_primary_root; | 526 root_windows_[old_primary_display.id()] = non_primary_root; |
| 558 non_primary_root->SetProperty(internal::kDisplayIdKey, | 527 non_primary_root->SetProperty(internal::kDisplayIdKey, |
| 559 old_primary_display.id()); | 528 old_primary_display.id()); |
| 560 | 529 |
| 561 primary_display_id = new_primary_display.id(); | 530 primary_display_id = new_primary_display.id(); |
| 562 paired_layouts_[GetCurrentDisplayIdPair()].primary_id = primary_display_id; | 531 GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( |
| 532 GetCurrentDisplayIdPair(), primary_display_id); | |
| 563 | 533 |
| 564 display_manager->UpdateWorkAreaOfDisplayNearestWindow( | 534 display_manager->UpdateWorkAreaOfDisplayNearestWindow( |
| 565 primary_root, old_primary_display.GetWorkAreaInsets()); | 535 primary_root, old_primary_display.GetWorkAreaInsets()); |
| 566 display_manager->UpdateWorkAreaOfDisplayNearestWindow( | 536 display_manager->UpdateWorkAreaOfDisplayNearestWindow( |
| 567 non_primary_root, new_primary_display.GetWorkAreaInsets()); | 537 non_primary_root, new_primary_display.GetWorkAreaInsets()); |
| 568 | 538 |
| 569 // Update the dispay manager with new display info. | 539 // Update the dispay manager with new display info. |
| 570 std::vector<internal::DisplayInfo> display_info_list; | 540 std::vector<internal::DisplayInfo> display_info_list; |
| 571 display_info_list.push_back(display_manager->GetDisplayInfo( | 541 display_info_list.push_back(display_manager->GetDisplayInfo( |
| 572 primary_display_id)); | 542 primary_display_id)); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 void DisplayController::NotifyDisplayConfigurationChanged() { | 757 void DisplayController::NotifyDisplayConfigurationChanged() { |
| 788 if (in_bootstrap()) | 758 if (in_bootstrap()) |
| 789 return; | 759 return; |
| 790 | 760 |
| 791 if (limiter_) | 761 if (limiter_) |
| 792 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); | 762 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); |
| 793 | 763 |
| 794 focus_activation_store_->Restore(); | 764 focus_activation_store_->Restore(); |
| 795 | 765 |
| 796 internal::DisplayManager* display_manager = GetDisplayManager(); | 766 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 767 internal::DisplayLayoutStore* layout_store = display_manager->layout_store(); | |
| 797 if (display_manager->num_connected_displays() > 1) { | 768 if (display_manager->num_connected_displays() > 1) { |
| 798 DisplayIdPair pair = GetCurrentDisplayIdPair(); | 769 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
| 799 if (paired_layouts_.find(pair) == paired_layouts_.end()) | 770 layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored()); |
| 800 CreateDisplayLayout(pair); | 771 DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair); |
| 801 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); | 772 |
| 802 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { | 773 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { |
| 803 int64 primary_id = paired_layouts_[pair].primary_id; | 774 int64 primary_id = layout.primary_id; |
| 804 SetPrimaryDisplayId( | 775 SetPrimaryDisplayId( |
| 805 primary_id == gfx::Display::kInvalidDisplayID ? | 776 primary_id == gfx::Display::kInvalidDisplayID ? |
| 806 pair.first : primary_id); | 777 pair.first : primary_id); |
| 807 // Update the primary_id in case the above call is | 778 // Update the primary_id in case the above call is |
| 808 // ignored. Happens when a) default layout's primary id | 779 // ignored. Happens when a) default layout's primary id |
| 809 // doesn't exist, or b) the primary_id has already been | 780 // doesn't exist, or b) the primary_id has already been |
| 810 // set to the same and didn't update it. | 781 // set to the same and didn't update it. |
| 811 paired_layouts_[pair].primary_id = GetPrimaryDisplay().id(); | 782 layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); |
| 812 } | 783 } |
| 813 } | 784 } |
| 814 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); | 785 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); |
| 815 UpdateHostWindowNames(); | 786 UpdateHostWindowNames(); |
| 816 } | 787 } |
| 817 | 788 |
| 818 void DisplayController::RegisterLayoutForDisplayIdPairInternal( | |
| 819 int64 id1, | |
| 820 int64 id2, | |
| 821 const DisplayLayout& layout, | |
| 822 bool override) { | |
| 823 DisplayIdPair pair = std::make_pair(id1, id2); | |
| 824 if (override || paired_layouts_.find(pair) == paired_layouts_.end()) | |
| 825 paired_layouts_[pair] = layout; | |
| 826 } | |
| 827 | |
| 828 void DisplayController::OnFadeOutForSwapDisplayFinished() { | 789 void DisplayController::OnFadeOutForSwapDisplayFinished() { |
| 829 #if defined(OS_CHROMEOS) && defined(USE_X11) | 790 #if defined(OS_CHROMEOS) && defined(USE_X11) |
| 830 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 791 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); |
| 831 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); | 792 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); |
| 832 #endif | 793 #endif |
| 833 } | 794 } |
| 834 | 795 |
| 835 DisplayLayout DisplayController::ComputeDisplayLayoutForDisplayIdPair( | |
| 836 const DisplayIdPair& pair) { | |
| 837 DisplayLayout layout = GetRegisteredDisplayLayout(pair); | |
| 838 int64 primary_id = layout.primary_id; | |
| 839 // TODO(oshima): replace this with DCHECK. | |
| 840 if (primary_id == gfx::Display::kInvalidDisplayID) | |
| 841 primary_id = GetPrimaryDisplay().id(); | |
| 842 // Invert if the primary was swapped. If mirrored, first is always | |
| 843 // primary. | |
| 844 return pair.first == primary_id ? layout : layout.Invert(); | |
| 845 } | |
| 846 | |
| 847 void DisplayController::UpdateHostWindowNames() { | 796 void DisplayController::UpdateHostWindowNames() { |
| 848 #if defined(USE_X11) | 797 #if defined(USE_X11) |
| 849 // crbug.com/120229 - set the window title for the primary dislpay | 798 // crbug.com/120229 - set the window title for the primary dislpay |
| 850 // to "aura_root_0" so gtalk can find the primary root window to broadcast. | 799 // to "aura_root_0" so gtalk can find the primary root window to broadcast. |
| 851 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. | 800 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. |
| 852 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); | 801 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); |
| 853 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 802 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
| 854 for (size_t i = 0; i < root_windows.size(); ++i) { | 803 for (size_t i = 0; i < root_windows.size(); ++i) { |
| 855 std::string name = | 804 std::string name = |
| 856 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; | 805 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; |
| 857 gfx::AcceleratedWidget xwindow = root_windows[i]->GetAcceleratedWidget(); | 806 gfx::AcceleratedWidget xwindow = root_windows[i]->GetAcceleratedWidget(); |
| 858 XStoreName(ui::GetXDisplay(), xwindow, name.c_str()); | 807 XStoreName(ui::GetXDisplay(), xwindow, name.c_str()); |
| 859 } | 808 } |
| 860 #endif | 809 #endif |
| 861 } | 810 } |
| 862 | 811 |
| 863 DisplayLayout DisplayController::CreateDisplayLayout( | |
| 864 const DisplayIdPair& pair) { | |
| 865 DisplayLayout layout = default_display_layout_; | |
| 866 layout.primary_id = pair.first; | |
| 867 paired_layouts_[pair] = layout; | |
| 868 return layout; | |
| 869 } | |
| 870 | |
| 871 } // namespace ash | 812 } // namespace ash |
| OLD | NEW |