1// Copyright (c) 2013 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.
4
5#include "ash/wm/panels/panel_window_resizer.h"
6
7#include "ash/root_window_controller.h"
8#include "ash/shelf/shelf.h"
9#include "ash/shelf/shelf_layout_manager.h"
10#include "ash/shelf/shelf_model.h"
11#include "ash/shelf/shelf_types.h"
12#include "ash/shelf/shelf_util.h"
13#include "ash/shelf/shelf_widget.h"
14#include "ash/shell.h"
15#include "ash/shell_window_ids.h"
16#include "ash/test/ash_test_base.h"
17#include "ash/test/cursor_manager_test_api.h"
18#include "ash/test/shell_test_api.h"
19#include "ash/test/test_shelf_delegate.h"
20#include "ash/wm/drag_window_resizer.h"
21#include "ash/wm/panels/panel_layout_manager.h"
22#include "ash/wm/window_state.h"
23#include "ash/wm/wm_event.h"
24#include "base/win/windows_version.h"
25#include "ui/aura/client/aura_constants.h"
26#include "ui/aura/window_event_dispatcher.h"
27#include "ui/base/hit_test.h"
28#include "ui/base/l10n/l10n_util.h"
29#include "ui/base/ui_base_types.h"
30#include "ui/views/widget/widget.h"
31#include "ui/wm/core/window_util.h"
32
33namespace ash {
34
35class PanelWindowResizerTest : public test::AshTestBase {
36 public:
37  PanelWindowResizerTest() {}
38  virtual ~PanelWindowResizerTest() {}
39
40  virtual void SetUp() OVERRIDE {
41    AshTestBase::SetUp();
42    UpdateDisplay("600x400");
43    test::ShellTestApi test_api(Shell::GetInstance());
44    model_ = test_api.shelf_model();
45    shelf_delegate_ = test::TestShelfDelegate::instance();
46  }
47
48  virtual void TearDown() OVERRIDE {
49    AshTestBase::TearDown();
50  }
51
52 protected:
53  gfx::Point CalculateDragPoint(const WindowResizer& resizer,
54                                int delta_x,
55                                int delta_y) const {
56    gfx::Point location = resizer.GetInitialLocation();
57    location.set_x(location.x() + delta_x);
58    location.set_y(location.y() + delta_y);
59    return location;
60  }
61
62  aura::Window* CreatePanelWindow(const gfx::Point& origin) {
63    gfx::Rect bounds(origin, gfx::Size(101, 101));
64    aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
65        NULL, ui::wm::WINDOW_TYPE_PANEL, 0, bounds);
66    shelf_delegate_->AddShelfItem(window);
67    return window;
68  }
69
70  void DragStart(aura::Window* window) {
71    resizer_.reset(CreateWindowResizer(
72        window,
73        window->bounds().origin(),
74        HTCAPTION,
75        aura::client::WINDOW_MOVE_SOURCE_MOUSE).release());
76    ASSERT_TRUE(resizer_.get());
77  }
78
79  void DragMove(int dx, int dy) {
80    resizer_->Drag(CalculateDragPoint(*resizer_, dx, dy), 0);
81  }
82
83  void DragEnd() {
84    resizer_->CompleteDrag();
85    resizer_.reset();
86  }
87
88  void DragRevert() {
89    resizer_->RevertDrag();
90    resizer_.reset();
91  }
92
93  // Test dragging the panel slightly, then detaching, and then reattaching
94  // dragging out by the vector (dx, dy).
95  void DetachReattachTest(aura::Window* window, int dx, int dy) {
96    wm::WindowState* window_state = wm::GetWindowState(window);
97    EXPECT_TRUE(window_state->panel_attached());
98    aura::Window* root_window = window->GetRootWindow();
99    EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
100    DragStart(window);
101    gfx::Rect initial_bounds = window->GetBoundsInScreen();
102
103    // Drag the panel slightly. The window should still be snapped to the
104    // launcher.
105    DragMove(dx * 5, dy * 5);
106    EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
107    EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
108
109    // Drag further out and the window should now move to the cursor.
110    DragMove(dx * 100, dy * 100);
111    EXPECT_EQ(initial_bounds.x() + dx * 100, window->GetBoundsInScreen().x());
112    EXPECT_EQ(initial_bounds.y() + dy * 100, window->GetBoundsInScreen().y());
113
114    // The panel should be detached when the drag completes.
115    DragEnd();
116
117    EXPECT_FALSE(window_state->panel_attached());
118    EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
119    EXPECT_EQ(root_window, window->GetRootWindow());
120
121    DragStart(window);
122    // Drag the panel down.
123    DragMove(dx * -95, dy * -95);
124    // Release the mouse and the panel should be reattached.
125    DragEnd();
126
127    // The panel should be reattached and have snapped to the launcher.
128    EXPECT_TRUE(window_state->panel_attached());
129    EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
130    EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
131    EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
132  }
133
134  void TestWindowOrder(const std::vector<aura::Window*>& window_order) {
135    int panel_index = model_->FirstPanelIndex();
136    EXPECT_EQ((int)(panel_index + window_order.size()), model_->item_count());
137    for (std::vector<aura::Window*>::const_iterator iter =
138         window_order.begin(); iter != window_order.end();
139         ++iter, ++panel_index) {
140      ShelfID id = GetShelfIDForWindow(*iter);
141      EXPECT_EQ(id, model_->items()[panel_index].id);
142    }
143  }
144
145  // Test dragging panel window along the shelf and verify that panel icons
146  // are reordered appropriately.
147  void DragAlongShelfReorder(int dx, int dy) {
148    gfx::Point origin(0, 0);
149    scoped_ptr<aura::Window> w1(CreatePanelWindow(origin));
150    scoped_ptr<aura::Window> w2(CreatePanelWindow(origin));
151    std::vector<aura::Window*> window_order_original;
152    std::vector<aura::Window*> window_order_swapped;
153    window_order_original.push_back(w1.get());
154    window_order_original.push_back(w2.get());
155    window_order_swapped.push_back(w2.get());
156    window_order_swapped.push_back(w1.get());
157    TestWindowOrder(window_order_original);
158
159    // Drag window #2 to the beginning of the shelf.
160    DragStart(w2.get());
161    DragMove(400 * dx, 400 * dy);
162    TestWindowOrder(window_order_swapped);
163    DragEnd();
164
165    // Expect swapped window order.
166    TestWindowOrder(window_order_swapped);
167
168    // Drag window #2 back to the end.
169    DragStart(w2.get());
170    DragMove(-400 * dx, -400 * dy);
171    TestWindowOrder(window_order_original);
172    DragEnd();
173
174    // Expect original order.
175    TestWindowOrder(window_order_original);
176  }
177
178 private:
179  scoped_ptr<WindowResizer> resizer_;
180  PanelLayoutManager* panel_layout_manager_;
181  ShelfModel* model_;
182  test::TestShelfDelegate* shelf_delegate_;
183
184  DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTest);
185};
186
187class PanelWindowResizerTextDirectionTest
188    : public PanelWindowResizerTest,
189      public testing::WithParamInterface<bool> {
190 public:
191  PanelWindowResizerTextDirectionTest() : is_rtl_(GetParam()) {}
192  virtual ~PanelWindowResizerTextDirectionTest() {}
193
194  virtual void SetUp() OVERRIDE {
195    original_locale = l10n_util::GetApplicationLocale(std::string());
196    if (is_rtl_)
197      base::i18n::SetICUDefaultLocale("he");
198    PanelWindowResizerTest::SetUp();
199    ASSERT_EQ(is_rtl_, base::i18n::IsRTL());
200  }
201
202  virtual void TearDown() OVERRIDE {
203    if (is_rtl_)
204      base::i18n::SetICUDefaultLocale(original_locale);
205    PanelWindowResizerTest::TearDown();
206  }
207
208 private:
209  bool is_rtl_;
210  std::string original_locale;
211
212  DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTextDirectionTest);
213};
214
215// PanelLayoutManager and PanelWindowResizer should work if panels have
216// transient children of supported types.
217class PanelWindowResizerTransientTest
218    : public PanelWindowResizerTest,
219      public testing::WithParamInterface<ui::wm::WindowType> {
220 public:
221  PanelWindowResizerTransientTest() : transient_window_type_(GetParam()) {}
222  virtual ~PanelWindowResizerTransientTest() {}
223
224 protected:
225  ui::wm::WindowType transient_window_type_;
226
227 private:
228  DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTransientTest);
229};
230
231// Verifies a window can be dragged from the panel and detached and then
232// reattached.
233TEST_F(PanelWindowResizerTest, PanelDetachReattachBottom) {
234 if (!SupportsHostWindowResize())
235    return;
236
237  scoped_ptr<aura::Window> window(
238      CreatePanelWindow(gfx::Point(0, 0)));
239  DetachReattachTest(window.get(), 0, -1);
240}
241
242TEST_F(PanelWindowResizerTest, PanelDetachReattachLeft) {
243 if (!SupportsHostWindowResize())
244    return;
245
246  ash::Shell* shell = ash::Shell::GetInstance();
247  shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow());
248  scoped_ptr<aura::Window> window(
249      CreatePanelWindow(gfx::Point(0, 0)));
250  DetachReattachTest(window.get(), 1, 0);
251}
252
253TEST_F(PanelWindowResizerTest, PanelDetachReattachRight) {
254  if (!SupportsHostWindowResize())
255    return;
256
257  ash::Shell* shell = ash::Shell::GetInstance();
258  shell->SetShelfAlignment(SHELF_ALIGNMENT_RIGHT,
259                           shell->GetPrimaryRootWindow());
260  scoped_ptr<aura::Window> window(
261      CreatePanelWindow(gfx::Point(0, 0)));
262  DetachReattachTest(window.get(), -1, 0);
263}
264
265TEST_F(PanelWindowResizerTest, PanelDetachReattachTop) {
266 if (!SupportsHostWindowResize())
267    return;
268
269  ash::Shell* shell = ash::Shell::GetInstance();
270  shell->SetShelfAlignment(SHELF_ALIGNMENT_TOP, shell->GetPrimaryRootWindow());
271  scoped_ptr<aura::Window> window(
272      CreatePanelWindow(gfx::Point(0, 0)));
273  DetachReattachTest(window.get(), 0, 1);
274}
275
276// Tests that a drag continues when the shelf is hidden. This occurs as part of
277// the animation when switching profiles. http://crbug.com/393047.
278TEST_F(PanelWindowResizerTest, DetachThenHideShelf) {
279  if (!SupportsHostWindowResize())
280    return;
281  scoped_ptr<aura::Window> window(
282      CreatePanelWindow(gfx::Point(0, 0)));
283  wm::WindowState* state = wm::GetWindowState(window.get());
284  gfx::Rect expected_bounds = window->GetBoundsInScreen();
285  expected_bounds.set_y(expected_bounds.y() - 100);
286  DragStart(window.get());
287  DragMove(0, -100);
288  EXPECT_FALSE(state->IsMinimized());
289
290  // Hide the shelf. This minimizes all attached windows but should ignore
291  // the dragged window.
292  ShelfLayoutManager* shelf = RootWindowController::ForWindow(window.get())->
293      shelf()->shelf_layout_manager();
294  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
295  shelf->UpdateVisibilityState();
296  RunAllPendingInMessageLoop();
297  EXPECT_FALSE(state->IsMinimized());
298  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
299  DragEnd();
300
301  // When the drag ends the window should be detached and placed where it was
302  // dragged to.
303  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
304  EXPECT_FALSE(state->IsMinimized());
305  EXPECT_EQ(expected_bounds.ToString(), window->GetBoundsInScreen().ToString());
306}
307
308TEST_F(PanelWindowResizerTest, PanelDetachReattachMultipleDisplays) {
309  if (!SupportsMultipleDisplays())
310    return;
311
312  UpdateDisplay("600x400,600x400");
313  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
314  scoped_ptr<aura::Window> window(
315      CreatePanelWindow(gfx::Point(600, 0)));
316  EXPECT_EQ(root_windows[1], window->GetRootWindow());
317  DetachReattachTest(window.get(), 0, -1);
318}
319
320TEST_F(PanelWindowResizerTest, DetachThenDragAcrossDisplays) {
321  if (!SupportsMultipleDisplays())
322    return;
323
324  UpdateDisplay("600x400,600x400");
325  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
326  scoped_ptr<aura::Window> window(
327      CreatePanelWindow(gfx::Point(0, 0)));
328  gfx::Rect initial_bounds = window->GetBoundsInScreen();
329  EXPECT_EQ(root_windows[0], window->GetRootWindow());
330  DragStart(window.get());
331  DragMove(0, -100);
332  DragEnd();
333  EXPECT_EQ(root_windows[0], window->GetRootWindow());
334  EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
335  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
336  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
337  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
338
339  DragStart(window.get());
340  DragMove(500, 0);
341  DragEnd();
342  EXPECT_EQ(root_windows[1], window->GetRootWindow());
343  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
344  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
345  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
346  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
347}
348
349TEST_F(PanelWindowResizerTest, DetachAcrossDisplays) {
350  if (!SupportsMultipleDisplays())
351    return;
352
353  UpdateDisplay("600x400,600x400");
354  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
355  scoped_ptr<aura::Window> window(
356      CreatePanelWindow(gfx::Point(0, 0)));
357  gfx::Rect initial_bounds = window->GetBoundsInScreen();
358  EXPECT_EQ(root_windows[0], window->GetRootWindow());
359  DragStart(window.get());
360  DragMove(500, -100);
361  DragEnd();
362  EXPECT_EQ(root_windows[1], window->GetRootWindow());
363  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
364  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
365  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
366  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
367}
368
369TEST_F(PanelWindowResizerTest, DetachThenAttachToSecondDisplay) {
370  if (!SupportsMultipleDisplays())
371    return;
372
373  UpdateDisplay("600x400,600x600");
374  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
375  scoped_ptr<aura::Window> window(
376      CreatePanelWindow(gfx::Point(0, 0)));
377  gfx::Rect initial_bounds = window->GetBoundsInScreen();
378  EXPECT_EQ(root_windows[0], window->GetRootWindow());
379
380  // Detach the window.
381  DragStart(window.get());
382  DragMove(0, -100);
383  DragEnd();
384  EXPECT_EQ(root_windows[0], window->GetRootWindow());
385  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
386
387  // Drag the window just above the other display's launcher.
388  DragStart(window.get());
389  DragMove(500, 295);
390  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
391
392  // Should stick to other launcher.
393  EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
394  DragEnd();
395
396  // When dropped should move to second display's panel container.
397  EXPECT_EQ(root_windows[1], window->GetRootWindow());
398  EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
399  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
400}
401
402TEST_F(PanelWindowResizerTest, AttachToSecondDisplay) {
403  if (!SupportsMultipleDisplays())
404    return;
405
406  UpdateDisplay("600x400,600x600");
407  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
408  scoped_ptr<aura::Window> window(
409      CreatePanelWindow(gfx::Point(0, 0)));
410  gfx::Rect initial_bounds = window->GetBoundsInScreen();
411  EXPECT_EQ(root_windows[0], window->GetRootWindow());
412
413  // Drag the window just above the other display's launcher.
414  DragStart(window.get());
415  DragMove(500, 195);
416  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
417
418  // Should stick to other launcher.
419  EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
420  DragEnd();
421
422  // When dropped should move to second display's panel container.
423  EXPECT_EQ(root_windows[1], window->GetRootWindow());
424  EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
425  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
426}
427
428TEST_F(PanelWindowResizerTest, AttachToSecondFullscreenDisplay) {
429  if (!SupportsMultipleDisplays())
430    return;
431
432  UpdateDisplay("600x400,600x600");
433  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
434  scoped_ptr<aura::Window> window(
435      CreatePanelWindow(gfx::Point(0, 0)));
436  scoped_ptr<aura::Window> fullscreen(
437      CreateTestWindowInShellWithBounds(gfx::Rect(600, 0, 101, 101)));
438  wm::GetWindowState(fullscreen.get())->Activate();
439  const wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
440  wm::GetWindowState(fullscreen.get())->OnWMEvent(&event);
441  EXPECT_TRUE(wm::GetWindowState(fullscreen.get())->IsFullscreen());
442
443  gfx::Rect initial_bounds = window->GetBoundsInScreen();
444  EXPECT_EQ(root_windows[0], window->GetRootWindow());
445
446  // Activate and drag the window to the other display's launcher.
447  wm::GetWindowState(window.get())->Activate();
448  DragStart(window.get());
449  DragMove(500, 250);
450  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
451  EXPECT_GT(window->GetBoundsInScreen().y(),
452            initial_bounds.y() + 200);
453  DragEnd();
454
455  // When dropped should move to second display's panel container.
456  EXPECT_EQ(root_windows[1], window->GetRootWindow());
457  EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
458  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
459  EXPECT_TRUE(window->IsVisible());
460  EXPECT_TRUE(wm::GetWindowState(window.get())->IsActive());
461  EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
462}
463
464TEST_F(PanelWindowResizerTest, RevertDragRestoresAttachment) {
465  scoped_ptr<aura::Window> window(
466      CreatePanelWindow(gfx::Point(0, 0)));
467  EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
468  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
469  DragStart(window.get());
470  DragMove(0, -100);
471  DragRevert();
472  EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
473  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
474
475  // Detach panel.
476  DragStart(window.get());
477  DragMove(0, -100);
478  DragEnd();
479  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
480  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
481
482  // Drag back to launcher.
483  DragStart(window.get());
484  DragMove(0, 100);
485
486  // When the drag is reverted it should remain detached.
487  DragRevert();
488  EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
489  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
490}
491
492TEST_F(PanelWindowResizerTest, DragMovesToPanelLayer) {
493  scoped_ptr<aura::Window> window(CreatePanelWindow(gfx::Point(0, 0)));
494  DragStart(window.get());
495  DragMove(0, -100);
496  DragEnd();
497  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
498
499  // While moving the panel window should be moved to the panel container.
500  DragStart(window.get());
501  DragMove(20, 0);
502  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
503  DragEnd();
504
505  // When dropped it should return to the default container.
506  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
507}
508
509TEST_P(PanelWindowResizerTextDirectionTest, DragReordersPanelsHorizontal) {
510  if (!SupportsHostWindowResize())
511    return;
512
513  DragAlongShelfReorder(base::i18n::IsRTL() ? 1 : -1, 0);
514}
515
516TEST_F(PanelWindowResizerTest, DragReordersPanelsVertical) {
517  if (!SupportsHostWindowResize())
518    return;
519
520  ash::Shell* shell = ash::Shell::GetInstance();
521  shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow());
522  DragAlongShelfReorder(0, -1);
523}
524
525// Tests that panels can have transient children of different types.
526// The transient children should be reparented in sync with the panel.
527TEST_P(PanelWindowResizerTransientTest, PanelWithTransientChild) {
528  if (!SupportsHostWindowResize())
529    return;
530
531  scoped_ptr<aura::Window> window(CreatePanelWindow(gfx::Point(0, 0)));
532  scoped_ptr<aura::Window> child(CreateTestWindowInShellWithDelegateAndType(
533      NULL, transient_window_type_, 0, gfx::Rect(20, 20, 150, 40)));
534  ::wm::AddTransientChild(window.get(), child.get());
535  if (window->parent() != child->parent())
536    window->parent()->AddChild(child.get());
537  EXPECT_EQ(window.get(), ::wm::GetTransientParent(child.get()));
538
539  // Drag the child to the shelf. Its new position should not be overridden.
540  const gfx::Rect attached_bounds(window->GetBoundsInScreen());
541  const int dy = window->GetBoundsInScreen().bottom() -
542      child->GetBoundsInScreen().bottom();
543  DragStart(child.get());
544  DragMove(50, dy);
545  // While moving the transient child window should be in the panel container.
546  EXPECT_EQ(kShellWindowId_PanelContainer, child->parent()->id());
547  DragEnd();
548  // Child should move, |window| should not.
549  EXPECT_EQ(gfx::Point(20 + 50, 20 + dy).ToString(),
550            child->GetBoundsInScreen().origin().ToString());
551  EXPECT_EQ(attached_bounds.ToString(), window->GetBoundsInScreen().ToString());
552
553  // Drag the child along the the shelf past the |window|.
554  // Its new position should not be overridden.
555  DragStart(child.get());
556  DragMove(350, 0);
557  // While moving the transient child window should be in the panel container.
558  EXPECT_EQ(kShellWindowId_PanelContainer, child->parent()->id());
559  DragEnd();
560  // |child| should move, |window| should not.
561  EXPECT_EQ(gfx::Point(20 + 50 + 350, 20 + dy).ToString(),
562            child->GetBoundsInScreen().origin().ToString());
563  EXPECT_EQ(attached_bounds.ToString(), window->GetBoundsInScreen().ToString());
564
565  DragStart(window.get());
566  DragMove(0, -100);
567  // While moving the windows should be in the panel container.
568  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
569  EXPECT_EQ(kShellWindowId_PanelContainer, child->parent()->id());
570  DragEnd();
571  // When dropped they should return to the default container.
572  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
573  EXPECT_EQ(kShellWindowId_DefaultContainer, child->parent()->id());
574
575  // While moving the window and child should be moved to the panel container.
576  DragStart(window.get());
577  DragMove(20, 0);
578  EXPECT_EQ(kShellWindowId_PanelContainer, window->parent()->id());
579  EXPECT_EQ(kShellWindowId_PanelContainer, child->parent()->id());
580  DragEnd();
581
582  // When dropped they should return to the default container.
583  EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id());
584  EXPECT_EQ(kShellWindowId_DefaultContainer, child->parent()->id());
585}
586
587INSTANTIATE_TEST_CASE_P(LtrRtl, PanelWindowResizerTextDirectionTest,
588                        testing::Bool());
589INSTANTIATE_TEST_CASE_P(NormalPanelPopup,
590                        PanelWindowResizerTransientTest,
591                        testing::Values(ui::wm::WINDOW_TYPE_NORMAL,
592                                        ui::wm::WINDOW_TYPE_PANEL,
593                                        ui::wm::WINDOW_TYPE_POPUP));
594
595}  // namespace ash
596