diff options
Diffstat (limited to 'ash/display')
-rw-r--r-- | ash/display/display_controller.cc | 127 | ||||
-rw-r--r-- | ash/display/display_controller.h | 23 | ||||
-rw-r--r-- | ash/display/display_controller_unittest.cc | 50 | ||||
-rw-r--r-- | ash/display/display_manager.cc | 47 | ||||
-rw-r--r-- | ash/display/display_manager.h | 13 | ||||
-rw-r--r-- | ash/display/display_manager_unittest.cc | 43 | ||||
-rw-r--r-- | ash/display/event_transformation_handler.cc | 1 | ||||
-rw-r--r-- | ash/display/mouse_cursor_event_filter.cc | 6 | ||||
-rw-r--r-- | ash/display/resolution_notification_controller_unittest.cc | 24 | ||||
-rw-r--r-- | ash/display/root_window_transformers_unittest.cc | 18 | ||||
-rw-r--r-- | ash/display/screen_ash.cc | 284 | ||||
-rw-r--r-- | ash/display/screen_ash.h | 99 | ||||
-rw-r--r-- | ash/display/screen_position_controller_unittest.cc | 6 |
13 files changed, 545 insertions, 196 deletions
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc index 343db545..7b7cc58 100644 --- a/ash/display/display_controller.cc +++ b/ash/display/display_controller.cc @@ -17,16 +17,14 @@ #include "ash/host/root_window_host_factory.h" #include "ash/root_window_controller.h" #include "ash/root_window_settings.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/wm/coordinate_conversion.h" #include "base/command_line.h" #include "base/strings/stringprintf.h" -#include "third_party/skia/include/utils/SkMatrix44.h" #include "ui/aura/client/activation_client.h" #include "ui/aura/client/capture_client.h" -#include "ui/aura/client/cursor_client.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/client/screen_position_client.h" #include "ui/aura/root_window.h" @@ -35,7 +33,6 @@ #include "ui/aura/window_property.h" #include "ui/aura/window_tracker.h" #include "ui/compositor/compositor.h" -#include "ui/compositor/dip_util.h" #include "ui/gfx/display.h" #include "ui/gfx/screen.h" @@ -63,10 +60,6 @@ namespace { // during the shutdown instead of always keeping two display instances // (one here and another one in display_manager) in sync, which is error prone. int64 primary_display_id = gfx::Display::kInvalidDisplayID; -gfx::Display* primary_display_for_shutdown = NULL; -// Keeps the number of displays during the shutdown after -// ash::Shell:: is deleted. -int num_displays_for_shutdown = -1; // Specifies how long the display change should have been disabled // after each display change operations. @@ -235,13 +228,9 @@ DisplayController::DisplayController() // Reset primary display to make sure that tests don't use // stale display info from previous tests. primary_display_id = gfx::Display::kInvalidDisplayID; - delete primary_display_for_shutdown; - primary_display_for_shutdown = NULL; - num_displays_for_shutdown = -1; } DisplayController::~DisplayController() { - DCHECK(primary_display_for_shutdown); } void DisplayController::Start() { @@ -263,11 +252,6 @@ void DisplayController::Shutdown() { mirror_window_controller_.reset(); virtual_keyboard_window_controller_.reset(); - DCHECK(!primary_display_for_shutdown); - primary_display_for_shutdown = new gfx::Display( - GetDisplayManager()->GetDisplayForId(primary_display_id)); - num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); - Shell::GetScreen()->RemoveObserver(this); // Delete all root window controllers, which deletes root window // from the last so that the primary root window gets deleted last. @@ -280,21 +264,6 @@ void DisplayController::Shutdown() { } } -// static -const gfx::Display& DisplayController::GetPrimaryDisplay() { - DCHECK_NE(primary_display_id, gfx::Display::kInvalidDisplayID); - if (primary_display_for_shutdown) - return *primary_display_for_shutdown; - return GetDisplayManager()->GetDisplayForId(primary_display_id); -} - -// static -int DisplayController::GetNumDisplays() { - if (num_displays_for_shutdown >= 0) - return num_displays_for_shutdown; - return GetDisplayManager()->GetNumDisplays(); -} - void DisplayController::InitPrimaryDisplay() { const gfx::Display& primary_candidate = GetDisplayManager()->GetPrimaryDisplayCandidate(); @@ -322,6 +291,11 @@ void DisplayController::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } +// static +int64 DisplayController::GetPrimaryDisplayId() { + return primary_display_id; +} + aura::Window* DisplayController::GetPrimaryRootWindow() { DCHECK(!root_windows_.empty()); return root_windows_[primary_display_id]; @@ -418,10 +392,10 @@ void DisplayController::SwapPrimaryDisplay() { &DisplayController::OnFadeOutForSwapDisplayFinished, base::Unretained(this))); } else { - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); + SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); } #else - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); + SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); #endif } } @@ -461,7 +435,7 @@ void DisplayController::SetPrimaryDisplay( if (!non_primary_root) return; - gfx::Display old_primary_display = GetPrimaryDisplay(); + gfx::Display old_primary_display = Shell::GetScreen()->GetPrimaryDisplay(); // Swap root windows between current and new primary display. aura::Window* primary_root = root_windows_[primary_display_id]; @@ -490,7 +464,7 @@ void DisplayController::SetPrimaryDisplay( display_info_list.push_back(display_manager->GetDisplayInfo( primary_display_id)); display_info_list.push_back(display_manager->GetDisplayInfo( - ScreenAsh::GetSecondaryDisplay().id())); + ScreenUtil::GetSecondaryDisplay().id())); GetDisplayManager()->set_force_bounds_changed(true); GetDisplayManager()->UpdateDisplays(display_info_list); GetDisplayManager()->set_force_bounds_changed(false); @@ -553,70 +527,6 @@ bool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); } -const gfx::Display& DisplayController::GetDisplayNearestWindow( - const aura::Window* window) const { - if (!window) - return GetPrimaryDisplay(); - const aura::Window* root_window = window->GetRootWindow(); - if (!root_window) - return GetPrimaryDisplay(); - int64 id = internal::GetRootWindowSettings(root_window)->display_id; - // if id is |kInvaildDisplayID|, it's being deleted. - DCHECK(id != gfx::Display::kInvalidDisplayID); - - internal::DisplayManager* display_manager = GetDisplayManager(); - // RootWindow needs Display to determine its device scale factor - // for non desktop display. - if (display_manager->non_desktop_display().id() == id) - return display_manager->non_desktop_display(); - return display_manager->GetDisplayForId(id); -} - -const gfx::Display& DisplayController::GetDisplayNearestPoint( - const gfx::Point& point) const { - const gfx::Display& display = - GetDisplayManager()->FindDisplayContainingPoint(point); - if (display.is_valid()) - return display; - - // Fallback to the display that has the shortest Manhattan distance from - // the |point|. This is correct in the only areas that matter, namely in the - // corners between the physical screens. - int min_distance = INT_MAX; - const gfx::Display* nearest_display = NULL; - for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { - const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); - int distance = display.bounds().ManhattanDistanceToPoint(point); - if (distance < min_distance) { - min_distance = distance; - nearest_display = &display; - } - } - // There should always be at least one display that is less than INT_MAX away. - DCHECK(nearest_display); - return *nearest_display; -} - -const gfx::Display& DisplayController::GetDisplayMatching( - const gfx::Rect& rect) const { - if (rect.IsEmpty()) - return GetDisplayNearestPoint(rect.origin()); - - int max_area = 0; - const gfx::Display* matching = NULL; - for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { - const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); - gfx::Rect intersect = gfx::IntersectRects(display.bounds(), rect); - int area = intersect.width() * intersect.height(); - if (area > max_area) { - max_area = area; - matching = &display; - } - } - // Fallback to the primary display if there is no matching display. - return matching ? *matching : GetPrimaryDisplay(); -} - void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { const internal::DisplayInfo& display_info = GetDisplayManager()->GetDisplayInfo(display.id()); @@ -669,7 +579,7 @@ void DisplayController::OnDisplayRemoved(const gfx::Display& display) { return; } DCHECK_EQ(1U, root_windows_.size()); - primary_display_id = ScreenAsh::GetSecondaryDisplay().id(); + primary_display_id = ScreenUtil::GetSecondaryDisplay().id(); aura::Window* primary_root = root_to_delete; // Delete the other root instead. @@ -695,8 +605,10 @@ void DisplayController::OnDisplayRemoved(const gfx::Display& display) { } void DisplayController::OnWindowTreeHostResized(const aura::RootWindow* root) { + gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( + const_cast<aura::Window*>(root->window())); + internal::DisplayManager* display_manager = GetDisplayManager(); - gfx::Display display = GetDisplayNearestWindow(root->window()); if (display_manager->UpdateDisplayBounds( display.id(), root->host()->GetBounds())) { @@ -728,9 +640,9 @@ void DisplayController::CloseNonDesktopDisplay() { void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); focus_activation_store_->Store(clear_focus); - - gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); - gfx::Display display = GetDisplayNearestPoint(point_in_screen); + gfx::Screen* screen = Shell::GetScreen(); + gfx::Point point_in_screen = screen->GetCursorScreenPoint(); + gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); aura::Window* root_window = GetRootWindowForDisplayId(display.id()); aura::client::ScreenPositionClient* client = @@ -763,7 +675,8 @@ void DisplayController::PostDisplayConfigurationChange() { // ignored. Happens when a) default layout's primary id // doesn't exist, or b) the primary_id has already been // set to the same and didn't update it. - layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); + layout_store->UpdatePrimaryDisplayId( + pair, Shell::GetScreen()->GetPrimaryDisplay().id()); } } FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); @@ -806,7 +719,7 @@ aura::RootWindow* DisplayController::AddRootWindowForDisplay( void DisplayController::OnFadeOutForSwapDisplayFinished() { #if defined(OS_CHROMEOS) && defined(USE_X11) - SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); + SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); #endif } diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h index dcc78ed..839e70b 100644 --- a/ash/display/display_controller.h +++ b/ash/display/display_controller.h @@ -72,13 +72,9 @@ class ASH_EXPORT DisplayController : public gfx::DisplayObserver, void Start(); void Shutdown(); - // Returns primary display. This is safe to use after ash::Shell is - // deleted. - static const gfx::Display& GetPrimaryDisplay(); - - // Returns the number of display. This is safe to use after - // ash::Shell is deleted. - static int GetNumDisplays(); + // Returns primary display's ID. + // TODO(oshima): Move this out from DisplayController; + static int64 GetPrimaryDisplayId(); internal::MirrorWindowController* mirror_window_controller() { return mirror_window_controller_.get(); @@ -142,19 +138,6 @@ class ASH_EXPORT DisplayController : public gfx::DisplayObserver, // Sets the work area's |insets| to the display assigned to |window|. bool UpdateWorkAreaOfDisplayNearestWindow(const aura::Window* window, const gfx::Insets& insets); - - // Returns the display object nearest given |point|. - const gfx::Display& GetDisplayNearestPoint( - const gfx::Point& point) const; - - // Returns the display object nearest given |window|. - const gfx::Display& GetDisplayNearestWindow( - const aura::Window* window) const; - - // Returns the display that most closely intersects |match_rect|. - const gfx::Display& GetDisplayMatching( - const gfx::Rect& match_rect)const; - // aura::DisplayObserver overrides: virtual void OnDisplayBoundsChanged( const gfx::Display& display) OVERRIDE; diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc index ffcd6b0..9b85654 100644 --- a/ash/display/display_controller_unittest.cc +++ b/ash/display/display_controller_unittest.cc @@ -8,7 +8,7 @@ #include "ash/display/display_info.h" #include "ash/display/display_layout_store.h" #include "ash/display/display_manager.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" @@ -324,7 +324,7 @@ TEST_F(DisplayControllerTest, SecondaryDisplayLayout) { EXPECT_EQ(0, observer.GetFocusChangedCountAndReset()); EXPECT_EQ(0, observer.GetActivationChangedCountAndReset()); gfx::Insets insets(5, 5, 5, 5); - int64 secondary_display_id = ScreenAsh::GetSecondaryDisplay().id(); + int64 secondary_display_id = ScreenUtil::GetSecondaryDisplay().id(); Shell::GetInstance()->display_manager()->UpdateWorkAreaOfDisplay( secondary_display_id, insets); @@ -520,7 +520,7 @@ TEST_F(DisplayControllerTest, BoundsUpdated) { Shell::GetInstance()->display_manager(); gfx::Insets insets(5, 5, 5, 5); display_manager->UpdateWorkAreaOfDisplay( - ScreenAsh::GetSecondaryDisplay().id(), insets); + ScreenUtil::GetSecondaryDisplay().id(), insets); EXPECT_EQ("0,0 200x200", GetPrimaryDisplay().bounds().ToString()); EXPECT_EQ("0,200 300x300", GetSecondaryDisplay().bounds().ToString()); @@ -604,7 +604,7 @@ TEST_F(DisplayControllerTest, SwapPrimary) { UpdateDisplay("200x200,300x300"); gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); + gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); DisplayLayout display_layout(DisplayLayout::RIGHT, 50); display_manager->SetLayoutForCurrentDisplays(display_layout); @@ -640,7 +640,7 @@ TEST_F(DisplayControllerTest, SwapPrimary) { EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); + EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id()); EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint( gfx::Point(-100, -100)).id()); @@ -658,7 +658,7 @@ TEST_F(DisplayControllerTest, SwapPrimary) { // Test if the bounds are correctly swapped. gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); + gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay(); EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); EXPECT_EQ("0,0 300x253", swapped_primary.work_area().ToString()); EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); @@ -698,7 +698,7 @@ TEST_F(DisplayControllerTest, FindNearestDisplay) { display_manager->SetLayoutForCurrentDisplays(display_layout); gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); + gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); EXPECT_NE(primary_display.id(), secondary_display.id()); aura::Window* primary_root = display_controller->GetRootWindowForDisplayId(primary_display.id()); @@ -741,7 +741,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { UpdateDisplay("200x200,300x300"); gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); + gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); DisplayLayout display_layout(DisplayLayout::RIGHT, 50); display_manager->SetLayoutForCurrentDisplays(display_layout); @@ -777,7 +777,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); + EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id()); EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetDisplayNearestPoint( gfx::Point(-100, -100)).id()); @@ -795,7 +795,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryForLegacyShelfLayout) { // Test if the bounds are correctly swapped. gfx::Display swapped_primary = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display swapped_secondary = ScreenAsh::GetSecondaryDisplay(); + gfx::Display swapped_secondary = ScreenUtil::GetSecondaryDisplay(); EXPECT_EQ("0,0 300x300", swapped_primary.bounds().ToString()); EXPECT_EQ("0,0 300x252", swapped_primary.work_area().ToString()); EXPECT_EQ("-200,-50 200x200", swapped_secondary.bounds().ToString()); @@ -832,7 +832,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) { UpdateDisplay("200x200,300x300"); gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); + gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); DisplayLayout display_layout(DisplayLayout::RIGHT, 50); display_manager->SetLayoutForCurrentDisplays(display_layout); @@ -858,7 +858,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) { display_controller->SetPrimaryDisplayId(secondary_display.id()); EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); + EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id()); EXPECT_LT(0, observer.CountAndReset()); EXPECT_EQ( @@ -909,7 +909,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) { EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); EXPECT_EQ(secondary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id()); + EXPECT_EQ(primary_display.id(), ScreenUtil::GetSecondaryDisplay().id()); EXPECT_EQ( primary_root, display_controller->GetRootWindowForDisplayId(secondary_display.id())); @@ -935,7 +935,7 @@ TEST_F(DisplayControllerTest, SwapPrimaryById) { EXPECT_EQ(2, Shell::GetScreen()->GetNumDisplays()); EXPECT_EQ(primary_display.id(), Shell::GetScreen()->GetPrimaryDisplay().id()); - EXPECT_EQ(third_display_info.id(), ScreenAsh::GetSecondaryDisplay().id()); + EXPECT_EQ(third_display_info.id(), ScreenUtil::GetSecondaryDisplay().id()); EXPECT_EQ( primary_root, display_controller->GetRootWindowForDisplayId(primary_display.id())); @@ -954,7 +954,7 @@ TEST_F(DisplayControllerTest, CursorDeviceScaleFactorSwapPrimary) { UpdateDisplay("200x200,200x200*2"); gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay(); - gfx::Display secondary_display = ScreenAsh::GetSecondaryDisplay(); + gfx::Display secondary_display = ScreenUtil::GetSecondaryDisplay(); aura::Window* primary_root = display_controller->GetRootWindowForDisplayId(primary_display.id()); @@ -1018,7 +1018,7 @@ TEST_F(DisplayControllerTest, OverscanInsets) { EXPECT_EQ("0,0 80x170", root_windows[0]->bounds().ToString()); EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("80,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); aura::test::EventGenerator generator(root_windows[0]); generator.MoveMouseToInHost(20, 25); @@ -1027,7 +1027,7 @@ TEST_F(DisplayControllerTest, OverscanInsets) { display_controller->SetOverscanInsets(display1.id(), gfx::Insets()); EXPECT_EQ("0,0 120x200", root_windows[0]->bounds().ToString()); EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator.MoveMouseToInHost(30, 20); EXPECT_EQ("30,20", event_handler.GetLocationAndReset()); @@ -1061,14 +1061,14 @@ TEST_F(DisplayControllerTest, Rotate) { UpdateDisplay("120x200,300x400*2"); gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); + int64 display2_id = ScreenUtil::GetSecondaryDisplay().id(); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); aura::test::EventGenerator generator1(root_windows[0]); EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator1.MoveMouseToInHost(50, 40); EXPECT_EQ("50,40", event_handler.GetLocationAndReset()); EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id())); @@ -1079,7 +1079,7 @@ TEST_F(DisplayControllerTest, Rotate) { EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("200,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator1.MoveMouseToInHost(50, 40); EXPECT_EQ("40,69", event_handler.GetLocationAndReset()); EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); @@ -1088,14 +1088,14 @@ TEST_F(DisplayControllerTest, Rotate) { DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); display_manager->SetLayoutForCurrentDisplays(display_layout); EXPECT_EQ("50,120 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); display_manager->SetDisplayRotation(display2_id, gfx::Display::ROTATE_270); EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("50,120 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id())); EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); @@ -1110,7 +1110,7 @@ TEST_F(DisplayControllerTest, Rotate) { EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); // Dislay must share at least 100, so the x's offset becomes 20. EXPECT_EQ("20,200 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id)); @@ -1133,7 +1133,7 @@ TEST_F(DisplayControllerTest, ScaleRootWindow) { gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); gfx::Display::SetInternalDisplayId(display1.id()); - gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); + gfx::Display display2 = ScreenUtil::GetSecondaryDisplay(); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); EXPECT_EQ("0,0 450x300", display1.bounds().ToString()); EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString()); @@ -1149,7 +1149,7 @@ TEST_F(DisplayControllerTest, ScaleRootWindow) { Shell::GetInstance()->display_manager(); display_manager->SetDisplayUIScale(display1.id(), 1.25f); display1 = Shell::GetScreen()->GetPrimaryDisplay(); - display2 = ScreenAsh::GetSecondaryDisplay(); + display2 = ScreenUtil::GetSecondaryDisplay(); EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString()); EXPECT_EQ("375,0 500x300", display2.bounds().ToString()); diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc index 2731144..9bb154e 100644 --- a/ash/display/display_manager.cc +++ b/ash/display/display_manager.cc @@ -11,7 +11,8 @@ #include "ash/ash_switches.h" #include "ash/display/display_layout_store.h" -#include "ash/screen_ash.h" +#include "ash/display/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "base/auto_reset.h" #include "base/command_line.h" @@ -48,6 +49,10 @@ typedef std::vector<DisplayInfo> DisplayInfoList; namespace { +// We need to keep this in order for unittests to tell if +// the object in gfx::Screen::GetScreenByType is for shutdown. +gfx::Screen* screen_for_shutdown = NULL; + // The number of pixels to overlap between the primary and secondary displays, // in case that the offset value is too large. const int kMinimumOverlapForInvalidOffset = 100; @@ -143,6 +148,8 @@ using std::vector; DisplayManager::DisplayManager() : delegate_(NULL), + screen_ash_(new ScreenAsh), + screen_(screen_ash_.get()), layout_store_(new DisplayLayoutStore), first_display_id_(gfx::Display::kInvalidDisplayID), num_connected_displays_(0), @@ -153,6 +160,13 @@ DisplayManager::DisplayManager() #if defined(OS_CHROMEOS) change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); #endif + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, + screen_ash_.get()); + if (gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE) == + screen_for_shutdown) { + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, + screen_ash_.get()); + } } DisplayManager::~DisplayManager() { @@ -302,7 +316,7 @@ void DisplayManager::SetLayoutForCurrentDisplays( DCHECK_EQ(2U, GetNumDisplays()); if (GetNumDisplays() < 2) return; - const gfx::Display& primary = Shell::GetScreen()->GetPrimaryDisplay(); + const gfx::Display& primary = screen_->GetPrimaryDisplay(); const DisplayIdPair pair = GetCurrentDisplayIdPair(); // Invert if the primary was swapped. DisplayLayout to_set = pair.first == primary.id() ? @@ -322,13 +336,12 @@ void DisplayManager::SetLayoutForCurrentDisplays( const DisplayLayout layout = GetCurrentDisplayLayout(); UpdateDisplayBoundsForLayoutById( layout, primary, - ScreenAsh::GetSecondaryDisplay().id()); + ScreenUtil::GetSecondaryDisplay().id()); - //UpdateCurrentDisplayBoundsForLayout(); // Primary's bounds stay the same. Just notify bounds change // on the secondary. - Shell::GetInstance()->screen()->NotifyBoundsChanged( - ScreenAsh::GetSecondaryDisplay()); + screen_ash_->NotifyBoundsChanged( + ScreenUtil::GetSecondaryDisplay()); if (delegate_) delegate_->PostDisplayConfigurationChange(); } @@ -751,7 +764,7 @@ void DisplayManager::UpdateDisplays( for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); iter != removed_displays.rend(); ++iter) { - Shell::GetInstance()->screen()->NotifyDisplayRemoved(displays_.back()); + screen_ash_->NotifyDisplayRemoved(displays_.back()); displays_.pop_back(); } // Close the non desktop window here to avoid creating two compositor on @@ -760,7 +773,7 @@ void DisplayManager::UpdateDisplays( non_desktop_display_updater.reset(); for (std::vector<size_t>::iterator iter = added_display_indices.begin(); iter != added_display_indices.end(); ++iter) { - Shell::GetInstance()->screen()->NotifyDisplayAdded(displays_[*iter]); + screen_ash_->NotifyDisplayAdded(displays_[*iter]); } // Create the non destkop window after all displays are added so that // it can mirror the display newly added. This can happen when switching @@ -768,7 +781,7 @@ void DisplayManager::UpdateDisplays( non_desktop_display_updater.reset(); for (std::vector<size_t>::iterator iter = changed_display_indices.begin(); iter != changed_display_indices.end(); ++iter) { - Shell::GetInstance()->screen()->NotifyBoundsChanged(displays_[*iter]); + screen_ash_->NotifyBoundsChanged(displays_[*iter]); } if (delegate_) delegate_->PostDisplayConfigurationChange(); @@ -915,7 +928,7 @@ bool DisplayManager::UpdateDisplayBounds(int64 display_id, return false; gfx::Display* display = FindDisplayForId(display_id); display->SetSize(display_info_[display_id].size_in_pixel()); - Shell::GetInstance()->screen()->NotifyBoundsChanged(*display); + screen_ash_->NotifyBoundsChanged(*display); return true; } return false; @@ -925,6 +938,20 @@ void DisplayManager::CreateMirrorWindowIfAny() { NonDesktopDisplayUpdater updater(this, delegate_); } +void DisplayManager::CreateScreenForShutdown() const { + bool native_is_ash = + gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE) == + screen_ash_.get(); + delete screen_for_shutdown; + screen_for_shutdown = screen_ash_->CloneForShutdown(); + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, + screen_for_shutdown); + if (native_is_ash) { + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, + screen_for_shutdown); + } +} + gfx::Display* DisplayManager::FindDisplayForId(int64 id) { for (DisplayList::iterator iter = displays_.begin(); iter != displays_.end(); ++iter) { diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h index 4e03f33..3450a5d 100644 --- a/ash/display/display_manager.h +++ b/ash/display/display_manager.h @@ -24,11 +24,13 @@ namespace gfx { class Display; class Insets; class Rect; +class Screen; } namespace ash { class AcceleratorControllerTest; class DisplayController; +class ScreenAsh; namespace test { class DisplayManagerTestApi; @@ -98,6 +100,10 @@ class ASH_EXPORT DisplayManager return layout_store_.get(); } + gfx::Screen* screen() { + return screen_; + } + void set_delegate(Delegate* delegate) { delegate_ = delegate; } // When set to true, the MonitorManager calls OnDisplayBoundsChanged @@ -265,6 +271,9 @@ class ASH_EXPORT DisplayManager // This is used only for bootstrap. void CreateMirrorWindowIfAny(); + // Create a screen instance to be used during shutdown. + void CreateScreenForShutdown() const; + private: FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint); FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged); @@ -313,6 +322,10 @@ private: Delegate* delegate_; // not owned. + scoped_ptr<ScreenAsh> screen_ash_; + // This is to have an accessor without ScreenAsh definition. + gfx::Screen* screen_; + scoped_ptr<DisplayLayoutStore> layout_store_; int64 first_display_id_; diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 9ada6a8..ec8d35b 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc @@ -6,7 +6,7 @@ #include "ash/display/display_controller.h" #include "ash/display/display_layout_store.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/display_manager_test_api.h" @@ -20,6 +20,8 @@ #include "ui/aura/window_observer.h" #include "ui/gfx/display_observer.h" #include "ui/gfx/display.h" +#include "ui/gfx/screen.h" +#include "ui/gfx/screen_type_delegate.h" namespace ash { namespace internal { @@ -273,7 +275,7 @@ TEST_F(DisplayManagerTest, OverscanInsetsTest) { EXPECT_EQ("13,12,11,10", updated_display_info2.overscan_insets_in_dip().ToString()); EXPECT_EQ("500,0 378x376", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); // Make sure that SetOverscanInsets() is idempotent. display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets()); @@ -340,11 +342,11 @@ TEST_F(DisplayManagerTest, OverscanInsetsTest) { // Make sure switching primary display applies the overscan offset only once. ash::Shell::GetInstance()->display_controller()->SetPrimaryDisplay( - ScreenAsh::GetSecondaryDisplay()); + ScreenUtil::GetSecondaryDisplay()); EXPECT_EQ("-500,0 500x500", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); EXPECT_EQ("0,0 500x500", - GetDisplayInfo(ScreenAsh::GetSecondaryDisplay()). + GetDisplayInfo(ScreenUtil::GetSecondaryDisplay()). bounds_in_native().ToString()); EXPECT_EQ("0,501 400x400", GetDisplayInfo(Shell::GetScreen()->GetPrimaryDisplay()). @@ -655,7 +657,7 @@ TEST_F(DisplayManagerTest, MAYBE_EnsurePointerInDisplays_2ndOnLeft) { aura::Window::Windows root_windows = Shell::GetAllRootWindows(); EXPECT_EQ("-300,0 300x300", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); aura::Env* env = aura::Env::GetInstance(); @@ -1181,5 +1183,34 @@ TEST_F(DisplayManagerTest, MAYBE_UpdateDisplayWithHostOrigin) { EXPECT_EQ("200x300", dispatcher1->host()->GetBounds().size().ToString()); } + +class ScreenShutdownTest : public test::AshTestBase { + public: + ScreenShutdownTest() { + } + virtual ~ScreenShutdownTest() {} + + virtual void TearDown() OVERRIDE { + gfx::Screen* orig_screen = + gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); + AshTestBase::TearDown(); + gfx::Screen* screen = + gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); + EXPECT_NE(orig_screen, screen); + EXPECT_EQ(2, screen->GetNumDisplays()); + EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString()); + std::vector<gfx::Display> all = screen->GetAllDisplays(); + EXPECT_EQ("500x300", all[0].size().ToString()); + EXPECT_EQ("800x400", all[1].size().ToString()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScreenShutdownTest); +}; + +TEST_F(DisplayManagerTest, ScreenAfterShutdown) { + UpdateDisplay("500x300,800x400"); +} + } // namespace internal } // namespace ash diff --git a/ash/display/event_transformation_handler.cc b/ash/display/event_transformation_handler.cc index aaac56c..0c869f8 100644 --- a/ash/display/event_transformation_handler.cc +++ b/ash/display/event_transformation_handler.cc @@ -6,7 +6,6 @@ #include <cmath> -#include "ash/screen_ash.h" #include "ash/shell.h" #include "ash/wm/coordinate_conversion.h" #include "ash/wm/window_util.h" diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc index ebac900..bc1368f 100644 --- a/ash/display/mouse_cursor_event_filter.cc +++ b/ash/display/mouse_cursor_event_filter.cc @@ -8,7 +8,7 @@ #include "ash/display/display_manager.h" #include "ash/display/mirror_window_controller.h" #include "ash/display/shared_display_edge_indicator.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "ash/wm/coordinate_conversion.h" #include "ash/wm/window_util.h" @@ -176,7 +176,7 @@ void MouseCursorEventFilter::UpdateHorizontalIndicatorWindowBounds() { // instead of using reference. const gfx::Rect primary_bounds = Shell::GetScreen()->GetPrimaryDisplay().bounds(); - const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds(); + const gfx::Rect secondary_bounds = ScreenUtil::GetSecondaryDisplay().bounds(); DisplayLayout::Position position = Shell::GetInstance()-> display_manager()->GetCurrentDisplayLayout().position; @@ -205,7 +205,7 @@ void MouseCursorEventFilter::UpdateVerticalIndicatorWindowBounds() { // instead of using reference. const gfx::Rect primary_bounds = Shell::GetScreen()->GetPrimaryDisplay().bounds(); - const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds(); + const gfx::Rect secondary_bounds = ScreenUtil::GetSecondaryDisplay().bounds(); DisplayLayout::Position position = Shell::GetInstance()-> display_manager()->GetCurrentDisplayLayout().position; diff --git a/ash/display/resolution_notification_controller_unittest.cc b/ash/display/resolution_notification_controller_unittest.cc index 0ec8852..e167c61 100644 --- a/ash/display/resolution_notification_controller_unittest.cc +++ b/ash/display/resolution_notification_controller_unittest.cc @@ -5,7 +5,7 @@ #include "ash/display/resolution_notification_controller.h" #include "ash/display/display_manager.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/bind.h" @@ -107,7 +107,7 @@ TEST_F(ResolutionNotificationControllerTest, Basic) { return; UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); + int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id(); ash::internal::DisplayManager* display_manager = ash::Shell::GetInstance()->display_manager(); ASSERT_EQ(0, accept_count()); @@ -115,7 +115,7 @@ TEST_F(ResolutionNotificationControllerTest, Basic) { // Changes the resolution and apply the result. SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200)); EXPECT_TRUE(IsNotificationVisible()); EXPECT_FALSE(controller()->DoesNotificationTimeout()); gfx::Size resolution; @@ -137,7 +137,7 @@ TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) { return; UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); + int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id(); ash::internal::DisplayManager* display_manager = ash::Shell::GetInstance()->display_manager(); ASSERT_EQ(0, accept_count()); @@ -145,7 +145,7 @@ TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) { // Changes the resolution and apply the result. SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200)); EXPECT_TRUE(IsNotificationVisible()); EXPECT_FALSE(controller()->DoesNotificationTimeout()); gfx::Size resolution; @@ -204,7 +204,7 @@ TEST_F(ResolutionNotificationControllerTest, Close) { return; UpdateDisplay("100x100,150x150#150x150|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); + int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id(); ash::internal::DisplayManager* display_manager = ash::Shell::GetInstance()->display_manager(); ASSERT_EQ(0, accept_count()); @@ -212,7 +212,7 @@ TEST_F(ResolutionNotificationControllerTest, Close) { // Changes the resolution and apply the result. SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200)); EXPECT_TRUE(IsNotificationVisible()); EXPECT_FALSE(controller()->DoesNotificationTimeout()); gfx::Size resolution; @@ -256,11 +256,11 @@ TEST_F(ResolutionNotificationControllerTest, DisplayDisconnected) { return; UpdateDisplay("300x300#300x300|200x200,200x200#250x250|200x200|100x100"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); + int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id(); ash::internal::DisplayManager* display_manager = ash::Shell::GetInstance()->display_manager(); SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(100, 100)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(100, 100)); ASSERT_TRUE(IsNotificationVisible()); // Disconnects the secondary display and verifies it doesn't cause crashes. @@ -279,12 +279,12 @@ TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) { return; UpdateDisplay("300x300#300x300|200x200,250x250#250x250|200x200"); - int64 id2 = ash::ScreenAsh::GetSecondaryDisplay().id(); + int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id(); ash::internal::DisplayManager* display_manager = ash::Shell::GetInstance()->display_manager(); SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(200, 200)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200)); EXPECT_TRUE(IsNotificationVisible()); EXPECT_FALSE(controller()->DoesNotificationTimeout()); gfx::Size resolution; @@ -295,7 +295,7 @@ TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) { // Invokes SetDisplayResolutionAndNotify during the previous notification is // visible. SetDisplayResolutionAndNotify( - ScreenAsh::GetSecondaryDisplay(), gfx::Size(250, 250)); + ScreenUtil::GetSecondaryDisplay(), gfx::Size(250, 250)); EXPECT_FALSE( display_manager->GetSelectedResolutionForDisplayId(id2, &resolution)); diff --git a/ash/display/root_window_transformers_unittest.cc b/ash/display/root_window_transformers_unittest.cc index e3b5e85..9ace7df 100644 --- a/ash/display/root_window_transformers_unittest.cc +++ b/ash/display/root_window_transformers_unittest.cc @@ -7,7 +7,7 @@ #include "ash/display/display_info.h" #include "ash/display/display_manager.h" #include "ash/magnifier/magnification_controller.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" @@ -143,7 +143,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { UpdateDisplay("120x200,300x400*2"); gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); - int64 display2_id = ScreenAsh::GetSecondaryDisplay().id(); + int64 display2_id = ScreenUtil::GetSecondaryDisplay().id(); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); aura::test::EventGenerator generator1(root_windows[0]); @@ -154,7 +154,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("120,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator1.MoveMouseToInHost(40, 80); EXPECT_EQ("50,90", event_handler.GetLocationAndReset()); EXPECT_EQ("50,90", @@ -173,7 +173,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("200,0 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator1.MoveMouseToInHost(39, 120); EXPECT_EQ("110,70", event_handler.GetLocationAndReset()); EXPECT_EQ("110,70", @@ -185,7 +185,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { DisplayLayout display_layout(DisplayLayout::BOTTOM, 50); display_manager->SetLayoutForCurrentDisplays(display_layout); EXPECT_EQ("50,120 150x200", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); display_manager->SetDisplayRotation(display2_id, gfx::Display::ROTATE_270); @@ -196,7 +196,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString()); EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); EXPECT_EQ("50,120 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator2.MoveMouseToInHost(172, 219); EXPECT_EQ("95,80", event_handler.GetLocationAndReset()); EXPECT_EQ("145,200", @@ -215,7 +215,7 @@ TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString()); // Dislay must share at least 100, so the x's offset becomes 20. EXPECT_EQ("20,200 200x150", - ScreenAsh::GetSecondaryDisplay().bounds().ToString()); + ScreenUtil::GetSecondaryDisplay().bounds().ToString()); generator1.MoveMouseToInHost(39, 59); EXPECT_EQ("70,120", event_handler.GetLocationAndReset()); EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id())); @@ -236,7 +236,7 @@ TEST_F(RootWindowTransformersTest, ScaleAndMagnify) { gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay(); gfx::Display::SetInternalDisplayId(display1.id()); - gfx::Display display2 = ScreenAsh::GetSecondaryDisplay(); + gfx::Display display2 = ScreenUtil::GetSecondaryDisplay(); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); MagnificationController* magnifier = Shell::GetInstance()->magnification_controller(); @@ -257,7 +257,7 @@ TEST_F(RootWindowTransformersTest, ScaleAndMagnify) { DisplayManager* display_manager = Shell::GetInstance()->display_manager(); display_manager->SetDisplayUIScale(display1.id(), 1.25); display1 = Shell::GetScreen()->GetPrimaryDisplay(); - display2 = ScreenAsh::GetSecondaryDisplay(); + display2 = ScreenUtil::GetSecondaryDisplay(); magnifier->SetEnabled(true); EXPECT_EQ(2.0f, magnifier->GetScale()); EXPECT_EQ("0,0 375x250", display1.bounds().ToString()); diff --git a/ash/display/screen_ash.cc b/ash/display/screen_ash.cc new file mode 100644 index 0000000..7effb38 --- /dev/null +++ b/ash/display/screen_ash.cc @@ -0,0 +1,284 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/display/screen_ash.h" + +#include "ash/display/display_controller.h" +#include "ash/display/display_manager.h" +#include "ash/root_window_controller.h" +#include "ash/root_window_settings.h" +#include "ash/shelf/shelf_layout_manager.h" +#include "ash/shelf/shelf_widget.h" +#include "ash/shell.h" +#include "ash/wm/coordinate_conversion.h" +#include "base/logging.h" +#include "ui/aura/client/screen_position_client.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" + +namespace ash { + +namespace { + +internal::DisplayManager* GetDisplayManager() { + return Shell::GetInstance()->display_manager(); +} + +gfx::Display FindDisplayNearestPoint(const std::vector<gfx::Display>& displays, + const gfx::Point& point) { + int min_distance = INT_MAX; + const gfx::Display* nearest_display = NULL; + for (std::vector<gfx::Display>::const_iterator iter = displays.begin(); + iter != displays.end(); ++iter) { + const gfx::Display& display = *iter; + int distance = display.bounds().ManhattanDistanceToPoint(point); + if (distance < min_distance) { + min_distance = distance; + nearest_display = &display; + } + } + // There should always be at least one display that is less than INT_MAX away. + DCHECK(nearest_display); + return *nearest_display; +} + +const gfx::Display* FindDisplayMatching( + const std::vector<gfx::Display>& displays, + const gfx::Rect& match_rect) { + int max_area = 0; + const gfx::Display* matching = NULL; + for (std::vector<gfx::Display>::const_iterator iter = displays.begin(); + iter != displays.end(); ++iter) { + const gfx::Display& display = *iter; + gfx::Rect intersect = gfx::IntersectRects(display.bounds(), match_rect); + int area = intersect.width() * intersect.height(); + if (area > max_area) { + max_area = area; + matching = &display; + } + } + return matching; +} + +class ScreenForShutdown : public gfx::Screen { + public: + explicit ScreenForShutdown(ScreenAsh* screen_ash) + : display_list_(screen_ash->GetAllDisplays()), + primary_display_(screen_ash->GetPrimaryDisplay()) { + } + + // gfx::Screen overrides: + virtual bool IsDIPEnabled() OVERRIDE { + return true; + } + virtual gfx::Point GetCursorScreenPoint() OVERRIDE { + return gfx::Point(); + } + virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE { + return NULL; + } + virtual gfx::NativeWindow GetWindowAtScreenPoint( + const gfx::Point& point) OVERRIDE { + return NULL; + } + virtual int GetNumDisplays() const OVERRIDE { + return display_list_.size(); + } + virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE { + return display_list_; + } + virtual gfx::Display GetDisplayNearestWindow(gfx::NativeView view) + const OVERRIDE { + return primary_display_; + } + virtual gfx::Display GetDisplayNearestPoint( + const gfx::Point& point) const OVERRIDE { + return FindDisplayNearestPoint(display_list_, point); + } + virtual gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) + const OVERRIDE { + const gfx::Display* matching = + FindDisplayMatching(display_list_, match_rect); + // Fallback to the primary display if there is no matching display. + return matching ? *matching : GetPrimaryDisplay(); + } + virtual gfx::Display GetPrimaryDisplay() const OVERRIDE { + return primary_display_; + } + virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE { + NOTREACHED() << "Observer should not be added during shutdown"; + } + virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE { + } + + private: + const std::vector<gfx::Display> display_list_; + const gfx::Display primary_display_; + + DISALLOW_COPY_AND_ASSIGN(ScreenForShutdown); +}; + +} // namespace + +ScreenAsh::ScreenAsh() { +} + +ScreenAsh::~ScreenAsh() { +} + +// static +gfx::Display ScreenAsh::FindDisplayContainingPoint(const gfx::Point& point) { + return GetDisplayManager()->FindDisplayContainingPoint(point); +} + +// static +gfx::Rect ScreenAsh::GetMaximizedWindowBoundsInParent(aura::Window* window) { + if (internal::GetRootWindowController(window->GetRootWindow())->shelf()) + return GetDisplayWorkAreaBoundsInParent(window); + else + return GetDisplayBoundsInParent(window); +} + +// static +gfx::Rect ScreenAsh::GetDisplayBoundsInParent(aura::Window* window) { + return ConvertRectFromScreen( + window->parent(), + Shell::GetScreen()->GetDisplayNearestWindow(window).bounds()); +} + +// static +gfx::Rect ScreenAsh::GetDisplayWorkAreaBoundsInParent(aura::Window* window) { + return ConvertRectFromScreen( + window->parent(), + Shell::GetScreen()->GetDisplayNearestWindow(window).work_area()); +} + +// static +gfx::Rect ScreenAsh::ConvertRectToScreen(aura::Window* window, + const gfx::Rect& rect) { + gfx::Point point = rect.origin(); + aura::client::GetScreenPositionClient(window->GetRootWindow())-> + ConvertPointToScreen(window, &point); + return gfx::Rect(point, rect.size()); +} + +// static +gfx::Rect ScreenAsh::ConvertRectFromScreen(aura::Window* window, + const gfx::Rect& rect) { + gfx::Point point = rect.origin(); + aura::client::GetScreenPositionClient(window->GetRootWindow())-> + ConvertPointFromScreen(window, &point); + return gfx::Rect(point, rect.size()); +} + +// static +const gfx::Display& ScreenAsh::GetSecondaryDisplay() { + internal::DisplayManager* display_manager = GetDisplayManager(); + CHECK_EQ(2U, display_manager->GetNumDisplays()); + return display_manager->GetDisplayAt(0).id() == + Shell::GetScreen()->GetPrimaryDisplay().id() ? + display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0); +} + +// static +const gfx::Display& ScreenAsh::GetDisplayForId(int64 display_id) { + return GetDisplayManager()->GetDisplayForId(display_id); +} + +void ScreenAsh::NotifyBoundsChanged(const gfx::Display& display) { + FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, + OnDisplayBoundsChanged(display)); +} + +void ScreenAsh::NotifyDisplayAdded(const gfx::Display& display) { + FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, OnDisplayAdded(display)); +} + +void ScreenAsh::NotifyDisplayRemoved(const gfx::Display& display) { + FOR_EACH_OBSERVER( + gfx::DisplayObserver, observers_, OnDisplayRemoved(display)); +} + +bool ScreenAsh::IsDIPEnabled() { + return true; +} + +gfx::Point ScreenAsh::GetCursorScreenPoint() { + return aura::Env::GetInstance()->last_mouse_location(); +} + +gfx::NativeWindow ScreenAsh::GetWindowUnderCursor() { + return GetWindowAtScreenPoint(Shell::GetScreen()->GetCursorScreenPoint()); +} + +gfx::NativeWindow ScreenAsh::GetWindowAtScreenPoint(const gfx::Point& point) { + return wm::GetRootWindowAt(point)->GetTopWindowContainingPoint(point); +} + +int ScreenAsh::GetNumDisplays() const { + return GetDisplayManager()->GetNumDisplays(); +} + +std::vector<gfx::Display> ScreenAsh::GetAllDisplays() const { + return GetDisplayManager()->displays(); +} + +gfx::Display ScreenAsh::GetDisplayNearestWindow(gfx::NativeView window) const { + if (!window) + return GetPrimaryDisplay(); + const aura::Window* root_window = window->GetRootWindow(); + if (!root_window) + return GetPrimaryDisplay(); + int64 id = internal::GetRootWindowSettings(root_window)->display_id; + // if id is |kInvaildDisplayID|, it's being deleted. + DCHECK(id != gfx::Display::kInvalidDisplayID); + + internal::DisplayManager* display_manager = GetDisplayManager(); + // RootWindow needs Display to determine its device scale factor + // for non desktop display. + if (display_manager->non_desktop_display().id() == id) + return display_manager->non_desktop_display(); + return display_manager->GetDisplayForId(id); +} + +gfx::Display ScreenAsh::GetDisplayNearestPoint(const gfx::Point& point) const { + const gfx::Display& display = + GetDisplayManager()->FindDisplayContainingPoint(point); + if (display.is_valid()) + return display; + // Fallback to the display that has the shortest Manhattan distance from + // the |point|. This is correct in the only areas that matter, namely in the + // corners between the physical screens. + return FindDisplayNearestPoint(GetDisplayManager()->displays(), point); +} + +gfx::Display ScreenAsh::GetDisplayMatching(const gfx::Rect& match_rect) const { + if (match_rect.IsEmpty()) + return GetDisplayNearestPoint(match_rect.origin()); + const gfx::Display* matching = + FindDisplayMatching(GetDisplayManager()->displays(), match_rect); + // Fallback to the primary display if there is no matching display. + return matching ? *matching : GetPrimaryDisplay(); +} + +gfx::Display ScreenAsh::GetPrimaryDisplay() const { + return GetDisplayManager()->GetDisplayForId( + DisplayController::GetPrimaryDisplayId()); +} + +void ScreenAsh::AddObserver(gfx::DisplayObserver* observer) { + observers_.AddObserver(observer); +} + +void ScreenAsh::RemoveObserver(gfx::DisplayObserver* observer) { + observers_.RemoveObserver(observer); +} + +gfx::Screen* ScreenAsh::CloneForShutdown() { + return new ScreenForShutdown(this); +} + +} // namespace ash diff --git a/ash/display/screen_ash.h b/ash/display/screen_ash.h new file mode 100644 index 0000000..eb8cf75a --- /dev/null +++ b/ash/display/screen_ash.h @@ -0,0 +1,99 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_DISPLAY_SCREEN_ASH_H_ +#define ASH_DISPLAY_SCREEN_ASH_H_ + +#include "ash/ash_export.h" +#include "base/compiler_specific.h" +#include "base/observer_list.h" +#include "ui/gfx/screen.h" + +namespace gfx { +class Rect; +} + +namespace ash { +namespace internal { +class DisplayManager; +} + +// Aura implementation of gfx::Screen. Implemented here to avoid circular +// dependencies. +class ASH_EXPORT ScreenAsh : public gfx::Screen { + public: + ScreenAsh(); + virtual ~ScreenAsh(); + + // Finds the display that contains |point| in screeen coordinates. + // Returns invalid display if there is no display that can satisfy + // the condition. + static gfx::Display FindDisplayContainingPoint(const gfx::Point& point); + + // Returns the bounds for maximized windows in parent coordinates. + // Maximized windows trigger auto-hiding the shelf. + static gfx::Rect GetMaximizedWindowBoundsInParent(aura::Window* window); + + // Returns the display bounds in parent coordinates. + static gfx::Rect GetDisplayBoundsInParent(aura::Window* window); + + // Returns the display's work area bounds in parent coordinates. + static gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window); + + // Converts |rect| from |window|'s coordinates to the virtual screen + // coordinates. + static gfx::Rect ConvertRectToScreen(aura::Window* window, + const gfx::Rect& rect); + + // Converts |rect| from virtual screen coordinates to the |window|'s + // coordinates. + static gfx::Rect ConvertRectFromScreen(aura::Window* window, + const gfx::Rect& rect); + + // Returns a gfx::Display object for secondary display. Returns + // invalid display if there is no secondary display connected. + static const gfx::Display& GetSecondaryDisplay(); + + // Returns a gfx::Display object for the specified id. Returns + // invalid display if no such display is connected. + static const gfx::Display& GetDisplayForId(int64 display_id); + + // gfx::Screen overrides: + virtual bool IsDIPEnabled() OVERRIDE; + virtual gfx::Point GetCursorScreenPoint() OVERRIDE; + virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE; + virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) + OVERRIDE; + virtual int GetNumDisplays() const OVERRIDE; + virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE; + virtual gfx::Display GetDisplayNearestWindow( + gfx::NativeView view) const OVERRIDE; + virtual gfx::Display GetDisplayNearestPoint( + const gfx::Point& point) const OVERRIDE; + virtual gfx::Display GetDisplayMatching( + const gfx::Rect& match_rect) const OVERRIDE; + virtual gfx::Display GetPrimaryDisplay() const OVERRIDE; + virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE; + virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE; + + private: + friend class internal::DisplayManager; + + // Notifies observers of display configuration changes. + void NotifyBoundsChanged(const gfx::Display& display); + void NotifyDisplayAdded(const gfx::Display& display); + void NotifyDisplayRemoved(const gfx::Display& display); + + // Creates a screen that can be used during shutdown. + // It simply has a copy of the displays. + gfx::Screen* CloneForShutdown(); + + ObserverList<gfx::DisplayObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(ScreenAsh); +}; + +} // namespace ash + +#endif // ASH_DISPLAY_SCREEN_ASH_H_ diff --git a/ash/display/screen_position_controller_unittest.cc b/ash/display/screen_position_controller_unittest.cc index c020d5b..4f6f7d0 100644 --- a/ash/display/screen_position_controller_unittest.cc +++ b/ash/display/screen_position_controller_unittest.cc @@ -5,7 +5,7 @@ #include "ash/display/screen_position_controller.h" #include "ash/display/display_manager.h" -#include "ash/screen_ash.h" +#include "ash/screen_util.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/shell_test_api.h" @@ -230,7 +230,7 @@ TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenRotate) { // Move |window_| to the 2nd. window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50), - ScreenAsh::GetSecondaryDisplay()); + ScreenUtil::GetSecondaryDisplay()); aura::Window::Windows root_windows = Shell::GetInstance()->GetAllRootWindows(); EXPECT_EQ(root_windows[1], window_->GetRootWindow()); @@ -262,7 +262,7 @@ TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenUIScale) { // Move |window_| to the 2nd. window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50), - ScreenAsh::GetSecondaryDisplay()); + ScreenUtil::GetSecondaryDisplay()); aura::Window::Windows root_windows = Shell::GetInstance()->GetAllRootWindows(); EXPECT_EQ(root_windows[1], window_->GetRootWindow()); |