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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h"
7 #include "ash/wm/window_state.h"
9 #include "base/callback.h"
10 #include "base/command_line.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/browser_iterator.h"
17 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/browser/ui/host_desktop.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/browser/ui/views/frame/browser_view.h"
21 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h"
22 #include "chrome/browser/ui/views/tabs/tab.h"
23 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
24 #include "chrome/browser/ui/views/tabs/tab_strip.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "chrome/test/base/interactive_test_utils.h"
28 #include "chrome/test/base/ui_test_utils.h"
29 #include "content/public/browser/notification_details.h"
30 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/notification_source.h"
33 #include "content/public/browser/web_contents.h"
34 #include "ui/base/test/ui_controls.h"
35 #include "ui/gfx/screen.h"
36 #include "ui/views/view.h"
37 #include "ui/views/widget/widget.h"
39 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
40 #include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h"
41 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
45 #include "ash/ash_switches.h"
46 #include "ash/display/display_controller.h"
47 #include "ash/display/display_manager.h"
48 #include "ash/shell.h"
49 #include "ash/test/cursor_manager_test_api.h"
50 #include "ash/wm/coordinate_conversion.h"
51 #include "ash/wm/window_state.h"
52 #include "ash/wm/window_util.h"
53 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
54 #include "ui/aura/client/screen_position_client.h"
55 #include "ui/aura/root_window.h"
56 #include "ui/aura/test/event_generator.h"
59 using content::WebContents
;
65 const char kTabDragControllerInteractiveUITestUserDataKey
[] =
66 "TabDragControllerInteractiveUITestUserData";
68 class TabDragControllerInteractiveUITestUserData
69 : public base::SupportsUserData::Data
{
71 explicit TabDragControllerInteractiveUITestUserData(int id
) : id_(id
) {}
72 virtual ~TabDragControllerInteractiveUITestUserData() {}
73 int id() { return id_
; }
81 class QuitDraggingObserver
: public content::NotificationObserver
{
83 QuitDraggingObserver() {
84 registrar_
.Add(this, chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE
,
85 content::NotificationService::AllSources());
88 virtual void Observe(int type
,
89 const content::NotificationSource
& source
,
90 const content::NotificationDetails
& details
) OVERRIDE
{
91 DCHECK_EQ(chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE
, type
);
92 base::MessageLoopForUI::current()->Quit();
97 virtual ~QuitDraggingObserver() {}
99 content::NotificationRegistrar registrar_
;
101 DISALLOW_COPY_AND_ASSIGN(QuitDraggingObserver
);
104 gfx::Point
GetCenterInScreenCoordinates(const views::View
* view
) {
105 gfx::Point
center(view
->width() / 2, view
->height() / 2);
106 views::View::ConvertPointToScreen(view
, ¢er
);
110 void SetID(WebContents
* web_contents
, int id
) {
111 web_contents
->SetUserData(&kTabDragControllerInteractiveUITestUserDataKey
,
112 new TabDragControllerInteractiveUITestUserData(id
));
115 void ResetIDs(TabStripModel
* model
, int start
) {
116 for (int i
= 0; i
< model
->count(); ++i
)
117 SetID(model
->GetWebContentsAt(i
), start
+ i
);
120 std::string
IDString(TabStripModel
* model
) {
122 for (int i
= 0; i
< model
->count(); ++i
) {
125 WebContents
* contents
= model
->GetWebContentsAt(i
);
126 TabDragControllerInteractiveUITestUserData
* user_data
=
127 static_cast<TabDragControllerInteractiveUITestUserData
*>(
128 contents
->GetUserData(
129 &kTabDragControllerInteractiveUITestUserDataKey
));
131 result
+= base::IntToString(user_data
->id());
138 // Creates a listener that quits the message loop when no longer dragging.
139 void QuitWhenNotDraggingImpl() {
140 new QuitDraggingObserver(); // QuitDraggingObserver deletes itself.
143 TabStrip
* GetTabStripForBrowser(Browser
* browser
) {
144 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
145 return static_cast<TabStrip
*>(browser_view
->tabstrip());
150 using test::GetCenterInScreenCoordinates
;
152 using test::ResetIDs
;
153 using test::IDString
;
154 using test::GetTabStripForBrowser
;
156 TabDragControllerTest::TabDragControllerTest()
157 : native_browser_list(BrowserList::GetInstance(
158 chrome::HOST_DESKTOP_TYPE_NATIVE
)) {
161 TabDragControllerTest::~TabDragControllerTest() {
164 void TabDragControllerTest::SetUp() {
165 // TODO(danakj): Remove this when the tests are not flaky (crbug.com/270065)
166 // or we use test contexts in the renderer to keep things fast enough to
167 // avoid the flake (crbug.com/270918).
170 InProcessBrowserTest::SetUp();
173 void TabDragControllerTest::StopAnimating(TabStrip
* tab_strip
) {
174 tab_strip
->StopAnimating(true);
177 void TabDragControllerTest::AddTabAndResetBrowser(Browser
* browser
) {
178 AddBlankTabAndShow(browser
);
179 StopAnimating(GetTabStripForBrowser(browser
));
180 ResetIDs(browser
->tab_strip_model(), 0);
183 Browser
* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() {
184 // Create another browser.
185 Browser
* browser2
= CreateBrowser(browser()->profile());
186 ResetIDs(browser2
->tab_strip_model(), 100);
188 // Resize the two windows so they're right next to each other.
189 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
190 browser()->window()->GetNativeWindow()).work_area();
191 gfx::Size half_size
=
192 gfx::Size(work_area
.width() / 3 - 10, work_area
.height() / 2 - 10);
193 browser()->window()->SetBounds(gfx::Rect(work_area
.origin(), half_size
));
194 browser2
->window()->SetBounds(gfx::Rect(
195 work_area
.x() + half_size
.width(), work_area
.y(),
196 half_size
.width(), half_size
.height()));
203 INPUT_SOURCE_MOUSE
= 0,
204 INPUT_SOURCE_TOUCH
= 1
207 int GetDetachY(TabStrip
* tab_strip
) {
208 return std::max(TabDragController::kTouchVerticalDetachMagnetism
,
209 TabDragController::kVerticalDetachMagnetism
) +
210 tab_strip
->height() + 1;
213 bool GetIsDragged(Browser
* browser
) {
214 #if !defined(USE_ASH) || defined(OS_WIN) // TODO(win_ash)
217 return ash::wm::GetWindowState(browser
->window()->GetNativeWindow())->
224 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
225 class ScreenEventGeneratorDelegate
: public aura::test::EventGeneratorDelegate
{
227 explicit ScreenEventGeneratorDelegate(aura::Window
* root_window
)
228 : root_window_(root_window
) {}
229 virtual ~ScreenEventGeneratorDelegate() {}
231 // EventGeneratorDelegate overrides:
232 virtual aura::RootWindow
* GetRootWindowAt(
233 const gfx::Point
& point
) const OVERRIDE
{
234 return root_window_
->GetDispatcher();
237 virtual aura::client::ScreenPositionClient
* GetScreenPositionClient(
238 const aura::Window
* window
) const OVERRIDE
{
239 return aura::client::GetScreenPositionClient(root_window_
);
243 aura::Window
* root_window_
;
245 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate
);
250 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
252 // Following classes verify a crash scenario. Specifically on Windows when focus
253 // changes it can trigger capture being lost. This was causing a crash in tab
254 // dragging as it wasn't set up to handle this scenario. These classes
255 // synthesize this scenario.
257 // Allows making ClearNativeFocus() invoke ReleaseCapture().
258 class TestDesktopBrowserFrameAura
: public DesktopBrowserFrameAura
{
260 TestDesktopBrowserFrameAura(
261 BrowserFrame
* browser_frame
,
262 BrowserView
* browser_view
)
263 : DesktopBrowserFrameAura(browser_frame
, browser_view
),
264 release_capture_(false) {}
265 virtual ~TestDesktopBrowserFrameAura() {}
267 void ReleaseCaptureOnNextClear() {
268 release_capture_
= true;
271 virtual void ClearNativeFocus() OVERRIDE
{
272 views::DesktopNativeWidgetAura::ClearNativeFocus();
273 if (release_capture_
) {
274 release_capture_
= false;
275 GetWidget()->ReleaseCapture();
280 // If true ReleaseCapture() is invoked in ClearNativeFocus().
281 bool release_capture_
;
283 DISALLOW_COPY_AND_ASSIGN(TestDesktopBrowserFrameAura
);
286 // Factory for creating a TestDesktopBrowserFrameAura.
287 class TestNativeBrowserFrameFactory
: public NativeBrowserFrameFactory
{
289 TestNativeBrowserFrameFactory() {}
290 virtual ~TestNativeBrowserFrameFactory() {}
292 virtual NativeBrowserFrame
* Create(
293 BrowserFrame
* browser_frame
,
294 BrowserView
* browser_view
) OVERRIDE
{
295 return new TestDesktopBrowserFrameAura(browser_frame
, browser_view
);
299 DISALLOW_COPY_AND_ASSIGN(TestNativeBrowserFrameFactory
);
302 class TabDragCaptureLostTest
: public TabDragControllerTest
{
304 TabDragCaptureLostTest() {
305 NativeBrowserFrameFactory::Set(new TestNativeBrowserFrameFactory
);
309 DISALLOW_COPY_AND_ASSIGN(TabDragCaptureLostTest
);
312 // See description above for details.
313 IN_PROC_BROWSER_TEST_F(TabDragCaptureLostTest
, ReleaseCaptureOnDrag
) {
314 AddTabAndResetBrowser(browser());
316 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
317 gfx::Point
tab_1_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(1)));
318 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_1_center
) &&
319 ui_test_utils::SendMouseEventsSync(
320 ui_controls::LEFT
, ui_controls::DOWN
));
321 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
322 TestDesktopBrowserFrameAura
* frame
=
323 static_cast<TestDesktopBrowserFrameAura
*>(
324 BrowserView::GetBrowserViewForBrowser(browser())->GetWidget()->
325 native_widget_private());
326 // Invoke ReleaseCaptureOnDrag() so that when the drag happens and focus
327 // changes capture is released and the drag cancels.
328 frame
->ReleaseCaptureOnNextClear();
329 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_0_center
));
330 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
333 IN_PROC_BROWSER_TEST_F(TabDragControllerTest
, GestureEndShouldEndDragTest
) {
334 AddTabAndResetBrowser(browser());
336 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
337 TabStripModel
* model
= browser()->tab_strip_model();
339 Tab
* tab1
= tab_strip
->tab_at(1);
340 gfx::Point
tab_1_center(tab1
->width() / 2, tab1
->height() / 2);
342 ui::GestureEvent
gesture_begin(ui::ET_GESTURE_BEGIN
, tab_1_center
.x(),
343 tab_1_center
.x(), 0, base::TimeDelta(),
344 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN
, 0.0f
, 0.0f
), 0);
345 tab_strip
->MaybeStartDrag(tab1
, gesture_begin
,
346 tab_strip
->GetSelectionModel());
347 //tab_strip->tab_at(1)->OnGestureEvent(&gesture_begin);
348 EXPECT_TRUE(TabDragController::IsActive());
350 ui::GestureEvent
gesture_end(ui::ET_GESTURE_END
, tab_1_center
.x(),
351 tab_1_center
.x(), 0, base::TimeDelta(),
352 ui::GestureEventDetails(ui::ET_GESTURE_END
, 0.0f
, 0.0f
), 0);
353 tab_strip
->OnGestureEvent(&gesture_end
);
354 EXPECT_FALSE(TabDragController::IsActive());
355 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
360 class DetachToBrowserTabDragControllerTest
361 : public TabDragControllerTest
,
362 public ::testing::WithParamInterface
<const char*> {
364 DetachToBrowserTabDragControllerTest() {}
366 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
367 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
368 if (!docked_windows_enabled()) {
369 CommandLine::ForCurrentProcess()->AppendSwitch(
370 ash::switches::kAshDisableDockedWindows
);
375 virtual void SetUpOnMainThread() OVERRIDE
{
376 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
377 event_generator_
.reset(new aura::test::EventGenerator(
378 ash::Shell::GetPrimaryRootWindow()));
382 InputSource
input_source() const {
383 return strstr(GetParam(), "mouse") ?
384 INPUT_SOURCE_MOUSE
: INPUT_SOURCE_TOUCH
;
387 bool docked_windows_enabled() const {
388 return (strstr(GetParam(), "docked") != NULL
);
391 // Set root window from a point in screen coordinates
392 void SetEventGeneratorRootWindow(const gfx::Point
& point
) {
393 if (input_source() == INPUT_SOURCE_MOUSE
)
395 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
396 event_generator_
.reset(new aura::test::EventGenerator(
397 new ScreenEventGeneratorDelegate(ash::wm::GetRootWindowAt(point
))));
401 // The following methods update one of the mouse or touch input depending upon
403 bool PressInput(const gfx::Point
& location
) {
404 if (input_source() == INPUT_SOURCE_MOUSE
) {
405 return ui_test_utils::SendMouseMoveSync(location
) &&
406 ui_test_utils::SendMouseEventsSync(
407 ui_controls::LEFT
, ui_controls::DOWN
);
409 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
410 event_generator_
->set_current_location(location
);
411 event_generator_
->PressTouch();
419 // Second touch input is only used for touch sequence tests.
420 EXPECT_EQ(INPUT_SOURCE_TOUCH
, input_source());
421 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
422 event_generator_
->set_current_location(
423 event_generator_
->current_location());
424 event_generator_
->PressTouchId(1);
431 bool DragInputTo(const gfx::Point
& location
) {
432 if (input_source() == INPUT_SOURCE_MOUSE
)
433 return ui_test_utils::SendMouseMoveSync(location
);
434 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
435 event_generator_
->MoveTouch(location
);
442 bool DragInputToAsync(const gfx::Point
& location
) {
443 if (input_source() == INPUT_SOURCE_MOUSE
)
444 return ui_controls::SendMouseMove(location
.x(), location
.y());
445 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
446 event_generator_
->MoveTouch(location
);
453 bool DragInputToNotifyWhenDone(int x
,
455 const base::Closure
& task
) {
456 if (input_source() == INPUT_SOURCE_MOUSE
)
457 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
458 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
459 base::MessageLoop::current()->PostTask(FROM_HERE
, task
);
460 event_generator_
->MoveTouch(gfx::Point(x
, y
));
467 bool DragInputToDelayedNotifyWhenDone(int x
,
469 const base::Closure
& task
,
470 base::TimeDelta delay
) {
471 if (input_source() == INPUT_SOURCE_MOUSE
)
472 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
473 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
474 base::MessageLoop::current()->PostDelayedTask(FROM_HERE
, task
, delay
);
475 event_generator_
->MoveTouch(gfx::Point(x
, y
));
482 bool DragInput2ToNotifyWhenDone(int x
,
484 const base::Closure
& task
) {
485 if (input_source() == INPUT_SOURCE_MOUSE
)
486 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
487 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
488 base::MessageLoop::current()->PostTask(FROM_HERE
, task
);
489 event_generator_
->MoveTouchId(gfx::Point(x
, y
), 1);
496 bool ReleaseInput() {
497 if (input_source() == INPUT_SOURCE_MOUSE
) {
498 return ui_test_utils::SendMouseEventsSync(
499 ui_controls::LEFT
, ui_controls::UP
);
501 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
502 event_generator_
->ReleaseTouch();
509 bool ReleaseInput2() {
510 if (input_source() == INPUT_SOURCE_MOUSE
) {
511 return ui_test_utils::SendMouseEventsSync(
512 ui_controls::LEFT
, ui_controls::UP
);
514 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
515 event_generator_
->ReleaseTouchId(1);
522 bool ReleaseMouseAsync() {
523 return input_source() == INPUT_SOURCE_MOUSE
&&
524 ui_controls::SendMouseEvents(ui_controls::LEFT
, ui_controls::UP
);
527 void QuitWhenNotDragging() {
528 if (input_source() == INPUT_SOURCE_MOUSE
) {
529 // Schedule observer to quit message loop when done dragging. This has to
530 // be async so the message loop can run.
531 test::QuitWhenNotDraggingImpl();
532 base::MessageLoop::current()->Run();
534 // Touch events are sync, so we know we're not in a drag session. But some
535 // tests rely on the browser fully closing, which is async. So, run all
537 base::RunLoop run_loop
;
538 run_loop
.RunUntilIdle();
542 void AddBlankTabAndShow(Browser
* browser
) {
543 InProcessBrowserTest::AddBlankTabAndShow(browser
);
546 Browser
* browser() const { return InProcessBrowserTest::browser(); }
549 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
550 scoped_ptr
<aura::test::EventGenerator
> event_generator_
;
553 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTest
);
556 // Creates a browser with two tabs, drags the second to the first.
557 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
, DragInSameWindow
) {
558 // TODO(sky): this won't work with touch as it requires a long press.
559 if (input_source() == INPUT_SOURCE_TOUCH
) {
560 VLOG(1) << "Test is DISABLED for touch input.";
564 AddTabAndResetBrowser(browser());
566 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
567 TabStripModel
* model
= browser()->tab_strip_model();
569 gfx::Point
tab_1_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(1)));
570 ASSERT_TRUE(PressInput(tab_1_center
));
571 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
572 ASSERT_TRUE(DragInputTo(tab_0_center
));
573 ASSERT_TRUE(ReleaseInput());
574 EXPECT_EQ("1 0", IDString(model
));
575 EXPECT_FALSE(TabDragController::IsActive());
576 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
581 // Invoked from the nested message loop.
582 void DragToSeparateWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
583 TabStrip
* not_attached_tab_strip
,
584 TabStrip
* target_tab_strip
) {
585 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
586 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
587 ASSERT_TRUE(TabDragController::IsActive());
589 // Drag to target_tab_strip. This should stop the nested loop from dragging
591 gfx::Point
target_point(target_tab_strip
->width() -1,
592 target_tab_strip
->height() / 2);
593 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
594 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
599 #if defined(OS_CHROMEOS)
600 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
601 // compositor. crbug.com/331924
602 #define MAYBE_DragToSeparateWindow DISABLED_DragToSeparateWindow
604 #define MAYBE_DragToSeparateWindow DragToSeparateWindow
606 // Creates two browsers, drags from first into second.
607 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
608 MAYBE_DragToSeparateWindow
) {
609 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
611 // Add another tab to browser().
612 AddTabAndResetBrowser(browser());
614 // Create another browser.
615 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
616 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
618 // Move to the first tab and drag it enough so that it detaches, but not
619 // enough that it attaches to browser2.
620 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
621 ASSERT_TRUE(PressInput(tab_0_center
));
622 ASSERT_TRUE(DragInputToNotifyWhenDone(
623 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
624 base::Bind(&DragToSeparateWindowStep2
,
625 this, tab_strip
, tab_strip2
)));
626 QuitWhenNotDragging();
628 // Should now be attached to tab_strip2.
629 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
630 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
631 ASSERT_TRUE(TabDragController::IsActive());
632 EXPECT_FALSE(GetIsDragged(browser()));
634 // Release the mouse, stopping the drag session.
635 ASSERT_TRUE(ReleaseInput());
636 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
637 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
638 ASSERT_FALSE(TabDragController::IsActive());
639 EXPECT_EQ("100 0", IDString(browser2
->tab_strip_model()));
640 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
641 EXPECT_FALSE(GetIsDragged(browser2
));
643 // Both windows should not be maximized
644 EXPECT_FALSE(browser()->window()->IsMaximized());
645 EXPECT_FALSE(browser2
->window()->IsMaximized());
650 void DetachToOwnWindowStep2(DetachToBrowserTabDragControllerTest
* test
) {
651 if (test
->input_source() == INPUT_SOURCE_TOUCH
)
652 ASSERT_TRUE(test
->ReleaseInput());
655 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
656 bool IsWindowPositionManaged(aura::Window
* window
) {
657 return ash::wm::GetWindowState(window
)->window_position_managed();
659 bool HasUserChangedWindowPositionOrSize(aura::Window
* window
) {
660 return ash::wm::GetWindowState(window
)->bounds_changed_by_user();
663 bool IsWindowPositionManaged(gfx::NativeWindow window
) {
666 bool HasUserChangedWindowPositionOrSize(gfx::NativeWindow window
) {
673 #if defined(OS_CHROMEOS)
674 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
675 // compositor. crbug.com/331924
676 #define MAYBE_DetachToOwnWindow DISABLED_DetachToOwnWindow
678 #define MAYBE_DetachToOwnWindow DetachToOwnWindow
680 // Drags from browser to separate window and releases mouse.
681 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
682 MAYBE_DetachToOwnWindow
) {
683 const gfx::Rect
initial_bounds(browser()->window()->GetBounds());
685 AddTabAndResetBrowser(browser());
686 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
688 // Move to the first tab and drag it enough so that it detaches.
689 gfx::Point
tab_0_center(
690 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
691 ASSERT_TRUE(PressInput(tab_0_center
));
692 ASSERT_TRUE(DragInputToNotifyWhenDone(
693 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
694 base::Bind(&DetachToOwnWindowStep2
, this)));
695 if (input_source() == INPUT_SOURCE_MOUSE
) {
696 ASSERT_TRUE(ReleaseMouseAsync());
697 QuitWhenNotDragging();
700 // Should no longer be dragging.
701 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
702 ASSERT_FALSE(TabDragController::IsActive());
704 // There should now be another browser.
705 ASSERT_EQ(2u, native_browser_list
->size());
706 Browser
* new_browser
= native_browser_list
->get(1);
707 ASSERT_TRUE(new_browser
->window()->IsActive());
708 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
709 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
711 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
712 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
714 // The bounds of the initial window should not have changed.
715 EXPECT_EQ(initial_bounds
.ToString(),
716 browser()->window()->GetBounds().ToString());
718 EXPECT_FALSE(GetIsDragged(browser()));
719 EXPECT_FALSE(GetIsDragged(new_browser
));
720 // After this both windows should still be manageable.
721 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
722 EXPECT_TRUE(IsWindowPositionManaged(
723 new_browser
->window()->GetNativeWindow()));
725 // Both windows should not be maximized
726 EXPECT_FALSE(browser()->window()->IsMaximized());
727 EXPECT_FALSE(new_browser
->window()->IsMaximized());
730 #if defined(OS_CHROMEOS)
731 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
732 // compositor. crbug.com/331924
733 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
734 DISABLED_DetachToOwnWindowFromMaximizedWindow
736 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
737 DetachToOwnWindowFromMaximizedWindow
739 // Drags from browser to separate window and releases mouse.
740 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
741 MAYBE_DetachToOwnWindowFromMaximizedWindow
) {
742 // Maximize the initial browser window.
743 browser()->window()->Maximize();
744 ASSERT_TRUE(browser()->window()->IsMaximized());
747 AddTabAndResetBrowser(browser());
748 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
750 // Move to the first tab and drag it enough so that it detaches.
751 gfx::Point
tab_0_center(
752 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
753 ASSERT_TRUE(PressInput(tab_0_center
));
754 ASSERT_TRUE(DragInputToNotifyWhenDone(
755 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
756 base::Bind(&DetachToOwnWindowStep2
, this)));
757 if (input_source() == INPUT_SOURCE_MOUSE
) {
758 ASSERT_TRUE(ReleaseMouseAsync());
759 QuitWhenNotDragging();
762 // Should no longer be dragging.
763 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
764 ASSERT_FALSE(TabDragController::IsActive());
766 // There should now be another browser.
767 ASSERT_EQ(2u, native_browser_list
->size());
768 Browser
* new_browser
= native_browser_list
->get(1);
769 ASSERT_TRUE(new_browser
->window()->IsActive());
770 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
771 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
773 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
774 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
776 // The bounds of the initial window should not have changed.
777 EXPECT_TRUE(browser()->window()->IsMaximized());
779 EXPECT_FALSE(GetIsDragged(browser()));
780 EXPECT_FALSE(GetIsDragged(new_browser
));
781 // After this both windows should still be manageable.
782 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
783 EXPECT_TRUE(IsWindowPositionManaged(
784 new_browser
->window()->GetNativeWindow()));
786 // The new window should be maximized.
787 EXPECT_TRUE(new_browser
->window()->IsMaximized());
790 // Deletes a tab being dragged before the user moved enough to start a drag.
791 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
792 DeleteBeforeStartedDragging
) {
794 AddTabAndResetBrowser(browser());
795 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
797 // Click on the first tab, but don't move it.
798 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
799 ASSERT_TRUE(PressInput(tab_0_center
));
801 // Should be dragging.
802 ASSERT_TRUE(tab_strip
->IsDragSessionActive());
803 ASSERT_TRUE(TabDragController::IsActive());
805 // Delete the tab being dragged.
806 delete browser()->tab_strip_model()->GetWebContentsAt(0);
808 // Should have canceled dragging.
809 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
810 ASSERT_FALSE(TabDragController::IsActive());
812 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
813 EXPECT_FALSE(GetIsDragged(browser()));
816 // Deletes a tab being dragged while still attached.
817 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
818 DeleteTabWhileAttached
) {
819 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
820 // compositor. crbug.com/331924
821 if (input_source() == INPUT_SOURCE_MOUSE
) {
822 VLOG(1) << "Test is DISABLED for mouse input.";
827 AddTabAndResetBrowser(browser());
828 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
830 // Click on the first tab and move it enough so that it starts dragging but is
832 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
833 ASSERT_TRUE(PressInput(tab_0_center
));
834 ASSERT_TRUE(DragInputTo(
835 gfx::Point(tab_0_center
.x() + 20, tab_0_center
.y())));
837 // Should be dragging.
838 ASSERT_TRUE(tab_strip
->IsDragSessionActive());
839 ASSERT_TRUE(TabDragController::IsActive());
841 // Delete the tab being dragged.
842 delete browser()->tab_strip_model()->GetWebContentsAt(0);
844 // Should have canceled dragging.
845 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
846 ASSERT_FALSE(TabDragController::IsActive());
848 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
850 EXPECT_FALSE(GetIsDragged(browser()));
855 void DeleteWhileDetachedStep2(WebContents
* tab
) {
861 // Deletes a tab being dragged after dragging a tab so that a new window is
863 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
864 DeleteTabWhileDetached
) {
866 AddTabAndResetBrowser(browser());
867 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
869 // Move to the first tab and drag it enough so that it detaches.
870 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
871 WebContents
* to_delete
=
872 browser()->tab_strip_model()->GetWebContentsAt(0);
873 ASSERT_TRUE(PressInput(tab_0_center
));
874 ASSERT_TRUE(DragInputToNotifyWhenDone(
875 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
876 base::Bind(&DeleteWhileDetachedStep2
, to_delete
)));
877 QuitWhenNotDragging();
879 // Should not be dragging.
880 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
881 ASSERT_FALSE(TabDragController::IsActive());
883 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
885 EXPECT_FALSE(GetIsDragged(browser()));
890 void DeleteSourceDetachedStep2(WebContents
* tab
,
891 const BrowserList
* browser_list
) {
892 ASSERT_EQ(2u, browser_list
->size());
893 Browser
* new_browser
= browser_list
->get(1);
894 // This ends up closing the source window.
897 ui_controls::SendKeyPress(new_browser
->window()->GetNativeWindow(),
898 ui::VKEY_ESCAPE
, false, false, false, false);
903 #if defined(OS_CHROMEOS)
904 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
905 // compositor. crbug.com/331924
906 #define MAYBE_DeleteSourceDetached DISABLED_DeleteSourceDetached
908 #define MAYBE_DeleteSourceDetached DeleteSourceDetached
910 // Detaches a tab and while detached deletes a tab from the source so that the
911 // source window closes then presses escape to cancel the drag.
912 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
913 DeleteSourceDetached
) {
915 AddTabAndResetBrowser(browser());
916 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
918 // Move to the first tab and drag it enough so that it detaches.
919 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
920 WebContents
* to_delete
= browser()->tab_strip_model()->GetWebContentsAt(1);
921 ASSERT_TRUE(PressInput(tab_0_center
));
922 ASSERT_TRUE(DragInputToNotifyWhenDone(
923 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
924 base::Bind(&DeleteSourceDetachedStep2
, to_delete
, native_browser_list
)));
925 QuitWhenNotDragging();
927 // Should not be dragging.
928 ASSERT_EQ(1u, native_browser_list
->size());
929 Browser
* new_browser
= native_browser_list
->get(0);
930 ASSERT_FALSE(GetTabStripForBrowser(new_browser
)->IsDragSessionActive());
931 ASSERT_FALSE(TabDragController::IsActive());
933 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
935 EXPECT_FALSE(GetIsDragged(new_browser
));
937 // Remaining browser window should not be maximized
938 EXPECT_FALSE(new_browser
->window()->IsMaximized());
943 void PressEscapeWhileDetachedStep2(const BrowserList
* browser_list
) {
944 ASSERT_EQ(2u, browser_list
->size());
945 Browser
* new_browser
= browser_list
->get(1);
946 ui_controls::SendKeyPress(
947 new_browser
->window()->GetNativeWindow(), ui::VKEY_ESCAPE
, false, false,
953 #if defined(OS_CHROMEOS)
954 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
955 // compositor. crbug.com/331924
956 #define MAYBE_PressEscapeWhileDetached DISABLED_PressEscapeWhileDetached
958 #define MAYBE_PressEscapeWhileDetached PressEscapeWhileDetached
960 // This is disabled until NativeViewHost::Detach really detaches.
961 // Detaches a tab and while detached presses escape to revert the drag.
962 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
963 MAYBE_PressEscapeWhileDetached
) {
965 AddTabAndResetBrowser(browser());
966 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
968 // Move to the first tab and drag it enough so that it detaches.
969 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
970 ASSERT_TRUE(PressInput(tab_0_center
));
971 ASSERT_TRUE(DragInputToNotifyWhenDone(
972 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
973 base::Bind(&PressEscapeWhileDetachedStep2
, native_browser_list
)));
974 QuitWhenNotDragging();
976 // Should not be dragging.
977 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
978 ASSERT_FALSE(TabDragController::IsActive());
980 // And there should only be one window.
981 EXPECT_EQ(1u, native_browser_list
->size());
983 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
985 // Remaining browser window should not be maximized
986 EXPECT_FALSE(browser()->window()->IsMaximized());
991 void DragAllStep2(DetachToBrowserTabDragControllerTest
* test
,
992 const BrowserList
* browser_list
) {
993 // Should only be one window.
994 ASSERT_EQ(1u, browser_list
->size());
995 if (test
->input_source() == INPUT_SOURCE_TOUCH
) {
996 ASSERT_TRUE(test
->ReleaseInput());
998 ASSERT_TRUE(test
->ReleaseMouseAsync());
1004 #if defined(OS_CHROMEOS)
1005 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1006 // compositor. crbug.com/331924
1007 #define MAYBE_DragAll DISABLED_DragAll
1009 #define MAYBE_DragAll DragAll
1011 // Selects multiple tabs and starts dragging the window.
1012 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
, MAYBE_DragAll
) {
1014 AddTabAndResetBrowser(browser());
1015 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1016 browser()->tab_strip_model()->AddTabAtToSelection(0);
1017 browser()->tab_strip_model()->AddTabAtToSelection(1);
1019 // Move to the first tab and drag it enough so that it would normally
1021 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1022 ASSERT_TRUE(PressInput(tab_0_center
));
1023 ASSERT_TRUE(DragInputToNotifyWhenDone(
1024 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1025 base::Bind(&DragAllStep2
, this, native_browser_list
)));
1026 QuitWhenNotDragging();
1028 // Should not be dragging.
1029 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1030 ASSERT_FALSE(TabDragController::IsActive());
1032 // And there should only be one window.
1033 EXPECT_EQ(1u, native_browser_list
->size());
1035 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1037 EXPECT_FALSE(GetIsDragged(browser()));
1039 // Remaining browser window should not be maximized
1040 EXPECT_FALSE(browser()->window()->IsMaximized());
1045 // Invoked from the nested message loop.
1046 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
1047 TabStrip
* attached_tab_strip
,
1048 TabStrip
* target_tab_strip
,
1049 const BrowserList
* browser_list
) {
1050 ASSERT_TRUE(attached_tab_strip
->IsDragSessionActive());
1051 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1052 ASSERT_TRUE(TabDragController::IsActive());
1053 ASSERT_EQ(2u, browser_list
->size());
1055 // Drag to target_tab_strip. This should stop the nested loop from dragging
1057 gfx::Point
target_point(target_tab_strip
->width() - 1,
1058 target_tab_strip
->height() / 2);
1059 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
1060 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1065 #if defined(OS_CHROMEOS)
1066 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1067 // compositor. crbug.com/331924
1068 #define MAYBE_DragAllToSeparateWindow DISABLED_DragAllToSeparateWindow
1070 #define MAYBE_DragAllToSeparateWindow DragAllToSeparateWindow
1072 // Creates two browsers, selects all tabs in first and drags into second.
1073 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1074 MAYBE_DragAllToSeparateWindow
) {
1075 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1077 // Add another tab to browser().
1078 AddTabAndResetBrowser(browser());
1080 // Create another browser.
1081 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1082 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1084 browser()->tab_strip_model()->AddTabAtToSelection(0);
1085 browser()->tab_strip_model()->AddTabAtToSelection(1);
1087 // Move to the first tab and drag it enough so that it detaches, but not
1088 // enough that it attaches to browser2.
1089 gfx::Point
tab_0_center(
1090 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1091 ASSERT_TRUE(PressInput(tab_0_center
));
1092 ASSERT_TRUE(DragInputToNotifyWhenDone(
1093 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1094 base::Bind(&DragAllToSeparateWindowStep2
, this, tab_strip
, tab_strip2
,
1095 native_browser_list
)));
1096 QuitWhenNotDragging();
1098 // Should now be attached to tab_strip2.
1099 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1100 ASSERT_TRUE(TabDragController::IsActive());
1101 ASSERT_EQ(1u, native_browser_list
->size());
1103 // Release the mouse, stopping the drag session.
1104 ASSERT_TRUE(ReleaseInput());
1105 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1106 ASSERT_FALSE(TabDragController::IsActive());
1107 EXPECT_EQ("100 0 1", IDString(browser2
->tab_strip_model()));
1109 EXPECT_FALSE(GetIsDragged(browser2
));
1111 // Remaining browser window should not be maximized
1112 EXPECT_FALSE(browser2
->window()->IsMaximized());
1117 // Invoked from the nested message loop.
1118 void DragAllToSeparateWindowAndCancelStep2(
1119 DetachToBrowserTabDragControllerTest
* test
,
1120 TabStrip
* attached_tab_strip
,
1121 TabStrip
* target_tab_strip
,
1122 const BrowserList
* browser_list
) {
1123 ASSERT_TRUE(attached_tab_strip
->IsDragSessionActive());
1124 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1125 ASSERT_TRUE(TabDragController::IsActive());
1126 ASSERT_EQ(2u, browser_list
->size());
1128 // Drag to target_tab_strip. This should stop the nested loop from dragging
1130 gfx::Point
target_point(target_tab_strip
->width() - 1,
1131 target_tab_strip
->height() / 2);
1132 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
1133 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1138 #if defined(OS_CHROMEOS)
1139 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1140 // compositor. crbug.com/331924
1141 #define MAYBE_DragAllToSeparateWindowAndCancel \
1142 DISABLED_DragAllToSeparateWindowAndCancel
1144 #define MAYBE_DragAllToSeparateWindowAndCancel DragAllToSeparateWindowAndCancel
1146 // Creates two browsers, selects all tabs in first, drags into second, then hits
1148 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1149 MAYBE_DragAllToSeparateWindowAndCancel
) {
1150 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1152 // Add another tab to browser().
1153 AddTabAndResetBrowser(browser());
1155 // Create another browser.
1156 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1157 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1159 browser()->tab_strip_model()->AddTabAtToSelection(0);
1160 browser()->tab_strip_model()->AddTabAtToSelection(1);
1162 // Move to the first tab and drag it enough so that it detaches, but not
1163 // enough that it attaches to browser2.
1164 gfx::Point
tab_0_center(
1165 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1166 ASSERT_TRUE(PressInput(tab_0_center
));
1167 ASSERT_TRUE(DragInputToNotifyWhenDone(
1168 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1169 base::Bind(&DragAllToSeparateWindowAndCancelStep2
, this,
1170 tab_strip
, tab_strip2
, native_browser_list
)));
1171 QuitWhenNotDragging();
1173 // Should now be attached to tab_strip2.
1174 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1175 ASSERT_TRUE(TabDragController::IsActive());
1176 ASSERT_EQ(1u, native_browser_list
->size());
1179 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
1180 browser2
, ui::VKEY_ESCAPE
, false, false, false, false));
1182 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1183 ASSERT_FALSE(TabDragController::IsActive());
1184 EXPECT_EQ("100 0 1", IDString(browser2
->tab_strip_model()));
1186 // browser() will have been destroyed, but browser2 should remain.
1187 ASSERT_EQ(1u, native_browser_list
->size());
1189 EXPECT_FALSE(GetIsDragged(browser2
));
1191 // Remaining browser window should not be maximized
1192 EXPECT_FALSE(browser2
->window()->IsMaximized());
1195 #if defined(OS_CHROMEOS)
1196 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1197 // compositor. crbug.com/331924
1198 #define MAYBE_DragDirectlyToSecondWindow DISABLED_DragDirectlyToSecondWindow
1200 #define MAYBE_DragDirectlyToSecondWindow DragDirectlyToSecondWindow
1202 // Creates two browsers, drags from first into the second in such a way that
1203 // no detaching should happen.
1204 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1205 MAYBE_DragDirectlyToSecondWindow
) {
1206 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1208 // Add another tab to browser().
1209 AddTabAndResetBrowser(browser());
1211 // Create another browser.
1212 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1213 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1215 // Move the tabstrip down enough so that we can detach.
1216 gfx::Rect
bounds(browser2
->window()->GetBounds());
1217 bounds
.Offset(0, 100);
1218 browser2
->window()->SetBounds(bounds
);
1220 // Move to the first tab and drag it enough so that it detaches, but not
1221 // enough that it attaches to browser2.
1222 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1223 ASSERT_TRUE(PressInput(tab_0_center
));
1225 gfx::Point
b2_location(5, 0);
1226 views::View::ConvertPointToScreen(tab_strip2
, &b2_location
);
1227 ASSERT_TRUE(DragInputTo(b2_location
));
1229 // Should now be attached to tab_strip2.
1230 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1231 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1232 ASSERT_TRUE(TabDragController::IsActive());
1234 // Release the mouse, stopping the drag session.
1235 ASSERT_TRUE(ReleaseInput());
1236 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1237 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1238 ASSERT_FALSE(TabDragController::IsActive());
1239 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1240 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1242 EXPECT_FALSE(GetIsDragged(browser()));
1243 EXPECT_FALSE(GetIsDragged(browser2
));
1245 // Both windows should not be maximized
1246 EXPECT_FALSE(browser()->window()->IsMaximized());
1247 EXPECT_FALSE(browser2
->window()->IsMaximized());
1250 #if defined(OS_CHROMEOS)
1251 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1252 // compositor. crbug.com/331924
1253 #define MAYBE_DragSingleTabToSeparateWindow \
1254 DISABLED_DragSingleTabToSeparateWindow
1256 #define MAYBE_DragSingleTabToSeparateWindow DragSingleTabToSeparateWindow
1258 // Creates two browsers, the first browser has a single tab and drags into the
1260 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1261 MAYBE_DragSingleTabToSeparateWindow
) {
1262 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1264 ResetIDs(browser()->tab_strip_model(), 0);
1266 // Create another browser.
1267 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1268 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1269 const gfx::Rect
initial_bounds(browser2
->window()->GetBounds());
1271 // Move to the first tab and drag it enough so that it detaches, but not
1272 // enough that it attaches to browser2.
1273 gfx::Point
tab_0_center(
1274 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1275 ASSERT_TRUE(PressInput(tab_0_center
));
1276 ASSERT_TRUE(DragInputToNotifyWhenDone(
1277 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1278 base::Bind(&DragAllToSeparateWindowStep2
, this, tab_strip
, tab_strip2
,
1279 native_browser_list
)));
1280 QuitWhenNotDragging();
1282 // Should now be attached to tab_strip2.
1283 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1284 ASSERT_TRUE(TabDragController::IsActive());
1285 ASSERT_EQ(1u, native_browser_list
->size());
1287 // Release the mouse, stopping the drag session.
1288 ASSERT_TRUE(ReleaseInput());
1289 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1290 ASSERT_FALSE(TabDragController::IsActive());
1291 EXPECT_EQ("100 0", IDString(browser2
->tab_strip_model()));
1293 EXPECT_FALSE(GetIsDragged(browser2
));
1295 // Remaining browser window should not be maximized
1296 EXPECT_FALSE(browser2
->window()->IsMaximized());
1298 // Make sure that the window is still managed and not user moved.
1299 EXPECT_TRUE(IsWindowPositionManaged(browser2
->window()->GetNativeWindow()));
1300 EXPECT_FALSE(HasUserChangedWindowPositionOrSize(
1301 browser2
->window()->GetNativeWindow()));
1302 // Also make sure that the drag to window position has not changed.
1303 EXPECT_EQ(initial_bounds
.ToString(),
1304 browser2
->window()->GetBounds().ToString());
1309 // Invoked from the nested message loop.
1310 void CancelOnNewTabWhenDraggingStep2(
1311 DetachToBrowserTabDragControllerTest
* test
,
1312 const BrowserList
* browser_list
) {
1313 ASSERT_TRUE(TabDragController::IsActive());
1314 ASSERT_EQ(2u, browser_list
->size());
1316 // Add another tab. This should trigger exiting the nested loop.
1317 test
->AddBlankTabAndShow(browser_list
->GetLastActive());
1322 #if defined(OS_CHROMEOS)
1323 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1324 // compositor. crbug.com/331924
1325 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging
1327 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging
1329 // Adds another tab, detaches into separate window, adds another tab and
1330 // verifies the run loop ends.
1331 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1332 CancelOnNewTabWhenDragging
) {
1333 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1335 // Add another tab to browser().
1336 AddTabAndResetBrowser(browser());
1338 // Move to the first tab and drag it enough so that it detaches.
1339 gfx::Point
tab_0_center(
1340 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1341 ASSERT_TRUE(PressInput(tab_0_center
));
1342 ASSERT_TRUE(DragInputToNotifyWhenDone(
1343 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1344 base::Bind(&CancelOnNewTabWhenDraggingStep2
, this, native_browser_list
)));
1345 QuitWhenNotDragging();
1347 // Should be two windows and not dragging.
1348 ASSERT_FALSE(TabDragController::IsActive());
1349 ASSERT_EQ(2u, native_browser_list
->size());
1350 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1351 EXPECT_FALSE(GetIsDragged(*it
));
1352 // Should not be maximized
1353 EXPECT_FALSE(it
->window()->IsMaximized());
1357 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
1361 void DragInMaximizedWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
1363 TabStrip
* tab_strip
,
1364 const BrowserList
* browser_list
) {
1365 // There should be another browser.
1366 ASSERT_EQ(2u, browser_list
->size());
1367 Browser
* new_browser
= browser_list
->get(1);
1368 EXPECT_NE(browser
, new_browser
);
1369 ASSERT_TRUE(new_browser
->window()->IsActive());
1370 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
1372 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1373 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1375 // Both windows should be visible.
1376 EXPECT_TRUE(tab_strip
->GetWidget()->IsVisible());
1377 EXPECT_TRUE(tab_strip2
->GetWidget()->IsVisible());
1380 ASSERT_TRUE(test
->ReleaseInput());
1385 #if defined(OS_CHROMEOS)
1386 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1387 // compositor. crbug.com/331924
1388 #define MAYBE_DragInMaximizedWindow DISABLED_DragInMaximizedWindow
1390 #define MAYBE_DragInMaximizedWindow DragInMaximizedWindow
1392 // Creates a browser with two tabs, maximizes it, drags the tab out.
1393 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1394 MAYBE_DragInMaximizedWindow
) {
1395 AddTabAndResetBrowser(browser());
1396 browser()->window()->Maximize();
1398 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1400 // Move to the first tab and drag it enough so that it detaches.
1401 gfx::Point
tab_0_center(
1402 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1403 ASSERT_TRUE(PressInput(tab_0_center
));
1404 ASSERT_TRUE(DragInputToNotifyWhenDone(
1405 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1406 base::Bind(&DragInMaximizedWindowStep2
, this, browser(), tab_strip
,
1407 native_browser_list
)));
1408 QuitWhenNotDragging();
1410 ASSERT_FALSE(TabDragController::IsActive());
1412 // Should be two browsers.
1413 ASSERT_EQ(2u, native_browser_list
->size());
1414 Browser
* new_browser
= native_browser_list
->get(1);
1415 ASSERT_TRUE(new_browser
->window()->IsActive());
1417 EXPECT_TRUE(browser()->window()->GetNativeWindow()->IsVisible());
1418 EXPECT_TRUE(new_browser
->window()->GetNativeWindow()->IsVisible());
1420 EXPECT_FALSE(GetIsDragged(browser()));
1421 EXPECT_FALSE(GetIsDragged(new_browser
));
1423 // The source window should be maximized.
1424 EXPECT_TRUE(browser()->window()->IsMaximized());
1425 // The new window should be maximized.
1426 EXPECT_TRUE(new_browser
->window()->IsMaximized());
1429 // Subclass of DetachToBrowserTabDragControllerTest that
1430 // creates multiple displays.
1431 class DetachToBrowserInSeparateDisplayTabDragControllerTest
1432 : public DetachToBrowserTabDragControllerTest
{
1434 DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1435 virtual ~DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1437 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1438 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line
);
1439 // Make screens sufficiently wide to host 2 browsers side by side.
1440 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1441 "0+0-600x600,601+0-600x600");
1445 DISALLOW_COPY_AND_ASSIGN(
1446 DetachToBrowserInSeparateDisplayTabDragControllerTest
);
1449 // Subclass of DetachToBrowserTabDragControllerTest that runs tests only with
1451 class DetachToBrowserTabDragControllerTestTouch
1452 : public DetachToBrowserTabDragControllerTest
{
1454 DetachToBrowserTabDragControllerTestTouch() {}
1455 virtual ~DetachToBrowserTabDragControllerTestTouch() {}
1458 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTestTouch
);
1463 void DragSingleTabToSeparateWindowInSecondDisplayStep3(
1464 DetachToBrowserTabDragControllerTest
* test
) {
1465 ASSERT_TRUE(test
->ReleaseInput());
1468 void DragSingleTabToSeparateWindowInSecondDisplayStep2(
1469 DetachToBrowserTabDragControllerTest
* test
,
1470 const gfx::Point
& target_point
) {
1471 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
1472 target_point
.x(), target_point
.y(),
1473 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep3
, test
)));
1478 // Drags from browser to a second display and releases input.
1479 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1480 DragSingleTabToSeparateWindowInSecondDisplay
) {
1482 AddTabAndResetBrowser(browser());
1483 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1485 // Move to the first tab and drag it enough so that it detaches.
1486 // Then drag it to the final destination on the second screen.
1487 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1488 ASSERT_TRUE(PressInput(tab_0_center
));
1489 ASSERT_TRUE(DragInputToNotifyWhenDone(
1490 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1491 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep2
,
1492 this, gfx::Point(600 + tab_0_center
.x(),
1494 + GetDetachY(tab_strip
)))));
1495 QuitWhenNotDragging();
1497 // Should no longer be dragging.
1498 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1499 ASSERT_FALSE(TabDragController::IsActive());
1501 // There should now be another browser.
1502 ASSERT_EQ(2u, native_browser_list
->size());
1503 Browser
* new_browser
= native_browser_list
->get(1);
1504 ASSERT_TRUE(new_browser
->window()->IsActive());
1505 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
1506 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1508 // This other browser should be on the second screen (with mouse drag)
1509 // With the touch input the browser cannot be dragged from one screen
1510 // to another and the window stays on the first screen.
1511 if (input_source() == INPUT_SOURCE_MOUSE
) {
1512 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1513 ASSERT_EQ(2u, roots
.size());
1514 aura::Window
* second_root
= roots
[1];
1515 EXPECT_EQ(second_root
,
1516 new_browser
->window()->GetNativeWindow()->GetRootWindow());
1519 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
1520 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1522 // Both windows should not be maximized
1523 EXPECT_FALSE(browser()->window()->IsMaximized());
1524 EXPECT_FALSE(new_browser
->window()->IsMaximized());
1529 // Invoked from the nested message loop.
1530 void DragTabToWindowInSeparateDisplayStep2(
1531 DetachToBrowserTabDragControllerTest
* test
,
1532 TabStrip
* not_attached_tab_strip
,
1533 TabStrip
* target_tab_strip
) {
1534 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
1535 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1536 ASSERT_TRUE(TabDragController::IsActive());
1538 // Drag to target_tab_strip. This should stop the nested loop from dragging
1540 gfx::Point
target_point(
1541 GetCenterInScreenCoordinates(target_tab_strip
->tab_at(0)));
1543 // Move it close to the beginning of the target tabstrip.
1545 target_point
.x() - target_tab_strip
->tab_at(0)->width() / 2 + 10);
1546 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1551 #if defined(OS_CHROMEOS)
1552 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1553 // compositor. crbug.com/331924
1554 #define MAYBE_DragTabToWindowInSeparateDisplay \
1555 DISABLED_DragTabToWindowInSeparateDisplay
1557 #define MAYBE_DragTabToWindowInSeparateDisplay DragTabToWindowInSeparateDisplay
1559 // Drags from browser to another browser on a second display and releases input.
1560 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1561 MAYBE_DragTabToWindowInSeparateDisplay
) {
1563 AddTabAndResetBrowser(browser());
1564 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1566 // Create another browser.
1567 Browser
* browser2
= CreateBrowser(browser()->profile());
1568 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1569 ResetIDs(browser2
->tab_strip_model(), 100);
1571 // Move the second browser to the second display.
1572 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1573 ASSERT_EQ(2u, roots
.size());
1574 aura::Window
* second_root
= roots
[1];
1575 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1576 second_root
).work_area();
1577 browser2
->window()->SetBounds(work_area
);
1578 EXPECT_EQ(second_root
,
1579 browser2
->window()->GetNativeWindow()->GetRootWindow());
1581 // Move to the first tab and drag it enough so that it detaches, but not
1582 // enough that it attaches to browser2.
1583 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1584 ASSERT_TRUE(PressInput(tab_0_center
));
1585 ASSERT_TRUE(DragInputToNotifyWhenDone(
1586 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1587 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1588 this, tab_strip
, tab_strip2
)));
1589 QuitWhenNotDragging();
1591 // Should now be attached to tab_strip2.
1592 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1593 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1594 ASSERT_TRUE(TabDragController::IsActive());
1596 // Release the mouse, stopping the drag session.
1597 ASSERT_TRUE(ReleaseInput());
1598 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1599 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1600 ASSERT_FALSE(TabDragController::IsActive());
1601 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1602 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1604 // Both windows should not be maximized
1605 EXPECT_FALSE(browser()->window()->IsMaximized());
1606 EXPECT_FALSE(browser2
->window()->IsMaximized());
1609 #if defined(OS_CHROMEOS)
1610 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1611 // compositor. crbug.com/331924
1612 #define MAYBE_DragTabToWindowOnSecondDisplay \
1613 DISABLED_DragTabToWindowOnSecondDisplay
1615 #define MAYBE_DragTabToWindowOnSecondDisplay DragTabToWindowOnSecondDisplay
1617 // Drags from browser to another browser on a second display and releases input.
1618 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1619 MAYBE_DragTabToWindowOnSecondDisplay
) {
1621 AddTabAndResetBrowser(browser());
1622 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1624 // Create another browser.
1625 Browser
* browser2
= CreateBrowser(browser()->profile());
1626 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1627 ResetIDs(browser2
->tab_strip_model(), 100);
1629 // Move both browsers to the second display.
1630 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1631 ASSERT_EQ(2u, roots
.size());
1632 aura::Window
* second_root
= roots
[1];
1633 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1634 second_root
).work_area();
1635 browser()->window()->SetBounds(work_area
);
1637 // position both browser windows side by side on the second screen.
1638 gfx::Rect
work_area2(work_area
);
1639 work_area
.set_width(work_area
.width()/2);
1640 browser()->window()->SetBounds(work_area
);
1641 work_area2
.set_x(work_area2
.x() + work_area2
.width()/2);
1642 work_area2
.set_width(work_area2
.width()/2);
1643 browser2
->window()->SetBounds(work_area2
);
1644 EXPECT_EQ(second_root
,
1645 browser()->window()->GetNativeWindow()->GetRootWindow());
1646 EXPECT_EQ(second_root
,
1647 browser2
->window()->GetNativeWindow()->GetRootWindow());
1649 // Move to the first tab and drag it enough so that it detaches, but not
1650 // enough that it attaches to browser2.
1651 // SetEventGeneratorRootWindow sets correct (second) RootWindow
1652 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1653 SetEventGeneratorRootWindow(tab_0_center
);
1654 ASSERT_TRUE(PressInput(tab_0_center
));
1655 ASSERT_TRUE(DragInputToNotifyWhenDone(
1656 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1657 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1658 this, tab_strip
, tab_strip2
)));
1659 QuitWhenNotDragging();
1661 // Should now be attached to tab_strip2.
1662 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1663 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1664 ASSERT_TRUE(TabDragController::IsActive());
1666 // Release the mouse, stopping the drag session.
1667 ASSERT_TRUE(ReleaseInput());
1668 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1669 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1670 ASSERT_FALSE(TabDragController::IsActive());
1671 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1672 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1674 // Both windows should not be maximized
1675 EXPECT_FALSE(browser()->window()->IsMaximized());
1676 EXPECT_FALSE(browser2
->window()->IsMaximized());
1679 #if defined(OS_CHROMEOS)
1680 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1681 // compositor. crbug.com/331924
1682 #define MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay \
1683 DISABLED_DragMaxTabToNonMaxWindowInSeparateDisplay
1685 #define MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay \
1686 DragMaxTabToNonMaxWindowInSeparateDisplay
1688 // Drags from a maximized browser to another non-maximized browser on a second
1689 // display and releases input.
1690 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1691 MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay
) {
1693 AddTabAndResetBrowser(browser());
1694 browser()->window()->Maximize();
1695 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1697 // Create another browser on the second display.
1698 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1699 ASSERT_EQ(2u, roots
.size());
1700 aura::Window
* first_root
= roots
[0];
1701 aura::Window
* second_root
= roots
[1];
1702 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1703 second_root
).work_area();
1704 work_area
.Inset(20,20,20,60);
1705 Browser::CreateParams
params(browser()->profile(),
1706 browser()->host_desktop_type());
1707 params
.initial_show_state
= ui::SHOW_STATE_NORMAL
;
1708 params
.initial_bounds
= work_area
;
1709 Browser
* browser2
= new Browser(params
);
1710 AddBlankTabAndShow(browser2
);
1712 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1713 ResetIDs(browser2
->tab_strip_model(), 100);
1715 EXPECT_EQ(second_root
,
1716 browser2
->window()->GetNativeWindow()->GetRootWindow());
1717 EXPECT_EQ(first_root
,
1718 browser()->window()->GetNativeWindow()->GetRootWindow());
1719 EXPECT_EQ(2, tab_strip
->tab_count());
1720 EXPECT_EQ(1, tab_strip2
->tab_count());
1722 // Move to the first tab and drag it enough so that it detaches, but not
1723 // enough that it attaches to browser2.
1724 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1725 ASSERT_TRUE(PressInput(tab_0_center
));
1726 ASSERT_TRUE(DragInputToNotifyWhenDone(
1727 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1728 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1729 this, tab_strip
, tab_strip2
)));
1730 QuitWhenNotDragging();
1732 // Should now be attached to tab_strip2.
1733 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1734 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1735 ASSERT_TRUE(TabDragController::IsActive());
1737 // Release the mouse, stopping the drag session.
1738 ASSERT_TRUE(ReleaseInput());
1740 // tab should have moved
1741 EXPECT_EQ(1, tab_strip
->tab_count());
1742 EXPECT_EQ(2, tab_strip2
->tab_count());
1744 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1745 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1746 ASSERT_FALSE(TabDragController::IsActive());
1747 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1748 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1750 // Source browser should still be maximized, target should not
1751 EXPECT_TRUE(browser()->window()->IsMaximized());
1752 EXPECT_FALSE(browser2
->window()->IsMaximized());
1755 // Immersive fullscreen is ChromeOS only.
1756 #if defined(OS_CHROMEOS)
1757 // Drags from a restored browser to an immersive fullscreen browser on a
1758 // second display and releases input.
1759 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1760 DragTabToImmersiveBrowserOnSeparateDisplay
) {
1762 AddTabAndResetBrowser(browser());
1763 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1765 // Create another browser.
1766 Browser
* browser2
= CreateBrowser(browser()->profile());
1767 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1768 ResetIDs(browser2
->tab_strip_model(), 100);
1770 // Move the second browser to the second display.
1771 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1772 ASSERT_EQ(2u, roots
.size());
1773 aura::Window
* second_root
= roots
[1];
1774 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1775 second_root
).work_area();
1776 browser2
->window()->SetBounds(work_area
);
1777 EXPECT_EQ(second_root
,
1778 browser2
->window()->GetNativeWindow()->GetRootWindow());
1780 // Put the second browser into immersive fullscreen.
1781 BrowserView
* browser_view2
= BrowserView::GetBrowserViewForBrowser(browser2
);
1782 ImmersiveModeController
* immersive_controller2
=
1783 browser_view2
->immersive_mode_controller();
1784 immersive_controller2
->SetupForTest();
1785 chrome::ToggleFullscreenMode(browser2
);
1786 ASSERT_TRUE(immersive_controller2
->IsEnabled());
1787 ASSERT_FALSE(immersive_controller2
->IsRevealed());
1788 ASSERT_TRUE(tab_strip2
->IsImmersiveStyle());
1790 // Move to the first tab and drag it enough so that it detaches, but not
1791 // enough that it attaches to browser2.
1792 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1793 ASSERT_TRUE(PressInput(tab_0_center
));
1794 ASSERT_TRUE(DragInputToNotifyWhenDone(
1795 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1796 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1797 this, tab_strip
, tab_strip2
)));
1798 QuitWhenNotDragging();
1800 // Should now be attached to tab_strip2.
1801 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1802 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1803 ASSERT_TRUE(TabDragController::IsActive());
1805 // browser2's top chrome should be revealed and the tab strip should be
1806 // at normal height while user is tragging tabs_strip2's tabs.
1807 ASSERT_TRUE(immersive_controller2
->IsRevealed());
1808 ASSERT_FALSE(tab_strip2
->IsImmersiveStyle());
1810 // Release the mouse, stopping the drag session.
1811 ASSERT_TRUE(ReleaseInput());
1812 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1813 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1814 ASSERT_FALSE(TabDragController::IsActive());
1815 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1816 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1818 // Move the mouse off of browser2's top chrome.
1819 aura::Window
* primary_root
= roots
[0];
1820 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
1821 primary_root
->GetBoundsInScreen().CenterPoint()));
1823 // The first browser window should not be in immersive fullscreen.
1824 // browser2 should still be in immersive fullscreen, but the top chrome should
1825 // no longer be revealed.
1826 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser());
1827 EXPECT_FALSE(browser_view
->immersive_mode_controller()->IsEnabled());
1829 EXPECT_TRUE(immersive_controller2
->IsEnabled());
1830 EXPECT_FALSE(immersive_controller2
->IsRevealed());
1831 EXPECT_TRUE(tab_strip2
->IsImmersiveStyle());
1833 #endif // OS_CHROMEOS
1835 // Subclass of DetachToBrowserTabDragControllerTest that
1836 // creates multiple displays with different device scale factors.
1837 class DifferentDeviceScaleFactorDisplayTabDragControllerTest
1838 : public DetachToBrowserTabDragControllerTest
{
1840 DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1841 virtual ~DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1843 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1844 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line
);
1845 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1846 "400x400,0+400-800x800*2");
1849 float GetCursorDeviceScaleFactor() const {
1850 ash::test::CursorManagerTestApi
cursor_test_api(
1851 ash::Shell::GetInstance()->cursor_manager());
1852 return cursor_test_api
.GetDisplay().device_scale_factor();
1856 DISALLOW_COPY_AND_ASSIGN(
1857 DifferentDeviceScaleFactorDisplayTabDragControllerTest
);
1862 // The points where a tab is dragged in CursorDeviceScaleFactorStep.
1863 const struct DragPoint
{
1874 // The expected device scale factors before the cursor is moved to the
1875 // corresponding kDragPoints in CursorDeviceScaleFactorStep.
1876 const float kDeviceScaleFactorExpectations
[] = {
1885 arraysize(kDragPoints
) == arraysize(kDeviceScaleFactorExpectations
),
1886 kDragPoints_and_kDeviceScaleFactorExpectations_must_have_same_size
);
1888 // Drags tab to |kDragPoints[index]|, then calls the next step function.
1889 void CursorDeviceScaleFactorStep(
1890 DifferentDeviceScaleFactorDisplayTabDragControllerTest
* test
,
1891 TabStrip
* not_attached_tab_strip
,
1893 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
1894 ASSERT_TRUE(TabDragController::IsActive());
1896 if (index
< arraysize(kDragPoints
)) {
1897 EXPECT_EQ(kDeviceScaleFactorExpectations
[index
],
1898 test
->GetCursorDeviceScaleFactor());
1899 const DragPoint p
= kDragPoints
[index
];
1900 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
1901 p
.x
, p
.y
, base::Bind(&CursorDeviceScaleFactorStep
,
1902 test
, not_attached_tab_strip
, index
+ 1)));
1904 // Finishes a serise of CursorDeviceScaleFactorStep calls and ends drag.
1905 EXPECT_EQ(1.0f
, test
->GetCursorDeviceScaleFactor());
1906 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
1907 ui_controls::LEFT
, ui_controls::UP
));
1913 #if defined(OS_CHROMEOS)
1914 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1915 // compositor. crbug.com/331924
1916 #define MAYBE_CursorDeviceScaleFactor DISABLED_CursorDeviceScaleFactor
1918 #define MAYBE_CursorDeviceScaleFactor CursorDeviceScaleFactor
1920 // Verifies cursor's device scale factor is updated when a tab is moved across
1921 // displays with different device scale factors (http://crbug.com/154183).
1922 IN_PROC_BROWSER_TEST_P(DifferentDeviceScaleFactorDisplayTabDragControllerTest
,
1923 MAYBE_CursorDeviceScaleFactor
) {
1925 AddTabAndResetBrowser(browser());
1926 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1928 // Move the second browser to the second display.
1929 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1930 ASSERT_EQ(2u, roots
.size());
1932 // Move to the first tab and drag it enough so that it detaches.
1933 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1934 ASSERT_TRUE(PressInput(tab_0_center
));
1935 ASSERT_TRUE(DragInputToNotifyWhenDone(
1936 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1937 base::Bind(&CursorDeviceScaleFactorStep
,
1938 this, tab_strip
, 0)));
1939 QuitWhenNotDragging();
1944 class DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
1945 : public TabDragControllerTest
{
1947 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest() {}
1949 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1950 TabDragControllerTest::SetUpCommandLine(command_line
);
1951 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1952 "0+0-250x250,251+0-250x250");
1955 bool Press(const gfx::Point
& position
) {
1956 return ui_test_utils::SendMouseMoveSync(position
) &&
1957 ui_test_utils::SendMouseEventsSync(ui_controls::LEFT
,
1961 bool DragTabAndExecuteTaskWhenDone(const gfx::Point
& position
,
1962 const base::Closure
& task
) {
1963 return ui_controls::SendMouseMoveNotifyWhenDone(
1964 position
.x(), position
.y(), task
);
1967 void QuitWhenNotDragging() {
1968 test::QuitWhenNotDraggingImpl();
1969 base::MessageLoop::current()->Run();
1973 DISALLOW_COPY_AND_ASSIGN(
1974 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
);
1977 // Invoked from the nested message loop.
1978 void CancelDragTabToWindowInSeparateDisplayStep3(
1979 TabStrip
* tab_strip
,
1980 const BrowserList
* browser_list
) {
1981 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1982 ASSERT_TRUE(TabDragController::IsActive());
1983 ASSERT_EQ(2u, browser_list
->size());
1985 // Switching display mode should cancel the drag operation.
1986 ash::internal::DisplayManager
* display_manager
=
1987 ash::Shell::GetInstance()->display_manager();
1988 display_manager
->AddRemoveDisplay();
1991 // Invoked from the nested message loop.
1992 void CancelDragTabToWindowInSeparateDisplayStep2(
1993 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
* test
,
1994 TabStrip
* tab_strip
,
1995 aura::Window
* current_root
,
1996 gfx::Point final_destination
,
1997 const BrowserList
* browser_list
) {
1998 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1999 ASSERT_TRUE(TabDragController::IsActive());
2000 ASSERT_EQ(2u, browser_list
->size());
2002 Browser
* new_browser
= browser_list
->get(1);
2003 EXPECT_EQ(current_root
,
2004 new_browser
->window()->GetNativeWindow()->GetRootWindow());
2006 ASSERT_TRUE(test
->DragTabAndExecuteTaskWhenDone(
2008 base::Bind(&CancelDragTabToWindowInSeparateDisplayStep3
,
2009 tab_strip
, browser_list
)));
2014 #if defined(OS_CHROMEOS)
2015 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2016 // compositor. crbug.com/331924
2017 #define MAYBE_CancelDragTabToWindowIn2ndDisplay \
2018 DISABLED_CancelDragTabToWindowIn2ndDisplay
2020 #define MAYBE_CancelDragTabToWindowIn2ndDisplay \
2021 CancelDragTabToWindowIn2ndDisplay
2023 // Drags from browser to a second display and releases input.
2024 IN_PROC_BROWSER_TEST_F(
2025 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
,
2026 MAYBE_CancelDragTabToWindowIn2ndDisplay
) {
2028 AddTabAndResetBrowser(browser());
2029 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2031 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2033 // Move the second browser to the second display.
2034 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
2035 ASSERT_EQ(2u, roots
.size());
2036 gfx::Point final_destination
=
2037 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2038 roots
[1]).work_area().CenterPoint();
2040 // Move to the first tab and drag it enough so that it detaches, but not
2041 // enough to move to another display.
2042 gfx::Point
tab_0_dst(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2043 ASSERT_TRUE(Press(tab_0_dst
));
2044 tab_0_dst
.Offset(0, GetDetachY(tab_strip
));
2045 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2046 tab_0_dst
, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2
,
2047 this, tab_strip
, roots
[0], final_destination
,
2048 native_browser_list
)));
2049 QuitWhenNotDragging();
2051 ASSERT_EQ(1u, native_browser_list
->size());
2052 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2053 ASSERT_FALSE(TabDragController::IsActive());
2054 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2056 // Release the mouse
2057 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2058 ui_controls::LEFT
, ui_controls::UP
));
2061 // Drags from browser from a second display to primary and releases input.
2062 IN_PROC_BROWSER_TEST_F(
2063 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
,
2064 CancelDragTabToWindowIn1stDisplay
) {
2065 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
2066 ASSERT_EQ(2u, roots
.size());
2069 AddTabAndResetBrowser(browser());
2070 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2072 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2073 EXPECT_EQ(roots
[0], browser()->window()->GetNativeWindow()->GetRootWindow());
2075 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->
2076 GetDisplayNearestWindow(roots
[1]).work_area();
2077 browser()->window()->SetBounds(work_area
);
2078 EXPECT_EQ(roots
[1], browser()->window()->GetNativeWindow()->GetRootWindow());
2080 // Move the second browser to the display.
2081 gfx::Point final_destination
=
2082 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2083 roots
[0]).work_area().CenterPoint();
2085 // Move to the first tab and drag it enough so that it detaches, but not
2086 // enough to move to another display.
2087 gfx::Point
tab_0_dst(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2088 ASSERT_TRUE(Press(tab_0_dst
));
2089 tab_0_dst
.Offset(0, GetDetachY(tab_strip
));
2090 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2091 tab_0_dst
, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2
,
2092 this, tab_strip
, roots
[1], final_destination
,
2093 native_browser_list
)));
2094 QuitWhenNotDragging();
2096 ASSERT_EQ(1u, native_browser_list
->size());
2097 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2098 ASSERT_FALSE(TabDragController::IsActive());
2099 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2101 // Release the mouse
2102 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2103 ui_controls::LEFT
, ui_controls::UP
));
2108 void DetachToOwnWindowTwoFingersDragStep5(
2109 DetachToBrowserTabDragControllerTest
* test
) {
2110 ASSERT_EQ(2u, test
->native_browser_list
->size());
2111 Browser
* new_browser
= test
->native_browser_list
->get(1);
2112 ASSERT_TRUE(new_browser
->window()->IsActive());
2114 ASSERT_TRUE(test
->ReleaseInput());
2115 ASSERT_TRUE(test
->ReleaseInput2());
2116 ASSERT_TRUE(new_browser
->window()->IsActive());
2119 void DetachToOwnWindowTwoFingersDragStep4(
2120 DetachToBrowserTabDragControllerTest
* test
,
2121 const gfx::Point
& target_point
) {
2122 ASSERT_EQ(2u, test
->native_browser_list
->size());
2123 Browser
* new_browser
= test
->native_browser_list
->get(1);
2124 ASSERT_TRUE(new_browser
->window()->IsActive());
2126 ASSERT_TRUE(test
->DragInput2ToNotifyWhenDone(
2127 target_point
.x(), target_point
.y(),
2128 base::Bind(&DetachToOwnWindowTwoFingersDragStep5
, test
)));
2131 void DetachToOwnWindowTwoFingersDragStep3(
2132 DetachToBrowserTabDragControllerTest
* test
,
2133 const gfx::Point
& target_point
) {
2134 ASSERT_TRUE(test
->PressInput2());
2136 ASSERT_EQ(2u, test
->native_browser_list
->size());
2137 Browser
* new_browser
= test
->native_browser_list
->get(1);
2138 ASSERT_TRUE(new_browser
->window()->IsActive());
2140 ASSERT_TRUE(test
->DragInputToDelayedNotifyWhenDone(
2141 target_point
.x(), target_point
.y(),
2142 base::Bind(&DetachToOwnWindowTwoFingersDragStep4
,
2145 base::TimeDelta::FromMilliseconds(60)));
2148 void DetachToOwnWindowTwoFingersDragStep2(
2149 DetachToBrowserTabDragControllerTest
* test
,
2150 const gfx::Point
& target_point
) {
2151 ASSERT_EQ(2u, test
->native_browser_list
->size());
2152 Browser
* new_browser
= test
->native_browser_list
->get(1);
2153 ASSERT_TRUE(new_browser
->window()->IsActive());
2155 ASSERT_TRUE(test
->DragInputToDelayedNotifyWhenDone(
2156 target_point
.x(), target_point
.y(),
2157 base::Bind(&DetachToOwnWindowTwoFingersDragStep3
,
2159 target_point
+ gfx::Vector2d(-2, 1)),
2160 base::TimeDelta::FromMilliseconds(60)));
2165 #if defined(OS_CHROMEOS)
2166 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2167 // compositor. crbug.com/331924
2168 #define MAYBE_DetachToOwnWindowTwoFingers DISABLED_DetachToOwnWindowTwoFingers
2170 #define MAYBE_DetachToOwnWindowTwoFingers DetachToOwnWindowTwoFingers
2172 // Drags from browser to separate window starting with one finger and
2173 // then continuing with two fingers.
2174 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestTouch
,
2175 MAYBE_DetachToOwnWindowTwoFingers
) {
2176 gfx::Rect
bounds(browser()->window()->GetBounds());
2178 AddTabAndResetBrowser(browser());
2179 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2181 // Move to the first tab and drag it enough so that it detaches.
2182 gfx::Point
tab_0_center(
2183 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2184 ASSERT_TRUE(PressInput(tab_0_center
));
2185 // Drags in this test are very short to avoid fling.
2186 ASSERT_TRUE(DragInputToDelayedNotifyWhenDone(
2187 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
2188 base::Bind(&DetachToOwnWindowTwoFingersDragStep2
,
2189 this, gfx::Point(5 + tab_0_center
.x(),
2190 1 + tab_0_center
.y()
2191 + GetDetachY(tab_strip
))),
2192 base::TimeDelta::FromMilliseconds(60)));
2193 // Continue dragging, first with one finger, then with two fingers.
2194 QuitWhenNotDragging();
2196 // There should now be another browser.
2197 ASSERT_EQ(2u, native_browser_list
->size());
2198 Browser
* new_browser
= native_browser_list
->get(1);
2199 ASSERT_TRUE(new_browser
->window()->IsActive());
2200 // The sequence of drags should successfully move the browser window.
2201 bounds
+= gfx::Vector2d(5 - 2, 1 + 1 + GetDetachY(tab_strip
));
2202 EXPECT_EQ(bounds
.ToString(),
2203 new_browser
->window()->GetNativeWindow()->bounds().ToString());
2206 // Subclass of DetachToBrowserTabDragControllerTest that runs tests with
2207 // docked windows enabled and disabled.
2208 class DetachToDockedTabDragControllerTest
2209 : public DetachToBrowserTabDragControllerTest
{
2211 DetachToDockedTabDragControllerTest() {}
2212 virtual ~DetachToDockedTabDragControllerTest() {}
2215 DISALLOW_COPY_AND_ASSIGN(DetachToDockedTabDragControllerTest
);
2220 void DetachToDockedWindowNextStep(
2221 DetachToDockedTabDragControllerTest
* test
,
2222 const gfx::Point
& target_point
,
2224 ASSERT_EQ(2u, test
->native_browser_list
->size());
2225 Browser
* new_browser
= test
->native_browser_list
->get(1);
2226 ASSERT_TRUE(new_browser
->window()->IsActive());
2229 ASSERT_TRUE(test
->ReleaseInput());
2232 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
2233 target_point
.x(), target_point
.y(),
2234 base::Bind(&DetachToDockedWindowNextStep
,
2236 gfx::Point(target_point
.x(), 1 + target_point
.y()),
2242 // Drags from browser to separate window, docks that window and releases mouse.
2243 IN_PROC_BROWSER_TEST_P(DetachToDockedTabDragControllerTest
,
2244 DetachToDockedWindowFromMaximizedWindow
) {
2245 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2246 // compositor. crbug.com/331924
2247 if (docked_windows_enabled()) {
2248 VLOG(1) << "Test is DISABLED for docked windows.";
2252 // Maximize the initial browser window.
2253 browser()->window()->Maximize();
2254 ASSERT_TRUE(browser()->window()->IsMaximized());
2257 AddTabAndResetBrowser(browser());
2258 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2260 // Move to the first tab and drag it enough so that it detaches.
2261 gfx::Point
tab_0_center(
2262 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2263 ASSERT_TRUE(PressInput(tab_0_center
));
2265 // The following matches kMovesBeforeAdjust in snap_sizer.cc
2266 const int kNumIterations
= 25 * 5 + 10;
2267 ASSERT_TRUE(DragInputToNotifyWhenDone(
2268 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
2269 base::Bind(&DetachToDockedWindowNextStep
, this,
2270 gfx::Point(0, tab_0_center
.y() + GetDetachY(tab_strip
)),
2272 // Continue dragging enough times to go through snapping sequence and dock
2274 QuitWhenNotDragging();
2275 // Should no longer be dragging.
2276 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2277 ASSERT_FALSE(TabDragController::IsActive());
2279 // There should now be another browser.
2280 ASSERT_EQ(2u, native_browser_list
->size());
2281 Browser
* new_browser
= native_browser_list
->get(1);
2282 ASSERT_TRUE(new_browser
->window()->IsActive());
2283 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
2284 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
2286 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
2287 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
2289 // The bounds of the initial window should not have changed.
2290 EXPECT_TRUE(browser()->window()->IsMaximized());
2292 EXPECT_FALSE(GetIsDragged(browser()));
2293 EXPECT_FALSE(GetIsDragged(new_browser
));
2294 // After this both windows should still be manageable.
2295 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
2296 EXPECT_TRUE(IsWindowPositionManaged(
2297 new_browser
->window()->GetNativeWindow()));
2299 ash::wm::WindowState
* window_state
=
2300 ash::wm::GetWindowState(new_browser
->window()->GetNativeWindow());
2301 // The new window should not be maximized because it gets docked or snapped.
2302 EXPECT_FALSE(new_browser
->window()->IsMaximized());
2303 if (docked_windows_enabled()) {
2304 // The new window should be docked and not snapped if docking is allowed.
2305 EXPECT_TRUE(window_state
->IsDocked());
2306 EXPECT_FALSE(window_state
->IsSnapped());
2308 // The new window should be snapped and not docked if docking is disabled.
2309 EXPECT_FALSE(window_state
->IsDocked());
2310 EXPECT_TRUE(window_state
->IsSnapped());
2317 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
2318 INSTANTIATE_TEST_CASE_P(TabDragging
,
2319 DetachToBrowserInSeparateDisplayTabDragControllerTest
,
2320 ::testing::Values("mouse", "touch"));
2321 INSTANTIATE_TEST_CASE_P(TabDragging
,
2322 DifferentDeviceScaleFactorDisplayTabDragControllerTest
,
2323 ::testing::Values("mouse"));
2324 INSTANTIATE_TEST_CASE_P(TabDragging
,
2325 DetachToBrowserTabDragControllerTest
,
2326 ::testing::Values("mouse", "touch"));
2327 INSTANTIATE_TEST_CASE_P(TabDragging
,
2328 DetachToDockedTabDragControllerTest
,
2329 ::testing::Values("mouse", "mouse docked"));
2330 INSTANTIATE_TEST_CASE_P(TabDragging
,
2331 DetachToBrowserTabDragControllerTestTouch
,
2332 ::testing::Values("touch", "touch docked"));
2334 INSTANTIATE_TEST_CASE_P(TabDragging
,
2335 DetachToBrowserTabDragControllerTest
,
2336 ::testing::Values("mouse"));