Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc

Issue 1747803003: MacViews: Implement Tab Dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed click simulation, reimplemented CocoaWindowMoveLoop without relying on the WindowServer. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "chrome/browser/chrome_notification_types.h" 19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/platform_util.h"
20 #include "chrome/browser/ui/browser.h" 21 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_commands.h" 22 #include "chrome/browser/ui/browser_commands.h"
22 #include "chrome/browser/ui/browser_list.h" 23 #include "chrome/browser/ui/browser_list.h"
23 #include "chrome/browser/ui/browser_tabstrip.h" 24 #include "chrome/browser/ui/browser_tabstrip.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h" 25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/browser/ui/views/frame/browser_view.h" 26 #include "chrome/browser/ui/views/frame/browser_view.h"
26 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" 27 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h"
27 #include "chrome/browser/ui/views/tabs/tab.h" 28 #include "chrome/browser/ui/views/tabs/tab.h"
28 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" 29 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
29 #include "chrome/browser/ui/views/tabs/tab_strip.h" 30 #include "chrome/browser/ui/views/tabs/tab_strip.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 179 }
179 180
180 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() { 181 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() {
181 // Create another browser. 182 // Create another browser.
182 Browser* browser2 = CreateBrowser(browser()->profile()); 183 Browser* browser2 = CreateBrowser(browser()->profile());
183 ResetIDs(browser2->tab_strip_model(), 100); 184 ResetIDs(browser2->tab_strip_model(), 100);
184 185
185 // Resize the two windows so they're right next to each other. 186 // Resize the two windows so they're right next to each other.
186 gfx::Rect work_area = 187 gfx::Rect work_area =
187 display::Screen::GetScreen() 188 display::Screen::GetScreen()
188 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) 189 ->GetDisplayNearestWindow(platform_util::GetViewForWindow(
190 browser()->window()->GetNativeWindow()))
189 .work_area(); 191 .work_area();
190 gfx::Size half_size = 192 gfx::Size half_size =
191 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10); 193 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10);
192 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size)); 194 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size));
193 browser2->window()->SetBounds(gfx::Rect( 195 browser2->window()->SetBounds(gfx::Rect(
194 work_area.x() + half_size.width(), work_area.y(), 196 work_area.x() + half_size.width(), work_area.y(),
195 half_size.width(), half_size.height())); 197 half_size.width(), half_size.height()));
196 return browser2; 198 return browser2;
197 } 199 }
198 200
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 } 248 }
247 249
248 private: 250 private:
249 aura::Window* root_window_; 251 aura::Window* root_window_;
250 252
251 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate); 253 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate);
252 }; 254 };
253 255
254 #endif 256 #endif
255 257
256 #if !defined(OS_CHROMEOS) 258 #if !defined(OS_CHROMEOS) && defined(USE_AURA)
257 259
258 // Following classes verify a crash scenario. Specifically on Windows when focus 260 // Following classes verify a crash scenario. Specifically on Windows when focus
259 // changes it can trigger capture being lost. This was causing a crash in tab 261 // changes it can trigger capture being lost. This was causing a crash in tab
260 // dragging as it wasn't set up to handle this scenario. These classes 262 // dragging as it wasn't set up to handle this scenario. These classes
261 // synthesize this scenario. 263 // synthesize this scenario.
262 264
263 // Allows making ClearNativeFocus() invoke ReleaseCapture(). 265 // Allows making ClearNativeFocus() invoke ReleaseCapture().
264 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura { 266 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura {
265 public: 267 public:
266 TestDesktopBrowserFrameAura( 268 TestDesktopBrowserFrameAura(
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 : public TabDragControllerTest, 371 : public TabDragControllerTest,
370 public ::testing::WithParamInterface<const char*> { 372 public ::testing::WithParamInterface<const char*> {
371 public: 373 public:
372 DetachToBrowserTabDragControllerTest() {} 374 DetachToBrowserTabDragControllerTest() {}
373 375
374 void SetUpOnMainThread() override { 376 void SetUpOnMainThread() override {
375 #if defined(OS_CHROMEOS) 377 #if defined(OS_CHROMEOS)
376 event_generator_.reset( 378 event_generator_.reset(
377 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow())); 379 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow()));
378 #endif 380 #endif
381 #if defined(OS_MACOSX)
382 // Currently MacViews' browser windows are shown in the background and could
383 // be obscured by other windows if there are any. This should be fixed in
384 // order to be consistent with other platforms.
385 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
386 #endif // OS_MACOSX
379 } 387 }
380 388
381 InputSource input_source() const { 389 InputSource input_source() const {
382 return strstr(GetParam(), "mouse") ? 390 return strstr(GetParam(), "mouse") ?
383 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH; 391 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH;
384 } 392 }
385 393
386 // Set root window from a point in screen coordinates 394 // Set root window from a point in screen coordinates
387 void SetEventGeneratorRootWindow(const gfx::Point& point) { 395 void SetEventGeneratorRootWindow(const gfx::Point& point) {
388 if (input_source() == INPUT_SOURCE_MOUSE) 396 if (input_source() == INPUT_SOURCE_MOUSE)
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 // Both windows should not be maximized 854 // Both windows should not be maximized
847 EXPECT_FALSE(browser()->window()->IsMaximized()); 855 EXPECT_FALSE(browser()->window()->IsMaximized());
848 EXPECT_FALSE(new_browser->window()->IsMaximized()); 856 EXPECT_FALSE(new_browser->window()->IsMaximized());
849 857
850 // The tab strip should no longer have capture because the drag was ended and 858 // The tab strip should no longer have capture because the drag was ended and
851 // mouse/touch was released. 859 // mouse/touch was released.
852 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); 860 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
853 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); 861 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture());
854 } 862 }
855 863
856 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 864 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX)
857 // TODO(sky,sad): Disabled as it fails due to resize locks with a real 865 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
858 // compositor. crbug.com/331924 866 // compositor. crbug.com/331924
867 // TODO(tapted,mblsha): Disabled as the IsMaximized behavior is not consistent
tapted 2016/05/23 07:29:27 nit: add "Mac, parens" in ".. as the Mac IsMaximiz
themblsha 2016/05/26 15:13:24 Done.
868 // with other platforms. crbug.com/603562
859 #define MAYBE_DetachFromFullsizeWindow DISABLED_DetachFromFullsizeWindow 869 #define MAYBE_DetachFromFullsizeWindow DISABLED_DetachFromFullsizeWindow
860 #else 870 #else
861 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow 871 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow
862 #endif 872 #endif
863 // Tests that a tab can be dragged from a browser window that is resized to full 873 // Tests that a tab can be dragged from a browser window that is resized to full
864 // screen. 874 // screen.
865 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, 875 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
866 MAYBE_DetachFromFullsizeWindow) { 876 MAYBE_DetachFromFullsizeWindow) {
867 // Resize the browser window so that it is as big as the work area. 877 // Resize the browser window so that it is as big as the work area.
868 gfx::Rect work_area = 878 gfx::Rect work_area =
869 display::Screen::GetScreen() 879 display::Screen::GetScreen()
870 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) 880 ->GetDisplayNearestWindow(platform_util::GetViewForWindow(
881 browser()->window()->GetNativeWindow()))
871 .work_area(); 882 .work_area();
872 browser()->window()->SetBounds(work_area); 883 browser()->window()->SetBounds(work_area);
873 const gfx::Rect initial_bounds(browser()->window()->GetBounds()); 884 const gfx::Rect initial_bounds(browser()->window()->GetBounds());
874 // Add another tab. 885 // Add another tab.
875 AddTabAndResetBrowser(browser()); 886 AddTabAndResetBrowser(browser());
876 TabStrip* tab_strip = GetTabStripForBrowser(browser()); 887 TabStrip* tab_strip = GetTabStripForBrowser(browser());
877 888
878 // Move to the first tab and drag it enough so that it detaches. 889 // Move to the first tab and drag it enough so that it detaches.
879 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); 890 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
880 ASSERT_TRUE(PressInput(tab_0_center)); 891 ASSERT_TRUE(PressInput(tab_0_center));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 // Only second window should be maximized. 925 // Only second window should be maximized.
915 EXPECT_FALSE(browser()->window()->IsMaximized()); 926 EXPECT_FALSE(browser()->window()->IsMaximized());
916 EXPECT_TRUE(new_browser->window()->IsMaximized()); 927 EXPECT_TRUE(new_browser->window()->IsMaximized());
917 928
918 // The tab strip should no longer have capture because the drag was ended and 929 // The tab strip should no longer have capture because the drag was ended and
919 // mouse/touch was released. 930 // mouse/touch was released.
920 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); 931 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture());
921 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); 932 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture());
922 } 933 }
923 934
924 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 935 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX)
925 // TODO(sky,sad): Disabled as it fails due to resize locks with a real 936 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
926 // compositor. crbug.com/331924 937 // compositor. crbug.com/331924
938 // TODO(tapted,mblsha): Disabled as the IsMaximized behavior is not consistent
tapted 2016/05/23 07:29:27 ".. as the Mac IsMaximized() behavior ..".
themblsha 2016/05/26 15:13:24 Done.
939 // with other platforms. crbug.com/603562
927 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ 940 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
928 DISABLED_DetachToOwnWindowFromMaximizedWindow 941 DISABLED_DetachToOwnWindowFromMaximizedWindow
929 #else 942 #else
930 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ 943 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
931 DetachToOwnWindowFromMaximizedWindow 944 DetachToOwnWindowFromMaximizedWindow
932 #endif 945 #endif
933 // Drags from browser to a separate window and releases mouse. 946 // Drags from browser to a separate window and releases mouse.
934 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, 947 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
935 MAYBE_DetachToOwnWindowFromMaximizedWindow) { 948 MAYBE_DetachToOwnWindowFromMaximizedWindow) {
936 // Maximize the initial browser window. 949 // Maximize the initial browser window.
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 #else 1289 #else
1277 #define MAYBE_DragAll DragAll 1290 #define MAYBE_DragAll DragAll
1278 #endif 1291 #endif
1279 // Selects multiple tabs and starts dragging the window. 1292 // Selects multiple tabs and starts dragging the window.
1280 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) { 1293 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) {
1281 // Add another tab. 1294 // Add another tab.
1282 AddTabAndResetBrowser(browser()); 1295 AddTabAndResetBrowser(browser());
1283 TabStrip* tab_strip = GetTabStripForBrowser(browser()); 1296 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1284 browser()->tab_strip_model()->AddTabAtToSelection(0); 1297 browser()->tab_strip_model()->AddTabAtToSelection(0);
1285 browser()->tab_strip_model()->AddTabAtToSelection(1); 1298 browser()->tab_strip_model()->AddTabAtToSelection(1);
1299 const gfx::Rect initial_bounds = browser()->window()->GetBounds();
1286 1300
1287 // Move to the first tab and drag it enough so that it would normally 1301 // Move to the first tab and drag it enough so that it would normally
1288 // detach. 1302 // detach.
1289 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); 1303 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1290 ASSERT_TRUE(PressInput(tab_0_center)); 1304 ASSERT_TRUE(PressInput(tab_0_center));
1291 ASSERT_TRUE(DragInputToNotifyWhenDone( 1305 ASSERT_TRUE(DragInputToNotifyWhenDone(
1292 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), 1306 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1293 base::Bind(&DragAllStep2, this, browser_list))); 1307 base::Bind(&DragAllStep2, this, browser_list)));
1294 QuitWhenNotDragging(); 1308 QuitWhenNotDragging();
1295 1309
1296 // Should not be dragging. 1310 // Should not be dragging.
1297 ASSERT_FALSE(tab_strip->IsDragSessionActive()); 1311 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1298 ASSERT_FALSE(TabDragController::IsActive()); 1312 ASSERT_FALSE(TabDragController::IsActive());
1299 1313
1300 // And there should only be one window. 1314 // And there should only be one window.
1301 EXPECT_EQ(1u, browser_list->size()); 1315 EXPECT_EQ(1u, browser_list->size());
1302 1316
1303 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); 1317 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1304 1318
1305 EXPECT_FALSE(GetIsDragged(browser())); 1319 EXPECT_FALSE(GetIsDragged(browser()));
1306 1320
1307 // Remaining browser window should not be maximized 1321 // Remaining browser window should not be maximized
1308 EXPECT_FALSE(browser()->window()->IsMaximized()); 1322 EXPECT_FALSE(browser()->window()->IsMaximized());
1323
1324 const gfx::Rect final_bounds = browser()->window()->GetBounds();
1325 // Size unchanged, but it should have moved down.
1326 EXPECT_EQ(initial_bounds.size(), final_bounds.size());
1327 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x());
1328 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip),
1329 final_bounds.origin().y());
1309 } 1330 }
1310 1331
1332 #if defined(OS_MACOSX)
1333 // Makes sure we can drag the window using WindowServer by dragging on a tab.
1334 //
1335 // All other tests move the windows without relying on the WindowServer, because
1336 // BridgedNativeWidget::RunMoveLoop() immediately offsets the window on first
1337 // mouse drag. If we generate more mouse move events after that, it's presumed
1338 // that the WindowServer will move the window. In order for that to work we need
1339 // to generate global CGEvents instead of app-specific NSEvents, that's what
1340 // ui_test_utils::DragAndDrop() is for.
1341 //
1342 // If the WindowServer fails to move the window, the final window bounds won't
1343 // match the expected ones.
1344 //
1345 // Note that Mac doesn't simply rely on NSEvents, since they would not allow
1346 // correct interactions with the window server. E.g., a window could not be
1347 // dragged to another desktop Space.
1348
1349 // Test dragging all the tabs in the window, this should move the entire window.
1350 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1351 MacDragsWindowUsingCocoaMoveLoop) {
1352 // Add another tab.
1353 AddTabAndResetBrowser(browser());
1354
1355 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1356 browser()->tab_strip_model()->AddTabAtToSelection(0);
1357 browser()->tab_strip_model()->AddTabAtToSelection(1);
1358 const gfx::Rect initial_bounds = browser()->window()->GetBounds();
1359
1360 // Move to the first tab and drag it enough so that it would normally
1361 // detach.
1362 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1363
1364 // If we don't make the interactive_ui_tests the active application, we won't
1365 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop()
1366 // will deadlock.
1367 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1368
1369 // We need to move the window using multiple intermediate events in order
1370 // to verify that CocoaWindowMoveLoop is working correctly.
1371 const int steps = 10;
1372 ui_test_utils::DragAndDrop(
1373 tab_0_center,
1374 gfx::Point(tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip)),
1375 steps);
1376
1377 // Should not be dragging.
1378 EXPECT_FALSE(tab_strip->IsDragSessionActive());
1379 EXPECT_FALSE(TabDragController::IsActive());
1380 EXPECT_FALSE(GetIsDragged(browser()));
1381
1382 // And there should only be one window.
1383 EXPECT_EQ(1u, browser_list->size());
1384 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1385
1386 // Remaining browser window should not be maximized
1387 EXPECT_FALSE(browser()->window()->IsMaximized());
1388
1389 const gfx::Rect final_bounds = browser()->window()->GetBounds();
1390 EXPECT_EQ(initial_bounds.size(), final_bounds.size());
1391 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x());
1392 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip),
1393 final_bounds.origin().y());
1394 }
1395
1396 // Tests that when the first mouse event that starts RunMoveLoop does not
1397 // overlap the Mac menu bar. BridgedNativeWidget::RunMoveLoop() shifts both the
1398 // mouse position and the expected window frame after detachment.
1399 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1400 MacDetachesWindowAtTopOfScreen) {
1401 // Add another tab.
1402 AddTabAndResetBrowser(browser());
1403
1404 // Make sure there's enough space to trigger detachment.
1405 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1406 browser()->window()->SetBounds(gfx::Rect(100, 200, 400, 200));
1407 DCHECK_GT(browser()->window()->GetBounds().y(), GetDetachY(tab_strip));
1408
1409 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1410 gfx::Point at_top_of_screen(tab_0_center.x(), 0);
1411 gfx::Point below_top_of_screen(tab_0_center.x(), 100);
1412
1413 using ui_test_utils::DragAndDropOperation;
1414 std::list<DragAndDropOperation> operations;
1415 operations.push_back(DragAndDropOperation::Move(tab_0_center));
1416 operations.push_back(DragAndDropOperation::MouseDown());
1417 operations.push_back(DragAndDropOperation::Move(at_top_of_screen));
1418 operations.push_back(DragAndDropOperation::Move(below_top_of_screen));
1419 operations.push_back(DragAndDropOperation::MouseUp());
1420 ui_test_utils::DragAndDrop(operations);
1421
1422 // Should not be dragging.
1423 EXPECT_FALSE(tab_strip->IsDragSessionActive());
1424 EXPECT_FALSE(TabDragController::IsActive());
1425 EXPECT_FALSE(GetIsDragged(browser()));
1426
1427 // Second tab should successfully detach.
1428 EXPECT_EQ(2u, browser_list->size());
1429 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1430
1431 Browser* browser2 = browser_list->get(1);
1432 EXPECT_EQ(browser2->window()->GetBounds().size(),
1433 browser()->window()->GetBounds().size());
1434 }
1435
1436 // Detaches and reattaches second tab. Will fail if detached window is not moved
1437 // synchronously at the start of BridgedNativeWidget::RunMoveLoop(): the check
1438 // for expected WindowServerFrame() will fail.
1439 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1440 MacDetachesAndReattachesSecondTab) {
1441 // Add another tab.
1442 AddTabAndResetBrowser(browser());
1443
1444 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1445 browser()->window()->SetBounds(gfx::Rect(100, 100, 400, 200));
1446 const gfx::Rect initial_bounds = browser()->window()->GetBounds();
1447
1448 gfx::Point tab_1_center(GetCenterInScreenCoordinates(tab_strip->tab_at(1)));
1449 gfx::Point tab_1_shake(tab_1_center.x(),
1450 tab_1_center.y() + GetDetachY(tab_strip) * 2);
1451
1452 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1453
1454 using ui_test_utils::DragAndDropOperation;
1455 std::list<DragAndDropOperation> operations;
1456 operations.push_back(DragAndDropOperation::Move(tab_1_center));
1457 operations.push_back(DragAndDropOperation::MouseDown());
1458 operations.push_back(DragAndDropOperation::Move(tab_1_shake));
1459 operations.push_back(DragAndDropOperation::Move(tab_1_center));
1460 operations.push_back(DragAndDropOperation::MouseUp());
1461
1462 ui_test_utils::DragAndDrop(operations);
1463
1464 // Should not be dragging.
1465 EXPECT_FALSE(tab_strip->IsDragSessionActive());
1466 EXPECT_FALSE(TabDragController::IsActive());
1467 EXPECT_FALSE(GetIsDragged(browser()));
1468
1469 // And there should only be one window.
1470 EXPECT_EQ(1u, browser_list->size());
1471 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1472
1473 // The window should remain in its original place.
1474 const gfx::Rect final_bounds = browser()->window()->GetBounds();
1475 EXPECT_EQ(initial_bounds, final_bounds);
1476 }
1477 #endif // OS_MACOSX
1478
1311 namespace { 1479 namespace {
1312 1480
1313 // Invoked from the nested message loop. 1481 // Invoked from the nested message loop.
1314 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test, 1482 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test,
1315 TabStrip* attached_tab_strip, 1483 TabStrip* attached_tab_strip,
1316 TabStrip* target_tab_strip, 1484 TabStrip* target_tab_strip,
1317 const BrowserList* browser_list) { 1485 const BrowserList* browser_list) {
1318 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive()); 1486 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive());
1319 ASSERT_FALSE(target_tab_strip->IsDragSessionActive()); 1487 ASSERT_FALSE(target_tab_strip->IsDragSessionActive());
1320 ASSERT_TRUE(TabDragController::IsActive()); 1488 ASSERT_TRUE(TabDragController::IsActive());
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 MAYBE_DragSingleTabToSeparateWindow) { 1697 MAYBE_DragSingleTabToSeparateWindow) {
1530 TabStrip* tab_strip = GetTabStripForBrowser(browser()); 1698 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1531 1699
1532 ResetIDs(browser()->tab_strip_model(), 0); 1700 ResetIDs(browser()->tab_strip_model(), 0);
1533 1701
1534 // Create another browser. 1702 // Create another browser.
1535 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); 1703 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout();
1536 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); 1704 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2);
1537 const gfx::Rect initial_bounds(browser2->window()->GetBounds()); 1705 const gfx::Rect initial_bounds(browser2->window()->GetBounds());
1538 1706
1707 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1708
1539 // Move to the first tab and drag it enough so that it detaches, but not 1709 // Move to the first tab and drag it enough so that it detaches, but not
1540 // enough that it attaches to browser2. 1710 // enough that it attaches to browser2.
1541 gfx::Point tab_0_center( 1711 gfx::Point tab_0_center(
1542 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); 1712 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1543 ASSERT_TRUE(PressInput(tab_0_center)); 1713 ASSERT_TRUE(PressInput(tab_0_center));
1544 ASSERT_TRUE(DragInputToNotifyWhenDone( 1714 ASSERT_TRUE(DragInputToNotifyWhenDone(
1545 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), 1715 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1546 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2, 1716 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2,
1547 browser_list))); 1717 browser_list)));
1548 QuitWhenNotDragging(); 1718 QuitWhenNotDragging();
(...skipping 25 matching lines...) Expand all
1574 1744
1575 namespace { 1745 namespace {
1576 1746
1577 // Invoked from the nested message loop. 1747 // Invoked from the nested message loop.
1578 void CancelOnNewTabWhenDraggingStep2( 1748 void CancelOnNewTabWhenDraggingStep2(
1579 DetachToBrowserTabDragControllerTest* test, 1749 DetachToBrowserTabDragControllerTest* test,
1580 const BrowserList* browser_list) { 1750 const BrowserList* browser_list) {
1581 ASSERT_TRUE(TabDragController::IsActive()); 1751 ASSERT_TRUE(TabDragController::IsActive());
1582 ASSERT_EQ(2u, browser_list->size()); 1752 ASSERT_EQ(2u, browser_list->size());
1583 1753
1584 // Add another tab. This should trigger exiting the nested loop. Add at the
1585 // to exercise past crash when model/tabstrip got out of sync (474082).
1586 content::WindowedNotificationObserver observer(
1587 content::NOTIFICATION_LOAD_STOP,
1588 content::NotificationService::AllSources());
1589 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL), 1754 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL),
1590 0, false); 1755 0, false);
1591 observer.Wait();
1592 } 1756 }
1593 1757
1594 } // namespace 1758 } // namespace
1595 1759
1596 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 1760 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1597 // TODO(sky,sad): Disabled as it fails due to resize locks with a real 1761 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1598 // compositor. crbug.com/331924 1762 // compositor. crbug.com/331924
1599 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging 1763 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging
1600 #else 1764 #else
1601 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging 1765 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging
1602 #endif 1766 #endif
1603 // Adds another tab, detaches into separate window, adds another tab and 1767 // Adds another tab, detaches into separate window, adds another tab and
1604 // verifies the run loop ends. 1768 // verifies the run loop ends.
1605 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, 1769 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
1606 MAYBE_CancelOnNewTabWhenDragging) { 1770 MAYBE_CancelOnNewTabWhenDragging) {
1607 TabStrip* tab_strip = GetTabStripForBrowser(browser()); 1771 TabStrip* tab_strip = GetTabStripForBrowser(browser());
1608 1772
1609 // Add another tab to browser(). 1773 // Add another tab to browser().
1610 AddTabAndResetBrowser(browser()); 1774 AddTabAndResetBrowser(browser());
1611 1775
1612 // Move to the first tab and drag it enough so that it detaches. 1776 // Move to the first tab and drag it enough so that it detaches.
1613 gfx::Point tab_0_center( 1777 gfx::Point tab_0_center(
1614 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); 1778 GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
1615 ASSERT_TRUE(PressInput(tab_0_center)); 1779 ASSERT_TRUE(PressInput(tab_0_center));
1780
1781 // Add another tab. This should trigger exiting the nested loop. Add at the
tapted 2016/05/23 07:29:27 I realise this is just moved, but there's a word m
themblsha 2016/05/26 15:13:24 Done.
1782 // to exercise past crash when model/tabstrip got out of sync (474082).
tapted 2016/05/23 07:29:27 nit: update bug reference: crbug.com/474082
themblsha 2016/05/26 15:13:24 Done.
1783 content::WindowedNotificationObserver observer(
1784 content::NOTIFICATION_LOAD_STOP,
1785 content::NotificationService::AllSources());
1616 ASSERT_TRUE(DragInputToNotifyWhenDone( 1786 ASSERT_TRUE(DragInputToNotifyWhenDone(
1617 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), 1787 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
1618 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list))); 1788 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list)));
1619 QuitWhenNotDragging(); 1789 observer.Wait();
1620 1790
1621 // Should be two windows and not dragging. 1791 // Should be two windows and not dragging.
1792 ASSERT_FALSE(tab_strip->IsDragSessionActive());
1622 ASSERT_FALSE(TabDragController::IsActive()); 1793 ASSERT_FALSE(TabDragController::IsActive());
1623 ASSERT_EQ(2u, browser_list->size()); 1794 ASSERT_EQ(2u, browser_list->size());
1624 for (auto* browser : *BrowserList::GetInstance()) { 1795 for (auto* browser : *BrowserList::GetInstance()) {
1625 EXPECT_FALSE(GetIsDragged(browser)); 1796 EXPECT_FALSE(GetIsDragged(browser));
1626 // Should not be maximized 1797 // Should not be maximized
1627 EXPECT_FALSE(browser->window()->IsMaximized()); 1798 EXPECT_FALSE(browser->window()->IsMaximized());
1628 } 1799 }
1629 } 1800 }
1630 1801
1631 #if defined(OS_CHROMEOS) 1802 #if defined(OS_CHROMEOS)
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 ui_controls::DOWN); 2366 ui_controls::DOWN);
2196 } 2367 }
2197 2368
2198 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position, 2369 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position,
2199 const base::Closure& task) { 2370 const base::Closure& task) {
2200 return ui_controls::SendMouseMoveNotifyWhenDone( 2371 return ui_controls::SendMouseMoveNotifyWhenDone(
2201 position.x(), position.y(), task); 2372 position.x(), position.y(), task);
2202 } 2373 }
2203 2374
2204 void QuitWhenNotDragging() { 2375 void QuitWhenNotDragging() {
2376 DCHECK(TabDragController::IsActive());
2205 test::QuitWhenNotDraggingImpl(); 2377 test::QuitWhenNotDraggingImpl();
2206 base::MessageLoop::current()->Run(); 2378 base::MessageLoop::current()->Run();
2207 } 2379 }
2208 2380
2209 private: 2381 private:
2210 DISALLOW_COPY_AND_ASSIGN( 2382 DISALLOW_COPY_AND_ASSIGN(
2211 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest); 2383 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest);
2212 }; 2384 };
2213 2385
2214 // Invoked from the nested message loop. 2386 // Invoked from the nested message loop.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 DetachToBrowserTabDragControllerTest, 2645 DetachToBrowserTabDragControllerTest,
2474 ::testing::Values("mouse", "touch")); 2646 ::testing::Values("mouse", "touch"));
2475 INSTANTIATE_TEST_CASE_P(TabDragging, 2647 INSTANTIATE_TEST_CASE_P(TabDragging,
2476 DetachToBrowserTabDragControllerTestTouch, 2648 DetachToBrowserTabDragControllerTestTouch,
2477 ::testing::Values("touch")); 2649 ::testing::Values("touch"));
2478 #else 2650 #else
2479 INSTANTIATE_TEST_CASE_P(TabDragging, 2651 INSTANTIATE_TEST_CASE_P(TabDragging,
2480 DetachToBrowserTabDragControllerTest, 2652 DetachToBrowserTabDragControllerTest,
2481 ::testing::Values("mouse")); 2653 ::testing::Values("mouse"));
2482 #endif 2654 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698