diff options
author | oshima <oshima@chromium.org> | 2016-03-24 14:33:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-24 21:34:38 +0000 |
commit | 77570cbc7acd24938eb6da1bed0d9884f31dcec1 (patch) | |
tree | 08ddb6f225ae5fc26f748f56d0ec0681eb1efb6e | |
parent | 5d4577497a8cdf24c1aaae8e6f4fc6454d2a4e69 (diff) | |
download | chromium_src-77570cbc7acd24938eb6da1bed0d9884f31dcec1.zip chromium_src-77570cbc7acd24938eb6da1bed0d9884f31dcec1.tar.gz chromium_src-77570cbc7acd24938eb6da1bed0d9884f31dcec1.tar.bz2 |
Allow moving cursors between connected displays.
* Use ComputeBoundary to detect edges instead of using DisplayPlacement.
* This also fixes a bug where wrong key was used when saving preference.
BUG=597274
TEST=covered by unit tests.
Review URL: https://codereview.chromium.org/1823913002
Cr-Commit-Position: refs/heads/master@{#383153}
-rw-r--r-- | ash/display/display_layout_store.cc | 8 | ||||
-rw-r--r-- | ash/display/display_manager_unittest.cc | 14 | ||||
-rw-r--r-- | ash/display/display_util.cc | 25 | ||||
-rw-r--r-- | ash/display/display_util.h | 3 | ||||
-rw-r--r-- | ash/display/display_util_unittest.cc | 42 | ||||
-rw-r--r-- | ash/display/extended_mouse_warp_controller.cc | 164 | ||||
-rw-r--r-- | ash/display/extended_mouse_warp_controller.h | 31 | ||||
-rw-r--r-- | ash/display/extended_mouse_warp_controller_unittest.cc | 365 | ||||
-rw-r--r-- | ash/display/unified_mouse_warp_controller.cc | 5 | ||||
-rw-r--r-- | chrome/browser/chromeos/display/display_preferences.cc | 16 | ||||
-rw-r--r-- | chrome/browser/chromeos/display/display_preferences_unittest.cc | 53 |
11 files changed, 450 insertions, 276 deletions
diff --git a/ash/display/display_layout_store.cc b/ash/display/display_layout_store.cc index 1deb3a4..faec7ab 100644 --- a/ash/display/display_layout_store.cc +++ b/ash/display/display_layout_store.cc @@ -50,6 +50,10 @@ void DisplayLayoutStore::SetDefaultDisplayPlacement( void DisplayLayoutStore::RegisterLayoutForDisplayIdList( const DisplayIdList& list, scoped_ptr<DisplayLayout> layout) { + // A dev/beta channel may have a bad layout data saved in local state. + // TODO(oshima): Consider removing this a coulpe of milestones later. + if (list.size() == 2 && layout->placement_list.size() > 1) + return; // Do not overwrite the valid data with old invalid date. if (layouts_.count(list) && !CompareDisplayIds(list[0], list[1])) @@ -67,7 +71,9 @@ void DisplayLayoutStore::RegisterLayoutForDisplayIdList( layout->placement_list[0].parent_display_id = list[0]; } } - DCHECK(DisplayLayout::Validate(list, *layout.get())) << layout->ToString(); + DCHECK(DisplayLayout::Validate(list, *layout.get())) + << "ids=" << DisplayIdListToString(list) + << ", layout=" << layout->ToString(); layouts_[list] = std::move(layout); } diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 9be39e9..7e98711 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc @@ -1999,6 +1999,19 @@ TEST_F(DisplayManagerTest, DockMode) { EXPECT_FALSE(SetDisplayUIScale(gfx::Display::kInvalidDisplayID, 1.0f)); } +// Make sure that bad layout information is ignored and does not crash. +TEST_F(DisplayManagerTest, DontRegisterBadConfig) { + if (!SupportsMultipleDisplays()) + return; + DisplayIdList list = ash::test::CreateDisplayIdList2(1, 2); + DisplayLayoutBuilder builder(1); + builder.AddDisplayPlacement(2, 1, ash::DisplayPlacement::LEFT, 0); + builder.AddDisplayPlacement(3, 1, ash::DisplayPlacement::BOTTOM, 0); + + display_manager()->layout_store()->RegisterLayoutForDisplayIdList( + list, builder.Build()); +} + class ScreenShutdownTest : public test::AshTestBase { public: ScreenShutdownTest() { @@ -2029,7 +2042,6 @@ TEST_F(ScreenShutdownTest, ScreenAfterShutdown) { UpdateDisplay("500x300,800x400"); } - #if defined(OS_CHROMEOS) namespace { diff --git a/ash/display/display_util.cc b/ash/display/display_util.cc index 7c1b7c9..02fa6c9 100644 --- a/ash/display/display_util.cc +++ b/ash/display/display_util.cc @@ -222,7 +222,7 @@ bool HasDisplayModeForUIScale(const DisplayInfo& info, float ui_scale) { return std::find_if(modes.begin(), modes.end(), comparator) != modes.end(); } -void ComputeBoundary(const gfx::Display& a_display, +bool ComputeBoundary(const gfx::Display& a_display, const gfx::Display& b_display, gfx::Rect* a_edge_in_screen, gfx::Rect* b_edge_in_screen) { @@ -240,18 +240,20 @@ void ComputeBoundary(const gfx::Display& a_display, // top bottom if (a_bounds.bottom() == b_bounds.y()) { position = DisplayPlacement::BOTTOM; - } else { - DCHECK_EQ(a_bounds.y(), b_bounds.bottom()); + } else if (a_bounds.y() == b_bounds.bottom()) { position = DisplayPlacement::TOP; + } else { + return false; } } else { - DCHECK((rr - rx) == 0); // left right if (a_bounds.right() == b_bounds.x()) { position = DisplayPlacement::RIGHT; - } else { - DCHECK_EQ(a_bounds.x(), b_bounds.right()); + } else if (a_bounds.x() == b_bounds.right()) { position = DisplayPlacement::LEFT; + } else { + DCHECK_NE(rr, rx); + return false; } } @@ -278,11 +280,12 @@ void ComputeBoundary(const gfx::Display& a_display, b_edge_in_screen->SetRect(b_bounds.right() - 1, top, 1, bottom - top); } else { a_edge_in_screen->SetRect(a_bounds.right() - 1, top, 1, bottom - top); - b_edge_in_screen->SetRect(b_bounds.y(), top, 1, bottom - top); + b_edge_in_screen->SetRect(b_bounds.x(), top, 1, bottom - top); } break; } } + return true; } gfx::Rect GetNativeEdgeBounds(AshWindowTreeHost* ash_host, @@ -383,7 +386,13 @@ void SortDisplayIdList(DisplayIdList* ids) { } std::string DisplayIdListToString(const ash::DisplayIdList& list) { - return base::Int64ToString(list[0]) + "," + base::Int64ToString(list[1]); + std::stringstream s; + const char* sep = ""; + for (int64_t id : list) { + s << sep << id; + sep = ","; + } + return s.str(); } bool CompareDisplayIds(int64_t id1, int64_t id2) { diff --git a/ash/display/display_util.h b/ash/display/display_util.h index f48ad34..3267d70 100644 --- a/ash/display/display_util.h +++ b/ash/display/display_util.h @@ -63,7 +63,8 @@ ASH_EXPORT bool SetDisplayUIScale(int64_t display_id, float scale); bool HasDisplayModeForUIScale(const DisplayInfo& info, float ui_scale); // Computes the bounds that defines the bounds between two displays. -void ComputeBoundary(const gfx::Display& primary_display, +// Returns false if two displays does not intersect. +bool ComputeBoundary(const gfx::Display& primary_display, const gfx::Display& secondary_display, gfx::Rect* primary_edge_in_screen, gfx::Rect* secondary_edge_in_screen); diff --git a/ash/display/display_util_unittest.cc b/ash/display/display_util_unittest.cc index 14e3b03..10866ba 100644 --- a/ash/display/display_util_unittest.cc +++ b/ash/display/display_util_unittest.cc @@ -98,12 +98,26 @@ TEST_F(DisplayUtilTest, GenerateDisplayIdList) { list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); EXPECT_EQ(1, list[0]); EXPECT_EQ(10, list[1]); + + int64_t three_ids[] = {10, 5, 1}; + list = GenerateDisplayIdList(std::begin(three_ids), std::end(three_ids)); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(1, list[0]); + EXPECT_EQ(5, list[1]); + EXPECT_EQ(10, list[2]); } { int64_t ids[] = {10, 100}; list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); EXPECT_EQ(10, list[0]); EXPECT_EQ(100, list[1]); + + int64_t three_ids[] = {10, 100, 1000}; + list = GenerateDisplayIdList(std::begin(three_ids), std::end(three_ids)); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(10, list[0]); + EXPECT_EQ(100, list[1]); + EXPECT_EQ(1000, list[2]); } { test::ScopedSetInternalDisplayId set_internal(100); @@ -116,6 +130,13 @@ TEST_F(DisplayUtilTest, GenerateDisplayIdList) { list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); EXPECT_EQ(100, list[0]); EXPECT_EQ(10, list[1]); + + int64_t three_ids[] = {10, 100, 1000}; + list = GenerateDisplayIdList(std::begin(three_ids), std::end(three_ids)); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(100, list[0]); + EXPECT_EQ(10, list[1]); + EXPECT_EQ(1000, list[2]); } { test::ScopedSetInternalDisplayId set_internal(10); @@ -128,6 +149,27 @@ TEST_F(DisplayUtilTest, GenerateDisplayIdList) { list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); EXPECT_EQ(10, list[0]); EXPECT_EQ(100, list[1]); + + int64_t three_ids[] = {10, 100, 1000}; + list = GenerateDisplayIdList(std::begin(three_ids), std::end(three_ids)); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(10, list[0]); + EXPECT_EQ(100, list[1]); + EXPECT_EQ(1000, list[2]); + } +} + +TEST_F(DisplayUtilTest, DisplayIdListToString) { + { + int64_t ids[] = {10, 1, 16}; + DisplayIdList list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); + EXPECT_EQ("1,10,16", DisplayIdListToString(list)); + } + { + test::ScopedSetInternalDisplayId set_internal(16); + int64_t ids[] = {10, 1, 16}; + DisplayIdList list = GenerateDisplayIdList(std::begin(ids), std::end(ids)); + EXPECT_EQ("16,1,10", DisplayIdListToString(list)); } } diff --git a/ash/display/extended_mouse_warp_controller.cc b/ash/display/extended_mouse_warp_controller.cc index 879b04b..26a199d 100644 --- a/ash/display/extended_mouse_warp_controller.cc +++ b/ash/display/extended_mouse_warp_controller.cc @@ -31,8 +31,6 @@ const int kMaximumSnapHeight = 16; // this, entire edge will be used as a draggable space. const int kMinimumIndicatorHeight = 200; -const int kIndicatorThickness = 1; - // Helper method that maps a gfx::Display to an aura::Window. aura::Window* GetRootWindowForDisplayId(int64_t display_id) { return Shell::GetInstance() @@ -40,9 +38,25 @@ aura::Window* GetRootWindowForDisplayId(int64_t display_id) { ->GetRootWindowForDisplayId(display_id); } -// Helper method that maps an aura::Window to a gfx::Display. -gfx::Display GetDisplayFromWindow(aura::Window* window) { - return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window); +// Helper method that maps an aura::Window to display id; +int64_t GetDisplayIdFromWindow(aura::Window* window) { + return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window).id(); +} + +// Adjust the edge so that it has |barrier_size| gap at the top to +// trigger snap window action. +void AdjustSourceEdgeBounds(const gfx::Rect& display_bounds, + int barrier_size, + gfx::Rect* edge) { + DCHECK_GT(edge->height(), edge->width()); + int target_y = display_bounds.y() + barrier_size; + if (target_y < edge->y()) + return; + + int available_height = edge->height() - kMinimumIndicatorHeight; + if (available_height <= 0) + return; + edge->Inset(0, std::min(available_height, target_y - edge->y()), 0, 0); } } // namespace @@ -72,29 +86,32 @@ ExtendedMouseWarpController::WarpRegion::WarpRegion( ExtendedMouseWarpController::WarpRegion::~WarpRegion() {} +const gfx::Rect& +ExtendedMouseWarpController::WarpRegion::GetIndicatorBoundsForTest( + int64_t id) const { + if (a_display_id_ == id) + return a_indicator_bounds_; + CHECK_EQ(b_display_id_, id); + return b_indicator_bounds_; +} + ExtendedMouseWarpController::ExtendedMouseWarpController( aura::Window* drag_source) : drag_source_root_(drag_source), allow_non_native_event_(false) { ash::DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - - // TODO(oshima): Use ComputeBondary instead and try all combinations. - for (const auto& placement : - display_manager->GetCurrentDisplayLayout().placement_list) { - DisplayPlacement::Position position = placement.position; - const gfx::Display& a = - display_manager->GetDisplayForId(placement.parent_display_id); - const gfx::Display& b = - display_manager->GetDisplayForId(placement.display_id); - - if (position == DisplayPlacement::TOP || - position == DisplayPlacement::BOTTOM) { - AddWarpRegion(CreateHorizontalEdgeBounds(a, b, position), - drag_source != nullptr); - } else { - AddWarpRegion(CreateVerticalEdgeBounds(a, b, position), - drag_source != nullptr); + int64_t drag_source_id = drag_source ? GetDisplayIdFromWindow(drag_source) + : gfx::Display::kInvalidDisplayID; + DisplayList display_list = display_manager->active_display_list(); + while (display_list.size() > 0) { + gfx::Display display = display_list.back(); + display_list.pop_back(); + for (const gfx::Display& peer : display_list) { + scoped_ptr<WarpRegion> region = + CreateWarpRegion(display, peer, drag_source_id); + if (region) + AddWarpRegion(std::move(region), drag_source != nullptr); } } } @@ -179,92 +196,27 @@ bool ExtendedMouseWarpController::WarpMouseCursorInNativeCoords( } scoped_ptr<ExtendedMouseWarpController::WarpRegion> -ExtendedMouseWarpController::CreateHorizontalEdgeBounds( - const gfx::Display& a, - const gfx::Display& b, - DisplayPlacement::Position position) { - bool from_a = a.id() == GetDisplayFromWindow(drag_source_root_).id(); - - const gfx::Rect& a_bounds = a.bounds(); - const gfx::Rect& b_bounds = b.bounds(); - - gfx::Rect a_indicator_bounds; - a_indicator_bounds.set_x(std::max(a_bounds.x(), b_bounds.x())); - a_indicator_bounds.set_width(std::min(a_bounds.right(), b_bounds.right()) - - a_indicator_bounds.x()); - a_indicator_bounds.set_height(kIndicatorThickness); - a_indicator_bounds.set_y( - position == DisplayPlacement::TOP - ? a_bounds.y() - (from_a ? 0 : kIndicatorThickness) - : a_bounds.bottom() - (from_a ? kIndicatorThickness : 0)); - - gfx::Rect b_indicator_bounds; - b_indicator_bounds = a_indicator_bounds; - b_indicator_bounds.set_height(kIndicatorThickness); - b_indicator_bounds.set_y( - position == DisplayPlacement::TOP - ? a_bounds.y() - (from_a ? kIndicatorThickness : 0) - : a_bounds.bottom() - (from_a ? 0 : kIndicatorThickness)); - - return make_scoped_ptr( - new WarpRegion(a.id(), b.id(), a_indicator_bounds, b_indicator_bounds)); -} - -scoped_ptr<ExtendedMouseWarpController::WarpRegion> -ExtendedMouseWarpController::CreateVerticalEdgeBounds( - const gfx::Display& a, - const gfx::Display& b, - DisplayPlacement::Position position) { - int snap_height = drag_source_root_ ? kMaximumSnapHeight : 0; - bool in_a = a.id() == GetDisplayFromWindow(drag_source_root_).id(); - - const gfx::Rect& a_bounds = a.bounds(); - const gfx::Rect& b_bounds = b.bounds(); - - int upper_shared_y = std::max(a_bounds.y(), b_bounds.y()); - int lower_shared_y = std::min(a_bounds.bottom(), b_bounds.bottom()); - int shared_height = lower_shared_y - upper_shared_y; - - gfx::Rect a_indicator_bounds; - gfx::Rect b_indicator_bounds; - - int dst_x = position == DisplayPlacement::LEFT - ? a_bounds.x() - (in_a ? kIndicatorThickness : 0) - : a_bounds.right() - (in_a ? 0 : kIndicatorThickness); - b_indicator_bounds.SetRect(dst_x, upper_shared_y, kIndicatorThickness, - shared_height); - - // The indicator on the source display. - a_indicator_bounds.set_width(kIndicatorThickness); - a_indicator_bounds.set_x(position == DisplayPlacement::LEFT - ? a_bounds.x() - (in_a ? 0 : kIndicatorThickness) - : a_bounds.right() - - (in_a ? kIndicatorThickness : 0)); - - const gfx::Rect& source_bounds = in_a ? a_bounds : b_bounds; - int upper_indicator_y = source_bounds.y() + snap_height; - int lower_indicator_y = std::min(source_bounds.bottom(), lower_shared_y); - - // This gives a hight that can be used without sacrifying the snap space. - int available_space = - lower_indicator_y - std::max(upper_shared_y, upper_indicator_y); - - if (shared_height < kMinimumIndicatorHeight) { - // If the shared height is smaller than minimum height, use the - // entire height. - upper_indicator_y = upper_shared_y; - } else if (available_space < kMinimumIndicatorHeight) { - // Snap to the bottom. - upper_indicator_y = - std::max(upper_shared_y, lower_indicator_y + kMinimumIndicatorHeight); - } else { - upper_indicator_y = std::max(upper_indicator_y, upper_shared_y); +ExtendedMouseWarpController::CreateWarpRegion(const gfx::Display& a, + const gfx::Display& b, + int64_t drag_source_id) { + gfx::Rect a_edge; + gfx::Rect b_edge; + int snap_barrier = drag_source_id == gfx::Display::kInvalidDisplayID + ? 0 + : kMaximumSnapHeight; + + if (!ComputeBoundary(a, b, &a_edge, &b_edge)) + return nullptr; + + // Creates the snap window barrirer only when horizontally connected. + if (a_edge.height() > a_edge.width()) { + if (drag_source_id == a.id()) + AdjustSourceEdgeBounds(a.bounds(), snap_barrier, &a_edge); + else if (drag_source_id == b.id()) + AdjustSourceEdgeBounds(b.bounds(), snap_barrier, &b_edge); } - a_indicator_bounds.set_y(upper_indicator_y); - a_indicator_bounds.set_height(lower_indicator_y - upper_indicator_y); - return make_scoped_ptr( - new WarpRegion(a.id(), b.id(), a_indicator_bounds, b_indicator_bounds)); + return make_scoped_ptr(new WarpRegion(a.id(), b.id(), a_edge, b_edge)); } } // namespace ash diff --git a/ash/display/extended_mouse_warp_controller.h b/ash/display/extended_mouse_warp_controller.h index fa65eed..1126ef3 100644 --- a/ash/display/extended_mouse_warp_controller.h +++ b/ash/display/extended_mouse_warp_controller.h @@ -42,17 +42,16 @@ class ASH_EXPORT ExtendedMouseWarpController : public MouseWarpController { private: friend class test::DisplayManagerTestApi; + friend class ExtendedMouseWarpControllerTest; FRIEND_TEST_ALL_PREFIXES(ExtendedMouseWarpControllerTest, - IndicatorBoundsTestOnRight); - FRIEND_TEST_ALL_PREFIXES(ExtendedMouseWarpControllerTest, - IndicatorBoundsTestOnLeft); + IndicatorBoundsTestThreeDisplays); FRIEND_TEST_ALL_PREFIXES(ExtendedMouseWarpControllerTest, - IndicatorBoundsTestOnTopBottom); + IndicatorBoundsTestThreeDisplaysWithLayout); FRIEND_TEST_ALL_PREFIXES(ExtendedMouseWarpControllerTest, - IndicatorBoundsTestThreeDisplays); + IndicatorBoundsTestThreeDisplaysWithLayout2); // Defined in header file because tests need access. - class WarpRegion { + class ASH_EXPORT WarpRegion { public: WarpRegion(int64_t a_display_id, int64_t b_display_id, @@ -63,6 +62,8 @@ class ASH_EXPORT ExtendedMouseWarpController : public MouseWarpController { const gfx::Rect& a_indicator_bounds() { return a_indicator_bounds_; } const gfx::Rect& b_indicator_bounds() { return b_indicator_bounds_; } + const gfx::Rect& GetIndicatorBoundsForTest(int64_t id) const; + private: friend class ExtendedMouseWarpController; @@ -104,16 +105,14 @@ class ASH_EXPORT ExtendedMouseWarpController : public MouseWarpController { const gfx::Point& point_in_screen, bool update_mouse_location_now); - // Update the edge/indicator bounds based on the current - // display configuration. - scoped_ptr<WarpRegion> CreateHorizontalEdgeBounds( - const gfx::Display& a, - const gfx::Display& b, - DisplayPlacement::Position position); - scoped_ptr<WarpRegion> CreateVerticalEdgeBounds( - const gfx::Display& a, - const gfx::Display& b, - DisplayPlacement::Position position); + // Creates WarpRegion between display |a| and + // |b|. |drag_source_dispaly_id| is used to indicate in which + // display a drag is started, or invalid id passed if this is not + // for dragging. Returns null scoped_ptr if two displays do not + // share the edge. + scoped_ptr<WarpRegion> CreateWarpRegion(const gfx::Display& a, + const gfx::Display& b, + int64_t drag_source_dispay_id); void allow_non_native_event_for_test() { allow_non_native_event_ = true; } diff --git a/ash/display/extended_mouse_warp_controller_unittest.cc b/ash/display/extended_mouse_warp_controller_unittest.cc index 13f5e02..85988cc 100644 --- a/ash/display/extended_mouse_warp_controller_unittest.cc +++ b/ash/display/extended_mouse_warp_controller_unittest.cc @@ -4,6 +4,7 @@ #include "ash/display/extended_mouse_warp_controller.h" +#include "ash/display/display_layout_builder.h" #include "ash/display/display_layout_store.h" #include "ash/display/display_manager.h" #include "ash/display/mouse_cursor_event_filter.h" @@ -31,6 +32,18 @@ class ExtendedMouseWarpControllerTest : public test::AshTestBase { event_filter()->mouse_warp_controller_for_test()); } + size_t GetWarpRegionsCount() { + return mouse_warp_controller()->warp_regions_.size(); + } + + const ExtendedMouseWarpController::WarpRegion* GetWarpRegion(size_t index) { + return mouse_warp_controller()->warp_regions_[index].get(); + } + + const gfx::Rect& GetIndicatorBounds(int64_t id) { + return GetWarpRegion(0)->GetIndicatorBoundsForTest(id); + } + private: DISALLOW_COPY_AND_ASSIGN(ExtendedMouseWarpControllerTest); }; @@ -42,23 +55,25 @@ TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnRight) { UpdateDisplay("360x360,700x700"); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + int64_t display_0_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]).id(); DisplayManager* display_manager = Shell::GetInstance()->display_manager(); scoped_ptr<DisplayLayout> layout( test::CreateDisplayLayout(DisplayPlacement::RIGHT, 0)); + display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(359, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(360, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 16, 1, 344), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 0, 1, 360), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ(gfx::Rect(360, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + EXPECT_EQ(gfx::Rect(359, 0, 1, 360), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 16, 1, 344), GetIndicatorBounds(display_1_id)); // Move 2nd display downwards a bit. layout->placement_list[0].offset = 5; @@ -66,51 +81,41 @@ TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnRight) { event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); // This is same as before because the 2nd display's y is above // the indicator's x. - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(359, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(360, 5, 1, 355), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 16, 1, 344), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 5, 1, 355), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - EXPECT_EQ(gfx::Rect(360, 21, 1, 339), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 5, 1, 355), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + EXPECT_EQ(gfx::Rect(359, 5, 1, 355), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 21, 1, 339), GetIndicatorBounds(display_1_id)); // Move it down further so that the shared edge is shorter than // minimum hole size (160). layout->placement_list[0].offset = 200; display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(359, 200, 1, 160), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(360, 200, 1, 160), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 200, 1, 160), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 200, 1, 160), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(360, 200, 1, 160), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 200, 1, 160), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 200, 1, 160), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 200, 1, 160), GetIndicatorBounds(display_1_id)); // Now move 2nd display upwards layout->placement_list[0].offset = -5; display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(359, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(360, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 16, 1, 344), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 0, 1, 360), GetIndicatorBounds(display_1_id)); event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); // 16 px are reserved on 2nd display from top, so y must be // (16 - 5) = 11 - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(360, 11, 1, 349), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(359, 0, 1, 360), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 11, 1, 349), GetIndicatorBounds(display_1_id)); event_filter()->HideSharedEdgeIndicator(); } @@ -122,37 +127,38 @@ TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnLeft) { UpdateDisplay("360x360,700x700"); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + int64_t display_0_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]).id(); + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); scoped_ptr<DisplayLayout> layout( test::CreateDisplayLayout(DisplayPlacement::LEFT, 0)); display_manager->SetLayoutForCurrentDisplays(layout->Copy()); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(-1, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 16, 1, 344), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(-1, 0, 1, 360), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(-1, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 0, 1, 360), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(-1, 16, 1, 344), GetIndicatorBounds(display_1_id)); layout->placement_list[0].offset = 250; display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, 250, 1, 110), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 250, 1, 110), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, 250, 1, 110), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 250, 1, 110), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), GetIndicatorBounds(display_1_id)); + event_filter()->HideSharedEdgeIndicator(); } @@ -162,54 +168,49 @@ TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnTopBottom) { UpdateDisplay("360x360,700x700"); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + int64_t display_0_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = + gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]).id(); DisplayManager* display_manager = Shell::GetInstance()->display_manager(); scoped_ptr<DisplayLayout> layout( test::CreateDisplayLayout(DisplayPlacement::TOP, 0)); display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, 0, 360, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, -1, 360, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, -1, 360, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, 0, 360, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id)); layout->placement_list[0].offset = 250; display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(250, 0, 110, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(250, -1, 110, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(250, -1, 110, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(250, 0, 110, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id)); layout->placement_list[0].position = DisplayPlacement::BOTTOM; layout->placement_list[0].offset = 0; display_manager->SetLayoutForCurrentDisplays(layout->Copy()); event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, 359, 360, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, 360, 360, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 359, 360, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(0, 360, 360, 1), GetIndicatorBounds(display_1_id)); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); - ASSERT_EQ(1U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(0, 360, 360, 1), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(0, 359, 360, 1), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); + ASSERT_EQ(1U, GetWarpRegionsCount()); + EXPECT_EQ(gfx::Rect(0, 359, 360, 1), GetIndicatorBounds(display_0_id)); + EXPECT_EQ(gfx::Rect(0, 360, 360, 1), GetIndicatorBounds(display_1_id)); event_filter()->HideSharedEdgeIndicator(); } @@ -219,52 +220,152 @@ TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestThreeDisplays) { if (!SupportsMultipleDisplays()) return; - auto run_test = [this] { - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - // Left most display - event_filter()->ShowSharedEdgeIndicator(root_windows[0]); - ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(359, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(360, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1060, 16, 1, 684), - mouse_warp_controller()->warp_regions_[1]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1059, 0, 1, 700), - mouse_warp_controller()->warp_regions_[1]->b_indicator_bounds()); - - // Middle display - event_filter()->ShowSharedEdgeIndicator(root_windows[1]); - ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(360, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1059, 16, 1, 684), - mouse_warp_controller()->warp_regions_[1]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1060, 0, 1, 700), - mouse_warp_controller()->warp_regions_[1]->b_indicator_bounds()); - - // Right most display - event_filter()->ShowSharedEdgeIndicator(root_windows[2]); - ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size()); - EXPECT_EQ(gfx::Rect(360, 16, 1, 344), - mouse_warp_controller()->warp_regions_[0]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(359, 0, 1, 360), - mouse_warp_controller()->warp_regions_[0]->b_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1060, 16, 1, 684), - mouse_warp_controller()->warp_regions_[1]->a_indicator_bounds()); - EXPECT_EQ(gfx::Rect(1059, 0, 1, 700), - mouse_warp_controller()->warp_regions_[1]->b_indicator_bounds()); - - event_filter()->HideSharedEdgeIndicator(); - }; - UpdateDisplay("360x360,700x700,1000x1000"); - run_test(); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + gfx::Screen* screen = gfx::Screen::GetScreen(); + int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id(); + int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id(); + + // Drag from left most display + event_filter()->ShowSharedEdgeIndicator(root_windows[0]); + ASSERT_EQ(2U, GetWarpRegionsCount()); + const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0); + const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1); + EXPECT_EQ(gfx::Rect(359, 16, 1, 344), + region_1->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 0, 1, 360), + region_1->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1059, 0, 1, 700), + region_0->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1060, 0, 1, 700), + region_0->GetIndicatorBoundsForTest(display_2_id)); + + // Drag from middle display + event_filter()->ShowSharedEdgeIndicator(root_windows[1]); + ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size()); + region_0 = GetWarpRegion(0); + region_1 = GetWarpRegion(1); + EXPECT_EQ(gfx::Rect(359, 0, 1, 360), + region_1->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 16, 1, 344), + region_1->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1059, 16, 1, 684), + region_0->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1060, 0, 1, 700), + region_0->GetIndicatorBoundsForTest(display_2_id)); + + // Right most display + event_filter()->ShowSharedEdgeIndicator(root_windows[2]); + ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size()); + region_0 = GetWarpRegion(0); + region_1 = GetWarpRegion(1); + EXPECT_EQ(gfx::Rect(359, 0, 1, 360), + region_1->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(360, 0, 1, 360), + region_1->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1059, 0, 1, 700), + region_0->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(1060, 16, 1, 684), + region_0->GetIndicatorBoundsForTest(display_2_id)); + event_filter()->HideSharedEdgeIndicator(); + // TODO(oshima): Add test cases primary swap. +} - // TODO(oshima): Add test cases with layouts, primary swap. +TEST_F(ExtendedMouseWarpControllerTest, + IndicatorBoundsTestThreeDisplaysWithLayout) { + if (!SupportsMultipleDisplays()) + return; + UpdateDisplay("700x500,500x500,1000x1000"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + gfx::Screen* screen = gfx::Screen::GetScreen(); + int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id(); + int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id(); + + // Layout so that all displays touches togter like this: + // +-----+---+ + // | 0 | 1 | + // +-+---+--++ + // | 2 | + // +------+ + ash::DisplayLayoutBuilder builder(display_0_id); + builder.AddDisplayPlacement(display_1_id, display_0_id, + ash::DisplayPlacement::RIGHT, 0); + builder.AddDisplayPlacement(display_2_id, display_0_id, + ash::DisplayPlacement::BOTTOM, 100); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + display_manager->SetLayoutForCurrentDisplays(builder.Build()); + ASSERT_EQ(3U, GetWarpRegionsCount()); + + // Drag from 0. + event_filter()->ShowSharedEdgeIndicator(root_windows[0]); + ASSERT_EQ(3U, GetWarpRegionsCount()); + const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0); + const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1); + const ExtendedMouseWarpController::WarpRegion* region_2 = GetWarpRegion(2); + // between 2 and 0 + EXPECT_EQ(gfx::Rect(100, 499, 600, 1), + region_0->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(100, 500, 600, 1), + region_0->GetIndicatorBoundsForTest(display_2_id)); + // between 2 and 1 + EXPECT_EQ(gfx::Rect(700, 499, 400, 1), + region_1->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(700, 500, 400, 1), + region_1->GetIndicatorBoundsForTest(display_2_id)); + // between 1 and 0 + EXPECT_EQ(gfx::Rect(699, 16, 1, 484), + region_2->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(700, 0, 1, 500), + region_2->GetIndicatorBoundsForTest(display_1_id)); + event_filter()->HideSharedEdgeIndicator(); +} + +TEST_F(ExtendedMouseWarpControllerTest, + IndicatorBoundsTestThreeDisplaysWithLayout2) { + if (!SupportsMultipleDisplays()) + return; + UpdateDisplay("700x500,500x500,1000x1000"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + gfx::Screen* screen = gfx::Screen::GetScreen(); + int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id(); + int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id(); + int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id(); + + // Layout so that 0 and 1 displays are disconnected. + // +-----+ +---+ + // | 0 | |1 | + // +-+---+-+++ + // | 2 | + // +------+ + ash::DisplayLayoutBuilder builder(display_0_id); + builder.AddDisplayPlacement(display_2_id, display_0_id, + ash::DisplayPlacement::BOTTOM, 100); + builder.AddDisplayPlacement(display_1_id, display_2_id, + ash::DisplayPlacement::TOP, 800); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + display_manager->SetLayoutForCurrentDisplays(builder.Build()); + ASSERT_EQ(2U, GetWarpRegionsCount()); + + // Drag from 0. + event_filter()->ShowSharedEdgeIndicator(root_windows[0]); + ASSERT_EQ(2U, GetWarpRegionsCount()); + const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0); + const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1); + // between 2 and 0 + EXPECT_EQ(gfx::Rect(100, 499, 600, 1), + region_0->GetIndicatorBoundsForTest(display_0_id)); + EXPECT_EQ(gfx::Rect(100, 500, 600, 1), + region_0->GetIndicatorBoundsForTest(display_2_id)); + // between 2 and 1 + EXPECT_EQ(gfx::Rect(900, 499, 200, 1), + region_1->GetIndicatorBoundsForTest(display_1_id)); + EXPECT_EQ(gfx::Rect(900, 500, 200, 1), + region_1->GetIndicatorBoundsForTest(display_2_id)); + event_filter()->HideSharedEdgeIndicator(); } } // namespace ash diff --git a/ash/display/unified_mouse_warp_controller.cc b/ash/display/unified_mouse_warp_controller.cc index 267f2f5..fec9b60 100644 --- a/ash/display/unified_mouse_warp_controller.cc +++ b/ash/display/unified_mouse_warp_controller.cc @@ -131,8 +131,9 @@ void UnifiedMouseWarpController::ComputeBounds() { const gfx::Display& first = display_list[0]; const gfx::Display& second = display_list[1]; - ComputeBoundary(first, second, &first_edge_bounds_in_native_, - &second_edge_bounds_in_native_); + bool success = ComputeBoundary(first, second, &first_edge_bounds_in_native_, + &second_edge_bounds_in_native_); + DCHECK(success); first_edge_bounds_in_native_ = GetNativeEdgeBounds(GetMirroringAshWindowTreeHostForDisplayId(first.id()), diff --git a/chrome/browser/chromeos/display/display_preferences.cc b/chrome/browser/chromeos/display/display_preferences.cc index bb2a063..646cc95 100644 --- a/chrome/browser/chromeos/display/display_preferences.cc +++ b/chrome/browser/chromeos/display/display_preferences.cc @@ -127,17 +127,15 @@ void LoadDisplayLayouts() { if (it.key().find(",") != std::string::npos) { std::vector<std::string> ids_str = base::SplitString( it.key(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - int64_t id1 = gfx::Display::kInvalidDisplayID; - int64_t id2 = gfx::Display::kInvalidDisplayID; - if (!base::StringToInt64(ids_str[0], &id1) || - !base::StringToInt64(ids_str[1], &id2) || - id1 == gfx::Display::kInvalidDisplayID || - id2 == gfx::Display::kInvalidDisplayID) { - continue; + std::vector<int64_t> ids; + for (std::string id_str : ids_str) { + int64_t id; + if (!base::StringToInt64(id_str, &id)) + continue; + ids.push_back(id); } - int64_t ids[] = {id1, id2}; ash::DisplayIdList list = - ash::GenerateDisplayIdList(std::begin(ids), std::end(ids)); + ash::GenerateDisplayIdList(ids.begin(), ids.end()); layout_store->RegisterLayoutForDisplayIdList(list, std::move(layout)); } } diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc index 18f0d2a..297c286 100644 --- a/chrome/browser/chromeos/display/display_preferences_unittest.cc +++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc @@ -1053,4 +1053,57 @@ TEST_F(DisplayPreferencesTest, RestoreUnifiedMode) { EXPECT_FALSE(display_manager->IsInUnifiedMode()); } +TEST_F(DisplayPreferencesTest, SaveThreeDisplays) { + LoggedInAsUser(); + ash::DisplayManager* display_manager = + ash::Shell::GetInstance()->display_manager(); + UpdateDisplay("200x200,200x200,300x300"); + + ash::DisplayIdList list = display_manager->GetCurrentDisplayIdList(); + ASSERT_EQ(3u, list.size()); + + ash::DisplayLayoutBuilder builder(list[0]); + builder.AddDisplayPlacement(list[1], list[0], ash::DisplayPlacement::RIGHT, + 0); + builder.AddDisplayPlacement(list[2], list[0], ash::DisplayPlacement::BOTTOM, + 100); + display_manager->SetLayoutForCurrentDisplays(builder.Build()); + + const base::DictionaryValue* secondary_displays = + local_state()->GetDictionary(prefs::kSecondaryDisplays); + const base::DictionaryValue* new_value = nullptr; + EXPECT_TRUE(secondary_displays->GetDictionary( + ash::DisplayIdListToString(list), &new_value)); +} + +TEST_F(DisplayPreferencesTest, RestoreThreeDisplays) { + LoggedInAsUser(); + ash::DisplayManager* display_manager = + ash::Shell::GetInstance()->display_manager(); + int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id(); + ash::DisplayIdList list = + ash::test::CreateDisplayIdListN(3, id1, id1 + 1, id1 + 2); + + ash::DisplayLayoutBuilder builder(list[0]); + builder.AddDisplayPlacement(list[1], list[0], ash::DisplayPlacement::LEFT, 0); + builder.AddDisplayPlacement(list[2], list[1], ash::DisplayPlacement::BOTTOM, + 100); + StoreDisplayLayoutPrefForTest(list, *builder.Build()); + LoadDisplayPreferences(false); + + UpdateDisplay("200x200,200x200,300x300"); + ash::DisplayIdList new_list = display_manager->GetCurrentDisplayIdList(); + ASSERT_EQ(3u, list.size()); + ASSERT_EQ(list[0], new_list[0]); + ASSERT_EQ(list[1], new_list[1]); + ASSERT_EQ(list[2], new_list[2]); + + EXPECT_EQ(gfx::Rect(0, 0, 200, 200), + display_manager->GetDisplayForId(list[0]).bounds()); + EXPECT_EQ(gfx::Rect(-200, 0, 200, 200), + display_manager->GetDisplayForId(list[1]).bounds()); + EXPECT_EQ(gfx::Rect(-100, 200, 300, 300), + display_manager->GetDisplayForId(list[2]).bounds()); +} + } // namespace chromeos |