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 } |
| 411 NOTREACHED() << "DisplayLayout is requested for single display"; |
435 // On release build, just fallback to default instead of blowing up. | 412 // On release build, just fallback to default instead of blowing up. |
436 DisplayLayout layout = default_display_layout_; | 413 DisplayLayout layout = |
| 414 GetDisplayManager()->layout_store()->default_display_layout(); |
437 layout.primary_id = primary_display_id; | 415 layout.primary_id = primary_display_id; |
438 return layout; | 416 return layout; |
439 } | 417 } |
440 | 418 |
441 DisplayIdPair DisplayController::GetCurrentDisplayIdPair() const { | 419 DisplayIdPair DisplayController::GetCurrentDisplayIdPair() const { |
442 internal::DisplayManager* display_manager = GetDisplayManager(); | 420 internal::DisplayManager* display_manager = GetDisplayManager(); |
443 const gfx::Display& primary = GetPrimaryDisplay(); | 421 const gfx::Display& primary = GetPrimaryDisplay(); |
444 if (display_manager->IsMirrored()) { | 422 if (display_manager->IsMirrored()) { |
445 return std::make_pair(primary.id(), | 423 return std::make_pair(primary.id(), |
446 display_manager->mirrored_display().id()); | 424 display_manager->mirrored_display().id()); |
447 } | 425 } |
448 | 426 |
449 const gfx::Display& secondary = ScreenAsh::GetSecondaryDisplay(); | 427 const gfx::Display& secondary = ScreenAsh::GetSecondaryDisplay(); |
450 if (primary.IsInternal() || | 428 if (primary.IsInternal() || |
451 GetDisplayManager()->first_display_id() == primary.id()) { | 429 GetDisplayManager()->first_display_id() == primary.id()) { |
452 return std::make_pair(primary.id(), secondary.id()); | 430 return std::make_pair(primary.id(), secondary.id()); |
453 } else { | 431 } else { |
454 // Display has been Swapped. | 432 // Display has been Swapped. |
455 return std::make_pair(secondary.id(), primary.id()); | 433 return std::make_pair(secondary.id(), primary.id()); |
456 } | 434 } |
457 } | 435 } |
458 | 436 |
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() { | 437 void DisplayController::ToggleMirrorMode() { |
468 internal::DisplayManager* display_manager = GetDisplayManager(); | 438 internal::DisplayManager* display_manager = GetDisplayManager(); |
469 if (display_manager->num_connected_displays() <= 1) | 439 if (display_manager->num_connected_displays() <= 1) |
470 return; | 440 return; |
471 | 441 |
472 if (limiter_) { | 442 if (limiter_) { |
473 if (limiter_->IsThrottled()) | 443 if (limiter_->IsThrottled()) |
474 return; | 444 return; |
475 limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); | 445 limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); |
476 } | 446 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 DCHECK_NE(primary_root, non_primary_root); | 522 DCHECK_NE(primary_root, non_primary_root); |
553 | 523 |
554 root_windows_[new_primary_display.id()] = primary_root; | 524 root_windows_[new_primary_display.id()] = primary_root; |
555 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); | 525 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); |
556 | 526 |
557 root_windows_[old_primary_display.id()] = non_primary_root; | 527 root_windows_[old_primary_display.id()] = non_primary_root; |
558 non_primary_root->SetProperty(internal::kDisplayIdKey, | 528 non_primary_root->SetProperty(internal::kDisplayIdKey, |
559 old_primary_display.id()); | 529 old_primary_display.id()); |
560 | 530 |
561 primary_display_id = new_primary_display.id(); | 531 primary_display_id = new_primary_display.id(); |
562 paired_layouts_[GetCurrentDisplayIdPair()].primary_id = primary_display_id; | 532 GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( |
| 533 GetCurrentDisplayIdPair(), primary_display_id); |
563 | 534 |
564 display_manager->UpdateWorkAreaOfDisplayNearestWindow( | 535 display_manager->UpdateWorkAreaOfDisplayNearestWindow( |
565 primary_root, old_primary_display.GetWorkAreaInsets()); | 536 primary_root, old_primary_display.GetWorkAreaInsets()); |
566 display_manager->UpdateWorkAreaOfDisplayNearestWindow( | 537 display_manager->UpdateWorkAreaOfDisplayNearestWindow( |
567 non_primary_root, new_primary_display.GetWorkAreaInsets()); | 538 non_primary_root, new_primary_display.GetWorkAreaInsets()); |
568 | 539 |
569 // Update the dispay manager with new display info. | 540 // Update the dispay manager with new display info. |
570 std::vector<internal::DisplayInfo> display_info_list; | 541 std::vector<internal::DisplayInfo> display_info_list; |
571 display_info_list.push_back(display_manager->GetDisplayInfo( | 542 display_info_list.push_back(display_manager->GetDisplayInfo( |
572 primary_display_id)); | 543 primary_display_id)); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 void DisplayController::NotifyDisplayConfigurationChanged() { | 758 void DisplayController::NotifyDisplayConfigurationChanged() { |
788 if (in_bootstrap()) | 759 if (in_bootstrap()) |
789 return; | 760 return; |
790 | 761 |
791 if (limiter_) | 762 if (limiter_) |
792 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); | 763 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); |
793 | 764 |
794 focus_activation_store_->Restore(); | 765 focus_activation_store_->Restore(); |
795 | 766 |
796 internal::DisplayManager* display_manager = GetDisplayManager(); | 767 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 768 internal::DisplayLayoutStore* layout_store = display_manager->layout_store(); |
797 if (display_manager->num_connected_displays() > 1) { | 769 if (display_manager->num_connected_displays() > 1) { |
798 DisplayIdPair pair = GetCurrentDisplayIdPair(); | 770 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
799 if (paired_layouts_.find(pair) == paired_layouts_.end()) | 771 layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored()); |
800 CreateDisplayLayout(pair); | 772 DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair); |
801 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); | 773 |
802 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { | 774 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { |
803 int64 primary_id = paired_layouts_[pair].primary_id; | 775 int64 primary_id = layout.primary_id; |
804 SetPrimaryDisplayId( | 776 SetPrimaryDisplayId( |
805 primary_id == gfx::Display::kInvalidDisplayID ? | 777 primary_id == gfx::Display::kInvalidDisplayID ? |
806 pair.first : primary_id); | 778 pair.first : primary_id); |
807 // Update the primary_id in case the above call is | 779 // Update the primary_id in case the above call is |
808 // ignored. Happens when a) default layout's primary id | 780 // ignored. Happens when a) default layout's primary id |
809 // doesn't exist, or b) the primary_id has already been | 781 // doesn't exist, or b) the primary_id has already been |
810 // set to the same and didn't update it. | 782 // set to the same and didn't update it. |
811 paired_layouts_[pair].primary_id = GetPrimaryDisplay().id(); | 783 layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); |
812 } | 784 } |
813 } | 785 } |
814 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); | 786 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); |
815 UpdateHostWindowNames(); | 787 UpdateHostWindowNames(); |
816 } | 788 } |
817 | 789 |
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() { | 790 void DisplayController::OnFadeOutForSwapDisplayFinished() { |
829 #if defined(OS_CHROMEOS) && defined(USE_X11) | 791 #if defined(OS_CHROMEOS) && defined(USE_X11) |
830 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 792 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); |
831 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); | 793 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); |
832 #endif | 794 #endif |
833 } | 795 } |
834 | 796 |
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() { | 797 void DisplayController::UpdateHostWindowNames() { |
848 #if defined(USE_X11) | 798 #if defined(USE_X11) |
849 // crbug.com/120229 - set the window title for the primary dislpay | 799 // 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. | 800 // 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. | 801 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. |
852 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); | 802 aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); |
853 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 803 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
854 for (size_t i = 0; i < root_windows.size(); ++i) { | 804 for (size_t i = 0; i < root_windows.size(); ++i) { |
855 std::string name = | 805 std::string name = |
856 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; | 806 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; |
857 gfx::AcceleratedWidget xwindow = root_windows[i]->GetAcceleratedWidget(); | 807 gfx::AcceleratedWidget xwindow = root_windows[i]->GetAcceleratedWidget(); |
858 XStoreName(ui::GetXDisplay(), xwindow, name.c_str()); | 808 XStoreName(ui::GetXDisplay(), xwindow, name.c_str()); |
859 } | 809 } |
860 #endif | 810 #endif |
861 } | 811 } |
862 | 812 |
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 | 813 } // namespace ash |
OLD | NEW |