OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h" | 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "ash/wm/window_state.h" | 11 #include "ash/wm/window_state.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/macros.h" | 15 #include "base/macros.h" |
16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
20 #include "chrome/browser/chrome_notification_types.h" | 20 #include "chrome/browser/chrome_notification_types.h" |
| 21 #include "chrome/browser/platform_util.h" |
21 #include "chrome/browser/ui/browser.h" | 22 #include "chrome/browser/ui/browser.h" |
22 #include "chrome/browser/ui/browser_commands.h" | 23 #include "chrome/browser/ui/browser_commands.h" |
23 #include "chrome/browser/ui/browser_list.h" | 24 #include "chrome/browser/ui/browser_list.h" |
24 #include "chrome/browser/ui/browser_tabstrip.h" | 25 #include "chrome/browser/ui/browser_tabstrip.h" |
25 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 26 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
26 #include "chrome/browser/ui/views/frame/browser_view.h" | 27 #include "chrome/browser/ui/views/frame/browser_view.h" |
27 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" | 28 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" |
28 #include "chrome/browser/ui/views/tabs/tab.h" | 29 #include "chrome/browser/ui/views/tabs/tab.h" |
29 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" | 30 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" |
30 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 31 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 166 } |
166 | 167 |
167 void TabDragControllerTest::StopAnimating(TabStrip* tab_strip) { | 168 void TabDragControllerTest::StopAnimating(TabStrip* tab_strip) { |
168 tab_strip->StopAnimating(true); | 169 tab_strip->StopAnimating(true); |
169 } | 170 } |
170 | 171 |
171 void TabDragControllerTest::AddTabAndResetBrowser(Browser* browser) { | 172 void TabDragControllerTest::AddTabAndResetBrowser(Browser* browser) { |
172 AddBlankTabAndShow(browser); | 173 AddBlankTabAndShow(browser); |
173 StopAnimating(GetTabStripForBrowser(browser)); | 174 StopAnimating(GetTabStripForBrowser(browser)); |
174 ResetIDs(browser->tab_strip_model(), 0); | 175 ResetIDs(browser->tab_strip_model(), 0); |
| 176 #if defined(OS_MACOSX) |
| 177 // Currently MacViews' browser windows are shown in the background anc could |
| 178 // be obscured by other windows if there are any. This should be fixed in |
| 179 // order to be consistent with other platforms. |
| 180 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser)); |
| 181 #endif // OS_MACOSX |
175 } | 182 } |
176 | 183 |
177 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() { | 184 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() { |
178 // Create another browser. | 185 // Create another browser. |
179 Browser* browser2 = CreateBrowser(browser()->profile()); | 186 Browser* browser2 = CreateBrowser(browser()->profile()); |
180 ResetIDs(browser2->tab_strip_model(), 100); | 187 ResetIDs(browser2->tab_strip_model(), 100); |
181 | 188 |
182 // Resize the two windows so they're right next to each other. | 189 // Resize the two windows so they're right next to each other. |
183 gfx::Rect work_area = | 190 gfx::Rect work_area = |
184 gfx::Screen::GetScreen() | 191 gfx::Screen::GetScreen() |
185 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) | 192 ->GetDisplayNearestWindow(platform_util::GetViewForWindow( |
| 193 browser()->window()->GetNativeWindow())) |
186 .work_area(); | 194 .work_area(); |
187 gfx::Size half_size = | 195 gfx::Size half_size = |
188 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10); | 196 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10); |
189 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size)); | 197 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size)); |
190 browser2->window()->SetBounds(gfx::Rect( | 198 browser2->window()->SetBounds(gfx::Rect( |
191 work_area.x() + half_size.width(), work_area.y(), | 199 work_area.x() + half_size.width(), work_area.y(), |
192 half_size.width(), half_size.height())); | 200 half_size.width(), half_size.height())); |
193 return browser2; | 201 return browser2; |
194 } | 202 } |
195 | 203 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 } | 251 } |
244 | 252 |
245 private: | 253 private: |
246 aura::Window* root_window_; | 254 aura::Window* root_window_; |
247 | 255 |
248 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate); | 256 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate); |
249 }; | 257 }; |
250 | 258 |
251 #endif | 259 #endif |
252 | 260 |
253 #if !defined(OS_CHROMEOS) | 261 #if !defined(OS_CHROMEOS) && defined(USE_AURA) |
254 | 262 |
255 // Following classes verify a crash scenario. Specifically on Windows when focus | 263 // Following classes verify a crash scenario. Specifically on Windows when focus |
256 // changes it can trigger capture being lost. This was causing a crash in tab | 264 // changes it can trigger capture being lost. This was causing a crash in tab |
257 // dragging as it wasn't set up to handle this scenario. These classes | 265 // dragging as it wasn't set up to handle this scenario. These classes |
258 // synthesize this scenario. | 266 // synthesize this scenario. |
259 | 267 |
260 // Allows making ClearNativeFocus() invoke ReleaseCapture(). | 268 // Allows making ClearNativeFocus() invoke ReleaseCapture(). |
261 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura { | 269 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura { |
262 public: | 270 public: |
263 TestDesktopBrowserFrameAura( | 271 TestDesktopBrowserFrameAura( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 : public TabDragControllerTest, | 374 : public TabDragControllerTest, |
367 public ::testing::WithParamInterface<const char*> { | 375 public ::testing::WithParamInterface<const char*> { |
368 public: | 376 public: |
369 DetachToBrowserTabDragControllerTest() {} | 377 DetachToBrowserTabDragControllerTest() {} |
370 | 378 |
371 void SetUpOnMainThread() override { | 379 void SetUpOnMainThread() override { |
372 #if defined(OS_CHROMEOS) | 380 #if defined(OS_CHROMEOS) |
373 event_generator_.reset( | 381 event_generator_.reset( |
374 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow())); | 382 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow())); |
375 #endif | 383 #endif |
| 384 #if defined(OS_MACOSX) |
| 385 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 386 #endif |
376 } | 387 } |
377 | 388 |
378 InputSource input_source() const { | 389 InputSource input_source() const { |
379 return strstr(GetParam(), "mouse") ? | 390 return strstr(GetParam(), "mouse") ? |
380 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH; | 391 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH; |
381 } | 392 } |
382 | 393 |
383 // Set root window from a point in screen coordinates | 394 // Set root window from a point in screen coordinates |
384 void SetEventGeneratorRootWindow(const gfx::Point& point) { | 395 void SetEventGeneratorRootWindow(const gfx::Point& point) { |
385 if (input_source() == INPUT_SOURCE_MOUSE) | 396 if (input_source() == INPUT_SOURCE_MOUSE) |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 #else | 867 #else |
857 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow | 868 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow |
858 #endif | 869 #endif |
859 // Tests that a tab can be dragged from a browser window that is resized to full | 870 // Tests that a tab can be dragged from a browser window that is resized to full |
860 // screen. | 871 // screen. |
861 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, | 872 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
862 MAYBE_DetachFromFullsizeWindow) { | 873 MAYBE_DetachFromFullsizeWindow) { |
863 // Resize the browser window so that it is as big as the work area. | 874 // Resize the browser window so that it is as big as the work area. |
864 gfx::Rect work_area = | 875 gfx::Rect work_area = |
865 gfx::Screen::GetScreen() | 876 gfx::Screen::GetScreen() |
866 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) | 877 ->GetDisplayNearestWindow(platform_util::GetViewForWindow( |
| 878 browser()->window()->GetNativeWindow())) |
867 .work_area(); | 879 .work_area(); |
868 browser()->window()->SetBounds(work_area); | 880 browser()->window()->SetBounds(work_area); |
869 const gfx::Rect initial_bounds(browser()->window()->GetBounds()); | 881 const gfx::Rect initial_bounds(browser()->window()->GetBounds()); |
870 // Add another tab. | 882 // Add another tab. |
871 AddTabAndResetBrowser(browser()); | 883 AddTabAndResetBrowser(browser()); |
872 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 884 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
873 | 885 |
874 // Move to the first tab and drag it enough so that it detaches. | 886 // Move to the first tab and drag it enough so that it detaches. |
875 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 887 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
876 ASSERT_TRUE(PressInput(tab_0_center)); | 888 ASSERT_TRUE(PressInput(tab_0_center)); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 #else | 1228 #else |
1217 #define MAYBE_DragAll DragAll | 1229 #define MAYBE_DragAll DragAll |
1218 #endif | 1230 #endif |
1219 // Selects multiple tabs and starts dragging the window. | 1231 // Selects multiple tabs and starts dragging the window. |
1220 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) { | 1232 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) { |
1221 // Add another tab. | 1233 // Add another tab. |
1222 AddTabAndResetBrowser(browser()); | 1234 AddTabAndResetBrowser(browser()); |
1223 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1235 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
1224 browser()->tab_strip_model()->AddTabAtToSelection(0); | 1236 browser()->tab_strip_model()->AddTabAtToSelection(0); |
1225 browser()->tab_strip_model()->AddTabAtToSelection(1); | 1237 browser()->tab_strip_model()->AddTabAtToSelection(1); |
| 1238 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
1226 | 1239 |
1227 // Move to the first tab and drag it enough so that it would normally | 1240 // Move to the first tab and drag it enough so that it would normally |
1228 // detach. | 1241 // detach. |
1229 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1242 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
1230 ASSERT_TRUE(PressInput(tab_0_center)); | 1243 ASSERT_TRUE(PressInput(tab_0_center)); |
1231 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1244 ASSERT_TRUE(DragInputToNotifyWhenDone( |
1232 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1245 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
1233 base::Bind(&DragAllStep2, this, browser_list))); | 1246 base::Bind(&DragAllStep2, this, browser_list))); |
1234 QuitWhenNotDragging(); | 1247 QuitWhenNotDragging(); |
1235 | 1248 |
1236 // Should not be dragging. | 1249 // Should not be dragging. |
1237 ASSERT_FALSE(tab_strip->IsDragSessionActive()); | 1250 ASSERT_FALSE(tab_strip->IsDragSessionActive()); |
1238 ASSERT_FALSE(TabDragController::IsActive()); | 1251 ASSERT_FALSE(TabDragController::IsActive()); |
1239 | 1252 |
1240 // And there should only be one window. | 1253 // And there should only be one window. |
1241 EXPECT_EQ(1u, browser_list->size()); | 1254 EXPECT_EQ(1u, browser_list->size()); |
1242 | 1255 |
1243 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); | 1256 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
1244 | 1257 |
1245 EXPECT_FALSE(GetIsDragged(browser())); | 1258 EXPECT_FALSE(GetIsDragged(browser())); |
1246 | 1259 |
1247 // Remaining browser window should not be maximized | 1260 // Remaining browser window should not be maximized |
1248 EXPECT_FALSE(browser()->window()->IsMaximized()); | 1261 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 1262 |
| 1263 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1264 EXPECT_EQ(initial_bounds.size(), final_bounds.size()); |
| 1265 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x()); |
| 1266 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip), |
| 1267 final_bounds.origin().y()); |
1249 } | 1268 } |
1250 | 1269 |
| 1270 #if defined(OS_MACOSX) |
| 1271 // Makes sure we can drag the window using WindowServer by dragging on a tab. |
| 1272 // |
| 1273 // All other tests move the windows without relying on the WindowServer, because |
| 1274 // BridgedNativeWidget::RunMoveLoop() immediately offsets the window on first |
| 1275 // mouse drag. If we generate more mouse move events after that, it's presumed |
| 1276 // that the WindowServer will move the window. In order for that to work we need |
| 1277 // to generate global CGEvents instead of app-specific NSEvents, that's what |
| 1278 // ui_test_utils::DragAndDrop() is for. |
| 1279 // |
| 1280 // If the WindowServer fails to move the window, the final window bounds won't |
| 1281 // match the expected ones. |
| 1282 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1283 MacDragsWindowUsingCocoaMoveLoop) { |
| 1284 // Add another tab. |
| 1285 AddTabAndResetBrowser(browser()); |
| 1286 |
| 1287 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1288 browser()->tab_strip_model()->AddTabAtToSelection(0); |
| 1289 browser()->tab_strip_model()->AddTabAtToSelection(1); |
| 1290 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
| 1291 |
| 1292 // Move to the first tab and drag it enough so that it would normally |
| 1293 // detach. |
| 1294 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1295 |
| 1296 // If we don't make the interactive_ui_tests the active application, we won't |
| 1297 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop() |
| 1298 // will deadlock. |
| 1299 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1300 |
| 1301 // We need to move the window using multiple intermediate events in order |
| 1302 // to verify that CocoaWindowMoveLoop is working correctly. |
| 1303 const int steps = 10; |
| 1304 ui_test_utils::DragAndDrop( |
| 1305 tab_0_center, |
| 1306 gfx::Point(tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip)), |
| 1307 steps); |
| 1308 |
| 1309 // Should not be dragging. |
| 1310 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1311 EXPECT_FALSE(TabDragController::IsActive()); |
| 1312 EXPECT_FALSE(GetIsDragged(browser())); |
| 1313 |
| 1314 // And there should only be one window. |
| 1315 EXPECT_EQ(1u, browser_list->size()); |
| 1316 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
| 1317 |
| 1318 // Remaining browser window should not be maximized |
| 1319 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 1320 |
| 1321 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1322 EXPECT_EQ(initial_bounds.size(), final_bounds.size()); |
| 1323 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x()); |
| 1324 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip), |
| 1325 final_bounds.origin().y()); |
| 1326 } |
| 1327 |
| 1328 // Tests that when the first mouse event that starts RunMoveLoop does not |
| 1329 // overlap the Mac menu bar. BridgedNativeWidget::RunMoveLoop() shifts both the |
| 1330 // mouse position and the expected window frame after detachment. |
| 1331 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1332 MacDetachesWindowOnTopOfMacMenuBar) { |
| 1333 // Add another tab. |
| 1334 AddTabAndResetBrowser(browser()); |
| 1335 |
| 1336 // Make sure there's enough space to trigger detachment. |
| 1337 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1338 browser()->window()->SetBounds(gfx::Rect(100, 100, 400, 200)); |
| 1339 DCHECK_GT(browser()->window()->GetBounds().y(), GetDetachY(tab_strip)); |
| 1340 |
| 1341 // If we don't make the interactive_ui_tests the active application, we won't |
| 1342 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop() |
| 1343 // will deadlock. |
| 1344 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1345 |
| 1346 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1347 gfx::Point on_top_of_menu_bar(tab_0_center.x(), 0); |
| 1348 ui_test_utils::DragAndDrop(tab_0_center, on_top_of_menu_bar); |
| 1349 |
| 1350 // Should not be dragging. |
| 1351 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1352 EXPECT_FALSE(TabDragController::IsActive()); |
| 1353 EXPECT_FALSE(GetIsDragged(browser())); |
| 1354 |
| 1355 // Second tab should successfully detach. |
| 1356 EXPECT_EQ(2u, browser_list->size()); |
| 1357 EXPECT_EQ("1", IDString(browser()->tab_strip_model())); |
| 1358 } |
| 1359 |
| 1360 // Detaches and reattaches second tab. Will fail if detached window is not moved |
| 1361 // synchronously at the start of BridgedNativeWidget::RunMoveLoop(): the check |
| 1362 // for expected WindowServerFrame() will fail. |
| 1363 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1364 MacDetachesAndReattachesSecondTab) { |
| 1365 using ui_test_utils::DragAndDropOperation; |
| 1366 |
| 1367 // Add another tab. |
| 1368 AddTabAndResetBrowser(browser()); |
| 1369 |
| 1370 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1371 browser()->window()->SetBounds(gfx::Rect(100, 100, 400, 200)); |
| 1372 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
| 1373 |
| 1374 gfx::Point tab_1_center(GetCenterInScreenCoordinates(tab_strip->tab_at(1))); |
| 1375 gfx::Point tab_1_shake(tab_1_center.x(), |
| 1376 tab_1_center.y() + GetDetachY(tab_strip) * 2); |
| 1377 |
| 1378 // If we don't make the interactive_ui_tests the active application, we won't |
| 1379 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop() |
| 1380 // will deadlock. |
| 1381 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1382 |
| 1383 std::list<DragAndDropOperation> operations; |
| 1384 operations.emplace_back(DragAndDropOperation::Move(tab_1_center)); |
| 1385 operations.emplace_back(DragAndDropOperation::MouseDown()); |
| 1386 operations.emplace_back(DragAndDropOperation::Move(tab_1_shake)); |
| 1387 operations.emplace_back(DragAndDropOperation::Move(tab_1_center)); |
| 1388 operations.emplace_back(DragAndDropOperation::MouseUp()); |
| 1389 |
| 1390 ui_test_utils::DragAndDrop(operations); |
| 1391 |
| 1392 // Should not be dragging. |
| 1393 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1394 EXPECT_FALSE(TabDragController::IsActive()); |
| 1395 EXPECT_FALSE(GetIsDragged(browser())); |
| 1396 |
| 1397 // And there should only be one window. |
| 1398 EXPECT_EQ(1u, browser_list->size()); |
| 1399 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
| 1400 |
| 1401 // The window should remain in its original place. |
| 1402 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1403 EXPECT_EQ(initial_bounds, final_bounds); |
| 1404 } |
| 1405 |
| 1406 // Tests that when the first mouse event that starts RunMoveLoop does not |
| 1407 // overlap the Mac menu bar. BridgedNativeWidget::RunMoveLoop() shifts both the |
| 1408 // mouse position and the expected window frame after detachment. |
| 1409 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1410 MacDetachesWindowAtTopOfScreen) { |
| 1411 using ui_test_utils::DragAndDropOperation; |
| 1412 |
| 1413 // Add another tab. |
| 1414 AddTabAndResetBrowser(browser()); |
| 1415 |
| 1416 // Make sure there's enough space to trigger detachment. |
| 1417 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1418 browser()->window()->SetBounds(gfx::Rect(2500, 200, 400, 200)); |
| 1419 DCHECK_GT(browser()->window()->GetBounds().y(), GetDetachY(tab_strip)); |
| 1420 |
| 1421 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1422 gfx::Point at_top_of_screen(tab_0_center.x(), 0); |
| 1423 gfx::Point below_top_of_screen(tab_0_center.x(), 100); |
| 1424 |
| 1425 std::list<DragAndDropOperation> operations; |
| 1426 operations.push_back(DragAndDropOperation::Move(tab_0_center)); |
| 1427 operations.push_back(DragAndDropOperation::MouseDown()); |
| 1428 operations.push_back(DragAndDropOperation::Move(at_top_of_screen)); |
| 1429 operations.push_back(DragAndDropOperation::Move(below_top_of_screen)); |
| 1430 operations.push_back(DragAndDropOperation::MouseUp()); |
| 1431 ui_test_utils::DragAndDrop(operations); |
| 1432 |
| 1433 // Should not be dragging. |
| 1434 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1435 EXPECT_FALSE(TabDragController::IsActive()); |
| 1436 EXPECT_FALSE(GetIsDragged(browser())); |
| 1437 |
| 1438 // Second tab should successfully detach. |
| 1439 EXPECT_EQ(2u, browser_list->size()); |
| 1440 EXPECT_EQ("1", IDString(browser()->tab_strip_model())); |
| 1441 |
| 1442 Browser* browser2 = browser_list->get(1); |
| 1443 EXPECT_EQ(browser2->window()->GetBounds().size(), |
| 1444 browser()->window()->GetBounds().size()); |
| 1445 } |
| 1446 |
| 1447 #endif // OS_MACOSX |
| 1448 |
1251 namespace { | 1449 namespace { |
1252 | 1450 |
1253 // Invoked from the nested message loop. | 1451 // Invoked from the nested message loop. |
1254 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test, | 1452 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test, |
1255 TabStrip* attached_tab_strip, | 1453 TabStrip* attached_tab_strip, |
1256 TabStrip* target_tab_strip, | 1454 TabStrip* target_tab_strip, |
1257 const BrowserList* browser_list) { | 1455 const BrowserList* browser_list) { |
1258 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive()); | 1456 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive()); |
1259 ASSERT_FALSE(target_tab_strip->IsDragSessionActive()); | 1457 ASSERT_FALSE(target_tab_strip->IsDragSessionActive()); |
1260 ASSERT_TRUE(TabDragController::IsActive()); | 1458 ASSERT_TRUE(TabDragController::IsActive()); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1469 MAYBE_DragSingleTabToSeparateWindow) { | 1667 MAYBE_DragSingleTabToSeparateWindow) { |
1470 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1668 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
1471 | 1669 |
1472 ResetIDs(browser()->tab_strip_model(), 0); | 1670 ResetIDs(browser()->tab_strip_model(), 0); |
1473 | 1671 |
1474 // Create another browser. | 1672 // Create another browser. |
1475 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); | 1673 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); |
1476 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); | 1674 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); |
1477 const gfx::Rect initial_bounds(browser2->window()->GetBounds()); | 1675 const gfx::Rect initial_bounds(browser2->window()->GetBounds()); |
1478 | 1676 |
| 1677 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1678 |
1479 // Move to the first tab and drag it enough so that it detaches, but not | 1679 // Move to the first tab and drag it enough so that it detaches, but not |
1480 // enough that it attaches to browser2. | 1680 // enough that it attaches to browser2. |
1481 gfx::Point tab_0_center( | 1681 gfx::Point tab_0_center( |
1482 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1682 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
1483 ASSERT_TRUE(PressInput(tab_0_center)); | 1683 ASSERT_TRUE(PressInput(tab_0_center)); |
1484 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1684 ASSERT_TRUE(DragInputToNotifyWhenDone( |
1485 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1685 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
1486 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2, | 1686 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2, |
1487 browser_list))); | 1687 browser_list))); |
1488 QuitWhenNotDragging(); | 1688 QuitWhenNotDragging(); |
(...skipping 27 matching lines...) Expand all Loading... |
1516 | 1716 |
1517 // Invoked from the nested message loop. | 1717 // Invoked from the nested message loop. |
1518 void CancelOnNewTabWhenDraggingStep2( | 1718 void CancelOnNewTabWhenDraggingStep2( |
1519 DetachToBrowserTabDragControllerTest* test, | 1719 DetachToBrowserTabDragControllerTest* test, |
1520 const BrowserList* browser_list) { | 1720 const BrowserList* browser_list) { |
1521 ASSERT_TRUE(TabDragController::IsActive()); | 1721 ASSERT_TRUE(TabDragController::IsActive()); |
1522 ASSERT_EQ(2u, browser_list->size()); | 1722 ASSERT_EQ(2u, browser_list->size()); |
1523 | 1723 |
1524 // Add another tab. This should trigger exiting the nested loop. Add at the | 1724 // Add another tab. This should trigger exiting the nested loop. Add at the |
1525 // to exercise past crash when model/tabstrip got out of sync (474082). | 1725 // to exercise past crash when model/tabstrip got out of sync (474082). |
1526 content::WindowedNotificationObserver observer( | |
1527 content::NOTIFICATION_LOAD_STOP, | |
1528 content::NotificationService::AllSources()); | |
1529 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL), | 1726 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL), |
1530 0, false); | 1727 0, false); |
1531 observer.Wait(); | |
1532 } | 1728 } |
1533 | 1729 |
1534 } // namespace | 1730 } // namespace |
1535 | 1731 |
1536 #if defined(OS_CHROMEOS) || defined(OS_LINUX) | 1732 #if defined(OS_CHROMEOS) || defined(OS_LINUX) |
1537 // TODO(sky,sad): Disabled as it fails due to resize locks with a real | 1733 // TODO(sky,sad): Disabled as it fails due to resize locks with a real |
1538 // compositor. crbug.com/331924 | 1734 // compositor. crbug.com/331924 |
1539 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging | 1735 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging |
1540 #else | 1736 #else |
1541 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging | 1737 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging |
1542 #endif | 1738 #endif |
1543 // Adds another tab, detaches into separate window, adds another tab and | 1739 // Adds another tab, detaches into separate window, adds another tab and |
1544 // verifies the run loop ends. | 1740 // verifies the run loop ends. |
1545 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, | 1741 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
1546 MAYBE_CancelOnNewTabWhenDragging) { | 1742 MAYBE_CancelOnNewTabWhenDragging) { |
1547 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1743 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
1548 | 1744 |
1549 // Add another tab to browser(). | 1745 // Add another tab to browser(). |
1550 AddTabAndResetBrowser(browser()); | 1746 AddTabAndResetBrowser(browser()); |
1551 | 1747 |
1552 // Move to the first tab and drag it enough so that it detaches. | 1748 // Move to the first tab and drag it enough so that it detaches. |
1553 gfx::Point tab_0_center( | 1749 gfx::Point tab_0_center( |
1554 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1750 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
1555 ASSERT_TRUE(PressInput(tab_0_center)); | 1751 ASSERT_TRUE(PressInput(tab_0_center)); |
| 1752 content::WindowedNotificationObserver observer( |
| 1753 content::NOTIFICATION_LOAD_STOP, |
| 1754 content::NotificationService::AllSources()); |
1556 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1755 ASSERT_TRUE(DragInputToNotifyWhenDone( |
1557 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1756 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
1558 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list))); | 1757 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list))); |
1559 QuitWhenNotDragging(); | 1758 observer.Wait(); |
| 1759 |
| 1760 // On MacViews the Drag ends while waiting for NOTIFICATION_LOAD_STOP. |
| 1761 if (TabDragController::IsActive()) { |
| 1762 QuitWhenNotDragging(); |
| 1763 } |
1560 | 1764 |
1561 // Should be two windows and not dragging. | 1765 // Should be two windows and not dragging. |
1562 ASSERT_FALSE(TabDragController::IsActive()); | 1766 ASSERT_FALSE(TabDragController::IsActive()); |
1563 ASSERT_EQ(2u, browser_list->size()); | 1767 ASSERT_EQ(2u, browser_list->size()); |
1564 for (auto* browser : *BrowserList::GetInstance()) { | 1768 for (auto* browser : *BrowserList::GetInstance()) { |
1565 EXPECT_FALSE(GetIsDragged(browser)); | 1769 EXPECT_FALSE(GetIsDragged(browser)); |
1566 // Should not be maximized | 1770 // Should not be maximized |
1567 EXPECT_FALSE(browser->window()->IsMaximized()); | 1771 EXPECT_FALSE(browser->window()->IsMaximized()); |
1568 } | 1772 } |
1569 } | 1773 } |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2135 ui_controls::DOWN); | 2339 ui_controls::DOWN); |
2136 } | 2340 } |
2137 | 2341 |
2138 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position, | 2342 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position, |
2139 const base::Closure& task) { | 2343 const base::Closure& task) { |
2140 return ui_controls::SendMouseMoveNotifyWhenDone( | 2344 return ui_controls::SendMouseMoveNotifyWhenDone( |
2141 position.x(), position.y(), task); | 2345 position.x(), position.y(), task); |
2142 } | 2346 } |
2143 | 2347 |
2144 void QuitWhenNotDragging() { | 2348 void QuitWhenNotDragging() { |
| 2349 DCHECK(TabDragController::IsActive()); |
2145 test::QuitWhenNotDraggingImpl(); | 2350 test::QuitWhenNotDraggingImpl(); |
2146 base::MessageLoop::current()->Run(); | 2351 base::MessageLoop::current()->Run(); |
2147 } | 2352 } |
2148 | 2353 |
2149 private: | 2354 private: |
2150 DISALLOW_COPY_AND_ASSIGN( | 2355 DISALLOW_COPY_AND_ASSIGN( |
2151 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest); | 2356 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest); |
2152 }; | 2357 }; |
2153 | 2358 |
2154 // Invoked from the nested message loop. | 2359 // Invoked from the nested message loop. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2412 DetachToBrowserTabDragControllerTest, | 2617 DetachToBrowserTabDragControllerTest, |
2413 ::testing::Values("mouse", "touch")); | 2618 ::testing::Values("mouse", "touch")); |
2414 INSTANTIATE_TEST_CASE_P(TabDragging, | 2619 INSTANTIATE_TEST_CASE_P(TabDragging, |
2415 DetachToBrowserTabDragControllerTestTouch, | 2620 DetachToBrowserTabDragControllerTestTouch, |
2416 ::testing::Values("touch")); | 2621 ::testing::Values("touch")); |
2417 #else | 2622 #else |
2418 INSTANTIATE_TEST_CASE_P(TabDragging, | 2623 INSTANTIATE_TEST_CASE_P(TabDragging, |
2419 DetachToBrowserTabDragControllerTest, | 2624 DetachToBrowserTabDragControllerTest, |
2420 ::testing::Values("mouse")); | 2625 ::testing::Values("mouse")); |
2421 #endif | 2626 #endif |
OLD | NEW |