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 |