1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/widget/desktop_aura/desktop_screen_x11.h"
7 #include "base/message_loop/message_loop.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gfx/display_observer.h"
10 #include "ui/views/test/views_test_base.h"
11 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
12 #include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
16 const int64 kFirstDisplay = 5321829;
17 const int64 kSecondDisplay = 928310;
19 class DesktopScreenX11Test : public views::ViewsTestBase,
20 public gfx::DisplayObserver {
22 DesktopScreenX11Test() {}
23 virtual ~DesktopScreenX11Test() {}
25 // Overridden from testing::Test:
26 virtual void SetUp() OVERRIDE {
27 ViewsTestBase::SetUp();
28 // Initialize the world to the single monitor case.
29 std::vector<gfx::Display> displays;
30 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
31 screen_.reset(new DesktopScreenX11(displays));
32 screen_->AddObserver(this);
35 virtual void TearDown() OVERRIDE {
37 ViewsTestBase::TearDown();
41 std::vector<gfx::Display> changed_display_;
42 std::vector<gfx::Display> added_display_;
43 std::vector<gfx::Display> removed_display_;
45 DesktopScreenX11* screen() { return screen_.get(); }
47 void ResetDisplayChanges() {
48 changed_display_.clear();
49 added_display_.clear();
50 removed_display_.clear();
53 Widget* BuildTopLevelDesktopWidget(const gfx::Rect& bounds) {
54 Widget* toplevel = new Widget;
55 Widget::InitParams toplevel_params =
56 CreateParams(Widget::InitParams::TYPE_WINDOW);
57 toplevel_params.native_widget =
58 new views::DesktopNativeWidgetAura(toplevel);
59 toplevel_params.bounds = bounds;
60 toplevel->Init(toplevel_params);
65 // Overridden from gfx::DisplayObserver:
66 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE {
67 changed_display_.push_back(display);
70 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE {
71 added_display_.push_back(new_display);
74 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE {
75 removed_display_.push_back(old_display);
78 scoped_ptr<DesktopScreenX11> screen_;
80 DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11Test);
83 TEST_F(DesktopScreenX11Test, BoundsChangeSingleMonitor) {
84 std::vector<gfx::Display> displays;
85 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 1024, 768)));
86 screen()->ProcessDisplayChange(displays);
88 EXPECT_EQ(1u, changed_display_.size());
89 EXPECT_EQ(0u, added_display_.size());
90 EXPECT_EQ(0u, removed_display_.size());
93 TEST_F(DesktopScreenX11Test, AddMonitorToTheRight) {
94 std::vector<gfx::Display> displays;
95 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
96 displays.push_back(gfx::Display(kSecondDisplay,
97 gfx::Rect(640, 0, 1024, 768)));
98 screen()->ProcessDisplayChange(displays);
100 EXPECT_EQ(0u, changed_display_.size());
101 EXPECT_EQ(1u, added_display_.size());
102 EXPECT_EQ(0u, removed_display_.size());
105 TEST_F(DesktopScreenX11Test, AddMonitorToTheLeft) {
106 std::vector<gfx::Display> displays;
107 displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
108 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(1024, 0, 640, 480)));
109 screen()->ProcessDisplayChange(displays);
111 EXPECT_EQ(1u, changed_display_.size());
112 EXPECT_EQ(1u, added_display_.size());
113 EXPECT_EQ(0u, removed_display_.size());
116 TEST_F(DesktopScreenX11Test, RemoveMonitorOnRight) {
117 std::vector<gfx::Display> displays;
118 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
119 displays.push_back(gfx::Display(kSecondDisplay,
120 gfx::Rect(640, 0, 1024, 768)));
121 screen()->ProcessDisplayChange(displays);
123 ResetDisplayChanges();
126 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
127 screen()->ProcessDisplayChange(displays);
129 EXPECT_EQ(0u, changed_display_.size());
130 EXPECT_EQ(0u, added_display_.size());
131 EXPECT_EQ(1u, removed_display_.size());
134 TEST_F(DesktopScreenX11Test, RemoveMonitorOnLeft) {
135 std::vector<gfx::Display> displays;
136 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
137 displays.push_back(gfx::Display(kSecondDisplay,
138 gfx::Rect(640, 0, 1024, 768)));
139 screen()->ProcessDisplayChange(displays);
141 ResetDisplayChanges();
144 displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
145 screen()->ProcessDisplayChange(displays);
147 EXPECT_EQ(1u, changed_display_.size());
148 EXPECT_EQ(0u, added_display_.size());
149 EXPECT_EQ(1u, removed_display_.size());
152 TEST_F(DesktopScreenX11Test, GetDisplayNearestPoint) {
153 std::vector<gfx::Display> displays;
154 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
155 displays.push_back(gfx::Display(kSecondDisplay,
156 gfx::Rect(640, 0, 1024, 768)));
157 screen()->ProcessDisplayChange(displays);
159 EXPECT_EQ(kSecondDisplay,
160 screen()->GetDisplayNearestPoint(gfx::Point(650, 10)).id());
161 EXPECT_EQ(kFirstDisplay,
162 screen()->GetDisplayNearestPoint(gfx::Point(10, 10)).id());
163 EXPECT_EQ(kFirstDisplay,
164 screen()->GetDisplayNearestPoint(gfx::Point(10000, 10000)).id());
167 TEST_F(DesktopScreenX11Test, GetDisplayMatchingBasic) {
168 std::vector<gfx::Display> displays;
169 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
170 displays.push_back(gfx::Display(kSecondDisplay,
171 gfx::Rect(640, 0, 1024, 768)));
172 screen()->ProcessDisplayChange(displays);
174 EXPECT_EQ(kSecondDisplay,
175 screen()->GetDisplayMatching(gfx::Rect(700, 20, 100, 100)).id());
178 TEST_F(DesktopScreenX11Test, GetDisplayMatchingOverlap) {
179 std::vector<gfx::Display> displays;
180 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
181 displays.push_back(gfx::Display(kSecondDisplay,
182 gfx::Rect(640, 0, 1024, 768)));
183 screen()->ProcessDisplayChange(displays);
185 EXPECT_EQ(kSecondDisplay,
186 screen()->GetDisplayMatching(gfx::Rect(630, 20, 100, 100)).id());
189 TEST_F(DesktopScreenX11Test, GetPrimaryDisplay) {
190 std::vector<gfx::Display> displays;
191 displays.push_back(gfx::Display(kFirstDisplay,
192 gfx::Rect(640, 0, 1024, 768)));
193 displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 640, 480)));
194 screen()->ProcessDisplayChange(displays);
196 // The first display in the list is always the primary, even if other
197 // displays are to the left in screen layout.
198 EXPECT_EQ(kFirstDisplay, screen()->GetPrimaryDisplay().id());
201 TEST_F(DesktopScreenX11Test, GetWindowAtScreenPoint) {
202 Widget* window_one = BuildTopLevelDesktopWidget(gfx::Rect(10, 10, 10, 10));
203 Widget* window_two = BuildTopLevelDesktopWidget(gfx::Rect(50, 50, 10, 10));
205 // Make sure the internal state of DesktopRootWindowHostX11 is set up
207 ASSERT_EQ(2u, DesktopRootWindowHostX11::GetAllOpenWindows().size());
209 EXPECT_EQ(window_one->GetNativeWindow(),
210 screen()->GetWindowAtScreenPoint(gfx::Point(15, 15)));
211 EXPECT_EQ(window_two->GetNativeWindow(),
212 screen()->GetWindowAtScreenPoint(gfx::Point(55, 55)));
214 screen()->GetWindowAtScreenPoint(gfx::Point(100, 100)));
216 window_one->CloseNow();
217 window_two->CloseNow();
220 TEST_F(DesktopScreenX11Test, GetDisplayNearestWindow) {
221 // Set up a two monitor situation.
222 std::vector<gfx::Display> displays;
223 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
224 displays.push_back(gfx::Display(kSecondDisplay,
225 gfx::Rect(640, 0, 1024, 768)));
226 screen()->ProcessDisplayChange(displays);
228 Widget* window_one = BuildTopLevelDesktopWidget(gfx::Rect(10, 10, 10, 10));
229 Widget* window_two = BuildTopLevelDesktopWidget(gfx::Rect(650, 50, 10, 10));
233 screen()->GetDisplayNearestWindow(window_one->GetNativeWindow()).id());
236 screen()->GetDisplayNearestWindow(window_two->GetNativeWindow()).id());
238 window_one->CloseNow();
239 window_two->CloseNow();