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::StopAnimating(TabStrip
* tab_strip
) {
165 tab_strip
->StopAnimating(true);
168 void TabDragControllerTest::AddTabAndResetBrowser(Browser
* browser
) {
169 AddBlankTabAndShow(browser
);
170 StopAnimating(GetTabStripForBrowser(browser
));
171 ResetIDs(browser
->tab_strip_model(), 0);
174 Browser
* TabDragControllerTest::CreateAnotherWindowBrowserAndRelayout() {
175 // Create another browser.
176 Browser
* browser2
= CreateBrowser(browser()->profile());
177 ResetIDs(browser2
->tab_strip_model(), 100);
179 // Resize the two windows so they're right next to each other.
180 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
181 browser()->window()->GetNativeWindow()).work_area();
182 gfx::Size half_size
=
183 gfx::Size(work_area
.width() / 3 - 10, work_area
.height() / 2 - 10);
184 browser()->window()->SetBounds(gfx::Rect(work_area
.origin(), half_size
));
185 browser2
->window()->SetBounds(gfx::Rect(
186 work_area
.x() + half_size
.width(), work_area
.y(),
187 half_size
.width(), half_size
.height()));
194 INPUT_SOURCE_MOUSE
= 0,
195 INPUT_SOURCE_TOUCH
= 1
198 int GetDetachY(TabStrip
* tab_strip
) {
199 return std::max(TabDragController::kTouchVerticalDetachMagnetism
,
200 TabDragController::kVerticalDetachMagnetism
) +
201 tab_strip
->height() + 1;
204 bool GetIsDragged(Browser
* browser
) {
205 #if !defined(USE_ASH) || defined(OS_WIN) // TODO(win_ash)
208 return ash::wm::GetWindowState(browser
->window()->GetNativeWindow())->
215 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
216 class ScreenEventGeneratorDelegate
: public aura::test::EventGeneratorDelegate
{
218 explicit ScreenEventGeneratorDelegate(aura::Window
* root_window
)
219 : root_window_(root_window
) {}
220 virtual ~ScreenEventGeneratorDelegate() {}
222 // EventGeneratorDelegate overrides:
223 virtual aura::RootWindow
* GetRootWindowAt(
224 const gfx::Point
& point
) const OVERRIDE
{
225 return root_window_
->GetDispatcher();
228 virtual aura::client::ScreenPositionClient
* GetScreenPositionClient(
229 const aura::Window
* window
) const OVERRIDE
{
230 return aura::client::GetScreenPositionClient(root_window_
);
234 aura::Window
* root_window_
;
236 DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate
);
241 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
243 // Following classes verify a crash scenario. Specifically on Windows when focus
244 // changes it can trigger capture being lost. This was causing a crash in tab
245 // dragging as it wasn't set up to handle this scenario. These classes
246 // synthesize this scenario.
248 // Allows making ClearNativeFocus() invoke ReleaseCapture().
249 class TestDesktopBrowserFrameAura
: public DesktopBrowserFrameAura
{
251 TestDesktopBrowserFrameAura(
252 BrowserFrame
* browser_frame
,
253 BrowserView
* browser_view
)
254 : DesktopBrowserFrameAura(browser_frame
, browser_view
),
255 release_capture_(false) {}
256 virtual ~TestDesktopBrowserFrameAura() {}
258 void ReleaseCaptureOnNextClear() {
259 release_capture_
= true;
262 virtual void ClearNativeFocus() OVERRIDE
{
263 views::DesktopNativeWidgetAura::ClearNativeFocus();
264 if (release_capture_
) {
265 release_capture_
= false;
266 GetWidget()->ReleaseCapture();
271 // If true ReleaseCapture() is invoked in ClearNativeFocus().
272 bool release_capture_
;
274 DISALLOW_COPY_AND_ASSIGN(TestDesktopBrowserFrameAura
);
277 // Factory for creating a TestDesktopBrowserFrameAura.
278 class TestNativeBrowserFrameFactory
: public NativeBrowserFrameFactory
{
280 TestNativeBrowserFrameFactory() {}
281 virtual ~TestNativeBrowserFrameFactory() {}
283 virtual NativeBrowserFrame
* Create(
284 BrowserFrame
* browser_frame
,
285 BrowserView
* browser_view
) OVERRIDE
{
286 return new TestDesktopBrowserFrameAura(browser_frame
, browser_view
);
290 DISALLOW_COPY_AND_ASSIGN(TestNativeBrowserFrameFactory
);
293 class TabDragCaptureLostTest
: public TabDragControllerTest
{
295 TabDragCaptureLostTest() {
296 NativeBrowserFrameFactory::Set(new TestNativeBrowserFrameFactory
);
300 DISALLOW_COPY_AND_ASSIGN(TabDragCaptureLostTest
);
303 // See description above for details.
304 IN_PROC_BROWSER_TEST_F(TabDragCaptureLostTest
, ReleaseCaptureOnDrag
) {
305 AddTabAndResetBrowser(browser());
307 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
308 gfx::Point
tab_1_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(1)));
309 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_1_center
) &&
310 ui_test_utils::SendMouseEventsSync(
311 ui_controls::LEFT
, ui_controls::DOWN
));
312 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
313 TestDesktopBrowserFrameAura
* frame
=
314 static_cast<TestDesktopBrowserFrameAura
*>(
315 BrowserView::GetBrowserViewForBrowser(browser())->GetWidget()->
316 native_widget_private());
317 // Invoke ReleaseCaptureOnDrag() so that when the drag happens and focus
318 // changes capture is released and the drag cancels.
319 frame
->ReleaseCaptureOnNextClear();
320 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(tab_0_center
));
321 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
324 IN_PROC_BROWSER_TEST_F(TabDragControllerTest
, GestureEndShouldEndDragTest
) {
325 AddTabAndResetBrowser(browser());
327 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
328 TabStripModel
* model
= browser()->tab_strip_model();
330 Tab
* tab1
= tab_strip
->tab_at(1);
331 gfx::Point
tab_1_center(tab1
->width() / 2, tab1
->height() / 2);
333 ui::GestureEvent
gesture_begin(ui::ET_GESTURE_BEGIN
, tab_1_center
.x(),
334 tab_1_center
.x(), 0, base::TimeDelta(),
335 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN
, 0.0f
, 0.0f
), 0);
336 tab_strip
->MaybeStartDrag(tab1
, gesture_begin
,
337 tab_strip
->GetSelectionModel());
338 //tab_strip->tab_at(1)->OnGestureEvent(&gesture_begin);
339 EXPECT_TRUE(TabDragController::IsActive());
341 ui::GestureEvent
gesture_end(ui::ET_GESTURE_END
, tab_1_center
.x(),
342 tab_1_center
.x(), 0, base::TimeDelta(),
343 ui::GestureEventDetails(ui::ET_GESTURE_END
, 0.0f
, 0.0f
), 0);
344 tab_strip
->OnGestureEvent(&gesture_end
);
345 EXPECT_FALSE(TabDragController::IsActive());
346 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
351 class DetachToBrowserTabDragControllerTest
352 : public TabDragControllerTest
,
353 public ::testing::WithParamInterface
<const char*> {
355 DetachToBrowserTabDragControllerTest() {}
357 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
358 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
359 if (!docked_windows_enabled()) {
360 CommandLine::ForCurrentProcess()->AppendSwitch(
361 ash::switches::kAshDisableDockedWindows
);
366 virtual void SetUpOnMainThread() OVERRIDE
{
367 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
368 event_generator_
.reset(new aura::test::EventGenerator(
369 ash::Shell::GetPrimaryRootWindow()));
373 InputSource
input_source() const {
374 return strstr(GetParam(), "mouse") ?
375 INPUT_SOURCE_MOUSE
: INPUT_SOURCE_TOUCH
;
378 bool docked_windows_enabled() const {
379 return (strstr(GetParam(), "docked") != NULL
);
382 // Set root window from a point in screen coordinates
383 void SetEventGeneratorRootWindow(const gfx::Point
& point
) {
384 if (input_source() == INPUT_SOURCE_MOUSE
)
386 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
387 event_generator_
.reset(new aura::test::EventGenerator(
388 new ScreenEventGeneratorDelegate(ash::wm::GetRootWindowAt(point
))));
392 // The following methods update one of the mouse or touch input depending upon
394 bool PressInput(const gfx::Point
& location
) {
395 if (input_source() == INPUT_SOURCE_MOUSE
) {
396 return ui_test_utils::SendMouseMoveSync(location
) &&
397 ui_test_utils::SendMouseEventsSync(
398 ui_controls::LEFT
, ui_controls::DOWN
);
400 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
401 event_generator_
->set_current_location(location
);
402 event_generator_
->PressTouch();
410 // Second touch input is only used for touch sequence tests.
411 EXPECT_EQ(INPUT_SOURCE_TOUCH
, input_source());
412 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
413 event_generator_
->set_current_location(
414 event_generator_
->current_location());
415 event_generator_
->PressTouchId(1);
422 bool DragInputTo(const gfx::Point
& location
) {
423 if (input_source() == INPUT_SOURCE_MOUSE
)
424 return ui_test_utils::SendMouseMoveSync(location
);
425 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
426 event_generator_
->MoveTouch(location
);
433 bool DragInputToAsync(const gfx::Point
& location
) {
434 if (input_source() == INPUT_SOURCE_MOUSE
)
435 return ui_controls::SendMouseMove(location
.x(), location
.y());
436 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
437 event_generator_
->MoveTouch(location
);
444 bool DragInputToNotifyWhenDone(int x
,
446 const base::Closure
& task
) {
447 if (input_source() == INPUT_SOURCE_MOUSE
)
448 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
449 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
450 base::MessageLoop::current()->PostTask(FROM_HERE
, task
);
451 event_generator_
->MoveTouch(gfx::Point(x
, y
));
458 bool DragInputToDelayedNotifyWhenDone(int x
,
460 const base::Closure
& task
,
461 base::TimeDelta delay
) {
462 if (input_source() == INPUT_SOURCE_MOUSE
)
463 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
464 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
465 base::MessageLoop::current()->PostDelayedTask(FROM_HERE
, task
, delay
);
466 event_generator_
->MoveTouch(gfx::Point(x
, y
));
473 bool DragInput2ToNotifyWhenDone(int x
,
475 const base::Closure
& task
) {
476 if (input_source() == INPUT_SOURCE_MOUSE
)
477 return ui_controls::SendMouseMoveNotifyWhenDone(x
, y
, task
);
478 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
479 base::MessageLoop::current()->PostTask(FROM_HERE
, task
);
480 event_generator_
->MoveTouchId(gfx::Point(x
, y
), 1);
487 bool ReleaseInput() {
488 if (input_source() == INPUT_SOURCE_MOUSE
) {
489 return ui_test_utils::SendMouseEventsSync(
490 ui_controls::LEFT
, ui_controls::UP
);
492 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
493 event_generator_
->ReleaseTouch();
500 bool ReleaseInput2() {
501 if (input_source() == INPUT_SOURCE_MOUSE
) {
502 return ui_test_utils::SendMouseEventsSync(
503 ui_controls::LEFT
, ui_controls::UP
);
505 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
506 event_generator_
->ReleaseTouchId(1);
513 bool ReleaseMouseAsync() {
514 return input_source() == INPUT_SOURCE_MOUSE
&&
515 ui_controls::SendMouseEvents(ui_controls::LEFT
, ui_controls::UP
);
518 void QuitWhenNotDragging() {
519 if (input_source() == INPUT_SOURCE_MOUSE
) {
520 // Schedule observer to quit message loop when done dragging. This has to
521 // be async so the message loop can run.
522 test::QuitWhenNotDraggingImpl();
523 base::MessageLoop::current()->Run();
525 // Touch events are sync, so we know we're not in a drag session. But some
526 // tests rely on the browser fully closing, which is async. So, run all
528 base::RunLoop run_loop
;
529 run_loop
.RunUntilIdle();
533 void AddBlankTabAndShow(Browser
* browser
) {
534 InProcessBrowserTest::AddBlankTabAndShow(browser
);
537 Browser
* browser() const { return InProcessBrowserTest::browser(); }
540 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
541 scoped_ptr
<aura::test::EventGenerator
> event_generator_
;
544 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTest
);
547 // Creates a browser with two tabs, drags the second to the first.
548 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
, DragInSameWindow
) {
549 // TODO(sky): this won't work with touch as it requires a long press.
550 if (input_source() == INPUT_SOURCE_TOUCH
) {
551 VLOG(1) << "Test is DISABLED for touch input.";
555 AddTabAndResetBrowser(browser());
557 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
558 TabStripModel
* model
= browser()->tab_strip_model();
560 gfx::Point
tab_1_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(1)));
561 ASSERT_TRUE(PressInput(tab_1_center
));
562 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
563 ASSERT_TRUE(DragInputTo(tab_0_center
));
564 ASSERT_TRUE(ReleaseInput());
565 EXPECT_EQ("1 0", IDString(model
));
566 EXPECT_FALSE(TabDragController::IsActive());
567 EXPECT_FALSE(tab_strip
->IsDragSessionActive());
569 // The tab strip should no longer have capture because the drag was ended and
570 // mouse/touch was released.
571 EXPECT_FALSE(tab_strip
->GetWidget()->HasCapture());
576 // Invoked from the nested message loop.
577 void DragToSeparateWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
578 TabStrip
* not_attached_tab_strip
,
579 TabStrip
* target_tab_strip
) {
580 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
581 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
582 ASSERT_TRUE(TabDragController::IsActive());
584 // Drag to target_tab_strip. This should stop the nested loop from dragging
586 gfx::Point
target_point(target_tab_strip
->width() -1,
587 target_tab_strip
->height() / 2);
588 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
589 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
594 #if defined(OS_CHROMEOS)
595 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
596 // compositor. crbug.com/331924
597 #define MAYBE_DragToSeparateWindow DISABLED_DragToSeparateWindow
599 #define MAYBE_DragToSeparateWindow DragToSeparateWindow
601 // Creates two browsers, drags from first into second.
602 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
603 MAYBE_DragToSeparateWindow
) {
604 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
606 // Add another tab to browser().
607 AddTabAndResetBrowser(browser());
609 // Create another browser.
610 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
611 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
613 // Move to the first tab and drag it enough so that it detaches, but not
614 // enough that it attaches to browser2.
615 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
616 ASSERT_TRUE(PressInput(tab_0_center
));
617 ASSERT_TRUE(DragInputToNotifyWhenDone(
618 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
619 base::Bind(&DragToSeparateWindowStep2
,
620 this, tab_strip
, tab_strip2
)));
621 QuitWhenNotDragging();
623 // Should now be attached to tab_strip2.
624 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
625 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
626 ASSERT_TRUE(TabDragController::IsActive());
627 EXPECT_FALSE(GetIsDragged(browser()));
629 // Release mouse or touch, stopping the drag session.
630 ASSERT_TRUE(ReleaseInput());
631 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
632 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
633 ASSERT_FALSE(TabDragController::IsActive());
634 EXPECT_EQ("100 0", IDString(browser2
->tab_strip_model()));
635 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
636 EXPECT_FALSE(GetIsDragged(browser2
));
638 // Both windows should not be maximized
639 EXPECT_FALSE(browser()->window()->IsMaximized());
640 EXPECT_FALSE(browser2
->window()->IsMaximized());
642 // The tab strip should no longer have capture because the drag was ended and
643 // mouse/touch was released.
644 EXPECT_FALSE(tab_strip
->GetWidget()->HasCapture());
645 EXPECT_FALSE(tab_strip2
->GetWidget()->HasCapture());
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());
729 // The tab strip should no longer have capture because the drag was ended and
730 // mouse/touch was released.
731 EXPECT_FALSE(tab_strip
->GetWidget()->HasCapture());
732 EXPECT_FALSE(tab_strip2
->GetWidget()->HasCapture());
735 #if defined(OS_CHROMEOS)
736 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
737 // compositor. crbug.com/331924
738 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
739 DISABLED_DetachToOwnWindowFromMaximizedWindow
741 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
742 DetachToOwnWindowFromMaximizedWindow
744 // Drags from browser to a separate window and releases mouse.
745 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
746 MAYBE_DetachToOwnWindowFromMaximizedWindow
) {
747 // Maximize the initial browser window.
748 browser()->window()->Maximize();
749 ASSERT_TRUE(browser()->window()->IsMaximized());
752 AddTabAndResetBrowser(browser());
753 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
755 // Move to the first tab and drag it enough so that it detaches.
756 gfx::Point
tab_0_center(
757 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
758 ASSERT_TRUE(PressInput(tab_0_center
));
759 ASSERT_TRUE(DragInputToNotifyWhenDone(
760 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
761 base::Bind(&DetachToOwnWindowStep2
, this)));
762 if (input_source() == INPUT_SOURCE_MOUSE
) {
763 ASSERT_TRUE(ReleaseMouseAsync());
764 QuitWhenNotDragging();
767 // Should no longer be dragging.
768 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
769 ASSERT_FALSE(TabDragController::IsActive());
771 // There should now be another browser.
772 ASSERT_EQ(2u, native_browser_list
->size());
773 Browser
* new_browser
= native_browser_list
->get(1);
774 ASSERT_TRUE(new_browser
->window()->IsActive());
775 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
776 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
778 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
779 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
781 // The bounds of the initial window should not have changed.
782 EXPECT_TRUE(browser()->window()->IsMaximized());
784 EXPECT_FALSE(GetIsDragged(browser()));
785 EXPECT_FALSE(GetIsDragged(new_browser
));
786 // After this both windows should still be manageable.
787 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
788 EXPECT_TRUE(IsWindowPositionManaged(
789 new_browser
->window()->GetNativeWindow()));
791 // The new window should be maximized.
792 EXPECT_TRUE(new_browser
->window()->IsMaximized());
795 // Deletes a tab being dragged before the user moved enough to start a drag.
796 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
797 DeleteBeforeStartedDragging
) {
799 AddTabAndResetBrowser(browser());
800 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
802 // Click on the first tab, but don't move it.
803 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
804 ASSERT_TRUE(PressInput(tab_0_center
));
806 // Should be dragging.
807 ASSERT_TRUE(tab_strip
->IsDragSessionActive());
808 ASSERT_TRUE(TabDragController::IsActive());
810 // Delete the tab being dragged.
811 delete browser()->tab_strip_model()->GetWebContentsAt(0);
813 // Should have canceled dragging.
814 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
815 ASSERT_FALSE(TabDragController::IsActive());
817 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
818 EXPECT_FALSE(GetIsDragged(browser()));
821 #if defined(OS_CHROMEOS)
822 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
823 // compositor. crbug.com/331924
824 #define MAYBE_DeleteTabWhileAttached DISABLED_DeleteTabWhileAttached
826 #define MAYBE_DeleteTabWhileAttached DeleteTabWhileAttached
828 // Deletes a tab being dragged while still attached.
829 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
830 MAYBE_DeleteTabWhileAttached
) {
831 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
832 // compositor. crbug.com/331924
833 if (input_source() == INPUT_SOURCE_MOUSE
) {
834 VLOG(1) << "Test is DISABLED for mouse input.";
839 AddTabAndResetBrowser(browser());
840 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
842 // Click on the first tab and move it enough so that it starts dragging but is
844 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
845 ASSERT_TRUE(PressInput(tab_0_center
));
846 ASSERT_TRUE(DragInputTo(
847 gfx::Point(tab_0_center
.x() + 20, tab_0_center
.y())));
849 // Should be dragging.
850 ASSERT_TRUE(tab_strip
->IsDragSessionActive());
851 ASSERT_TRUE(TabDragController::IsActive());
853 // Delete the tab being dragged.
854 delete browser()->tab_strip_model()->GetWebContentsAt(0);
856 // Should have canceled dragging.
857 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
858 ASSERT_FALSE(TabDragController::IsActive());
860 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
862 EXPECT_FALSE(GetIsDragged(browser()));
867 void DeleteWhileDetachedStep2(WebContents
* tab
) {
873 #if defined(OS_CHROMEOS)
874 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
875 // compositor. crbug.com/331924
876 #define MAYBE_DeleteTabWhileDetached DISABLED_DeleteTabWhileDetached
878 #define MAYBE_DeleteTabWhileDetached DeleteTabWhileDetached
880 // Deletes a tab being dragged after dragging a tab so that a new window is
882 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
883 MAYBE_DeleteTabWhileDetached
) {
885 AddTabAndResetBrowser(browser());
886 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
888 // Move to the first tab and drag it enough so that it detaches.
889 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
890 WebContents
* to_delete
=
891 browser()->tab_strip_model()->GetWebContentsAt(0);
892 ASSERT_TRUE(PressInput(tab_0_center
));
893 ASSERT_TRUE(DragInputToNotifyWhenDone(
894 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
895 base::Bind(&DeleteWhileDetachedStep2
, to_delete
)));
896 QuitWhenNotDragging();
898 // Should not be dragging.
899 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
900 ASSERT_FALSE(TabDragController::IsActive());
902 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
904 EXPECT_FALSE(GetIsDragged(browser()));
909 void DeleteSourceDetachedStep2(WebContents
* tab
,
910 const BrowserList
* browser_list
) {
911 ASSERT_EQ(2u, browser_list
->size());
912 Browser
* new_browser
= browser_list
->get(1);
913 // This ends up closing the source window.
916 ui_controls::SendKeyPress(new_browser
->window()->GetNativeWindow(),
917 ui::VKEY_ESCAPE
, false, false, false, false);
922 #if defined(OS_CHROMEOS)
923 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
924 // compositor. crbug.com/331924
925 #define MAYBE_DeleteSourceDetached DISABLED_DeleteSourceDetached
927 #define MAYBE_DeleteSourceDetached DeleteSourceDetached
929 // Detaches a tab and while detached deletes a tab from the source so that the
930 // source window closes then presses escape to cancel the drag.
931 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
932 MAYBE_DeleteSourceDetached
) {
934 AddTabAndResetBrowser(browser());
935 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
937 // Move to the first tab and drag it enough so that it detaches.
938 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
939 WebContents
* to_delete
= browser()->tab_strip_model()->GetWebContentsAt(1);
940 ASSERT_TRUE(PressInput(tab_0_center
));
941 ASSERT_TRUE(DragInputToNotifyWhenDone(
942 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
943 base::Bind(&DeleteSourceDetachedStep2
, to_delete
, native_browser_list
)));
944 QuitWhenNotDragging();
946 // Should not be dragging.
947 ASSERT_EQ(1u, native_browser_list
->size());
948 Browser
* new_browser
= native_browser_list
->get(0);
949 ASSERT_FALSE(GetTabStripForBrowser(new_browser
)->IsDragSessionActive());
950 ASSERT_FALSE(TabDragController::IsActive());
952 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
954 EXPECT_FALSE(GetIsDragged(new_browser
));
956 // Remaining browser window should not be maximized
957 EXPECT_FALSE(new_browser
->window()->IsMaximized());
962 void PressEscapeWhileDetachedStep2(const BrowserList
* browser_list
) {
963 ASSERT_EQ(2u, browser_list
->size());
964 Browser
* new_browser
= browser_list
->get(1);
965 ui_controls::SendKeyPress(
966 new_browser
->window()->GetNativeWindow(), ui::VKEY_ESCAPE
, false, false,
972 #if defined(OS_CHROMEOS)
973 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
974 // compositor. crbug.com/331924
975 #define MAYBE_PressEscapeWhileDetached DISABLED_PressEscapeWhileDetached
977 #define MAYBE_PressEscapeWhileDetached PressEscapeWhileDetached
979 // This is disabled until NativeViewHost::Detach really detaches.
980 // Detaches a tab and while detached presses escape to revert the drag.
981 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
982 MAYBE_PressEscapeWhileDetached
) {
984 AddTabAndResetBrowser(browser());
985 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
987 // Move to the first tab and drag it enough so that it detaches.
988 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
989 ASSERT_TRUE(PressInput(tab_0_center
));
990 ASSERT_TRUE(DragInputToNotifyWhenDone(
991 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
992 base::Bind(&PressEscapeWhileDetachedStep2
, native_browser_list
)));
993 QuitWhenNotDragging();
995 // Should not be dragging.
996 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
997 ASSERT_FALSE(TabDragController::IsActive());
999 // And there should only be one window.
1000 EXPECT_EQ(1u, native_browser_list
->size());
1002 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1004 // Remaining browser window should not be maximized
1005 EXPECT_FALSE(browser()->window()->IsMaximized());
1007 // The tab strip should no longer have capture because the drag was ended and
1008 // mouse/touch was released.
1009 EXPECT_FALSE(tab_strip
->GetWidget()->HasCapture());
1014 void DragAllStep2(DetachToBrowserTabDragControllerTest
* test
,
1015 const BrowserList
* browser_list
) {
1016 // Should only be one window.
1017 ASSERT_EQ(1u, browser_list
->size());
1018 if (test
->input_source() == INPUT_SOURCE_TOUCH
) {
1019 ASSERT_TRUE(test
->ReleaseInput());
1021 ASSERT_TRUE(test
->ReleaseMouseAsync());
1027 #if defined(OS_CHROMEOS)
1028 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1029 // compositor. crbug.com/331924
1030 #define MAYBE_DragAll DISABLED_DragAll
1032 #define MAYBE_DragAll DragAll
1034 // Selects multiple tabs and starts dragging the window.
1035 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
, MAYBE_DragAll
) {
1037 AddTabAndResetBrowser(browser());
1038 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1039 browser()->tab_strip_model()->AddTabAtToSelection(0);
1040 browser()->tab_strip_model()->AddTabAtToSelection(1);
1042 // Move to the first tab and drag it enough so that it would normally
1044 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1045 ASSERT_TRUE(PressInput(tab_0_center
));
1046 ASSERT_TRUE(DragInputToNotifyWhenDone(
1047 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1048 base::Bind(&DragAllStep2
, this, native_browser_list
)));
1049 QuitWhenNotDragging();
1051 // Should not be dragging.
1052 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1053 ASSERT_FALSE(TabDragController::IsActive());
1055 // And there should only be one window.
1056 EXPECT_EQ(1u, native_browser_list
->size());
1058 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
1060 EXPECT_FALSE(GetIsDragged(browser()));
1062 // Remaining browser window should not be maximized
1063 EXPECT_FALSE(browser()->window()->IsMaximized());
1068 // Invoked from the nested message loop.
1069 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
1070 TabStrip
* attached_tab_strip
,
1071 TabStrip
* target_tab_strip
,
1072 const BrowserList
* browser_list
) {
1073 ASSERT_TRUE(attached_tab_strip
->IsDragSessionActive());
1074 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1075 ASSERT_TRUE(TabDragController::IsActive());
1076 ASSERT_EQ(2u, browser_list
->size());
1078 // Drag to target_tab_strip. This should stop the nested loop from dragging
1080 gfx::Point
target_point(target_tab_strip
->width() - 1,
1081 target_tab_strip
->height() / 2);
1082 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
1083 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1088 #if defined(OS_CHROMEOS)
1089 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1090 // compositor. crbug.com/331924
1091 #define MAYBE_DragAllToSeparateWindow DISABLED_DragAllToSeparateWindow
1093 #define MAYBE_DragAllToSeparateWindow DragAllToSeparateWindow
1095 // Creates two browsers, selects all tabs in first and drags into second.
1096 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1097 MAYBE_DragAllToSeparateWindow
) {
1098 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1100 // Add another tab to browser().
1101 AddTabAndResetBrowser(browser());
1103 // Create another browser.
1104 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1105 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1107 browser()->tab_strip_model()->AddTabAtToSelection(0);
1108 browser()->tab_strip_model()->AddTabAtToSelection(1);
1110 // Move to the first tab and drag it enough so that it detaches, but not
1111 // enough that it attaches to browser2.
1112 gfx::Point
tab_0_center(
1113 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1114 ASSERT_TRUE(PressInput(tab_0_center
));
1115 ASSERT_TRUE(DragInputToNotifyWhenDone(
1116 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1117 base::Bind(&DragAllToSeparateWindowStep2
, this, tab_strip
, tab_strip2
,
1118 native_browser_list
)));
1119 QuitWhenNotDragging();
1121 // Should now be attached to tab_strip2.
1122 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1123 ASSERT_TRUE(TabDragController::IsActive());
1124 ASSERT_EQ(1u, native_browser_list
->size());
1126 // Release the mouse, stopping the drag session.
1127 ASSERT_TRUE(ReleaseInput());
1128 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1129 ASSERT_FALSE(TabDragController::IsActive());
1130 EXPECT_EQ("100 0 1", IDString(browser2
->tab_strip_model()));
1132 EXPECT_FALSE(GetIsDragged(browser2
));
1134 // Remaining browser window should not be maximized
1135 EXPECT_FALSE(browser2
->window()->IsMaximized());
1140 // Invoked from the nested message loop.
1141 void DragAllToSeparateWindowAndCancelStep2(
1142 DetachToBrowserTabDragControllerTest
* test
,
1143 TabStrip
* attached_tab_strip
,
1144 TabStrip
* target_tab_strip
,
1145 const BrowserList
* browser_list
) {
1146 ASSERT_TRUE(attached_tab_strip
->IsDragSessionActive());
1147 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1148 ASSERT_TRUE(TabDragController::IsActive());
1149 ASSERT_EQ(2u, browser_list
->size());
1151 // Drag to target_tab_strip. This should stop the nested loop from dragging
1153 gfx::Point
target_point(target_tab_strip
->width() - 1,
1154 target_tab_strip
->height() / 2);
1155 views::View::ConvertPointToScreen(target_tab_strip
, &target_point
);
1156 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1161 #if defined(OS_CHROMEOS)
1162 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1163 // compositor. crbug.com/331924
1164 #define MAYBE_DragAllToSeparateWindowAndCancel \
1165 DISABLED_DragAllToSeparateWindowAndCancel
1167 #define MAYBE_DragAllToSeparateWindowAndCancel DragAllToSeparateWindowAndCancel
1169 // Creates two browsers, selects all tabs in first, drags into second, then hits
1171 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1172 MAYBE_DragAllToSeparateWindowAndCancel
) {
1173 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1175 // Add another tab to browser().
1176 AddTabAndResetBrowser(browser());
1178 // Create another browser.
1179 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1180 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1182 browser()->tab_strip_model()->AddTabAtToSelection(0);
1183 browser()->tab_strip_model()->AddTabAtToSelection(1);
1185 // Move to the first tab and drag it enough so that it detaches, but not
1186 // enough that it attaches to browser2.
1187 gfx::Point
tab_0_center(
1188 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1189 ASSERT_TRUE(PressInput(tab_0_center
));
1190 ASSERT_TRUE(DragInputToNotifyWhenDone(
1191 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1192 base::Bind(&DragAllToSeparateWindowAndCancelStep2
, this,
1193 tab_strip
, tab_strip2
, native_browser_list
)));
1194 QuitWhenNotDragging();
1196 // Should now be attached to tab_strip2.
1197 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1198 ASSERT_TRUE(TabDragController::IsActive());
1199 ASSERT_EQ(1u, native_browser_list
->size());
1202 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
1203 browser2
, ui::VKEY_ESCAPE
, false, false, false, false));
1205 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1206 ASSERT_FALSE(TabDragController::IsActive());
1207 EXPECT_EQ("100 0 1", IDString(browser2
->tab_strip_model()));
1209 // browser() will have been destroyed, but browser2 should remain.
1210 ASSERT_EQ(1u, native_browser_list
->size());
1212 EXPECT_FALSE(GetIsDragged(browser2
));
1214 // Remaining browser window should not be maximized
1215 EXPECT_FALSE(browser2
->window()->IsMaximized());
1218 #if defined(OS_CHROMEOS)
1219 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1220 // compositor. crbug.com/331924
1221 #define MAYBE_DragDirectlyToSecondWindow DISABLED_DragDirectlyToSecondWindow
1223 #define MAYBE_DragDirectlyToSecondWindow DragDirectlyToSecondWindow
1225 // Creates two browsers, drags from first into the second in such a way that
1226 // no detaching should happen.
1227 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1228 MAYBE_DragDirectlyToSecondWindow
) {
1229 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1231 // Add another tab to browser().
1232 AddTabAndResetBrowser(browser());
1234 // Create another browser.
1235 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1236 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1238 // Move the tabstrip down enough so that we can detach.
1239 gfx::Rect
bounds(browser2
->window()->GetBounds());
1240 bounds
.Offset(0, 100);
1241 browser2
->window()->SetBounds(bounds
);
1243 // Move to the first tab and drag it enough so that it detaches, but not
1244 // enough that it attaches to browser2.
1245 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1246 ASSERT_TRUE(PressInput(tab_0_center
));
1248 gfx::Point
b2_location(5, 0);
1249 views::View::ConvertPointToScreen(tab_strip2
, &b2_location
);
1250 ASSERT_TRUE(DragInputTo(b2_location
));
1252 // Should now be attached to tab_strip2.
1253 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1254 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1255 ASSERT_TRUE(TabDragController::IsActive());
1257 // Release the mouse, stopping the drag session.
1258 ASSERT_TRUE(ReleaseInput());
1259 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1260 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1261 ASSERT_FALSE(TabDragController::IsActive());
1262 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1263 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1265 EXPECT_FALSE(GetIsDragged(browser()));
1266 EXPECT_FALSE(GetIsDragged(browser2
));
1268 // Both windows should not be maximized
1269 EXPECT_FALSE(browser()->window()->IsMaximized());
1270 EXPECT_FALSE(browser2
->window()->IsMaximized());
1273 #if defined(OS_CHROMEOS)
1274 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1275 // compositor. crbug.com/331924
1276 #define MAYBE_DragSingleTabToSeparateWindow \
1277 DISABLED_DragSingleTabToSeparateWindow
1279 #define MAYBE_DragSingleTabToSeparateWindow DragSingleTabToSeparateWindow
1281 // Creates two browsers, the first browser has a single tab and drags into the
1283 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1284 MAYBE_DragSingleTabToSeparateWindow
) {
1285 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1287 ResetIDs(browser()->tab_strip_model(), 0);
1289 // Create another browser.
1290 Browser
* browser2
= CreateAnotherWindowBrowserAndRelayout();
1291 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1292 const gfx::Rect
initial_bounds(browser2
->window()->GetBounds());
1294 // Move to the first tab and drag it enough so that it detaches, but not
1295 // enough that it attaches to browser2.
1296 gfx::Point
tab_0_center(
1297 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1298 ASSERT_TRUE(PressInput(tab_0_center
));
1299 ASSERT_TRUE(DragInputToNotifyWhenDone(
1300 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1301 base::Bind(&DragAllToSeparateWindowStep2
, this, tab_strip
, tab_strip2
,
1302 native_browser_list
)));
1303 QuitWhenNotDragging();
1305 // Should now be attached to tab_strip2.
1306 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1307 ASSERT_TRUE(TabDragController::IsActive());
1308 ASSERT_EQ(1u, native_browser_list
->size());
1310 // Release the mouse, stopping the drag session.
1311 ASSERT_TRUE(ReleaseInput());
1312 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1313 ASSERT_FALSE(TabDragController::IsActive());
1314 EXPECT_EQ("100 0", IDString(browser2
->tab_strip_model()));
1316 EXPECT_FALSE(GetIsDragged(browser2
));
1318 // Remaining browser window should not be maximized
1319 EXPECT_FALSE(browser2
->window()->IsMaximized());
1321 // Make sure that the window is still managed and not user moved.
1322 EXPECT_TRUE(IsWindowPositionManaged(browser2
->window()->GetNativeWindow()));
1323 EXPECT_FALSE(HasUserChangedWindowPositionOrSize(
1324 browser2
->window()->GetNativeWindow()));
1325 // Also make sure that the drag to window position has not changed.
1326 EXPECT_EQ(initial_bounds
.ToString(),
1327 browser2
->window()->GetBounds().ToString());
1332 // Invoked from the nested message loop.
1333 void CancelOnNewTabWhenDraggingStep2(
1334 DetachToBrowserTabDragControllerTest
* test
,
1335 const BrowserList
* browser_list
) {
1336 ASSERT_TRUE(TabDragController::IsActive());
1337 ASSERT_EQ(2u, browser_list
->size());
1339 // Add another tab. This should trigger exiting the nested loop.
1340 test
->AddBlankTabAndShow(browser_list
->GetLastActive());
1345 #if defined(OS_CHROMEOS)
1346 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1347 // compositor. crbug.com/331924
1348 #define MAYBE_CancelOnNewTabWhenDragging DISABLED_CancelOnNewTabWhenDragging
1350 #define MAYBE_CancelOnNewTabWhenDragging CancelOnNewTabWhenDragging
1352 // Adds another tab, detaches into separate window, adds another tab and
1353 // verifies the run loop ends.
1354 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1355 MAYBE_CancelOnNewTabWhenDragging
) {
1356 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1358 // Add another tab to browser().
1359 AddTabAndResetBrowser(browser());
1361 // Move to the first tab and drag it enough so that it detaches.
1362 gfx::Point
tab_0_center(
1363 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1364 ASSERT_TRUE(PressInput(tab_0_center
));
1365 ASSERT_TRUE(DragInputToNotifyWhenDone(
1366 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1367 base::Bind(&CancelOnNewTabWhenDraggingStep2
, this, native_browser_list
)));
1368 QuitWhenNotDragging();
1370 // Should be two windows and not dragging.
1371 ASSERT_FALSE(TabDragController::IsActive());
1372 ASSERT_EQ(2u, native_browser_list
->size());
1373 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1374 EXPECT_FALSE(GetIsDragged(*it
));
1375 // Should not be maximized
1376 EXPECT_FALSE(it
->window()->IsMaximized());
1380 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
1384 void DragInMaximizedWindowStep2(DetachToBrowserTabDragControllerTest
* test
,
1386 TabStrip
* tab_strip
,
1387 const BrowserList
* browser_list
) {
1388 // There should be another browser.
1389 ASSERT_EQ(2u, browser_list
->size());
1390 Browser
* new_browser
= browser_list
->get(1);
1391 EXPECT_NE(browser
, new_browser
);
1392 ASSERT_TRUE(new_browser
->window()->IsActive());
1393 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
1395 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1396 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1398 // Both windows should be visible.
1399 EXPECT_TRUE(tab_strip
->GetWidget()->IsVisible());
1400 EXPECT_TRUE(tab_strip2
->GetWidget()->IsVisible());
1403 ASSERT_TRUE(test
->ReleaseInput());
1408 #if defined(OS_CHROMEOS)
1409 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1410 // compositor. crbug.com/331924
1411 #define MAYBE_DragInMaximizedWindow DISABLED_DragInMaximizedWindow
1413 #define MAYBE_DragInMaximizedWindow DragInMaximizedWindow
1415 // Creates a browser with two tabs, maximizes it, drags the tab out.
1416 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest
,
1417 MAYBE_DragInMaximizedWindow
) {
1418 AddTabAndResetBrowser(browser());
1419 browser()->window()->Maximize();
1421 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1423 // Move to the first tab and drag it enough so that it detaches.
1424 gfx::Point
tab_0_center(
1425 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1426 ASSERT_TRUE(PressInput(tab_0_center
));
1427 ASSERT_TRUE(DragInputToNotifyWhenDone(
1428 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1429 base::Bind(&DragInMaximizedWindowStep2
, this, browser(), tab_strip
,
1430 native_browser_list
)));
1431 QuitWhenNotDragging();
1433 ASSERT_FALSE(TabDragController::IsActive());
1435 // Should be two browsers.
1436 ASSERT_EQ(2u, native_browser_list
->size());
1437 Browser
* new_browser
= native_browser_list
->get(1);
1438 ASSERT_TRUE(new_browser
->window()->IsActive());
1440 EXPECT_TRUE(browser()->window()->GetNativeWindow()->IsVisible());
1441 EXPECT_TRUE(new_browser
->window()->GetNativeWindow()->IsVisible());
1443 EXPECT_FALSE(GetIsDragged(browser()));
1444 EXPECT_FALSE(GetIsDragged(new_browser
));
1446 // The source window should be maximized.
1447 EXPECT_TRUE(browser()->window()->IsMaximized());
1448 // The new window should be maximized.
1449 EXPECT_TRUE(new_browser
->window()->IsMaximized());
1452 // Subclass of DetachToBrowserTabDragControllerTest that
1453 // creates multiple displays.
1454 class DetachToBrowserInSeparateDisplayTabDragControllerTest
1455 : public DetachToBrowserTabDragControllerTest
{
1457 DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1458 virtual ~DetachToBrowserInSeparateDisplayTabDragControllerTest() {}
1460 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1461 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line
);
1462 // Make screens sufficiently wide to host 2 browsers side by side.
1463 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1464 "0+0-600x600,601+0-600x600");
1468 DISALLOW_COPY_AND_ASSIGN(
1469 DetachToBrowserInSeparateDisplayTabDragControllerTest
);
1472 // Subclass of DetachToBrowserTabDragControllerTest that runs tests only with
1474 class DetachToBrowserTabDragControllerTestTouch
1475 : public DetachToBrowserTabDragControllerTest
{
1477 DetachToBrowserTabDragControllerTestTouch() {}
1478 virtual ~DetachToBrowserTabDragControllerTestTouch() {}
1481 DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTestTouch
);
1486 void DragSingleTabToSeparateWindowInSecondDisplayStep3(
1487 DetachToBrowserTabDragControllerTest
* test
) {
1488 ASSERT_TRUE(test
->ReleaseInput());
1491 void DragSingleTabToSeparateWindowInSecondDisplayStep2(
1492 DetachToBrowserTabDragControllerTest
* test
,
1493 const gfx::Point
& target_point
) {
1494 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
1495 target_point
.x(), target_point
.y(),
1496 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep3
, test
)));
1501 #if defined(OS_CHROMEOS)
1502 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1503 // compositor. crbug.com/331924
1504 #define MAYBE_DragSingleTabToSeparateWindowInSecondDisplay \
1505 DISABLED_DragSingleTabToSeparateWindowInSecondDisplay
1507 #define MAYBE_DragSingleTabToSeparateWindow \
1508 DragSingleTabToSeparateWindowInSecondDisplay
1510 // Drags from browser to a second display and releases input.
1511 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1512 MAYBE_DragSingleTabToSeparateWindowInSecondDisplay
) {
1514 AddTabAndResetBrowser(browser());
1515 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1517 // Move to the first tab and drag it enough so that it detaches.
1518 // Then drag it to the final destination on the second screen.
1519 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1520 ASSERT_TRUE(PressInput(tab_0_center
));
1521 ASSERT_TRUE(DragInputToNotifyWhenDone(
1522 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1523 base::Bind(&DragSingleTabToSeparateWindowInSecondDisplayStep2
,
1524 this, gfx::Point(600 + tab_0_center
.x(),
1526 + GetDetachY(tab_strip
)))));
1527 QuitWhenNotDragging();
1529 // Should no longer be dragging.
1530 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1531 ASSERT_FALSE(TabDragController::IsActive());
1533 // There should now be another browser.
1534 ASSERT_EQ(2u, native_browser_list
->size());
1535 Browser
* new_browser
= native_browser_list
->get(1);
1536 ASSERT_TRUE(new_browser
->window()->IsActive());
1537 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
1538 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1540 // This other browser should be on the second screen (with mouse drag)
1541 // With the touch input the browser cannot be dragged from one screen
1542 // to another and the window stays on the first screen.
1543 if (input_source() == INPUT_SOURCE_MOUSE
) {
1544 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1545 ASSERT_EQ(2u, roots
.size());
1546 aura::Window
* second_root
= roots
[1];
1547 EXPECT_EQ(second_root
,
1548 new_browser
->window()->GetNativeWindow()->GetRootWindow());
1551 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
1552 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1554 // Both windows should not be maximized
1555 EXPECT_FALSE(browser()->window()->IsMaximized());
1556 EXPECT_FALSE(new_browser
->window()->IsMaximized());
1561 // Invoked from the nested message loop.
1562 void DragTabToWindowInSeparateDisplayStep2(
1563 DetachToBrowserTabDragControllerTest
* test
,
1564 TabStrip
* not_attached_tab_strip
,
1565 TabStrip
* target_tab_strip
) {
1566 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
1567 ASSERT_FALSE(target_tab_strip
->IsDragSessionActive());
1568 ASSERT_TRUE(TabDragController::IsActive());
1570 // Drag to target_tab_strip. This should stop the nested loop from dragging
1572 gfx::Point
target_point(
1573 GetCenterInScreenCoordinates(target_tab_strip
->tab_at(0)));
1575 // Move it close to the beginning of the target tabstrip.
1577 target_point
.x() - target_tab_strip
->tab_at(0)->width() / 2 + 10);
1578 ASSERT_TRUE(test
->DragInputToAsync(target_point
));
1583 #if defined(OS_CHROMEOS)
1584 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1585 // compositor. crbug.com/331924
1586 #define MAYBE_DragTabToWindowInSeparateDisplay \
1587 DISABLED_DragTabToWindowInSeparateDisplay
1589 #define MAYBE_DragTabToWindowInSeparateDisplay DragTabToWindowInSeparateDisplay
1591 // Drags from browser to another browser on a second display and releases input.
1592 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1593 MAYBE_DragTabToWindowInSeparateDisplay
) {
1595 AddTabAndResetBrowser(browser());
1596 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1598 // Create another browser.
1599 Browser
* browser2
= CreateBrowser(browser()->profile());
1600 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1601 ResetIDs(browser2
->tab_strip_model(), 100);
1603 // Move the second browser to the second display.
1604 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1605 ASSERT_EQ(2u, roots
.size());
1606 aura::Window
* second_root
= roots
[1];
1607 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1608 second_root
).work_area();
1609 browser2
->window()->SetBounds(work_area
);
1610 EXPECT_EQ(second_root
,
1611 browser2
->window()->GetNativeWindow()->GetRootWindow());
1613 // Move to the first tab and drag it enough so that it detaches, but not
1614 // enough that it attaches to browser2.
1615 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1616 ASSERT_TRUE(PressInput(tab_0_center
));
1617 ASSERT_TRUE(DragInputToNotifyWhenDone(
1618 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1619 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1620 this, tab_strip
, tab_strip2
)));
1621 QuitWhenNotDragging();
1623 // Should now be attached to tab_strip2.
1624 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1625 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1626 ASSERT_TRUE(TabDragController::IsActive());
1628 // Release the mouse, stopping the drag session.
1629 ASSERT_TRUE(ReleaseInput());
1630 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1631 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1632 ASSERT_FALSE(TabDragController::IsActive());
1633 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1634 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1636 // Both windows should not be maximized
1637 EXPECT_FALSE(browser()->window()->IsMaximized());
1638 EXPECT_FALSE(browser2
->window()->IsMaximized());
1641 #if defined(OS_CHROMEOS)
1642 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1643 // compositor. crbug.com/331924
1644 #define MAYBE_DragTabToWindowOnSecondDisplay \
1645 DISABLED_DragTabToWindowOnSecondDisplay
1647 #define MAYBE_DragTabToWindowOnSecondDisplay DragTabToWindowOnSecondDisplay
1649 // Drags from browser to another browser on a second display and releases input.
1650 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1651 MAYBE_DragTabToWindowOnSecondDisplay
) {
1653 AddTabAndResetBrowser(browser());
1654 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1656 // Create another browser.
1657 Browser
* browser2
= CreateBrowser(browser()->profile());
1658 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1659 ResetIDs(browser2
->tab_strip_model(), 100);
1661 // Move both browsers to the second display.
1662 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1663 ASSERT_EQ(2u, roots
.size());
1664 aura::Window
* second_root
= roots
[1];
1665 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1666 second_root
).work_area();
1667 browser()->window()->SetBounds(work_area
);
1669 // position both browser windows side by side on the second screen.
1670 gfx::Rect
work_area2(work_area
);
1671 work_area
.set_width(work_area
.width()/2);
1672 browser()->window()->SetBounds(work_area
);
1673 work_area2
.set_x(work_area2
.x() + work_area2
.width()/2);
1674 work_area2
.set_width(work_area2
.width()/2);
1675 browser2
->window()->SetBounds(work_area2
);
1676 EXPECT_EQ(second_root
,
1677 browser()->window()->GetNativeWindow()->GetRootWindow());
1678 EXPECT_EQ(second_root
,
1679 browser2
->window()->GetNativeWindow()->GetRootWindow());
1681 // Move to the first tab and drag it enough so that it detaches, but not
1682 // enough that it attaches to browser2.
1683 // SetEventGeneratorRootWindow sets correct (second) RootWindow
1684 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1685 SetEventGeneratorRootWindow(tab_0_center
);
1686 ASSERT_TRUE(PressInput(tab_0_center
));
1687 ASSERT_TRUE(DragInputToNotifyWhenDone(
1688 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1689 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1690 this, tab_strip
, tab_strip2
)));
1691 QuitWhenNotDragging();
1693 // Should now be attached to tab_strip2.
1694 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1695 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1696 ASSERT_TRUE(TabDragController::IsActive());
1698 // Release the mouse, stopping the drag session.
1699 ASSERT_TRUE(ReleaseInput());
1700 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1701 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1702 ASSERT_FALSE(TabDragController::IsActive());
1703 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1704 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1706 // Both windows should not be maximized
1707 EXPECT_FALSE(browser()->window()->IsMaximized());
1708 EXPECT_FALSE(browser2
->window()->IsMaximized());
1711 #if defined(OS_CHROMEOS)
1712 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1713 // compositor. crbug.com/331924
1714 #define MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay \
1715 DISABLED_DragMaxTabToNonMaxWindowInSeparateDisplay
1717 #define MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay \
1718 DragMaxTabToNonMaxWindowInSeparateDisplay
1720 // Drags from a maximized browser to another non-maximized browser on a second
1721 // display and releases input.
1722 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1723 MAYBE_DragMaxTabToNonMaxWindowInSeparateDisplay
) {
1725 AddTabAndResetBrowser(browser());
1726 browser()->window()->Maximize();
1727 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1729 // Create another browser on the second display.
1730 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1731 ASSERT_EQ(2u, roots
.size());
1732 aura::Window
* first_root
= roots
[0];
1733 aura::Window
* second_root
= roots
[1];
1734 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1735 second_root
).work_area();
1736 work_area
.Inset(20,20,20,60);
1737 Browser::CreateParams
params(browser()->profile(),
1738 browser()->host_desktop_type());
1739 params
.initial_show_state
= ui::SHOW_STATE_NORMAL
;
1740 params
.initial_bounds
= work_area
;
1741 Browser
* browser2
= new Browser(params
);
1742 AddBlankTabAndShow(browser2
);
1744 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1745 ResetIDs(browser2
->tab_strip_model(), 100);
1747 EXPECT_EQ(second_root
,
1748 browser2
->window()->GetNativeWindow()->GetRootWindow());
1749 EXPECT_EQ(first_root
,
1750 browser()->window()->GetNativeWindow()->GetRootWindow());
1751 EXPECT_EQ(2, tab_strip
->tab_count());
1752 EXPECT_EQ(1, tab_strip2
->tab_count());
1754 // Move to the first tab and drag it enough so that it detaches, but not
1755 // enough that it attaches to browser2.
1756 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1757 ASSERT_TRUE(PressInput(tab_0_center
));
1758 ASSERT_TRUE(DragInputToNotifyWhenDone(
1759 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1760 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1761 this, tab_strip
, tab_strip2
)));
1762 QuitWhenNotDragging();
1764 // Should now be attached to tab_strip2.
1765 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1766 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1767 ASSERT_TRUE(TabDragController::IsActive());
1769 // Release the mouse, stopping the drag session.
1770 ASSERT_TRUE(ReleaseInput());
1772 // tab should have moved
1773 EXPECT_EQ(1, tab_strip
->tab_count());
1774 EXPECT_EQ(2, tab_strip2
->tab_count());
1776 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1777 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1778 ASSERT_FALSE(TabDragController::IsActive());
1779 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1780 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1782 // Source browser should still be maximized, target should not
1783 EXPECT_TRUE(browser()->window()->IsMaximized());
1784 EXPECT_FALSE(browser2
->window()->IsMaximized());
1787 // Immersive fullscreen is ChromeOS only.
1788 #if defined(OS_CHROMEOS)
1789 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1790 // compositor. crbug.com/331924
1791 #define MAYBE_DragTabToImmersiveBrowserOnSeparateDisplay \
1792 DISABLED_DragTabToImmersiveBrowserOnSeparateDisplay
1793 // Drags from a restored browser to an immersive fullscreen browser on a
1794 // second display and releases input.
1795 IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest
,
1796 MAYBE_DragTabToImmersiveBrowserOnSeparateDisplay
) {
1798 AddTabAndResetBrowser(browser());
1799 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1801 // Create another browser.
1802 Browser
* browser2
= CreateBrowser(browser()->profile());
1803 TabStrip
* tab_strip2
= GetTabStripForBrowser(browser2
);
1804 ResetIDs(browser2
->tab_strip_model(), 100);
1806 // Move the second browser to the second display.
1807 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1808 ASSERT_EQ(2u, roots
.size());
1809 aura::Window
* second_root
= roots
[1];
1810 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
1811 second_root
).work_area();
1812 browser2
->window()->SetBounds(work_area
);
1813 EXPECT_EQ(second_root
,
1814 browser2
->window()->GetNativeWindow()->GetRootWindow());
1816 // Put the second browser into immersive fullscreen.
1817 BrowserView
* browser_view2
= BrowserView::GetBrowserViewForBrowser(browser2
);
1818 ImmersiveModeController
* immersive_controller2
=
1819 browser_view2
->immersive_mode_controller();
1820 immersive_controller2
->SetupForTest();
1821 chrome::ToggleFullscreenMode(browser2
);
1822 ASSERT_TRUE(immersive_controller2
->IsEnabled());
1823 ASSERT_FALSE(immersive_controller2
->IsRevealed());
1824 ASSERT_TRUE(tab_strip2
->IsImmersiveStyle());
1826 // Move to the first tab and drag it enough so that it detaches, but not
1827 // enough that it attaches to browser2.
1828 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1829 ASSERT_TRUE(PressInput(tab_0_center
));
1830 ASSERT_TRUE(DragInputToNotifyWhenDone(
1831 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1832 base::Bind(&DragTabToWindowInSeparateDisplayStep2
,
1833 this, tab_strip
, tab_strip2
)));
1834 QuitWhenNotDragging();
1836 // Should now be attached to tab_strip2.
1837 ASSERT_TRUE(tab_strip2
->IsDragSessionActive());
1838 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1839 ASSERT_TRUE(TabDragController::IsActive());
1841 // browser2's top chrome should be revealed and the tab strip should be
1842 // at normal height while user is tragging tabs_strip2's tabs.
1843 ASSERT_TRUE(immersive_controller2
->IsRevealed());
1844 ASSERT_FALSE(tab_strip2
->IsImmersiveStyle());
1846 // Release the mouse, stopping the drag session.
1847 ASSERT_TRUE(ReleaseInput());
1848 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
1849 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
1850 ASSERT_FALSE(TabDragController::IsActive());
1851 EXPECT_EQ("0 100", IDString(browser2
->tab_strip_model()));
1852 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
1854 // Move the mouse off of browser2's top chrome.
1855 aura::Window
* primary_root
= roots
[0];
1856 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
1857 primary_root
->GetBoundsInScreen().CenterPoint()));
1859 // The first browser window should not be in immersive fullscreen.
1860 // browser2 should still be in immersive fullscreen, but the top chrome should
1861 // no longer be revealed.
1862 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser());
1863 EXPECT_FALSE(browser_view
->immersive_mode_controller()->IsEnabled());
1865 EXPECT_TRUE(immersive_controller2
->IsEnabled());
1866 EXPECT_FALSE(immersive_controller2
->IsRevealed());
1867 EXPECT_TRUE(tab_strip2
->IsImmersiveStyle());
1869 #endif // OS_CHROMEOS
1871 // Subclass of DetachToBrowserTabDragControllerTest that
1872 // creates multiple displays with different device scale factors.
1873 class DifferentDeviceScaleFactorDisplayTabDragControllerTest
1874 : public DetachToBrowserTabDragControllerTest
{
1876 DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1877 virtual ~DifferentDeviceScaleFactorDisplayTabDragControllerTest() {}
1879 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1880 DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line
);
1881 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1882 "400x400,0+400-800x800*2");
1885 float GetCursorDeviceScaleFactor() const {
1886 ash::test::CursorManagerTestApi
cursor_test_api(
1887 ash::Shell::GetInstance()->cursor_manager());
1888 return cursor_test_api
.GetDisplay().device_scale_factor();
1892 DISALLOW_COPY_AND_ASSIGN(
1893 DifferentDeviceScaleFactorDisplayTabDragControllerTest
);
1898 // The points where a tab is dragged in CursorDeviceScaleFactorStep.
1899 const struct DragPoint
{
1910 // The expected device scale factors before the cursor is moved to the
1911 // corresponding kDragPoints in CursorDeviceScaleFactorStep.
1912 const float kDeviceScaleFactorExpectations
[] = {
1921 arraysize(kDragPoints
) == arraysize(kDeviceScaleFactorExpectations
),
1922 kDragPoints_and_kDeviceScaleFactorExpectations_must_have_same_size
);
1924 // Drags tab to |kDragPoints[index]|, then calls the next step function.
1925 void CursorDeviceScaleFactorStep(
1926 DifferentDeviceScaleFactorDisplayTabDragControllerTest
* test
,
1927 TabStrip
* not_attached_tab_strip
,
1929 ASSERT_FALSE(not_attached_tab_strip
->IsDragSessionActive());
1930 ASSERT_TRUE(TabDragController::IsActive());
1932 if (index
< arraysize(kDragPoints
)) {
1933 EXPECT_EQ(kDeviceScaleFactorExpectations
[index
],
1934 test
->GetCursorDeviceScaleFactor());
1935 const DragPoint p
= kDragPoints
[index
];
1936 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
1937 p
.x
, p
.y
, base::Bind(&CursorDeviceScaleFactorStep
,
1938 test
, not_attached_tab_strip
, index
+ 1)));
1940 // Finishes a serise of CursorDeviceScaleFactorStep calls and ends drag.
1941 EXPECT_EQ(1.0f
, test
->GetCursorDeviceScaleFactor());
1942 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
1943 ui_controls::LEFT
, ui_controls::UP
));
1949 #if defined(OS_CHROMEOS)
1950 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
1951 // compositor. crbug.com/331924
1952 #define MAYBE_CursorDeviceScaleFactor DISABLED_CursorDeviceScaleFactor
1954 #define MAYBE_CursorDeviceScaleFactor CursorDeviceScaleFactor
1956 // Verifies cursor's device scale factor is updated when a tab is moved across
1957 // displays with different device scale factors (http://crbug.com/154183).
1958 IN_PROC_BROWSER_TEST_P(DifferentDeviceScaleFactorDisplayTabDragControllerTest
,
1959 MAYBE_CursorDeviceScaleFactor
) {
1961 AddTabAndResetBrowser(browser());
1962 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
1964 // Move the second browser to the second display.
1965 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
1966 ASSERT_EQ(2u, roots
.size());
1968 // Move to the first tab and drag it enough so that it detaches.
1969 gfx::Point
tab_0_center(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
1970 ASSERT_TRUE(PressInput(tab_0_center
));
1971 ASSERT_TRUE(DragInputToNotifyWhenDone(
1972 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
1973 base::Bind(&CursorDeviceScaleFactorStep
,
1974 this, tab_strip
, 0)));
1975 QuitWhenNotDragging();
1980 class DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
1981 : public TabDragControllerTest
{
1983 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest() {}
1985 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
1986 TabDragControllerTest::SetUpCommandLine(command_line
);
1987 command_line
->AppendSwitchASCII("ash-host-window-bounds",
1988 "0+0-250x250,251+0-250x250");
1991 bool Press(const gfx::Point
& position
) {
1992 return ui_test_utils::SendMouseMoveSync(position
) &&
1993 ui_test_utils::SendMouseEventsSync(ui_controls::LEFT
,
1997 bool DragTabAndExecuteTaskWhenDone(const gfx::Point
& position
,
1998 const base::Closure
& task
) {
1999 return ui_controls::SendMouseMoveNotifyWhenDone(
2000 position
.x(), position
.y(), task
);
2003 void QuitWhenNotDragging() {
2004 test::QuitWhenNotDraggingImpl();
2005 base::MessageLoop::current()->Run();
2009 DISALLOW_COPY_AND_ASSIGN(
2010 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
);
2013 // Invoked from the nested message loop.
2014 void CancelDragTabToWindowInSeparateDisplayStep3(
2015 TabStrip
* tab_strip
,
2016 const BrowserList
* browser_list
) {
2017 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2018 ASSERT_TRUE(TabDragController::IsActive());
2019 ASSERT_EQ(2u, browser_list
->size());
2021 // Switching display mode should cancel the drag operation.
2022 ash::internal::DisplayManager
* display_manager
=
2023 ash::Shell::GetInstance()->display_manager();
2024 display_manager
->AddRemoveDisplay();
2027 // Invoked from the nested message loop.
2028 void CancelDragTabToWindowInSeparateDisplayStep2(
2029 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
* test
,
2030 TabStrip
* tab_strip
,
2031 aura::Window
* current_root
,
2032 gfx::Point final_destination
,
2033 const BrowserList
* browser_list
) {
2034 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2035 ASSERT_TRUE(TabDragController::IsActive());
2036 ASSERT_EQ(2u, browser_list
->size());
2038 Browser
* new_browser
= browser_list
->get(1);
2039 EXPECT_EQ(current_root
,
2040 new_browser
->window()->GetNativeWindow()->GetRootWindow());
2042 ASSERT_TRUE(test
->DragTabAndExecuteTaskWhenDone(
2044 base::Bind(&CancelDragTabToWindowInSeparateDisplayStep3
,
2045 tab_strip
, browser_list
)));
2050 #if defined(OS_CHROMEOS)
2051 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2052 // compositor. crbug.com/331924
2053 #define MAYBE_CancelDragTabToWindowIn2ndDisplay \
2054 DISABLED_CancelDragTabToWindowIn2ndDisplay
2056 #define MAYBE_CancelDragTabToWindowIn2ndDisplay \
2057 CancelDragTabToWindowIn2ndDisplay
2059 // Drags from browser to a second display and releases input.
2060 IN_PROC_BROWSER_TEST_F(
2061 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
,
2062 MAYBE_CancelDragTabToWindowIn2ndDisplay
) {
2064 AddTabAndResetBrowser(browser());
2065 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2067 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2069 // Move the second browser to the second display.
2070 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
2071 ASSERT_EQ(2u, roots
.size());
2072 gfx::Point final_destination
=
2073 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2074 roots
[1]).work_area().CenterPoint();
2076 // Move to the first tab and drag it enough so that it detaches, but not
2077 // enough to move to another display.
2078 gfx::Point
tab_0_dst(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2079 ASSERT_TRUE(Press(tab_0_dst
));
2080 tab_0_dst
.Offset(0, GetDetachY(tab_strip
));
2081 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2082 tab_0_dst
, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2
,
2083 this, tab_strip
, roots
[0], final_destination
,
2084 native_browser_list
)));
2085 QuitWhenNotDragging();
2087 ASSERT_EQ(1u, native_browser_list
->size());
2088 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2089 ASSERT_FALSE(TabDragController::IsActive());
2090 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2092 // Release the mouse
2093 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2094 ui_controls::LEFT
, ui_controls::UP
));
2097 #if defined(OS_CHROMEOS)
2098 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2099 // compositor. crbug.com/331924
2100 #define MAYBE_CancelDragTabToWindowIn1stDisplay \
2101 DISABLED_CancelDragTabToWindowIn1stDisplay
2103 #define MAYBE_CancelDragTabToWindowIn1stDisplay \
2104 CancelDragTabToWindowIn1stDisplay
2106 // Drags from browser from a second display to primary and releases input.
2107 IN_PROC_BROWSER_TEST_F(
2108 DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest
,
2109 MAYBE_CancelDragTabToWindowIn1stDisplay
) {
2110 aura::Window::Windows roots
= ash::Shell::GetAllRootWindows();
2111 ASSERT_EQ(2u, roots
.size());
2114 AddTabAndResetBrowser(browser());
2115 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2117 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2118 EXPECT_EQ(roots
[0], browser()->window()->GetNativeWindow()->GetRootWindow());
2120 gfx::Rect work_area
= gfx::Screen::GetNativeScreen()->
2121 GetDisplayNearestWindow(roots
[1]).work_area();
2122 browser()->window()->SetBounds(work_area
);
2123 EXPECT_EQ(roots
[1], browser()->window()->GetNativeWindow()->GetRootWindow());
2125 // Move the second browser to the display.
2126 gfx::Point final_destination
=
2127 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
2128 roots
[0]).work_area().CenterPoint();
2130 // Move to the first tab and drag it enough so that it detaches, but not
2131 // enough to move to another display.
2132 gfx::Point
tab_0_dst(GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2133 ASSERT_TRUE(Press(tab_0_dst
));
2134 tab_0_dst
.Offset(0, GetDetachY(tab_strip
));
2135 ASSERT_TRUE(DragTabAndExecuteTaskWhenDone(
2136 tab_0_dst
, base::Bind(&CancelDragTabToWindowInSeparateDisplayStep2
,
2137 this, tab_strip
, roots
[1], final_destination
,
2138 native_browser_list
)));
2139 QuitWhenNotDragging();
2141 ASSERT_EQ(1u, native_browser_list
->size());
2142 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2143 ASSERT_FALSE(TabDragController::IsActive());
2144 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2146 // Release the mouse
2147 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
2148 ui_controls::LEFT
, ui_controls::UP
));
2153 void PressSecondFingerWhileDetachedStep2(
2154 DetachToBrowserTabDragControllerTest
* test
) {
2155 ASSERT_TRUE(TabDragController::IsActive());
2156 ASSERT_EQ(2u, test
->native_browser_list
->size());
2157 Browser
* new_browser
= test
->native_browser_list
->get(1);
2158 ASSERT_TRUE(new_browser
->window()->IsActive());
2160 ASSERT_TRUE(test
->PressInput2());
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_PressSecondFingerWhileDetached DISABLED_PressSecondFingerWhileDetached
2170 #define MAYBE_PressSecondFingerWhileDetached PressSecondFingerWhileDetached
2172 // Detaches a tab and while detached presses a second finger.
2173 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestTouch
,
2174 MAYBE_PressSecondFingerWhileDetached
) {
2175 gfx::Rect
bounds(browser()->window()->GetBounds());
2177 AddTabAndResetBrowser(browser());
2178 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2179 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
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 ASSERT_TRUE(DragInputToDelayedNotifyWhenDone(
2186 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
2187 base::Bind(&PressSecondFingerWhileDetachedStep2
, this),
2188 base::TimeDelta::FromMilliseconds(60)));
2189 QuitWhenNotDragging();
2191 // The drag should have been reverted.
2192 ASSERT_EQ(1u, native_browser_list
->size());
2193 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2194 ASSERT_FALSE(TabDragController::IsActive());
2195 EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
2197 ASSERT_TRUE(ReleaseInput());
2198 ASSERT_TRUE(ReleaseInput2());
2201 // Subclass of DetachToBrowserTabDragControllerTest that runs tests with
2202 // docked windows enabled and disabled.
2203 class DetachToDockedTabDragControllerTest
2204 : public DetachToBrowserTabDragControllerTest
{
2206 DetachToDockedTabDragControllerTest() {}
2207 virtual ~DetachToDockedTabDragControllerTest() {}
2210 DISALLOW_COPY_AND_ASSIGN(DetachToDockedTabDragControllerTest
);
2215 void DetachToDockedWindowNextStep(
2216 DetachToDockedTabDragControllerTest
* test
,
2217 const gfx::Point
& target_point
,
2219 ASSERT_EQ(2u, test
->native_browser_list
->size());
2220 Browser
* new_browser
= test
->native_browser_list
->get(1);
2221 ASSERT_TRUE(new_browser
->window()->IsActive());
2224 ASSERT_TRUE(test
->ReleaseInput());
2227 ASSERT_TRUE(test
->DragInputToNotifyWhenDone(
2228 target_point
.x(), target_point
.y(),
2229 base::Bind(&DetachToDockedWindowNextStep
,
2231 gfx::Point(target_point
.x(), 1 + target_point
.y()),
2237 #if defined(OS_CHROMEOS)
2238 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2239 // compositor. crbug.com/331924
2240 #define MAYBE_DetachToDockedWindowFromMaximizedWindow \
2241 DISABLED_DetachToDockedWindowFromMaximizedWindow
2243 #define MAYBE_DetachToDockedWindowFromMaximizedWindow \
2244 DetachToDockedWindowFromMaximizedWindow
2246 // Drags from browser to separate window, docks that window and releases mouse.
2247 IN_PROC_BROWSER_TEST_P(DetachToDockedTabDragControllerTest
,
2248 MAYBE_DetachToDockedWindowFromMaximizedWindow
) {
2249 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
2250 // compositor. crbug.com/331924
2251 if (docked_windows_enabled()) {
2252 VLOG(1) << "Test is DISABLED for docked windows.";
2256 // Maximize the initial browser window.
2257 browser()->window()->Maximize();
2258 ASSERT_TRUE(browser()->window()->IsMaximized());
2261 AddTabAndResetBrowser(browser());
2262 TabStrip
* tab_strip
= GetTabStripForBrowser(browser());
2264 // Move to the first tab and drag it enough so that it detaches.
2265 gfx::Point
tab_0_center(
2266 GetCenterInScreenCoordinates(tab_strip
->tab_at(0)));
2267 ASSERT_TRUE(PressInput(tab_0_center
));
2269 // The following matches kMovesBeforeAdjust in snap_sizer.cc
2270 const int kNumIterations
= 25 * 5 + 10;
2271 ASSERT_TRUE(DragInputToNotifyWhenDone(
2272 tab_0_center
.x(), tab_0_center
.y() + GetDetachY(tab_strip
),
2273 base::Bind(&DetachToDockedWindowNextStep
, this,
2274 gfx::Point(0, tab_0_center
.y() + GetDetachY(tab_strip
)),
2276 // Continue dragging enough times to go through snapping sequence and dock
2278 QuitWhenNotDragging();
2279 // Should no longer be dragging.
2280 ASSERT_FALSE(tab_strip
->IsDragSessionActive());
2281 ASSERT_FALSE(TabDragController::IsActive());
2283 // There should now be another browser.
2284 ASSERT_EQ(2u, native_browser_list
->size());
2285 Browser
* new_browser
= native_browser_list
->get(1);
2286 ASSERT_TRUE(new_browser
->window()->IsActive());
2287 TabStrip
* tab_strip2
= GetTabStripForBrowser(new_browser
);
2288 ASSERT_FALSE(tab_strip2
->IsDragSessionActive());
2290 EXPECT_EQ("0", IDString(new_browser
->tab_strip_model()));
2291 EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
2293 // The bounds of the initial window should not have changed.
2294 EXPECT_TRUE(browser()->window()->IsMaximized());
2296 EXPECT_FALSE(GetIsDragged(browser()));
2297 EXPECT_FALSE(GetIsDragged(new_browser
));
2298 // After this both windows should still be manageable.
2299 EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
2300 EXPECT_TRUE(IsWindowPositionManaged(
2301 new_browser
->window()->GetNativeWindow()));
2303 ash::wm::WindowState
* window_state
=
2304 ash::wm::GetWindowState(new_browser
->window()->GetNativeWindow());
2305 // The new window should not be maximized because it gets docked or snapped.
2306 EXPECT_FALSE(new_browser
->window()->IsMaximized());
2307 if (docked_windows_enabled()) {
2308 // The new window should be docked and not snapped if docking is allowed.
2309 EXPECT_TRUE(window_state
->IsDocked());
2310 EXPECT_FALSE(window_state
->IsSnapped());
2312 // The new window should be snapped and not docked if docking is disabled.
2313 EXPECT_FALSE(window_state
->IsDocked());
2314 EXPECT_TRUE(window_state
->IsSnapped());
2321 #if defined(USE_ASH) && !defined(OS_WIN) // TODO(win_ash)
2322 INSTANTIATE_TEST_CASE_P(TabDragging
,
2323 DetachToBrowserInSeparateDisplayTabDragControllerTest
,
2324 ::testing::Values("mouse", "touch"));
2325 INSTANTIATE_TEST_CASE_P(TabDragging
,
2326 DifferentDeviceScaleFactorDisplayTabDragControllerTest
,
2327 ::testing::Values("mouse"));
2328 INSTANTIATE_TEST_CASE_P(TabDragging
,
2329 DetachToBrowserTabDragControllerTest
,
2330 ::testing::Values("mouse", "touch"));
2331 INSTANTIATE_TEST_CASE_P(TabDragging
,
2332 DetachToDockedTabDragControllerTest
,
2333 ::testing::Values("mouse", "mouse docked"));
2334 INSTANTIATE_TEST_CASE_P(TabDragging
,
2335 DetachToBrowserTabDragControllerTestTouch
,
2336 ::testing::Values("touch", "touch docked"));
2338 INSTANTIATE_TEST_CASE_P(TabDragging
,
2339 DetachToBrowserTabDragControllerTest
,
2340 ::testing::Values("mouse"));