1 // Copyright 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 "chrome/browser/ui/views/app_list/linux/app_list_linux.h" 6 7 #include "base/logging.h" 8 #include "chrome/browser/ui/app_list/app_list_positioner.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "ui/gfx/display.h" 11 #include "ui/gfx/point.h" 12 #include "ui/gfx/rect.h" 13 #include "ui/gfx/size.h" 14 15 namespace { 16 17 const int kScreenWidth = 800; 18 const int kScreenHeight = 600; 19 20 const int kWindowWidth = 100; 21 const int kWindowHeight = 200; 22 23 // Size of the menu bar along the top of the screen. 24 const int kMenuBarSize = 22; 25 // Size of the normal (non-hidden) shelf. 26 const int kShelfSize = 30; 27 28 // A cursor position that is within the shelf. This must be < kShelfSize. 29 const int kCursorOnShelf = kShelfSize / 2; 30 // A cursor position that is within kWindowWidth pixels of the shelf. 31 const int kCursorNearShelfX = kShelfSize + kWindowWidth; 32 // A cursor position that is more than kWindowWidth pixels away from the shelf. 33 const int kCursorAwayFromShelfX = kCursorNearShelfX + 1; 34 // A cursor position that is within kWindowHeight pixels of the shelf. 35 const int kCursorNearShelfY = kShelfSize + kWindowHeight; 36 // A cursor position that is more than kWindowHeight pixels away from the shelf. 37 const int kCursorAwayFromShelfY = kCursorNearShelfY + 1; 38 39 // A position for the center of the window that causes the window to overlap the 40 // edge of the screen. This must be < kWindowWidth / 2 and < kWindowHeight / 2. 41 const int kWindowNearEdge = kWindowWidth / 4; 42 // A position for the center of the window that places the window away from all 43 // edges of the screen. This must be > kWindowWidth / 2, > kWindowHeight / 2, < 44 // kScreenWidth - kWindowWidth / 2 and < kScreenHeight - kWindowHeight / 2. 45 const int kWindowAwayFromEdge = 158; 46 47 } // namespace 48 49 class AppListLinuxUnitTest : public testing::Test { 50 public: 51 virtual void SetUp() OVERRIDE { 52 display_.set_bounds(gfx::Rect(0, 0, kScreenWidth, kScreenHeight)); 53 display_.set_work_area( 54 gfx::Rect(0, kMenuBarSize, kScreenWidth, kScreenHeight - kMenuBarSize)); 55 cursor_ = gfx::Point(); 56 center_window_ = false; 57 } 58 59 // Set the display work area. 60 void SetWorkArea(int x, int y, int width, int height) { 61 display_.set_work_area(gfx::Rect(x, y, width, height)); 62 } 63 64 // Sets up the test environment with the shelf along a given edge of the 65 // work area. 66 void PlaceShelf(AppListPositioner::ScreenEdge edge) { 67 switch (edge) { 68 case AppListPositioner::SCREEN_EDGE_LEFT: 69 display_.set_work_area(gfx::Rect(kShelfSize, 70 kMenuBarSize, 71 kScreenWidth - kShelfSize, 72 kScreenHeight - kMenuBarSize)); 73 break; 74 case AppListPositioner::SCREEN_EDGE_RIGHT: 75 display_.set_work_area(gfx::Rect(0, 76 kMenuBarSize, 77 kScreenWidth - kShelfSize, 78 kScreenHeight - kMenuBarSize)); 79 break; 80 case AppListPositioner::SCREEN_EDGE_TOP: 81 display_.set_work_area( 82 gfx::Rect(0, 83 kMenuBarSize + kShelfSize, 84 kScreenWidth, 85 kScreenHeight - kMenuBarSize - kShelfSize)); 86 break; 87 case AppListPositioner::SCREEN_EDGE_BOTTOM: 88 display_.set_work_area( 89 gfx::Rect(0, 90 kMenuBarSize, 91 kScreenWidth, 92 kScreenHeight - kMenuBarSize - kShelfSize)); 93 break; 94 case AppListPositioner::SCREEN_EDGE_UNKNOWN: 95 NOTREACHED(); 96 break; 97 } 98 } 99 100 // Set up the test mouse cursor in a given location. 101 void PlaceCursor(int x, int y) { 102 cursor_ = gfx::Point(x, y); 103 } 104 105 void EnableWindowCentering() { 106 center_window_ = true; 107 } 108 109 AppListPositioner::ScreenEdge ShelfEdge() const { 110 return AppListLinux::ShelfLocationInDisplay(display_); 111 } 112 113 gfx::Point DoFindAnchorPoint() const { 114 return AppListLinux::FindAnchorPoint(gfx::Size(kWindowWidth, kWindowHeight), 115 display_, 116 cursor_, 117 ShelfEdge(), 118 center_window_); 119 } 120 121 private: 122 gfx::Display display_; 123 gfx::Point cursor_; 124 bool center_window_; 125 }; 126 127 TEST_F(AppListLinuxUnitTest, ShelfLocationInDisplay) { 128 SetWorkArea(0, 0, kScreenWidth, kScreenHeight); 129 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_UNKNOWN, ShelfEdge()); 130 131 // The BOTTOM, LEFT and RIGHT tests test the case where there are two bars: 132 // one at the top and one at the bottom/left/right. The bigger one should be 133 // chosen, so TOP should not win in these cases. 134 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 135 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_BOTTOM, ShelfEdge()); 136 137 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 138 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_TOP, ShelfEdge()); 139 140 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 141 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_LEFT, ShelfEdge()); 142 143 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 144 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_RIGHT, ShelfEdge()); 145 146 // Bar at top and bottom, same size. Top should win. 147 SetWorkArea(0, 148 kMenuBarSize, 149 kScreenWidth, 150 kScreenHeight - kMenuBarSize - kMenuBarSize); 151 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_TOP, ShelfEdge()); 152 } 153 154 TEST_F(AppListLinuxUnitTest, FindAnchorPointNoShelf) { 155 // Position the app list when there is no shelf on the display. 156 PlaceCursor(0, 0); 157 // Expect the app list to be in the top-left corner. 158 EXPECT_EQ(gfx::Point(kWindowWidth / 2, kMenuBarSize + kWindowHeight / 2), 159 DoFindAnchorPoint()); 160 } 161 162 TEST_F(AppListLinuxUnitTest, FindAnchorPointMouseOffShelf) { 163 // Position the app list when the mouse is away from the shelf. 164 165 // Bottom shelf. Expect the app list to be in the bottom-left corner. 166 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 167 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorAwayFromShelfY); 168 EXPECT_EQ(gfx::Point(kWindowWidth / 2, 169 kScreenHeight - kShelfSize - kWindowHeight / 2), 170 DoFindAnchorPoint()); 171 172 // Top shelf. Expect the app list to be in the top-left corner. 173 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 174 PlaceCursor(kWindowAwayFromEdge, kMenuBarSize + kCursorAwayFromShelfY); 175 EXPECT_EQ(gfx::Point(kWindowWidth / 2, 176 kMenuBarSize + kShelfSize + kWindowHeight / 2), 177 DoFindAnchorPoint()); 178 179 // Left shelf. Expect the app list to be in the top-left corner. 180 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 181 PlaceCursor(kCursorAwayFromShelfX, kWindowAwayFromEdge); 182 EXPECT_EQ(gfx::Point(kShelfSize + kWindowWidth / 2, 183 kMenuBarSize + kWindowHeight / 2), 184 DoFindAnchorPoint()); 185 186 // Right shelf. Expect the app list to be in the top-right corner. 187 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 188 PlaceCursor(kScreenWidth - kCursorAwayFromShelfX, kWindowAwayFromEdge); 189 EXPECT_EQ(gfx::Point(kScreenWidth - kShelfSize - kWindowWidth / 2, 190 kMenuBarSize + kWindowHeight / 2), 191 DoFindAnchorPoint()); 192 } 193 194 TEST_F(AppListLinuxUnitTest, FindAnchorPointMouseOnShelf) { 195 // Position the app list when the mouse is over the shelf. 196 197 // Bottom shelf (mouse well within shelf). Expect the app list to be at 198 // the bottom centered on the mouse X coordinate. 199 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 200 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorOnShelf); 201 EXPECT_EQ(gfx::Point(kWindowAwayFromEdge, 202 kScreenHeight - kShelfSize - kWindowHeight / 2), 203 DoFindAnchorPoint()); 204 205 // Bottom shelf (outside the shelf but still close enough). 206 // Expect the app list to be at the bottom centered on the mouse X coordinate. 207 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 208 PlaceCursor(kWindowAwayFromEdge, kScreenHeight - kCursorNearShelfY); 209 EXPECT_EQ(gfx::Point(kWindowAwayFromEdge, 210 kScreenHeight - kShelfSize - kWindowHeight / 2), 211 DoFindAnchorPoint()); 212 213 // Top shelf. Expect the app list to be at the top centered on the 214 // mouse X coordinate. 215 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 216 PlaceCursor(kWindowAwayFromEdge, kMenuBarSize + kCursorNearShelfY); 217 EXPECT_EQ(gfx::Point(kWindowAwayFromEdge, 218 kMenuBarSize + kShelfSize + kWindowHeight / 2), 219 DoFindAnchorPoint()); 220 221 // Left shelf. Expect the app list to be at the left centered on the 222 // mouse Y coordinate. 223 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 224 PlaceCursor(kCursorNearShelfX, kWindowAwayFromEdge); 225 EXPECT_EQ(gfx::Point(kShelfSize + kWindowWidth / 2, kWindowAwayFromEdge), 226 DoFindAnchorPoint()); 227 228 // Right shelf. Expect the app list to be at the right centered on the 229 // mouse Y coordinate. 230 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 231 PlaceCursor(kScreenWidth - kCursorNearShelfX, kWindowAwayFromEdge); 232 EXPECT_EQ(gfx::Point(kScreenWidth - kShelfSize - kWindowWidth / 2, 233 kWindowAwayFromEdge), 234 DoFindAnchorPoint()); 235 236 // Bottom shelf. Mouse near left edge. App list must not go off screen. 237 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 238 PlaceCursor(kWindowNearEdge, kScreenHeight - kCursorOnShelf); 239 EXPECT_EQ(gfx::Point(kWindowWidth / 2, 240 kScreenHeight - kShelfSize - kWindowHeight / 2), 241 DoFindAnchorPoint()); 242 243 // Bottom shelf. Mouse near right edge. App list must not go off screen. 244 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 245 PlaceCursor(kScreenWidth - kWindowNearEdge, kScreenHeight - kCursorOnShelf); 246 EXPECT_EQ(gfx::Point(kScreenWidth - kWindowWidth / 2, 247 kScreenHeight - kShelfSize - kWindowHeight / 2), 248 DoFindAnchorPoint()); 249 } 250 251 TEST_F(AppListLinuxUnitTest, FindAnchorPointCentered) { 252 // Cursor on the top shelf; enable centered app list mode. 253 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 254 PlaceCursor(0, 0); 255 EnableWindowCentering(); 256 // Expect the app list to be in the center of the screen (ignore the cursor). 257 EXPECT_EQ(gfx::Point(kScreenWidth / 2, kScreenHeight / 2), 258 DoFindAnchorPoint()); 259 } 260