| 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 <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "ash/ash_root_window_transformer.h" | 10 #include "ash/ash_root_window_transformer.h" |
| 11 #include "ash/ash_switches.h" | 11 #include "ash/ash_switches.h" |
| 12 #include "ash/display/display_manager.h" | 12 #include "ash/display/display_manager.h" |
| 13 #include "ash/display/display_pref_util.h" | 13 #include "ash/display/display_pref_util.h" |
| 14 #include "ash/host/root_window_host_factory.h" | 14 #include "ash/host/root_window_host_factory.h" |
| 15 #include "ash/root_window_controller.h" | 15 #include "ash/root_window_controller.h" |
| 16 #include "ash/screen_ash.h" | 16 #include "ash/screen_ash.h" |
| 17 #include "ash/shell.h" | 17 #include "ash/shell.h" |
| 18 #include "ash/wm/coordinate_conversion.h" | 18 #include "ash/wm/coordinate_conversion.h" |
| 19 #include "ash/wm/property_util.h" | 19 #include "ash/wm/property_util.h" |
| 20 #include "ash/wm/window_util.h" | 20 #include "ash/wm/window_util.h" |
| 21 #include "base/command_line.h" | 21 #include "base/command_line.h" |
| 22 #include "base/json/json_value_converter.h" | 22 #include "base/json/json_value_converter.h" |
| 23 #include "base/string_piece.h" | 23 #include "base/string_piece.h" |
| 24 #include "base/stringprintf.h" | 24 #include "base/stringprintf.h" |
| 25 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
| 26 #include "base/values.h" | 26 #include "base/values.h" |
| 27 #include "ui/aura/client/cursor_client.h" |
| 27 #include "ui/aura/client/screen_position_client.h" | 28 #include "ui/aura/client/screen_position_client.h" |
| 28 #include "ui/aura/env.h" | 29 #include "ui/aura/env.h" |
| 29 #include "ui/aura/root_window.h" | 30 #include "ui/aura/root_window.h" |
| 30 #include "ui/aura/window.h" | 31 #include "ui/aura/window.h" |
| 31 #include "ui/aura/window_property.h" | 32 #include "ui/aura/window_property.h" |
| 32 #include "ui/compositor/compositor.h" | 33 #include "ui/compositor/compositor.h" |
| 33 #include "ui/compositor/dip_util.h" | 34 #include "ui/compositor/dip_util.h" |
| 34 #include "ui/gfx/display.h" | 35 #include "ui/gfx/display.h" |
| 35 #include "ui/gfx/screen.h" | 36 #include "ui/gfx/screen.h" |
| 36 | 37 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 } | 330 } |
| 330 | 331 |
| 331 bool DisplayController::DisplayChangeLimiter::IsThrottled() const { | 332 bool DisplayController::DisplayChangeLimiter::IsThrottled() const { |
| 332 return base::Time::Now() < throttle_timeout_; | 333 return base::Time::Now() < throttle_timeout_; |
| 333 } | 334 } |
| 334 | 335 |
| 335 //////////////////////////////////////////////////////////////////////////////// | 336 //////////////////////////////////////////////////////////////////////////////// |
| 336 // DisplayController | 337 // DisplayController |
| 337 | 338 |
| 338 DisplayController::DisplayController() | 339 DisplayController::DisplayController() |
| 339 : primary_root_window_for_replace_(NULL) { | 340 : primary_root_window_for_replace_(NULL), |
| 341 in_bootstrap_(true) { |
| 340 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 342 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 341 #if defined(OS_CHROMEOS) | 343 #if defined(OS_CHROMEOS) |
| 342 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && | 344 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && |
| 343 base::chromeos::IsRunningOnChromeOS()) | 345 base::chromeos::IsRunningOnChromeOS()) |
| 344 limiter_.reset(new DisplayChangeLimiter); | 346 limiter_.reset(new DisplayChangeLimiter); |
| 345 #endif | 347 #endif |
| 346 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { | 348 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { |
| 347 std::string value = command_line->GetSwitchValueASCII( | 349 std::string value = command_line->GetSwitchValueASCII( |
| 348 switches::kAshSecondaryDisplayLayout); | 350 switches::kAshSecondaryDisplayLayout); |
| 349 char layout; | 351 char layout; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 367 primary_display_for_shutdown = NULL; | 369 primary_display_for_shutdown = NULL; |
| 368 num_displays_for_shutdown = -1; | 370 num_displays_for_shutdown = -1; |
| 369 } | 371 } |
| 370 | 372 |
| 371 DisplayController::~DisplayController() { | 373 DisplayController::~DisplayController() { |
| 372 DCHECK(primary_display_for_shutdown); | 374 DCHECK(primary_display_for_shutdown); |
| 373 } | 375 } |
| 374 | 376 |
| 375 void DisplayController::Start() { | 377 void DisplayController::Start() { |
| 376 Shell::GetScreen()->AddObserver(this); | 378 Shell::GetScreen()->AddObserver(this); |
| 379 in_bootstrap_ = false; |
| 377 } | 380 } |
| 378 | 381 |
| 379 void DisplayController::Shutdown() { | 382 void DisplayController::Shutdown() { |
| 380 DCHECK(!primary_display_for_shutdown); | 383 DCHECK(!primary_display_for_shutdown); |
| 381 primary_display_for_shutdown = new gfx::Display( | 384 primary_display_for_shutdown = new gfx::Display( |
| 382 GetDisplayManager()->GetDisplayForId(primary_display_id)); | 385 GetDisplayManager()->GetDisplayForId(primary_display_id)); |
| 383 num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); | 386 num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); |
| 384 | 387 |
| 385 Shell::GetScreen()->RemoveObserver(this); | 388 Shell::GetScreen()->RemoveObserver(this); |
| 386 // Delete all root window controllers, which deletes root window | 389 // Delete all root window controllers, which deletes root window |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 GetDisplayManager()->set_force_bounds_changed(false); | 718 GetDisplayManager()->set_force_bounds_changed(false); |
| 716 } | 719 } |
| 717 | 720 |
| 718 gfx::Display* DisplayController::GetSecondaryDisplay() { | 721 gfx::Display* DisplayController::GetSecondaryDisplay() { |
| 719 internal::DisplayManager* display_manager = GetDisplayManager(); | 722 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 720 CHECK_EQ(2U, display_manager->GetNumDisplays()); | 723 CHECK_EQ(2U, display_manager->GetNumDisplays()); |
| 721 return display_manager->GetDisplayAt(0)->id() == primary_display_id ? | 724 return display_manager->GetDisplayAt(0)->id() == primary_display_id ? |
| 722 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0); | 725 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0); |
| 723 } | 726 } |
| 724 | 727 |
| 728 void DisplayController::EnsurePointerInDisplays() { |
| 729 // Don't try to move the pointer during the boot/startup. |
| 730 if (!HasPrimaryDisplay()) |
| 731 return; |
| 732 gfx::Point location_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); |
| 733 gfx::Point target_location; |
| 734 int64 closest_distance_squared = -1; |
| 735 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 736 |
| 737 aura::RootWindow* dst_root_window = NULL; |
| 738 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { |
| 739 const gfx::Display* display = display_manager->GetDisplayAt(i); |
| 740 aura::RootWindow* root_window = GetRootWindowForDisplayId(display->id()); |
| 741 if (display->bounds().Contains(location_in_screen)) { |
| 742 dst_root_window = root_window; |
| 743 target_location = location_in_screen; |
| 744 break; |
| 745 } |
| 746 gfx::Point center = display->bounds().CenterPoint(); |
| 747 // Use the distance squared from the center of the dislay. This is not |
| 748 // exactly "closest" display, but good enough to pick one |
| 749 // appropriate (and there are at most two displays). |
| 750 // We don't care about actual distance, only relative to other displays, so |
| 751 // using the LengthSquared() is cheaper than Length(). |
| 752 |
| 753 int64 distance_squared = (center - location_in_screen).LengthSquared(); |
| 754 if (closest_distance_squared < 0 || |
| 755 closest_distance_squared > distance_squared) { |
| 756 dst_root_window = root_window; |
| 757 target_location = center; |
| 758 closest_distance_squared = distance_squared; |
| 759 } |
| 760 } |
| 761 DCHECK(dst_root_window); |
| 762 aura::client::ScreenPositionClient* client = |
| 763 aura::client::GetScreenPositionClient(dst_root_window); |
| 764 client->ConvertPointFromScreen(dst_root_window, &target_location); |
| 765 dst_root_window->MoveCursorTo(target_location); |
| 766 } |
| 767 |
| 768 gfx::Point DisplayController::GetNativeMouseCursorLocation() const { |
| 769 if (in_bootstrap()) |
| 770 return gfx::Point(); |
| 771 |
| 772 gfx::Point location = Shell::GetScreen()->GetCursorScreenPoint(); |
| 773 const gfx::Display& display = |
| 774 Shell::GetScreen()->GetDisplayNearestPoint(location); |
| 775 const aura::RootWindow* root_window = |
| 776 root_windows_.find(display.id())->second; |
| 777 aura::client::ScreenPositionClient* client = |
| 778 aura::client::GetScreenPositionClient(root_window); |
| 779 client->ConvertPointFromScreen(root_window, &location); |
| 780 root_window->ConvertPointToNativeScreen(&location); |
| 781 return location; |
| 782 } |
| 783 |
| 784 void DisplayController::UpdateMouseCursor(const gfx::Point& point_in_native) { |
| 785 if (in_bootstrap()) |
| 786 return; |
| 787 |
| 788 std::vector<aura::RootWindow*> root_windows = GetAllRootWindows(); |
| 789 for (std::vector<aura::RootWindow*>::iterator iter = root_windows.begin(); |
| 790 iter != root_windows.end(); |
| 791 ++iter) { |
| 792 aura::RootWindow* root_window = *iter; |
| 793 gfx::Rect bounds_in_native(root_window->GetHostOrigin(), |
| 794 root_window->GetHostSize()); |
| 795 if (bounds_in_native.Contains(point_in_native)) { |
| 796 gfx::Point point(point_in_native); |
| 797 root_window->ConvertPointFromNativeScreen(&point); |
| 798 root_window->MoveCursorTo(point); |
| 799 break; |
| 800 } |
| 801 } |
| 802 } |
| 803 |
| 725 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { | 804 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { |
| 726 if (limiter_.get()) | 805 if (limiter_.get()) |
| 727 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); | 806 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); |
| 728 const internal::DisplayInfo& display_info = | 807 const internal::DisplayInfo& display_info = |
| 729 GetDisplayManager()->GetDisplayInfo(display.id()); | 808 GetDisplayManager()->GetDisplayInfo(display.id()); |
| 730 DCHECK(!display_info.bounds_in_pixel().IsEmpty()); | 809 DCHECK(!display_info.bounds_in_pixel().IsEmpty()); |
| 731 | 810 |
| 732 UpdateDisplayBoundsForLayout(); | 811 UpdateDisplayBoundsForLayout(); |
| 733 aura::RootWindow* root = root_windows_[display.id()]; | 812 aura::RootWindow* root = root_windows_[display.id()]; |
| 734 SetDisplayPropertiesOnHostWindow(root, display); | 813 SetDisplayPropertiesOnHostWindow(root, display); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 967 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
| 889 break; | 968 break; |
| 890 } | 969 } |
| 891 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 970 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
| 892 secondary_display->set_bounds( | 971 secondary_display->set_bounds( |
| 893 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 972 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
| 894 secondary_display->UpdateWorkAreaFromInsets(insets); | 973 secondary_display->UpdateWorkAreaFromInsets(insets); |
| 895 } | 974 } |
| 896 | 975 |
| 897 void DisplayController::NotifyDisplayConfigurationChanging() { | 976 void DisplayController::NotifyDisplayConfigurationChanging() { |
| 898 // |primary_display_id| is invalid during bootstrap. | 977 if (in_bootstrap()) |
| 899 if (primary_display_id == gfx::Display::kInvalidDisplayID) | |
| 900 return; | 978 return; |
| 901 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); | 979 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); |
| 902 } | 980 } |
| 903 | 981 |
| 904 void DisplayController::NotifyDisplayConfigurationChanged() { | 982 void DisplayController::NotifyDisplayConfigurationChanged() { |
| 905 // |primary_display_id| is invalid during bootstrap. | 983 if (in_bootstrap()) |
| 906 if (primary_display_id == gfx::Display::kInvalidDisplayID) | |
| 907 return; | 984 return; |
| 908 | 985 |
| 909 internal::DisplayManager* display_manager = GetDisplayManager(); | 986 internal::DisplayManager* display_manager = GetDisplayManager(); |
| 910 if (display_manager->num_connected_displays() > 1) { | 987 if (display_manager->num_connected_displays() > 1) { |
| 911 DisplayIdPair pair = GetCurrentDisplayIdPair(); | 988 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
| 912 if (paired_layouts_.find(pair) == paired_layouts_.end()) | 989 if (paired_layouts_.find(pair) == paired_layouts_.end()) |
| 913 paired_layouts_[pair] = default_display_layout_; | 990 paired_layouts_[pair] = default_display_layout_; |
| 914 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); | 991 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); |
| 915 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { | 992 if (Shell::GetScreen()->GetNumDisplays() > 1 ) { |
| 916 int64 primary_id = paired_layouts_[pair].primary_id; | 993 int64 primary_id = paired_layouts_[pair].primary_id; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 938 } | 1015 } |
| 939 | 1016 |
| 940 void DisplayController::OnFadeOutForSwapDisplayFinished() { | 1017 void DisplayController::OnFadeOutForSwapDisplayFinished() { |
| 941 #if defined(OS_CHROMEOS) | 1018 #if defined(OS_CHROMEOS) |
| 942 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 1019 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); |
| 943 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); | 1020 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); |
| 944 #endif | 1021 #endif |
| 945 } | 1022 } |
| 946 | 1023 |
| 947 } // namespace ash | 1024 } // namespace ash |
| OLD | NEW |