| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 176 } |
| 176 | 177 |
| 177 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() { | 178 Browser* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() { |
| 178 // Create another browser. | 179 // Create another browser. |
| 179 Browser* browser2 = CreateBrowser(browser()->profile()); | 180 Browser* browser2 = CreateBrowser(browser()->profile()); |
| 180 ResetIDs(browser2->tab_strip_model(), 100); | 181 ResetIDs(browser2->tab_strip_model(), 100); |
| 181 | 182 |
| 182 // Resize the two windows so they're right next to each other. | 183 // Resize the two windows so they're right next to each other. |
| 183 gfx::Rect work_area = | 184 gfx::Rect work_area = |
| 184 gfx::Screen::GetScreen() | 185 gfx::Screen::GetScreen() |
| 185 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) | 186 ->GetDisplayNearestWindow(platform_util::GetViewForWindow( |
| 187 browser()->window()->GetNativeWindow())) |
| 186 .work_area(); | 188 .work_area(); |
| 187 gfx::Size half_size = | 189 gfx::Size half_size = |
| 188 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10); | 190 gfx::Size(work_area.width() / 3 - 10, work_area.height() / 2 - 10); |
| 189 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size)); | 191 browser()->window()->SetBounds(gfx::Rect(work_area.origin(), half_size)); |
| 190 browser2->window()->SetBounds(gfx::Rect( | 192 browser2->window()->SetBounds(gfx::Rect( |
| 191 work_area.x() + half_size.width(), work_area.y(), | 193 work_area.x() + half_size.width(), work_area.y(), |
| 192 half_size.width(), half_size.height())); | 194 half_size.width(), half_size.height())); |
| 193 return browser2; | 195 return browser2; |
| 194 } | 196 } |
| 195 | 197 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 } | 245 } |
| 244 | 246 |
| 245 private: | 247 private: |
| 246 aura::Window* root_window_; | 248 aura::Window* root_window_; |
| 247 | 249 |
| 248 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate); | 250 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate); |
| 249 }; | 251 }; |
| 250 | 252 |
| 251 #endif | 253 #endif |
| 252 | 254 |
| 253 #if !defined(OS_CHROMEOS) | 255 #if !defined(OS_CHROMEOS) && defined(USE_AURA) |
| 254 | 256 |
| 255 // Following classes verify a crash scenario. Specifically on Windows when focus | 257 // 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 | 258 // 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 | 259 // dragging as it wasn't set up to handle this scenario. These classes |
| 258 // synthesize this scenario. | 260 // synthesize this scenario. |
| 259 | 261 |
| 260 // Allows making ClearNativeFocus() invoke ReleaseCapture(). | 262 // Allows making ClearNativeFocus() invoke ReleaseCapture(). |
| 261 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura { | 263 class TestDesktopBrowserFrameAura : public DesktopBrowserFrameAura { |
| 262 public: | 264 public: |
| 263 TestDesktopBrowserFrameAura( | 265 TestDesktopBrowserFrameAura( |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 : public TabDragControllerTest, | 368 : public TabDragControllerTest, |
| 367 public ::testing::WithParamInterface<const char*> { | 369 public ::testing::WithParamInterface<const char*> { |
| 368 public: | 370 public: |
| 369 DetachToBrowserTabDragControllerTest() {} | 371 DetachToBrowserTabDragControllerTest() {} |
| 370 | 372 |
| 371 void SetUpOnMainThread() override { | 373 void SetUpOnMainThread() override { |
| 372 #if defined(OS_CHROMEOS) | 374 #if defined(OS_CHROMEOS) |
| 373 event_generator_.reset( | 375 event_generator_.reset( |
| 374 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow())); | 376 new ui::test::EventGenerator(ash::Shell::GetPrimaryRootWindow())); |
| 375 #endif | 377 #endif |
| 378 #if defined(OS_MACOSX) |
| 379 // Currently MacViews' browser windows are shown in the background and could |
| 380 // be obscured by other windows if there are any. This should be fixed in |
| 381 // order to be consistent with other platforms. |
| 382 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 383 #endif // OS_MACOSX |
| 376 } | 384 } |
| 377 | 385 |
| 378 InputSource input_source() const { | 386 InputSource input_source() const { |
| 379 return strstr(GetParam(), "mouse") ? | 387 return strstr(GetParam(), "mouse") ? |
| 380 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH; | 388 INPUT_SOURCE_MOUSE : INPUT_SOURCE_TOUCH; |
| 381 } | 389 } |
| 382 | 390 |
| 383 // Set root window from a point in screen coordinates | 391 // Set root window from a point in screen coordinates |
| 384 void SetEventGeneratorRootWindow(const gfx::Point& point) { | 392 void SetEventGeneratorRootWindow(const gfx::Point& point) { |
| 385 if (input_source() == INPUT_SOURCE_MOUSE) | 393 if (input_source() == INPUT_SOURCE_MOUSE) |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 // Both windows should not be maximized | 850 // Both windows should not be maximized |
| 843 EXPECT_FALSE(browser()->window()->IsMaximized()); | 851 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 844 EXPECT_FALSE(new_browser->window()->IsMaximized()); | 852 EXPECT_FALSE(new_browser->window()->IsMaximized()); |
| 845 | 853 |
| 846 // The tab strip should no longer have capture because the drag was ended and | 854 // The tab strip should no longer have capture because the drag was ended and |
| 847 // mouse/touch was released. | 855 // mouse/touch was released. |
| 848 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); | 856 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); |
| 849 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); | 857 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); |
| 850 } | 858 } |
| 851 | 859 |
| 852 #if defined(OS_CHROMEOS) || defined(OS_LINUX) | 860 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX) |
| 853 // TODO(sky,sad): Disabled as it fails due to resize locks with a real | 861 // TODO(sky,sad): Disabled as it fails due to resize locks with a real |
| 854 // compositor. crbug.com/331924 | 862 // compositor. crbug.com/331924 |
| 863 // TODO(tapted,mblsha): Disabled as the IsMaximized behavior is not consistent |
| 864 // with other platforms. crbug.com/603562 |
| 855 #define MAYBE_DetachFromFullsizeWindow DISABLED_DetachFromFullsizeWindow | 865 #define MAYBE_DetachFromFullsizeWindow DISABLED_DetachFromFullsizeWindow |
| 856 #else | 866 #else |
| 857 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow | 867 #define MAYBE_DetachFromFullsizeWindow DetachFromFullsizeWindow |
| 858 #endif | 868 #endif |
| 859 // Tests that a tab can be dragged from a browser window that is resized to full | 869 // Tests that a tab can be dragged from a browser window that is resized to full |
| 860 // screen. | 870 // screen. |
| 861 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, | 871 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 862 MAYBE_DetachFromFullsizeWindow) { | 872 MAYBE_DetachFromFullsizeWindow) { |
| 863 // Resize the browser window so that it is as big as the work area. | 873 // Resize the browser window so that it is as big as the work area. |
| 864 gfx::Rect work_area = | 874 gfx::Rect work_area = |
| 865 gfx::Screen::GetScreen() | 875 gfx::Screen::GetScreen() |
| 866 ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()) | 876 ->GetDisplayNearestWindow(platform_util::GetViewForWindow( |
| 877 browser()->window()->GetNativeWindow())) |
| 867 .work_area(); | 878 .work_area(); |
| 868 browser()->window()->SetBounds(work_area); | 879 browser()->window()->SetBounds(work_area); |
| 869 const gfx::Rect initial_bounds(browser()->window()->GetBounds()); | 880 const gfx::Rect initial_bounds(browser()->window()->GetBounds()); |
| 870 // Add another tab. | 881 // Add another tab. |
| 871 AddTabAndResetBrowser(browser()); | 882 AddTabAndResetBrowser(browser()); |
| 872 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 883 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 873 | 884 |
| 874 // Move to the first tab and drag it enough so that it detaches. | 885 // 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))); | 886 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 876 ASSERT_TRUE(PressInput(tab_0_center)); | 887 ASSERT_TRUE(PressInput(tab_0_center)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 // Only second window should be maximized. | 921 // Only second window should be maximized. |
| 911 EXPECT_FALSE(browser()->window()->IsMaximized()); | 922 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 912 EXPECT_TRUE(new_browser->window()->IsMaximized()); | 923 EXPECT_TRUE(new_browser->window()->IsMaximized()); |
| 913 | 924 |
| 914 // The tab strip should no longer have capture because the drag was ended and | 925 // The tab strip should no longer have capture because the drag was ended and |
| 915 // mouse/touch was released. | 926 // mouse/touch was released. |
| 916 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); | 927 EXPECT_FALSE(tab_strip->GetWidget()->HasCapture()); |
| 917 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); | 928 EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture()); |
| 918 } | 929 } |
| 919 | 930 |
| 920 #if defined(OS_CHROMEOS) || defined(OS_LINUX) | 931 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX) |
| 921 // TODO(sky,sad): Disabled as it fails due to resize locks with a real | 932 // TODO(sky,sad): Disabled as it fails due to resize locks with a real |
| 922 // compositor. crbug.com/331924 | 933 // compositor. crbug.com/331924 |
| 934 // TODO(tapted,mblsha): Disabled as the IsMaximized behavior is not consistent |
| 935 // with other platforms. crbug.com/603562 |
| 923 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ | 936 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ |
| 924 DISABLED_DetachToOwnWindowFromMaximizedWindow | 937 DISABLED_DetachToOwnWindowFromMaximizedWindow |
| 925 #else | 938 #else |
| 926 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ | 939 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \ |
| 927 DetachToOwnWindowFromMaximizedWindow | 940 DetachToOwnWindowFromMaximizedWindow |
| 928 #endif | 941 #endif |
| 929 // Drags from browser to a separate window and releases mouse. | 942 // Drags from browser to a separate window and releases mouse. |
| 930 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, | 943 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 931 MAYBE_DetachToOwnWindowFromMaximizedWindow) { | 944 MAYBE_DetachToOwnWindowFromMaximizedWindow) { |
| 932 // Maximize the initial browser window. | 945 // Maximize the initial browser window. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 #else | 1229 #else |
| 1217 #define MAYBE_DragAll DragAll | 1230 #define MAYBE_DragAll DragAll |
| 1218 #endif | 1231 #endif |
| 1219 // Selects multiple tabs and starts dragging the window. | 1232 // Selects multiple tabs and starts dragging the window. |
| 1220 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) { | 1233 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, MAYBE_DragAll) { |
| 1221 // Add another tab. | 1234 // Add another tab. |
| 1222 AddTabAndResetBrowser(browser()); | 1235 AddTabAndResetBrowser(browser()); |
| 1223 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1236 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1224 browser()->tab_strip_model()->AddTabAtToSelection(0); | 1237 browser()->tab_strip_model()->AddTabAtToSelection(0); |
| 1225 browser()->tab_strip_model()->AddTabAtToSelection(1); | 1238 browser()->tab_strip_model()->AddTabAtToSelection(1); |
| 1239 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
| 1226 | 1240 |
| 1227 // Move to the first tab and drag it enough so that it would normally | 1241 // Move to the first tab and drag it enough so that it would normally |
| 1228 // detach. | 1242 // detach. |
| 1229 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1243 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1230 ASSERT_TRUE(PressInput(tab_0_center)); | 1244 ASSERT_TRUE(PressInput(tab_0_center)); |
| 1231 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1245 ASSERT_TRUE(DragInputToNotifyWhenDone( |
| 1232 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1246 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
| 1233 base::Bind(&DragAllStep2, this, browser_list))); | 1247 base::Bind(&DragAllStep2, this, browser_list))); |
| 1234 QuitWhenNotDragging(); | 1248 QuitWhenNotDragging(); |
| 1235 | 1249 |
| 1236 // Should not be dragging. | 1250 // Should not be dragging. |
| 1237 ASSERT_FALSE(tab_strip->IsDragSessionActive()); | 1251 ASSERT_FALSE(tab_strip->IsDragSessionActive()); |
| 1238 ASSERT_FALSE(TabDragController::IsActive()); | 1252 ASSERT_FALSE(TabDragController::IsActive()); |
| 1239 | 1253 |
| 1240 // And there should only be one window. | 1254 // And there should only be one window. |
| 1241 EXPECT_EQ(1u, browser_list->size()); | 1255 EXPECT_EQ(1u, browser_list->size()); |
| 1242 | 1256 |
| 1243 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); | 1257 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
| 1244 | 1258 |
| 1245 EXPECT_FALSE(GetIsDragged(browser())); | 1259 EXPECT_FALSE(GetIsDragged(browser())); |
| 1246 | 1260 |
| 1247 // Remaining browser window should not be maximized | 1261 // Remaining browser window should not be maximized |
| 1248 EXPECT_FALSE(browser()->window()->IsMaximized()); | 1262 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 1263 |
| 1264 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1265 // Size unchanged, but it should have moved down. |
| 1266 EXPECT_EQ(initial_bounds.size(), final_bounds.size()); |
| 1267 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x()); |
| 1268 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip), |
| 1269 final_bounds.origin().y()); |
| 1249 } | 1270 } |
| 1250 | 1271 |
| 1272 #if defined(OS_MACOSX) |
| 1273 // Makes sure we can drag the window using WindowServer by dragging on a tab. |
| 1274 // |
| 1275 // All other tests move the windows without relying on the WindowServer, because |
| 1276 // BridgedNativeWidget::RunMoveLoop() immediately offsets the window on first |
| 1277 // mouse drag. If we generate more mouse move events after that, it's presumed |
| 1278 // that the WindowServer will move the window. In order for that to work we need |
| 1279 // to generate global CGEvents instead of app-specific NSEvents, that's what |
| 1280 // ui_test_utils::DragAndDrop() is for. |
| 1281 // |
| 1282 // If the WindowServer fails to move the window, the final window bounds won't |
| 1283 // match the expected ones. |
| 1284 // |
| 1285 // Note that Mac doesn't simply rely on NSEvents, since they would not allow |
| 1286 // correct interactions with the window server. E.g., a window could not be |
| 1287 // dragged to another desktop Space. |
| 1288 |
| 1289 // Test dragging all the tabs in the window, this should move the entire window. |
| 1290 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1291 MacDragsWindowUsingCocoaMoveLoop) { |
| 1292 // Add another tab. |
| 1293 AddTabAndResetBrowser(browser()); |
| 1294 |
| 1295 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1296 browser()->tab_strip_model()->AddTabAtToSelection(0); |
| 1297 browser()->tab_strip_model()->AddTabAtToSelection(1); |
| 1298 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
| 1299 |
| 1300 // Move to the first tab and drag it enough so that it would normally |
| 1301 // detach. |
| 1302 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1303 |
| 1304 // If we don't make the interactive_ui_tests the active application, we won't |
| 1305 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop() |
| 1306 // will deadlock. |
| 1307 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1308 |
| 1309 // We need to move the window using multiple intermediate events in order |
| 1310 // to verify that CocoaWindowMoveLoop is working correctly. |
| 1311 const int steps = 10; |
| 1312 ui_test_utils::DragAndDrop( |
| 1313 tab_0_center, |
| 1314 gfx::Point(tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip)), |
| 1315 steps); |
| 1316 |
| 1317 // Should not be dragging. |
| 1318 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1319 EXPECT_FALSE(TabDragController::IsActive()); |
| 1320 EXPECT_FALSE(GetIsDragged(browser())); |
| 1321 |
| 1322 // And there should only be one window. |
| 1323 EXPECT_EQ(1u, browser_list->size()); |
| 1324 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
| 1325 |
| 1326 // Remaining browser window should not be maximized |
| 1327 EXPECT_FALSE(browser()->window()->IsMaximized()); |
| 1328 |
| 1329 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1330 EXPECT_EQ(initial_bounds.size(), final_bounds.size()); |
| 1331 EXPECT_EQ(initial_bounds.origin().x(), final_bounds.origin().x()); |
| 1332 EXPECT_EQ(initial_bounds.origin().y() + GetDetachY(tab_strip), |
| 1333 final_bounds.origin().y()); |
| 1334 } |
| 1335 |
| 1336 // Tests that when the first mouse event that starts RunMoveLoop does not |
| 1337 // overlap the Mac menu bar. BridgedNativeWidget::RunMoveLoop() shifts both the |
| 1338 // mouse position and the expected window frame after detachment. |
| 1339 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1340 MacDetachesWindowOnTopOfMacMenuBar) { |
| 1341 // Add another tab. |
| 1342 AddTabAndResetBrowser(browser()); |
| 1343 |
| 1344 // Make sure there's enough space to trigger detachment. |
| 1345 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1346 browser()->window()->SetBounds(gfx::Rect(100, 100, 400, 200)); |
| 1347 DCHECK_GT(browser()->window()->GetBounds().y(), GetDetachY(tab_strip)); |
| 1348 |
| 1349 // If we don't make the interactive_ui_tests the active application, we won't |
| 1350 // be able to monitor NSMouseMoved events and ui_test_utils::DragAndDrop() |
| 1351 // will deadlock. |
| 1352 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1353 |
| 1354 const gfx::Rect work_area = |
| 1355 gfx::Screen::GetScreen() |
| 1356 ->GetDisplayNearestWindow(platform_util::GetViewForWindow( |
| 1357 browser()->window()->GetNativeWindow())) |
| 1358 .work_area(); |
| 1359 EXPECT_GE(work_area.y(), 22) |
| 1360 << "Without the MenuBar on top of work_area this test is pointless."; |
| 1361 |
| 1362 gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1363 gfx::Point on_top_of_menu_bar(tab_0_center.x(), 0); |
| 1364 ui_test_utils::DragAndDrop(tab_0_center, on_top_of_menu_bar); |
| 1365 |
| 1366 // Should not be dragging. |
| 1367 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1368 EXPECT_FALSE(TabDragController::IsActive()); |
| 1369 EXPECT_FALSE(GetIsDragged(browser())); |
| 1370 |
| 1371 // Second tab should successfully detach. |
| 1372 EXPECT_EQ(2u, browser_list->size()); |
| 1373 EXPECT_EQ("1", IDString(browser()->tab_strip_model())); |
| 1374 } |
| 1375 |
| 1376 // Detaches and reattaches second tab. Will fail if detached window is not moved |
| 1377 // synchronously at the start of BridgedNativeWidget::RunMoveLoop(): the check |
| 1378 // for expected WindowServerFrame() will fail. |
| 1379 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1380 MacDetachesAndReattachesSecondTab) { |
| 1381 // Add another tab. |
| 1382 AddTabAndResetBrowser(browser()); |
| 1383 |
| 1384 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1385 browser()->window()->SetBounds(gfx::Rect(100, 100, 400, 200)); |
| 1386 const gfx::Rect initial_bounds = browser()->window()->GetBounds(); |
| 1387 |
| 1388 gfx::Point tab_1_center(GetCenterInScreenCoordinates(tab_strip->tab_at(1))); |
| 1389 gfx::Point tab_1_shake(tab_1_center.x(), |
| 1390 tab_1_center.y() + GetDetachY(tab_strip) * 2); |
| 1391 |
| 1392 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1393 |
| 1394 using ui_test_utils::DragAndDropOperation; |
| 1395 std::list<DragAndDropOperation> operations; |
| 1396 operations.push_back(DragAndDropOperation::Move(tab_1_center)); |
| 1397 operations.push_back(DragAndDropOperation::MouseDown()); |
| 1398 operations.push_back(DragAndDropOperation::Move(tab_1_shake)); |
| 1399 operations.push_back(DragAndDropOperation::Move(tab_1_center)); |
| 1400 operations.push_back(DragAndDropOperation::MouseUp()); |
| 1401 |
| 1402 ui_test_utils::DragAndDrop(operations); |
| 1403 |
| 1404 // Should not be dragging. |
| 1405 EXPECT_FALSE(tab_strip->IsDragSessionActive()); |
| 1406 EXPECT_FALSE(TabDragController::IsActive()); |
| 1407 EXPECT_FALSE(GetIsDragged(browser())); |
| 1408 |
| 1409 // And there should only be one window. |
| 1410 EXPECT_EQ(1u, browser_list->size()); |
| 1411 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); |
| 1412 |
| 1413 // The window should remain in its original place. |
| 1414 const gfx::Rect final_bounds = browser()->window()->GetBounds(); |
| 1415 EXPECT_EQ(initial_bounds, final_bounds); |
| 1416 } |
| 1417 #endif // OS_MACOSX |
| 1418 |
| 1251 namespace { | 1419 namespace { |
| 1252 | 1420 |
| 1253 // Invoked from the nested message loop. | 1421 // Invoked from the nested message loop. |
| 1254 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test, | 1422 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test, |
| 1255 TabStrip* attached_tab_strip, | 1423 TabStrip* attached_tab_strip, |
| 1256 TabStrip* target_tab_strip, | 1424 TabStrip* target_tab_strip, |
| 1257 const BrowserList* browser_list) { | 1425 const BrowserList* browser_list) { |
| 1258 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive()); | 1426 ASSERT_TRUE(attached_tab_strip->IsDragSessionActive()); |
| 1259 ASSERT_FALSE(target_tab_strip->IsDragSessionActive()); | 1427 ASSERT_FALSE(target_tab_strip->IsDragSessionActive()); |
| 1260 ASSERT_TRUE(TabDragController::IsActive()); | 1428 ASSERT_TRUE(TabDragController::IsActive()); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1469 MAYBE_DragSingleTabToSeparateWindow) { | 1637 MAYBE_DragSingleTabToSeparateWindow) { |
| 1470 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1638 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1471 | 1639 |
| 1472 ResetIDs(browser()->tab_strip_model(), 0); | 1640 ResetIDs(browser()->tab_strip_model(), 0); |
| 1473 | 1641 |
| 1474 // Create another browser. | 1642 // Create another browser. |
| 1475 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); | 1643 Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); |
| 1476 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); | 1644 TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); |
| 1477 const gfx::Rect initial_bounds(browser2->window()->GetBounds()); | 1645 const gfx::Rect initial_bounds(browser2->window()->GetBounds()); |
| 1478 | 1646 |
| 1647 EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| 1648 |
| 1479 // Move to the first tab and drag it enough so that it detaches, but not | 1649 // Move to the first tab and drag it enough so that it detaches, but not |
| 1480 // enough that it attaches to browser2. | 1650 // enough that it attaches to browser2. |
| 1481 gfx::Point tab_0_center( | 1651 gfx::Point tab_0_center( |
| 1482 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1652 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1483 ASSERT_TRUE(PressInput(tab_0_center)); | 1653 ASSERT_TRUE(PressInput(tab_0_center)); |
| 1484 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1654 ASSERT_TRUE(DragInputToNotifyWhenDone( |
| 1485 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1655 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
| 1486 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2, | 1656 base::Bind(&DragAllToSeparateWindowStep2, this, tab_strip, tab_strip2, |
| 1487 browser_list))); | 1657 browser_list))); |
| 1488 QuitWhenNotDragging(); | 1658 QuitWhenNotDragging(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1514 | 1684 |
| 1515 namespace { | 1685 namespace { |
| 1516 | 1686 |
| 1517 // Invoked from the nested message loop. | 1687 // Invoked from the nested message loop. |
| 1518 void CancelOnNewTabWhenDraggingStep2( | 1688 void CancelOnNewTabWhenDraggingStep2( |
| 1519 DetachToBrowserTabDragControllerTest* test, | 1689 DetachToBrowserTabDragControllerTest* test, |
| 1520 const BrowserList* browser_list) { | 1690 const BrowserList* browser_list) { |
| 1521 ASSERT_TRUE(TabDragController::IsActive()); | 1691 ASSERT_TRUE(TabDragController::IsActive()); |
| 1522 ASSERT_EQ(2u, browser_list->size()); | 1692 ASSERT_EQ(2u, browser_list->size()); |
| 1523 | 1693 |
| 1524 // 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). | |
| 1526 content::WindowedNotificationObserver observer( | |
| 1527 content::NOTIFICATION_LOAD_STOP, | |
| 1528 content::NotificationService::AllSources()); | |
| 1529 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL), | 1694 chrome::AddTabAt(browser_list->GetLastActive(), GURL(url::kAboutBlankURL), |
| 1530 0, false); | 1695 0, false); |
| 1531 observer.Wait(); | |
| 1532 } | 1696 } |
| 1533 | 1697 |
| 1534 } // namespace | 1698 } // namespace |
| 1535 | 1699 |
| 1536 #if defined(OS_CHROMEOS) || defined(OS_LINUX) | 1700 #if defined(OS_CHROMEOS) || defined(OS_LINUX) |
| 1537 // TODO(sky,sad): Disabled as it fails due to resize locks with a real | 1701 // TODO(sky,sad): Disabled as it fails due to resize locks with a real |
| 1538 // compositor. crbug.com/331924 | 1702 // compositor. crbug.com/331924 |
| 1539 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging | 1703 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging |
| 1540 #else | 1704 #else |
| 1541 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging | 1705 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging |
| 1542 #endif | 1706 #endif |
| 1543 // Adds another tab, detaches into separate window, adds another tab and | 1707 // Adds another tab, detaches into separate window, adds another tab and |
| 1544 // verifies the run loop ends. | 1708 // verifies the run loop ends. |
| 1545 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, | 1709 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, |
| 1546 MAYBE_CancelOnNewTabWhenDragging) { | 1710 MAYBE_CancelOnNewTabWhenDragging) { |
| 1547 TabStrip* tab_strip = GetTabStripForBrowser(browser()); | 1711 TabStrip* tab_strip = GetTabStripForBrowser(browser()); |
| 1548 | 1712 |
| 1549 // Add another tab to browser(). | 1713 // Add another tab to browser(). |
| 1550 AddTabAndResetBrowser(browser()); | 1714 AddTabAndResetBrowser(browser()); |
| 1551 | 1715 |
| 1552 // Move to the first tab and drag it enough so that it detaches. | 1716 // Move to the first tab and drag it enough so that it detaches. |
| 1553 gfx::Point tab_0_center( | 1717 gfx::Point tab_0_center( |
| 1554 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); | 1718 GetCenterInScreenCoordinates(tab_strip->tab_at(0))); |
| 1555 ASSERT_TRUE(PressInput(tab_0_center)); | 1719 ASSERT_TRUE(PressInput(tab_0_center)); |
| 1720 |
| 1721 // Add another tab. This should trigger exiting the nested loop. Add at the |
| 1722 // to exercise past crash when model/tabstrip got out of sync (474082). |
| 1723 content::WindowedNotificationObserver observer( |
| 1724 content::NOTIFICATION_LOAD_STOP, |
| 1725 content::NotificationService::AllSources()); |
| 1556 ASSERT_TRUE(DragInputToNotifyWhenDone( | 1726 ASSERT_TRUE(DragInputToNotifyWhenDone( |
| 1557 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), | 1727 tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), |
| 1558 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list))); | 1728 base::Bind(&CancelOnNewTabWhenDraggingStep2, this, browser_list))); |
| 1559 QuitWhenNotDragging(); | 1729 observer.Wait(); |
| 1560 | 1730 |
| 1561 // Should be two windows and not dragging. | 1731 // Should be two windows and not dragging. |
| 1732 ASSERT_FALSE(tab_strip->IsDragSessionActive()); |
| 1562 ASSERT_FALSE(TabDragController::IsActive()); | 1733 ASSERT_FALSE(TabDragController::IsActive()); |
| 1563 ASSERT_EQ(2u, browser_list->size()); | 1734 ASSERT_EQ(2u, browser_list->size()); |
| 1564 for (auto* browser : *BrowserList::GetInstance()) { | 1735 for (auto* browser : *BrowserList::GetInstance()) { |
| 1565 EXPECT_FALSE(GetIsDragged(browser)); | 1736 EXPECT_FALSE(GetIsDragged(browser)); |
| 1566 // Should not be maximized | 1737 // Should not be maximized |
| 1567 EXPECT_FALSE(browser->window()->IsMaximized()); | 1738 EXPECT_FALSE(browser->window()->IsMaximized()); |
| 1568 } | 1739 } |
| 1569 } | 1740 } |
| 1570 | 1741 |
| 1571 #if defined(OS_CHROMEOS) | 1742 #if defined(OS_CHROMEOS) |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2135 ui_controls::DOWN); | 2306 ui_controls::DOWN); |
| 2136 } | 2307 } |
| 2137 | 2308 |
| 2138 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position, | 2309 bool DragTabAndExecuteTaskWhenDone(const gfx::Point& position, |
| 2139 const base::Closure& task) { | 2310 const base::Closure& task) { |
| 2140 return ui_controls::SendMouseMoveNotifyWhenDone( | 2311 return ui_controls::SendMouseMoveNotifyWhenDone( |
| 2141 position.x(), position.y(), task); | 2312 position.x(), position.y(), task); |
| 2142 } | 2313 } |
| 2143 | 2314 |
| 2144 void QuitWhenNotDragging() { | 2315 void QuitWhenNotDragging() { |
| 2316 DCHECK(TabDragController::IsActive()); |
| 2145 test::QuitWhenNotDraggingImpl(); | 2317 test::QuitWhenNotDraggingImpl(); |
| 2146 base::MessageLoop::current()->Run(); | 2318 base::MessageLoop::current()->Run(); |
| 2147 } | 2319 } |
| 2148 | 2320 |
| 2149 private: | 2321 private: |
| 2150 DISALLOW_COPY_AND_ASSIGN( | 2322 DISALLOW_COPY_AND_ASSIGN( |
| 2151 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest); | 2323 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest); |
| 2152 }; | 2324 }; |
| 2153 | 2325 |
| 2154 // Invoked from the nested message loop. | 2326 // Invoked from the nested message loop. |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2412 DetachToBrowserTabDragControllerTest, | 2584 DetachToBrowserTabDragControllerTest, |
| 2413 ::testing::Values("mouse", "touch")); | 2585 ::testing::Values("mouse", "touch")); |
| 2414 INSTANTIATE_TEST_CASE_P(TabDragging, | 2586 INSTANTIATE_TEST_CASE_P(TabDragging, |
| 2415 DetachToBrowserTabDragControllerTestTouch, | 2587 DetachToBrowserTabDragControllerTestTouch, |
| 2416 ::testing::Values("touch")); | 2588 ::testing::Values("touch")); |
| 2417 #else | 2589 #else |
| 2418 INSTANTIATE_TEST_CASE_P(TabDragging, | 2590 INSTANTIATE_TEST_CASE_P(TabDragging, |
| 2419 DetachToBrowserTabDragControllerTest, | 2591 DetachToBrowserTabDragControllerTest, |
| 2420 ::testing::Values("mouse")); | 2592 ::testing::Values("mouse")); |
| 2421 #endif | 2593 #endif |
| OLD | NEW |