summaryrefslogtreecommitdiffstats
path: root/ash/display
diff options
context:
space:
mode:
Diffstat (limited to 'ash/display')
-rw-r--r--ash/display/display_controller.cc127
-rw-r--r--ash/display/display_controller.h23
-rw-r--r--ash/display/display_controller_unittest.cc50
-rw-r--r--ash/display/display_manager.cc47
-rw-r--r--ash/display/display_manager.h13
-rw-r--r--ash/display/display_manager_unittest.cc43
-rw-r--r--ash/display/event_transformation_handler.cc1
-rw-r--r--ash/display/mouse_cursor_event_filter.cc6
-rw-r--r--ash/display/resolution_notification_controller_unittest.cc24
-rw-r--r--ash/display/root_window_transformers_unittest.cc18
-rw-r--r--ash/display/screen_ash.cc284
-rw-r--r--ash/display/screen_ash.h99
-rw-r--r--ash/display/screen_position_controller_unittest.cc6
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());