desktop_screen_x11_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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. 4 5#include "ui/views/widget/desktop_aura/desktop_screen_x11.h" 6 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" 13 14namespace views { 15 16const int64 kFirstDisplay = 5321829; 17const int64 kSecondDisplay = 928310; 18 19class DesktopScreenX11Test : public views::ViewsTestBase, 20 public gfx::DisplayObserver { 21 public: 22 DesktopScreenX11Test() {} 23 virtual ~DesktopScreenX11Test() {} 24 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); 33 } 34 35 virtual void TearDown() OVERRIDE { 36 screen_.reset(); 37 ViewsTestBase::TearDown(); 38 } 39 40 protected: 41 std::vector<gfx::Display> changed_display_; 42 std::vector<gfx::Display> added_display_; 43 std::vector<gfx::Display> removed_display_; 44 45 DesktopScreenX11* screen() { return screen_.get(); } 46 47 void ResetDisplayChanges() { 48 changed_display_.clear(); 49 added_display_.clear(); 50 removed_display_.clear(); 51 } 52 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); 61 return toplevel; 62 } 63 64 private: 65 // Overridden from gfx::DisplayObserver: 66 virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE { 67 changed_display_.push_back(display); 68 } 69 70 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE { 71 added_display_.push_back(new_display); 72 } 73 74 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE { 75 removed_display_.push_back(old_display); 76 } 77 78 scoped_ptr<DesktopScreenX11> screen_; 79 80 DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11Test); 81}; 82 83TEST_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); 87 88 EXPECT_EQ(1u, changed_display_.size()); 89 EXPECT_EQ(0u, added_display_.size()); 90 EXPECT_EQ(0u, removed_display_.size()); 91} 92 93TEST_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); 99 100 EXPECT_EQ(0u, changed_display_.size()); 101 EXPECT_EQ(1u, added_display_.size()); 102 EXPECT_EQ(0u, removed_display_.size()); 103} 104 105TEST_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); 110 111 EXPECT_EQ(1u, changed_display_.size()); 112 EXPECT_EQ(1u, added_display_.size()); 113 EXPECT_EQ(0u, removed_display_.size()); 114} 115 116TEST_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); 122 123 ResetDisplayChanges(); 124 125 displays.clear(); 126 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480))); 127 screen()->ProcessDisplayChange(displays); 128 129 EXPECT_EQ(0u, changed_display_.size()); 130 EXPECT_EQ(0u, added_display_.size()); 131 EXPECT_EQ(1u, removed_display_.size()); 132} 133 134TEST_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); 140 141 ResetDisplayChanges(); 142 143 displays.clear(); 144 displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768))); 145 screen()->ProcessDisplayChange(displays); 146 147 EXPECT_EQ(1u, changed_display_.size()); 148 EXPECT_EQ(0u, added_display_.size()); 149 EXPECT_EQ(1u, removed_display_.size()); 150} 151 152TEST_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); 158 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()); 165} 166 167TEST_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); 173 174 EXPECT_EQ(kSecondDisplay, 175 screen()->GetDisplayMatching(gfx::Rect(700, 20, 100, 100)).id()); 176} 177 178TEST_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); 184 185 EXPECT_EQ(kSecondDisplay, 186 screen()->GetDisplayMatching(gfx::Rect(630, 20, 100, 100)).id()); 187} 188 189TEST_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); 195 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()); 199} 200 201TEST_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)); 204 Widget* window_three = BuildTopLevelDesktopWidget(gfx::Rect(15, 15, 20, 20)); 205 206 // Make sure the internal state of DesktopRootWindowHostX11 is set up 207 // correctly. 208 ASSERT_EQ(3u, DesktopRootWindowHostX11::GetAllOpenWindows().size()); 209 210 EXPECT_EQ(window_one->GetNativeWindow(), 211 screen()->GetWindowAtScreenPoint(gfx::Point(15, 15))); 212 EXPECT_EQ(window_two->GetNativeWindow(), 213 screen()->GetWindowAtScreenPoint(gfx::Point(55, 55))); 214 EXPECT_EQ(NULL, 215 screen()->GetWindowAtScreenPoint(gfx::Point(100, 100))); 216 217 // Bring the third window in front. It overlaps with the first window. 218 // Hit-testing on the intersecting region should give the third window. 219 window_three->Activate(); 220 EXPECT_EQ(window_three->GetNativeWindow(), 221 screen()->GetWindowAtScreenPoint(gfx::Point(15, 15))); 222 223 window_one->CloseNow(); 224 window_two->CloseNow(); 225} 226 227TEST_F(DesktopScreenX11Test, GetDisplayNearestWindow) { 228 // Set up a two monitor situation. 229 std::vector<gfx::Display> displays; 230 displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480))); 231 displays.push_back(gfx::Display(kSecondDisplay, 232 gfx::Rect(640, 0, 1024, 768))); 233 screen()->ProcessDisplayChange(displays); 234 235 Widget* window_one = BuildTopLevelDesktopWidget(gfx::Rect(10, 10, 10, 10)); 236 Widget* window_two = BuildTopLevelDesktopWidget(gfx::Rect(650, 50, 10, 10)); 237 238 EXPECT_EQ( 239 kFirstDisplay, 240 screen()->GetDisplayNearestWindow(window_one->GetNativeWindow()).id()); 241 EXPECT_EQ( 242 kSecondDisplay, 243 screen()->GetDisplayNearestWindow(window_two->GetNativeWindow()).id()); 244 245 window_one->CloseNow(); 246 window_two->CloseNow(); 247} 248 249} // namespace views 250