summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima <oshima@chromium.org>2016-03-24 14:33:23 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-24 21:34:38 +0000
commit77570cbc7acd24938eb6da1bed0d9884f31dcec1 (patch)
tree08ddb6f225ae5fc26f748f56d0ec0681eb1efb6e
parent5d4577497a8cdf24c1aaae8e6f4fc6454d2a4e69 (diff)
downloadchromium_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.cc8
-rw-r--r--ash/display/display_manager_unittest.cc14
-rw-r--r--ash/display/display_util.cc25
-rw-r--r--ash/display/display_util.h3
-rw-r--r--ash/display/display_util_unittest.cc42
-rw-r--r--ash/display/extended_mouse_warp_controller.cc164
-rw-r--r--ash/display/extended_mouse_warp_controller.h31
-rw-r--r--ash/display/extended_mouse_warp_controller_unittest.cc365
-rw-r--r--ash/display/unified_mouse_warp_controller.cc5
-rw-r--r--chrome/browser/chromeos/display/display_preferences.cc16
-rw-r--r--chrome/browser/chromeos/display/display_preferences_unittest.cc53
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