Home | History | Annotate | Download | only in panels
      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.
      4 
      5 #include "base/message_loop/message_loop.h"
      6 #include "chrome/browser/chrome_notification_types.h"
      7 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
      8 #include "chrome/browser/ui/panels/detached_panel_collection.h"
      9 #include "chrome/browser/ui/panels/docked_panel_collection.h"
     10 #include "chrome/browser/ui/panels/native_panel.h"
     11 #include "chrome/browser/ui/panels/panel.h"
     12 #include "chrome/browser/ui/panels/panel_drag_controller.h"
     13 #include "chrome/browser/ui/panels/panel_manager.h"
     14 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
     15 #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h"
     16 #include "content/public/browser/notification_service.h"
     17 #include "content/public/test/test_utils.h"
     18 
     19 class PanelDragBrowserTest : public BasePanelBrowserTest {
     20  public:
     21   PanelDragBrowserTest() : BasePanelBrowserTest() {
     22   }
     23 
     24   virtual ~PanelDragBrowserTest() {
     25   }
     26 
     27   virtual void SetUpOnMainThread() OVERRIDE {
     28     BasePanelBrowserTest::SetUpOnMainThread();
     29 
     30     // All the tests here assume using mocked 800x600 display area for the
     31     // primary monitor. Do the check now.
     32     gfx::Rect primary_display_area = PanelManager::GetInstance()->
     33         display_settings_provider()->GetPrimaryDisplayArea();
     34     DCHECK(primary_display_area.width() == 800);
     35     DCHECK(primary_display_area.height() == 600);
     36   }
     37 
     38   // Drag |panel| from its origin by the offset |delta|.
     39   void DragPanelByDelta(Panel* panel, const gfx::Vector2d& delta) {
     40     scoped_ptr<NativePanelTesting> panel_testing(
     41         CreateNativePanelTesting(panel));
     42     gfx::Point mouse_location(panel->GetBounds().origin());
     43     panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
     44     panel_testing->DragTitlebar(mouse_location + delta);
     45     panel_testing->FinishDragTitlebar();
     46   }
     47 
     48   // Drag |panel| from its origin to |new_mouse_location|.
     49   void DragPanelToMouseLocation(Panel* panel,
     50                                 const gfx::Point& new_mouse_location) {
     51     scoped_ptr<NativePanelTesting> panel_testing(
     52         CreateNativePanelTesting(panel));
     53     gfx::Point mouse_location(panel->GetBounds().origin());
     54     panel_testing->PressLeftMouseButtonTitlebar(panel->GetBounds().origin());
     55     panel_testing->DragTitlebar(new_mouse_location);
     56     panel_testing->FinishDragTitlebar();
     57   }
     58 
     59   // Return the bounds of a panel given its initial bounds and the bounds of the
     60   // panel above it.
     61   static gfx::Rect GetStackedAtBottomPanelBounds(
     62       const gfx::Rect& initial_bounds,
     63       const gfx::Rect& above_bounds) {
     64     return gfx::Rect(above_bounds.x(),
     65                      above_bounds.bottom(),
     66                      above_bounds.width(),
     67                      initial_bounds.height());
     68   }
     69 
     70   // Return the bounds of a panel given its initial bounds and the bounds of the
     71   // panel below it.
     72   static gfx::Rect GetStackedAtTopPanelBounds(
     73       const gfx::Rect& initial_bounds,
     74       const gfx::Rect& below_bounds) {
     75     return gfx::Rect(below_bounds.x(),
     76                      below_bounds.y() - initial_bounds.height(),
     77                      initial_bounds.width(),
     78                      initial_bounds.height());
     79   }
     80 
     81   static gfx::Vector2d GetDragDeltaToRemainDocked() {
     82     return gfx::Vector2d(
     83         -5,
     84         -(PanelDragController::GetDetachDockedPanelThresholdForTesting() / 2));
     85   }
     86 
     87   static gfx::Vector2d GetDragDeltaToDetach() {
     88     return gfx::Vector2d(
     89         -20,
     90         -(PanelDragController::GetDetachDockedPanelThresholdForTesting() + 20));
     91   }
     92 
     93   static gfx::Vector2d GetDragDeltaToRemainDetached(Panel* panel) {
     94     int distance =
     95       panel->manager()->docked_collection()->work_area().bottom() -
     96       panel->GetBounds().bottom();
     97     return gfx::Vector2d(
     98         -5,
     99         distance -
    100             PanelDragController::GetDockDetachedPanelThresholdForTesting() * 2);
    101   }
    102 
    103   static gfx::Vector2d GetDragDeltaToAttach(Panel* panel) {
    104     int distance =
    105         panel->manager()->docked_collection()->work_area().bottom() -
    106         panel->GetBounds().bottom();
    107     return gfx::Vector2d(
    108         -20,
    109         distance -
    110             PanelDragController::GetDockDetachedPanelThresholdForTesting() / 2);
    111   }
    112 
    113   // Return the delta needed to drag |panel1| to stack to the bottom of
    114   // |panel2|.
    115   static gfx::Vector2d GetDragDeltaToStackToBottom(Panel* panel1,
    116                                                    Panel* panel2) {
    117     gfx::Rect bounds1 = panel1->GetBounds();
    118     gfx::Rect bounds2 = panel2->GetBounds();
    119     return gfx::Vector2d(
    120         bounds2.x() - bounds1.x(),
    121         bounds2.bottom() - bounds1.y() +
    122             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2);
    123   }
    124 
    125   // Return the delta needed to drag |panel1| to unstack from the bottom of
    126   // |panel2|.
    127   static gfx::Vector2d GetDragDeltaToUnstackFromBottom(Panel* panel1,
    128                                                        Panel* panel2) {
    129     gfx::Rect bounds1 = panel1->GetBounds();
    130     gfx::Rect bounds2 = panel2->GetBounds();
    131     return gfx::Vector2d(
    132         0, PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
    133   }
    134 
    135   // Return the delta needed to drag |panel1| to stack to the top of |panel2|.
    136   static gfx::Vector2d GetDragDeltaToStackToTop(Panel* panel1, Panel* panel2) {
    137     gfx::Rect bounds1 = panel1->GetBounds();
    138     gfx::Rect bounds2 = panel2->GetBounds();
    139     StackedPanelCollection* stack1 = panel1->stack();
    140     int bottom = stack1 ? stack1->bottom_panel()->GetBounds().bottom()
    141                         : bounds1.bottom();
    142     return gfx::Vector2d(
    143         bounds2.x() - bounds1.x(),
    144         bounds2.y() - bottom -
    145             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2);
    146   }
    147 
    148   // Return the delta needed to drag |panel1| to unstack from the top of
    149   // |panel2|.
    150   static gfx::Vector2d GetDragDeltaToUnstackFromTop(Panel* panel1,
    151                                                     Panel* panel2) {
    152     gfx::Rect bounds1 = panel1->GetBounds();
    153     gfx::Rect bounds2 = panel2->GetBounds();
    154     return gfx::Vector2d(
    155         0, -PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
    156   }
    157 
    158   // Return the delta needed to drag |panel1| to snap to the left of |panel2|.
    159   static gfx::Vector2d GetDragDeltaToSnapToLeft(Panel* panel1,
    160                                                 Panel* panel2) {
    161     gfx::Rect bounds1 = panel1->GetBounds();
    162     gfx::Rect bounds2 = panel2->GetBounds();
    163     return gfx::Vector2d(
    164         bounds2.x() - bounds1.width() - bounds1.x() -
    165             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2,
    166         bounds2.y() - bounds1.y() +
    167             PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
    168   }
    169 
    170   // Return the delta needed to drag |panel1| to snap to the right of |panel2|.
    171   static gfx::Vector2d GetDragDeltaToSnapToRight(Panel* panel1,
    172                                                  Panel* panel2) {
    173     gfx::Rect bounds1 = panel1->GetBounds();
    174     gfx::Rect bounds2 = panel2->GetBounds();
    175     return gfx::Vector2d(
    176         bounds2.right() - bounds1.x() +
    177             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2,
    178         bounds2.y() - bounds1.y() +
    179             PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
    180   }
    181 
    182   // Return the delta needed to drag |panel| to unsnap from its current
    183   // position.
    184   static gfx::Vector2d GetDragDeltaToUnsnap(Panel* panel) {
    185     return gfx::Vector2d(
    186         PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2, 0);
    187   }
    188 };
    189 
    190 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragOneDockedPanel) {
    191   static const int big_delta_x = 70;
    192   static const int big_delta_y = 30;  // Do not exceed the threshold to detach.
    193 
    194   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
    195   scoped_ptr<NativePanelTesting> panel_testing(
    196       CreateNativePanelTesting(panel));
    197   gfx::Rect panel_old_bounds = panel->GetBounds();
    198 
    199   // Drag left.
    200   gfx::Point mouse_location = panel_old_bounds.origin();
    201   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    202   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    203 
    204   mouse_location.Offset(-big_delta_x, 0);
    205   panel_testing->DragTitlebar(mouse_location);
    206   gfx::Rect panel_new_bounds = panel_old_bounds;
    207   panel_new_bounds.Offset(-big_delta_x, 0);
    208   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    209 
    210   panel_testing->FinishDragTitlebar();
    211   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    212 
    213   // Drag left and cancel.
    214   mouse_location = panel_old_bounds.origin();
    215   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    216   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    217 
    218   mouse_location.Offset(-big_delta_x, 0);
    219   panel_testing->DragTitlebar(mouse_location);
    220   panel_new_bounds = panel_old_bounds;
    221   panel_new_bounds.Offset(-big_delta_x, 0);
    222   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    223 
    224   panel_testing->CancelDragTitlebar();
    225   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    226 
    227   // Drag right.
    228   mouse_location = panel_old_bounds.origin();
    229   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    230   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    231 
    232   mouse_location.Offset(big_delta_x, 0);
    233   panel_testing->DragTitlebar(mouse_location);
    234   panel_new_bounds = panel_old_bounds;
    235   panel_new_bounds.Offset(big_delta_x, 0);
    236   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    237 
    238   panel_testing->FinishDragTitlebar();
    239   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    240 
    241   // Drag right and up.  Expect no vertical movement.
    242   mouse_location = panel_old_bounds.origin();
    243   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    244   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    245 
    246   mouse_location.Offset(big_delta_x, big_delta_y);
    247   panel_testing->DragTitlebar(mouse_location);
    248   panel_new_bounds = panel_old_bounds;
    249   panel_new_bounds.Offset(big_delta_x, 0);
    250   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    251 
    252   panel_testing->FinishDragTitlebar();
    253   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    254 
    255   // Drag up.  Expect no movement on drag.
    256   mouse_location = panel_old_bounds.origin();
    257   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    258   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    259 
    260   mouse_location.Offset(0, -big_delta_y);
    261   panel_testing->DragTitlebar(mouse_location);
    262   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    263 
    264   panel_testing->FinishDragTitlebar();
    265   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    266 
    267   // Drag down.  Expect no movement on drag.
    268   mouse_location = panel_old_bounds.origin();
    269   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    270   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    271 
    272   mouse_location.Offset(0, big_delta_y);
    273   panel_testing->DragTitlebar(mouse_location);
    274   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    275 
    276   panel_testing->FinishDragTitlebar();
    277   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    278 
    279   PanelManager::GetInstance()->CloseAll();
    280 }
    281 
    282 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTwoDockedPanels) {
    283   static const gfx::Vector2d small_delta(10, 0);
    284 
    285   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
    286   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100));
    287   scoped_ptr<NativePanelTesting> panel1_testing(
    288       CreateNativePanelTesting(panel1));
    289   scoped_ptr<NativePanelTesting> panel2_testing(
    290       CreateNativePanelTesting(panel2));
    291   gfx::Point position1 = panel1->GetBounds().origin();
    292   gfx::Point position2 = panel2->GetBounds().origin();
    293 
    294   // Drag right panel towards left with small delta.
    295   // Expect no shuffle: P1 P2
    296   gfx::Point mouse_location = position1;
    297   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    298   EXPECT_EQ(position1, panel1->GetBounds().origin());
    299   EXPECT_EQ(position2, panel2->GetBounds().origin());
    300 
    301   mouse_location = mouse_location - small_delta;
    302   panel1_testing->DragTitlebar(mouse_location);
    303   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
    304   EXPECT_EQ(position2, panel2->GetBounds().origin());
    305 
    306   panel1_testing->FinishDragTitlebar();
    307   EXPECT_EQ(position1, panel1->GetBounds().origin());
    308   EXPECT_EQ(position2, panel2->GetBounds().origin());
    309 
    310   // Drag right panel towards left with big delta.
    311   // Expect shuffle: P2 P1
    312   mouse_location = position1;
    313   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    314   EXPECT_EQ(position1, panel1->GetBounds().origin());
    315   EXPECT_EQ(position2, panel2->GetBounds().origin());
    316 
    317   mouse_location = position2 + gfx::Vector2d(1, 0);
    318   panel1_testing->DragTitlebar(mouse_location);
    319   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
    320   EXPECT_EQ(position1, panel2->GetBounds().origin());
    321 
    322   panel1_testing->FinishDragTitlebar();
    323   EXPECT_EQ(position2, panel1->GetBounds().origin());
    324   EXPECT_EQ(position1, panel2->GetBounds().origin());
    325 
    326   // Drag left panel towards right with small delta.
    327   // Expect no shuffle: P2 P1
    328   mouse_location = position2;
    329   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    330   EXPECT_EQ(position2, panel1->GetBounds().origin());
    331   EXPECT_EQ(position1, panel2->GetBounds().origin());
    332 
    333   mouse_location = mouse_location + small_delta;
    334   panel1_testing->DragTitlebar(mouse_location);
    335   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
    336   EXPECT_EQ(position1, panel2->GetBounds().origin());
    337 
    338   panel1_testing->FinishDragTitlebar();
    339   EXPECT_EQ(position2, panel1->GetBounds().origin());
    340   EXPECT_EQ(position1, panel2->GetBounds().origin());
    341 
    342   // Drag left panel towards right with big delta.
    343   // Expect shuffle: P1 P2
    344   mouse_location = position2;
    345   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    346   EXPECT_EQ(position2, panel1->GetBounds().origin());
    347   EXPECT_EQ(position1, panel2->GetBounds().origin());
    348 
    349   mouse_location = position1 + gfx::Vector2d(1, 0);
    350   panel1_testing->DragTitlebar(mouse_location);
    351   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
    352   EXPECT_EQ(position2, panel2->GetBounds().origin());
    353 
    354   panel1_testing->FinishDragTitlebar();
    355   EXPECT_EQ(position1, panel1->GetBounds().origin());
    356   EXPECT_EQ(position2, panel2->GetBounds().origin());
    357 
    358   // Drag right panel towards left with big delta and then cancel the drag.
    359   // Expect shuffle after drag:   P2 P1
    360   // Expect shuffle after cancel: P1 P2
    361   mouse_location = position1;
    362   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    363   EXPECT_EQ(position1, panel1->GetBounds().origin());
    364   EXPECT_EQ(position2, panel2->GetBounds().origin());
    365 
    366   mouse_location = position2 + gfx::Vector2d(1, 0);
    367   panel1_testing->DragTitlebar(mouse_location);
    368   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
    369   EXPECT_EQ(position1, panel2->GetBounds().origin());
    370 
    371   panel1_testing->CancelDragTitlebar();
    372   EXPECT_EQ(position1, panel1->GetBounds().origin());
    373   EXPECT_EQ(position2, panel2->GetBounds().origin());
    374 
    375   PanelManager::GetInstance()->CloseAll();
    376 }
    377 
    378 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragThreeDockedPanels) {
    379   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
    380   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100));
    381   Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 100, 100));
    382   scoped_ptr<NativePanelTesting> panel2_testing(
    383       CreateNativePanelTesting(panel2));
    384   scoped_ptr<NativePanelTesting> panel3_testing(
    385       CreateNativePanelTesting(panel3));
    386   gfx::Point position1 = panel1->GetBounds().origin();
    387   gfx::Point position2 = panel2->GetBounds().origin();
    388   gfx::Point position3 = panel3->GetBounds().origin();
    389 
    390   // Drag leftmost panel to become the rightmost in 2 drags. Each drag will
    391   // shuffle one panel.
    392   // Expect shuffle after 1st drag: P1 P3 P2
    393   // Expect shuffle after 2nd drag: P3 P1 P2
    394   gfx::Point mouse_location = position3;
    395   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
    396   EXPECT_EQ(position1, panel1->GetBounds().origin());
    397   EXPECT_EQ(position2, panel2->GetBounds().origin());
    398   EXPECT_EQ(position3, panel3->GetBounds().origin());
    399 
    400   mouse_location = position2 + gfx::Vector2d(1, 0);
    401   panel3_testing->DragTitlebar(mouse_location);
    402   EXPECT_EQ(position1, panel1->GetBounds().origin());
    403   EXPECT_EQ(position3, panel2->GetBounds().origin());
    404   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
    405 
    406   mouse_location = position1 + gfx::Vector2d(1, 0);
    407   panel3_testing->DragTitlebar(mouse_location);
    408   EXPECT_EQ(position2, panel1->GetBounds().origin());
    409   EXPECT_EQ(position3, panel2->GetBounds().origin());
    410   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
    411 
    412   panel3_testing->FinishDragTitlebar();
    413   EXPECT_EQ(position2, panel1->GetBounds().origin());
    414   EXPECT_EQ(position3, panel2->GetBounds().origin());
    415   EXPECT_EQ(position1, panel3->GetBounds().origin());
    416 
    417   // Drag rightmost panel to become the leftmost in 2 drags and then cancel the
    418   // drag. Each drag will shuffle one panel and the cancellation will restore
    419   // all panels.
    420   // Expect shuffle after 1st drag: P1 P3 P2
    421   // Expect shuffle after 2nd drag: P1 P2 P3
    422   // Expect shuffle after cancel:   P3 P1 P2
    423   mouse_location = position1;
    424   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
    425   EXPECT_EQ(position2, panel1->GetBounds().origin());
    426   EXPECT_EQ(position3, panel2->GetBounds().origin());
    427   EXPECT_EQ(position1, panel3->GetBounds().origin());
    428 
    429   mouse_location = position2 + gfx::Vector2d(1, 0);
    430   panel3_testing->DragTitlebar(mouse_location);
    431   EXPECT_EQ(position1, panel1->GetBounds().origin());
    432   EXPECT_EQ(position3, panel2->GetBounds().origin());
    433   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
    434 
    435   mouse_location = position3 + gfx::Vector2d(1, 0);
    436   panel3_testing->DragTitlebar(mouse_location);
    437   EXPECT_EQ(position1, panel1->GetBounds().origin());
    438   EXPECT_EQ(position2, panel2->GetBounds().origin());
    439   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
    440 
    441   panel3_testing->CancelDragTitlebar();
    442   EXPECT_EQ(position2, panel1->GetBounds().origin());
    443   EXPECT_EQ(position3, panel2->GetBounds().origin());
    444   EXPECT_EQ(position1, panel3->GetBounds().origin());
    445 
    446   // Drag leftmost panel to become the rightmost in a single drag. The drag will
    447   // shuffle 2 panels at a time.
    448   // Expect shuffle: P2 P3 P1
    449   mouse_location = position3;
    450   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
    451   EXPECT_EQ(position2, panel1->GetBounds().origin());
    452   EXPECT_EQ(position3, panel2->GetBounds().origin());
    453   EXPECT_EQ(position1, panel3->GetBounds().origin());
    454 
    455   mouse_location = position1 + gfx::Vector2d(1, 0);
    456   panel2_testing->DragTitlebar(mouse_location);
    457   EXPECT_EQ(position3, panel1->GetBounds().origin());
    458   EXPECT_EQ(mouse_location, panel2->GetBounds().origin());
    459   EXPECT_EQ(position2, panel3->GetBounds().origin());
    460 
    461   panel2_testing->FinishDragTitlebar();
    462   EXPECT_EQ(position3, panel1->GetBounds().origin());
    463   EXPECT_EQ(position1, panel2->GetBounds().origin());
    464   EXPECT_EQ(position2, panel3->GetBounds().origin());
    465 
    466   // Drag rightmost panel to become the leftmost in a single drag. The drag will
    467   // shuffle 2 panels at a time.
    468   // Expect shuffle: P3 P1 P2
    469   mouse_location = position1;
    470   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
    471   EXPECT_EQ(position3, panel1->GetBounds().origin());
    472   EXPECT_EQ(position1, panel2->GetBounds().origin());
    473   EXPECT_EQ(position2, panel3->GetBounds().origin());
    474 
    475   mouse_location = position3 + gfx::Vector2d(1, 0);
    476   panel2_testing->DragTitlebar(mouse_location);
    477   EXPECT_EQ(position2, panel1->GetBounds().origin());
    478   EXPECT_EQ(mouse_location, panel2->GetBounds().origin());
    479   EXPECT_EQ(position1, panel3->GetBounds().origin());
    480 
    481   panel2_testing->FinishDragTitlebar();
    482   EXPECT_EQ(position2, panel1->GetBounds().origin());
    483   EXPECT_EQ(position3, panel2->GetBounds().origin());
    484   EXPECT_EQ(position1, panel3->GetBounds().origin());
    485 
    486   // Drag rightmost panel to become the leftmost in a single drag and then
    487   // cancel the drag. The drag will shuffle 2 panels and the cancellation will
    488   // restore all panels.
    489   // Expect shuffle after drag:   P1 P2 P3
    490   // Expect shuffle after cancel: P3 P1 P2
    491   mouse_location = position1;
    492   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
    493   EXPECT_EQ(position2, panel1->GetBounds().origin());
    494   EXPECT_EQ(position3, panel2->GetBounds().origin());
    495   EXPECT_EQ(position1, panel3->GetBounds().origin());
    496 
    497   mouse_location = position3 + gfx::Vector2d(1, 0);
    498   panel3_testing->DragTitlebar(mouse_location);
    499   EXPECT_EQ(position1, panel1->GetBounds().origin());
    500   EXPECT_EQ(position2, panel2->GetBounds().origin());
    501   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
    502 
    503   panel3_testing->CancelDragTitlebar();
    504   EXPECT_EQ(position2, panel1->GetBounds().origin());
    505   EXPECT_EQ(position3, panel2->GetBounds().origin());
    506   EXPECT_EQ(position1, panel3->GetBounds().origin());
    507 
    508   PanelManager::GetInstance()->CloseAll();
    509 }
    510 
    511 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragMinimizedPanel) {
    512   Panel* panel = CreatePanel("panel1");
    513   scoped_ptr<NativePanelTesting> panel_testing(
    514       CreateNativePanelTesting(panel));
    515 
    516   panel->Minimize();
    517   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    518 
    519   // Hover over minimized panel to bring up titlebar.
    520   gfx::Point hover_point(panel->GetBounds().origin());
    521   MoveMouseAndWaitForExpansionStateChange(panel, hover_point);
    522   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    523 
    524   // Verify we can drag a minimized panel.
    525   gfx::Rect panel_old_bounds = panel->GetBounds();
    526   gfx::Point mouse_location = panel_old_bounds.origin();
    527   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    528   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    529   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    530 
    531   mouse_location.Offset(-70, 0);
    532   panel_testing->DragTitlebar(mouse_location);
    533   gfx::Rect panel_new_bounds = panel_old_bounds;
    534   panel_new_bounds.Offset(-70, 0);
    535   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    536   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    537 
    538   // Verify panel returns to fully minimized state after dragging ends once
    539   // mouse moves away from panel.
    540   panel_testing->FinishDragTitlebar();
    541   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    542 
    543   MoveMouseAndWaitForExpansionStateChange(panel, mouse_location);
    544   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    545 
    546   panel->Close();
    547 }
    548 
    549 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
    550                        DragMinimizedPanelWhileDrawingAttention) {
    551   Panel* panel = CreatePanel("panel1");
    552   scoped_ptr<NativePanelTesting> panel_testing(
    553       CreateNativePanelTesting(panel));
    554   CreatePanel("panel2");
    555 
    556   panel->Minimize();
    557   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    558 
    559   panel->FlashFrame(true);
    560   EXPECT_TRUE(panel->IsDrawingAttention());
    561   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    562 
    563   // Drag the panel. Verify panel stays in title-only state after attention is
    564   // cleared because it is being dragged.
    565   gfx::Rect panel_old_bounds = panel->GetBounds();
    566   gfx::Point mouse_location = panel_old_bounds.origin();
    567   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    568   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
    569   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    570 
    571   mouse_location.Offset(-70, 0);
    572   panel_testing->DragTitlebar(mouse_location);
    573   gfx::Rect panel_new_bounds = panel_old_bounds;
    574   panel_new_bounds.Offset(-70, 0);
    575   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    576 
    577   panel->FlashFrame(false);
    578   EXPECT_FALSE(panel->IsDrawingAttention());
    579   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    580 
    581   // Typical user scenario will detect the mouse in the panel
    582   // after attention is cleared, causing titles to pop up, so
    583   // we simulate that here.
    584   MoveMouse(mouse_location);
    585 
    586   // Verify panel returns to fully minimized state after dragging ends once
    587   // mouse moves away from the panel.
    588   panel_testing->FinishDragTitlebar();
    589   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
    590 
    591   mouse_location.Offset(0, -50);
    592   MoveMouseAndWaitForExpansionStateChange(panel, mouse_location);
    593   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
    594 
    595   PanelManager::GetInstance()->CloseAll();
    596 }
    597 
    598 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDockedPanelOnDrag) {
    599   PanelManager* panel_manager = PanelManager::GetInstance();
    600   PanelDragController* drag_controller = panel_manager->drag_controller();
    601   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
    602 
    603   // Create 4 docked panels.
    604   // We have:  P4  P3  P2  P1
    605   Panel* panel1 = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 100, 100));
    606   Panel* panel2 = CreatePanelWithBounds("Panel2", gfx::Rect(0, 0, 100, 100));
    607   Panel* panel3 = CreatePanelWithBounds("Panel3", gfx::Rect(0, 0, 100, 100));
    608   Panel* panel4 = CreatePanelWithBounds("Panel4", gfx::Rect(0, 0, 100, 100));
    609   ASSERT_EQ(4, docked_collection->num_panels());
    610 
    611   scoped_ptr<NativePanelTesting> panel1_testing(
    612       CreateNativePanelTesting(panel1));
    613   gfx::Point position1 = panel1->GetBounds().origin();
    614   gfx::Point position2 = panel2->GetBounds().origin();
    615   gfx::Point position3 = panel3->GetBounds().origin();
    616   gfx::Point position4 = panel4->GetBounds().origin();
    617 
    618   // Test the scenario: drag a panel, close another panel, cancel the drag.
    619   {
    620     std::vector<Panel*> panels;
    621     gfx::Point panel1_new_position = position1;
    622     panel1_new_position.Offset(-500, 0);
    623 
    624     // Start dragging a panel.
    625     // We have:  P1*  P4  P3  P2
    626     gfx::Point mouse_location = panel1->GetBounds().origin();
    627     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    628     mouse_location.Offset(-500, -5);
    629     panel1_testing->DragTitlebar(mouse_location);
    630     EXPECT_TRUE(drag_controller->is_dragging());
    631     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    632 
    633     ASSERT_EQ(4, docked_collection->num_panels());
    634     panels = PanelManager::GetInstance()->panels();
    635     EXPECT_EQ(panel2, panels[0]);
    636     EXPECT_EQ(panel3, panels[1]);
    637     EXPECT_EQ(panel4, panels[2]);
    638     EXPECT_EQ(panel1, panels[3]);
    639     EXPECT_EQ(position1, panel2->GetBounds().origin());
    640     EXPECT_EQ(position2, panel3->GetBounds().origin());
    641     EXPECT_EQ(position3, panel4->GetBounds().origin());
    642     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    643 
    644     // Closing another panel while dragging in progress will keep the dragging
    645     // panel intact.
    646     // We have:  P1*  P4  P3
    647     CloseWindowAndWait(panel2);
    648     EXPECT_TRUE(drag_controller->is_dragging());
    649     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    650 
    651     ASSERT_EQ(3, docked_collection->num_panels());
    652     panels = PanelManager::GetInstance()->panels();
    653     EXPECT_EQ(panel3, panels[0]);
    654     EXPECT_EQ(panel4, panels[1]);
    655     EXPECT_EQ(panel1, panels[2]);
    656     EXPECT_EQ(position1, panel3->GetBounds().origin());
    657     EXPECT_EQ(position2, panel4->GetBounds().origin());
    658     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    659 
    660     // Cancel the drag.
    661     // We have:  P4  P3  P1
    662     panel1_testing->CancelDragTitlebar();
    663     EXPECT_FALSE(drag_controller->is_dragging());
    664 
    665     ASSERT_EQ(3, docked_collection->num_panels());
    666     panels = PanelManager::GetInstance()->panels();
    667     EXPECT_EQ(panel1, panels[0]);
    668     EXPECT_EQ(panel3, panels[1]);
    669     EXPECT_EQ(panel4, panels[2]);
    670     EXPECT_EQ(position1, panel1->GetBounds().origin());
    671     EXPECT_EQ(position2, panel3->GetBounds().origin());
    672     EXPECT_EQ(position3, panel4->GetBounds().origin());
    673   }
    674 
    675   // Test the scenario: drag a panel, close another panel, end the drag.
    676   {
    677     std::vector<Panel*> panels;
    678     gfx::Point panel1_new_position = position1;
    679     panel1_new_position.Offset(-500, 0);
    680 
    681     // Start dragging a panel.
    682     // We have:  P1*  P4  P3
    683     gfx::Point mouse_location = panel1->GetBounds().origin();
    684     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    685     mouse_location.Offset(-500, -5);
    686     panel1_testing->DragTitlebar(mouse_location);
    687     EXPECT_TRUE(drag_controller->is_dragging());
    688     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    689 
    690     ASSERT_EQ(3, docked_collection->num_panels());
    691     panels = PanelManager::GetInstance()->panels();
    692     EXPECT_EQ(panel3, panels[0]);
    693     EXPECT_EQ(panel4, panels[1]);
    694     EXPECT_EQ(panel1, panels[2]);
    695     EXPECT_EQ(position1, panel3->GetBounds().origin());
    696     EXPECT_EQ(position2, panel4->GetBounds().origin());
    697     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    698 
    699     // Closing another panel while dragging in progress will keep the dragging
    700     // panel intact.
    701     // We have:  P1*  P4
    702     CloseWindowAndWait(panel3);
    703     EXPECT_TRUE(drag_controller->is_dragging());
    704     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    705 
    706     ASSERT_EQ(2, docked_collection->num_panels());
    707     panels = PanelManager::GetInstance()->panels();
    708     EXPECT_EQ(panel4, panels[0]);
    709     EXPECT_EQ(panel1, panels[1]);
    710     EXPECT_EQ(position1, panel4->GetBounds().origin());
    711     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    712 
    713     // Finish the drag.
    714     // We have:  P1  P4
    715     panel1_testing->FinishDragTitlebar();
    716     EXPECT_FALSE(drag_controller->is_dragging());
    717 
    718     ASSERT_EQ(2, docked_collection->num_panels());
    719     panels = PanelManager::GetInstance()->panels();
    720     EXPECT_EQ(panel4, panels[0]);
    721     EXPECT_EQ(panel1, panels[1]);
    722     EXPECT_EQ(position1, panel4->GetBounds().origin());
    723     EXPECT_EQ(position2, panel1->GetBounds().origin());
    724   }
    725 
    726   // Test the scenario: drag a panel and close the dragging panel.
    727   {
    728     std::vector<Panel*> panels;
    729     gfx::Point panel1_new_position = position2;
    730     panel1_new_position.Offset(-500, 0);
    731 
    732     // Start dragging a panel again.
    733     // We have:  P1*  P4
    734     gfx::Point mouse_location = panel1->GetBounds().origin();
    735     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
    736     mouse_location.Offset(-500, -5);
    737     panel1_testing->DragTitlebar(mouse_location);
    738     EXPECT_TRUE(drag_controller->is_dragging());
    739     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    740     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    741 
    742     ASSERT_EQ(2, docked_collection->num_panels());
    743     panels = PanelManager::GetInstance()->panels();
    744     EXPECT_EQ(panel4, panels[0]);
    745     EXPECT_EQ(panel1, panels[1]);
    746     EXPECT_EQ(position1, panel4->GetBounds().origin());
    747 
    748     // Closing the dragging panel should make the drag controller abort.
    749     // We have:  P4
    750     content::WindowedNotificationObserver signal(
    751         chrome::NOTIFICATION_PANEL_CLOSED, content::Source<Panel>(panel1));
    752     panel1->Close();
    753     EXPECT_FALSE(drag_controller->is_dragging());
    754 
    755     // Continue the drag to ensure the drag controller does not crash.
    756     panel1_new_position.Offset(20, 30);
    757     panel1_testing->DragTitlebar(panel1_new_position);
    758     panel1_testing->FinishDragTitlebar();
    759 
    760     // Wait till the panel is fully closed.
    761     signal.Wait();
    762     ASSERT_EQ(1, docked_collection->num_panels());
    763     panels = PanelManager::GetInstance()->panels();
    764     EXPECT_EQ(panel4, panels[0]);
    765     EXPECT_EQ(position1, panel4->GetBounds().origin());
    766   }
    767 
    768   panel_manager->CloseAll();
    769 }
    770 
    771 // http://crbug.com/175760; several panel tests failing regularly on mac.
    772 #if defined(OS_MACOSX)
    773 #define MAYBE_DragOneDetachedPanel DISABLED_DragOneDetachedPanel
    774 #else
    775 #define MAYBE_DragOneDetachedPanel DragOneDetachedPanel
    776 #endif
    777 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragOneDetachedPanel) {
    778   Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200));
    779 
    780   // Test that the detached panel can be dragged almost anywhere except getting
    781   // close to the bottom of the docked area to trigger the attach.
    782   scoped_ptr<NativePanelTesting> panel_testing(
    783       CreateNativePanelTesting(panel));
    784   gfx::Point origin = panel->GetBounds().origin();
    785 
    786   panel_testing->PressLeftMouseButtonTitlebar(origin);
    787   EXPECT_EQ(origin, panel->GetBounds().origin());
    788 
    789   origin.Offset(-51, -102);
    790   panel_testing->DragTitlebar(origin);
    791   EXPECT_EQ(origin, panel->GetBounds().origin());
    792 
    793   origin.Offset(37, 45);
    794   panel_testing->DragTitlebar(origin);
    795   EXPECT_EQ(origin, panel->GetBounds().origin());
    796 
    797   panel_testing->FinishDragTitlebar();
    798   EXPECT_EQ(origin, panel->GetBounds().origin());
    799 
    800   // Test that cancelling the drag will return the panel the the original
    801   // position.
    802   gfx::Point original_position = panel->GetBounds().origin();
    803   origin = original_position;
    804 
    805   panel_testing->PressLeftMouseButtonTitlebar(origin);
    806   EXPECT_EQ(origin, panel->GetBounds().origin());
    807 
    808   origin.Offset(-51, -102);
    809   panel_testing->DragTitlebar(origin);
    810   EXPECT_EQ(origin, panel->GetBounds().origin());
    811 
    812   origin.Offset(37, 45);
    813   panel_testing->DragTitlebar(origin);
    814   EXPECT_EQ(origin, panel->GetBounds().origin());
    815 
    816   panel_testing->CancelDragTitlebar();
    817   WaitForBoundsAnimationFinished(panel);
    818   EXPECT_EQ(original_position, panel->GetBounds().origin());
    819 
    820   PanelManager::GetInstance()->CloseAll();
    821 }
    822 
    823 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDetachedPanelOnDrag) {
    824   PanelManager* panel_manager = PanelManager::GetInstance();
    825   PanelDragController* drag_controller = panel_manager->drag_controller();
    826   DetachedPanelCollection* detached_collection =
    827       panel_manager->detached_collection();
    828 
    829   // Create 1 detached panel.
    830   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(100, 200, 100, 100));
    831   ASSERT_EQ(1, detached_collection->num_panels());
    832 
    833   scoped_ptr<NativePanelTesting> panel1_testing(
    834       CreateNativePanelTesting(panel1));
    835   gfx::Point panel1_old_position = panel1->GetBounds().origin();
    836 
    837   // Test the scenario: drag a panel, close another panel, cancel the drag.
    838   {
    839     // Create a panel to be closed.
    840     Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110));
    841 
    842     // Start dragging a panel.
    843     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
    844     gfx::Point panel1_new_position = panel1_old_position;
    845     panel1_new_position.Offset(-51, -102);
    846     panel1_testing->DragTitlebar(panel1_new_position);
    847     EXPECT_TRUE(drag_controller->is_dragging());
    848     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    849 
    850     ASSERT_EQ(2, detached_collection->num_panels());
    851     EXPECT_TRUE(detached_collection->HasPanel(panel1));
    852     EXPECT_TRUE(detached_collection->HasPanel(panel2));
    853     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    854 
    855     // Closing another panel while dragging in progress will keep the dragging
    856     // panel intact.
    857     CloseWindowAndWait(panel2);
    858     EXPECT_TRUE(drag_controller->is_dragging());
    859     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    860 
    861     ASSERT_EQ(1, detached_collection->num_panels());
    862     EXPECT_TRUE(detached_collection->HasPanel(panel1));
    863     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    864 
    865     // Cancel the drag.
    866     panel1_testing->CancelDragTitlebar();
    867     WaitForBoundsAnimationFinished(panel1);
    868     EXPECT_FALSE(drag_controller->is_dragging());
    869     EXPECT_EQ(panel1_old_position, panel1->GetBounds().origin());
    870   }
    871 
    872   // Test the scenario: drag a panel, close another panel, end the drag.
    873   {
    874     // Create a panel to be closed.
    875     Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110));
    876 
    877     // Start dragging a panel.
    878     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
    879     gfx::Point panel1_new_position = panel1_old_position;
    880     panel1_new_position.Offset(-51, -102);
    881     panel1_testing->DragTitlebar(panel1_new_position);
    882     EXPECT_TRUE(drag_controller->is_dragging());
    883     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    884 
    885     ASSERT_EQ(2, detached_collection->num_panels());
    886     EXPECT_TRUE(detached_collection->HasPanel(panel1));
    887     EXPECT_TRUE(detached_collection->HasPanel(panel2));
    888     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    889 
    890     // Closing another panel while dragging in progress will keep the dragging
    891     // panel intact.
    892     CloseWindowAndWait(panel2);
    893     EXPECT_TRUE(drag_controller->is_dragging());
    894     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    895 
    896     ASSERT_EQ(1, detached_collection->num_panels());
    897     EXPECT_TRUE(detached_collection->HasPanel(panel1));
    898     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    899 
    900     // Finish the drag.
    901     panel1_testing->FinishDragTitlebar();
    902     EXPECT_FALSE(drag_controller->is_dragging());
    903     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    904   }
    905 
    906   // Test the scenario: drag a panel and close the dragging panel.
    907   {
    908     // Start dragging a panel again.
    909     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
    910     gfx::Point panel1_new_position = panel1->GetBounds().origin();
    911     panel1_new_position.Offset(45, 67);
    912     panel1_testing->DragTitlebar(panel1_new_position);
    913     EXPECT_TRUE(drag_controller->is_dragging());
    914     EXPECT_EQ(panel1, drag_controller->dragging_panel());
    915 
    916     ASSERT_EQ(1, detached_collection->num_panels());
    917     EXPECT_TRUE(detached_collection->HasPanel(panel1));
    918     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
    919 
    920     // Closing the dragging panel should make the drag controller abort.
    921     content::WindowedNotificationObserver signal(
    922         chrome::NOTIFICATION_PANEL_CLOSED, content::Source<Panel>(panel1));
    923     panel1->Close();
    924     EXPECT_FALSE(drag_controller->is_dragging());
    925 
    926     // Continue the drag to ensure the drag controller does not crash.
    927     panel1_new_position.Offset(20, 30);
    928     panel1_testing->DragTitlebar(panel1_new_position);
    929     panel1_testing->FinishDragTitlebar();
    930 
    931     // Wait till the panel is fully closed.
    932     signal.Wait();
    933     ASSERT_EQ(0, detached_collection->num_panels());
    934   }
    935 }
    936 
    937 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, Detach) {
    938   PanelManager* panel_manager = PanelManager::GetInstance();
    939   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
    940   DetachedPanelCollection* detached_collection =
    941       panel_manager->detached_collection();
    942 
    943   // Create one docked panel.
    944   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
    945   ASSERT_EQ(1, docked_collection->num_panels());
    946   ASSERT_EQ(0, detached_collection->num_panels());
    947 
    948   gfx::Rect panel_old_bounds = panel->GetBounds();
    949 
    950   // Press on title-bar.
    951   scoped_ptr<NativePanelTesting> panel_testing(
    952       CreateNativePanelTesting(panel));
    953   gfx::Point mouse_location(panel->GetBounds().origin());
    954   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
    955 
    956   // Drag up the panel in a small offset that does not trigger the detach.
    957   // Expect that the panel is still docked and only x coordinate of its position
    958   // is changed.
    959   gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked();
    960   mouse_location = mouse_location + drag_delta_to_remain_docked;
    961   panel_testing->DragTitlebar(mouse_location);
    962   ASSERT_EQ(1, docked_collection->num_panels());
    963   ASSERT_EQ(0, detached_collection->num_panels());
    964   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
    965   gfx::Rect panel_new_bounds = panel_old_bounds;
    966   panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0);
    967   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    968 
    969   // Continue dragging up the panel in big offset that triggers the detach.
    970   // Expect that the panel is previewed as detached.
    971   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
    972   mouse_location = mouse_location + drag_delta_to_detach;
    973   panel_testing->DragTitlebar(mouse_location);
    974   ASSERT_EQ(0, docked_collection->num_panels());
    975   ASSERT_EQ(1, detached_collection->num_panels());
    976   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
    977   panel_new_bounds.Offset(
    978       drag_delta_to_detach.x(),
    979       drag_delta_to_detach.y() + drag_delta_to_remain_docked.y());
    980   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    981 
    982   // Finish the drag.
    983   // Expect that the panel stays as detached.
    984   panel_testing->FinishDragTitlebar();
    985   ASSERT_EQ(0, docked_collection->num_panels());
    986   ASSERT_EQ(1, detached_collection->num_panels());
    987   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
    988   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
    989 
    990   panel_manager->CloseAll();
    991 }
    992 
    993 // http://crbug.com/175760; several panel tests failing regularly on mac.
    994 #if defined(OS_MACOSX)
    995 #define MAYBE_DetachAndCancel DISABLED_DetachAndCancel
    996 #else
    997 #define MAYBE_DetachAndCancel DetachAndCancel
    998 #endif
    999 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DetachAndCancel) {
   1000   PanelManager* panel_manager = PanelManager::GetInstance();
   1001   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1002   DetachedPanelCollection* detached_collection =
   1003       panel_manager->detached_collection();
   1004 
   1005   // Create one docked panel.
   1006   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
   1007   ASSERT_EQ(1, docked_collection->num_panels());
   1008   ASSERT_EQ(0, detached_collection->num_panels());
   1009 
   1010   gfx::Rect panel_old_bounds = panel->GetBounds();
   1011 
   1012   // Press on title-bar.
   1013   scoped_ptr<NativePanelTesting> panel_testing(
   1014       CreateNativePanelTesting(panel));
   1015   gfx::Point mouse_location(panel->GetBounds().origin());
   1016   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1017 
   1018   // Drag up the panel in a small offset that does not trigger the detach.
   1019   // Expect that the panel is still docked and only x coordinate of its position
   1020   // is changed.
   1021   gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked();
   1022   mouse_location = mouse_location + drag_delta_to_remain_docked;
   1023   panel_testing->DragTitlebar(mouse_location);
   1024   ASSERT_EQ(1, docked_collection->num_panels());
   1025   ASSERT_EQ(0, detached_collection->num_panels());
   1026   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1027   gfx::Rect panel_new_bounds = panel_old_bounds;
   1028   panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0);
   1029   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1030 
   1031   // Continue dragging up the panel in big offset that triggers the detach.
   1032   // Expect that the panel is previewed as detached.
   1033   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
   1034   mouse_location = mouse_location + drag_delta_to_detach;
   1035   panel_testing->DragTitlebar(mouse_location);
   1036   ASSERT_EQ(0, docked_collection->num_panels());
   1037   ASSERT_EQ(1, detached_collection->num_panels());
   1038   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1039   panel_new_bounds.Offset(
   1040       drag_delta_to_detach.x(),
   1041       drag_delta_to_detach.y() + drag_delta_to_remain_docked.y());
   1042   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1043 
   1044   // Cancel the drag.
   1045   // Expect that the panel is back as docked.
   1046   panel_testing->CancelDragTitlebar();
   1047   ASSERT_EQ(1, docked_collection->num_panels());
   1048   ASSERT_EQ(0, detached_collection->num_panels());
   1049   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1050   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
   1051 
   1052   panel_manager->CloseAll();
   1053 }
   1054 
   1055 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1056 #if defined(OS_MACOSX)
   1057 #define MAYBE_Attach DISABLED_Attach
   1058 #else
   1059 #define MAYBE_Attach Attach
   1060 #endif
   1061 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_Attach) {
   1062   PanelManager* panel_manager = PanelManager::GetInstance();
   1063   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1064   DetachedPanelCollection* detached_collection =
   1065       panel_manager->detached_collection();
   1066 
   1067   // Create one detached panel.
   1068   Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100));
   1069   ASSERT_EQ(0, docked_collection->num_panels());
   1070   ASSERT_EQ(1, detached_collection->num_panels());
   1071   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1072 
   1073   gfx::Rect panel_old_bounds = panel->GetBounds();
   1074 
   1075   // Press on title-bar.
   1076   scoped_ptr<NativePanelTesting> panel_testing(
   1077       CreateNativePanelTesting(panel));
   1078   gfx::Point mouse_location(panel->GetBounds().origin());
   1079   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1080 
   1081   // Drag down the panel but not close enough to the bottom of work area.
   1082   // Expect that the panel is still detached.
   1083   gfx::Vector2d drag_delta_to_remain_detached =
   1084       GetDragDeltaToRemainDetached(panel);
   1085   mouse_location = mouse_location + drag_delta_to_remain_detached;
   1086   panel_testing->DragTitlebar(mouse_location);
   1087   ASSERT_EQ(0, docked_collection->num_panels());
   1088   ASSERT_EQ(1, detached_collection->num_panels());
   1089   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1090   gfx::Rect panel_new_bounds = panel_old_bounds;
   1091   panel_new_bounds.Offset(drag_delta_to_remain_detached);
   1092   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1093 
   1094   // Continue dragging down the panel to make it close enough to the bottom of
   1095   // work area.
   1096   // Expect that the panel is previewed as docked.
   1097   gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel);
   1098   mouse_location = mouse_location + drag_delta_to_attach;
   1099   panel_testing->DragTitlebar(mouse_location);
   1100   ASSERT_EQ(1, docked_collection->num_panels());
   1101   ASSERT_EQ(0, detached_collection->num_panels());
   1102   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1103   panel_new_bounds.Offset(drag_delta_to_attach);
   1104   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1105 
   1106   // Finish the drag.
   1107   // Expect that the panel stays as docked and moves to the final position.
   1108   panel_testing->FinishDragTitlebar();
   1109   ASSERT_EQ(1, docked_collection->num_panels());
   1110   ASSERT_EQ(0, detached_collection->num_panels());
   1111   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1112   panel_new_bounds.set_x(
   1113       docked_collection->StartingRightPosition() - panel_new_bounds.width());
   1114   panel_new_bounds.set_y(
   1115       docked_collection->work_area().bottom() - panel_new_bounds.height());
   1116   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1117 
   1118   panel_manager->CloseAll();
   1119 }
   1120 
   1121 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1122 #if defined(OS_MACOSX)
   1123 #define MAYBE_AttachAndCancel DISABLED_AttachAndCancel
   1124 #else
   1125 #define MAYBE_AttachAndCancel AttachAndCancel
   1126 #endif
   1127 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_AttachAndCancel) {
   1128   PanelManager* panel_manager = PanelManager::GetInstance();
   1129   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1130   DetachedPanelCollection* detached_collection =
   1131       panel_manager->detached_collection();
   1132 
   1133   // Create one detached panel.
   1134   Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100));
   1135   ASSERT_EQ(0, docked_collection->num_panels());
   1136   ASSERT_EQ(1, detached_collection->num_panels());
   1137   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1138 
   1139   gfx::Rect panel_old_bounds = panel->GetBounds();
   1140 
   1141   // Press on title-bar.
   1142   scoped_ptr<NativePanelTesting> panel_testing(
   1143       CreateNativePanelTesting(panel));
   1144   gfx::Point mouse_location(panel->GetBounds().origin());
   1145   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1146 
   1147   // Drag down the panel but not close enough to the bottom of work area.
   1148   // Expect that the panel is still detached.
   1149   gfx::Vector2d drag_delta_to_remain_detached =
   1150       GetDragDeltaToRemainDetached(panel);
   1151   mouse_location = mouse_location + drag_delta_to_remain_detached;
   1152   panel_testing->DragTitlebar(mouse_location);
   1153   ASSERT_EQ(0, docked_collection->num_panels());
   1154   ASSERT_EQ(1, detached_collection->num_panels());
   1155   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1156   gfx::Rect panel_new_bounds = panel_old_bounds;
   1157   panel_new_bounds.Offset(drag_delta_to_remain_detached);
   1158   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1159 
   1160   // Continue dragging down the panel to make it close enough to the bottom of
   1161   // work area.
   1162   // Expect that the panel is previewed as docked.
   1163   gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel);
   1164   mouse_location = mouse_location + drag_delta_to_attach;
   1165   panel_testing->DragTitlebar(mouse_location);
   1166   ASSERT_EQ(1, docked_collection->num_panels());
   1167   ASSERT_EQ(0, detached_collection->num_panels());
   1168   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1169   panel_new_bounds.Offset(drag_delta_to_attach);
   1170   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1171 
   1172   // Cancel the drag.
   1173   // Expect that the panel is back as detached.
   1174   panel_testing->CancelDragTitlebar();
   1175   ASSERT_EQ(0, docked_collection->num_panels());
   1176   ASSERT_EQ(1, detached_collection->num_panels());
   1177   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1178   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
   1179 
   1180   panel_manager->CloseAll();
   1181 }
   1182 
   1183 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAttachAndCancel) {
   1184   PanelManager* panel_manager = PanelManager::GetInstance();
   1185   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1186   DetachedPanelCollection* detached_collection =
   1187       panel_manager->detached_collection();
   1188 
   1189   // Create one docked panel.
   1190   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
   1191   ASSERT_EQ(1, docked_collection->num_panels());
   1192   ASSERT_EQ(0, detached_collection->num_panels());
   1193 
   1194   gfx::Rect panel_old_bounds = panel->GetBounds();
   1195 
   1196   // Press on title-bar.
   1197   scoped_ptr<NativePanelTesting> panel_testing(
   1198       CreateNativePanelTesting(panel));
   1199   gfx::Point mouse_location(panel->GetBounds().origin());
   1200   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1201 
   1202   // Drag up the panel to trigger the detach.
   1203   // Expect that the panel is previewed as detached.
   1204   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
   1205   mouse_location = mouse_location + drag_delta_to_detach;
   1206   panel_testing->DragTitlebar(mouse_location);
   1207   ASSERT_EQ(0, docked_collection->num_panels());
   1208   ASSERT_EQ(1, detached_collection->num_panels());
   1209   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1210   gfx::Rect panel_new_bounds = panel_old_bounds;
   1211   panel_new_bounds.Offset(drag_delta_to_detach);
   1212   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1213 
   1214   // Continue dragging down the panel to trigger the re-attach.
   1215   gfx::Vector2d drag_delta_to_reattach = GetDragDeltaToAttach(panel);
   1216   mouse_location = mouse_location + drag_delta_to_reattach;
   1217   panel_testing->DragTitlebar(mouse_location);
   1218   ASSERT_EQ(1, docked_collection->num_panels());
   1219   ASSERT_EQ(0, detached_collection->num_panels());
   1220   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1221   panel_new_bounds.Offset(drag_delta_to_reattach);
   1222   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1223 
   1224   // Continue dragging up the panel to trigger the detach again.
   1225   gfx::Vector2d drag_delta_to_detach_again = GetDragDeltaToDetach();
   1226   mouse_location = mouse_location + drag_delta_to_detach_again;
   1227   panel_testing->DragTitlebar(mouse_location);
   1228   ASSERT_EQ(0, docked_collection->num_panels());
   1229   ASSERT_EQ(1, detached_collection->num_panels());
   1230   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1231   panel_new_bounds.Offset(drag_delta_to_detach_again);
   1232   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
   1233 
   1234   // Cancel the drag.
   1235   // Expect that the panel stays as docked.
   1236   panel_testing->CancelDragTitlebar();
   1237   ASSERT_EQ(1, docked_collection->num_panels());
   1238   ASSERT_EQ(0, detached_collection->num_panels());
   1239   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1240   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
   1241 
   1242   panel_manager->CloseAll();
   1243 }
   1244 
   1245 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachWithSqueeze) {
   1246   PanelManager* panel_manager = PanelManager::GetInstance();
   1247   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1248   DetachedPanelCollection* detached_collection =
   1249       panel_manager->detached_collection();
   1250 
   1251   // Create some docked panels.
   1252   //   docked:    P1  P2  P3  P4  P5
   1253   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
   1254   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
   1255   Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
   1256   Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
   1257   Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
   1258   ASSERT_EQ(0, detached_collection->num_panels());
   1259   ASSERT_EQ(5, docked_collection->num_panels());
   1260 
   1261   // Drag to detach the middle docked panel.
   1262   // Expect to have:
   1263   //   detached:  P2
   1264   //   docked:    P1  P3  P4 P5
   1265   gfx::Point panel2_docked_position = panel2->GetBounds().origin();
   1266   gfx::Vector2d drag_delta_to_detach_panel2(-20, -100);
   1267   DragPanelByDelta(panel2, drag_delta_to_detach_panel2);
   1268   ASSERT_EQ(1, detached_collection->num_panels());
   1269   ASSERT_EQ(4, docked_collection->num_panels());
   1270   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
   1271   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1272   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1273   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
   1274   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1275   gfx::Point panel2_new_position =
   1276       panel2_docked_position + drag_delta_to_detach_panel2;
   1277   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
   1278 
   1279   // Drag to detach the left-most docked panel.
   1280   // Expect to have:
   1281   //   detached:  P2  P4
   1282   //   docked:    P1  P3  P5
   1283   gfx::Point panel4_docked_position = panel4->GetBounds().origin();
   1284   gfx::Vector2d drag_delta_to_detach_panel4(-40, -250);
   1285   DragPanelByDelta(panel4, drag_delta_to_detach_panel4);
   1286   ASSERT_EQ(2, detached_collection->num_panels());
   1287   ASSERT_EQ(3, docked_collection->num_panels());
   1288   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
   1289   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1290   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1291   EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type());
   1292   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1293   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
   1294   gfx::Point panel4_new_position =
   1295       panel4_docked_position + drag_delta_to_detach_panel4;
   1296   EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin());
   1297 
   1298   // Drag to detach the right-most docked panel.
   1299   // Expect to have:
   1300   //   detached:  P1  P2  P4
   1301   //   docked:    P3  P5
   1302   gfx::Point docked_position1 = panel1->GetBounds().origin();
   1303   gfx::Point docked_position2 = panel3->GetBounds().origin();
   1304   gfx::Vector2d drag_delta_to_detach_panel1(-60, -400);
   1305   DragPanelByDelta(panel1, drag_delta_to_detach_panel1);
   1306   ASSERT_EQ(3, detached_collection->num_panels());
   1307   ASSERT_EQ(2, docked_collection->num_panels());
   1308   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1309   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1310   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1311   EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type());
   1312   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1313   gfx::Point panel1_new_position =
   1314       docked_position1 + drag_delta_to_detach_panel1;
   1315   EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
   1316   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
   1317   EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin());
   1318 
   1319   // No more squeeze, docked panels should stay put.
   1320   EXPECT_EQ(docked_position1, panel3->GetBounds().origin());
   1321   EXPECT_EQ(panel1->GetBounds().width(), panel1->GetRestoredBounds().width());
   1322   EXPECT_EQ(docked_position2, panel5->GetBounds().origin());
   1323   EXPECT_EQ(panel2->GetBounds().width(), panel2->GetRestoredBounds().width());
   1324 
   1325   panel_manager->CloseAll();
   1326 }
   1327 
   1328 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, AttachWithSqueeze) {
   1329   PanelManager* panel_manager = PanelManager::GetInstance();
   1330   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   1331   DetachedPanelCollection* detached_collection =
   1332       panel_manager->detached_collection();
   1333 
   1334   // Create some detached, docked panels.
   1335   //   detached:  P1  P2  P3
   1336   //   docked:    P4  P5  P6  P7
   1337   Panel* panel1 = CreateInactiveDetachedPanel(
   1338       "1", gfx::Rect(100, 300, 200, 100));
   1339   Panel* panel2 = CreateInactiveDetachedPanel(
   1340       "2", gfx::Rect(200, 300, 200, 100));
   1341   Panel* panel3 = CreateInactiveDetachedPanel(
   1342       "3", gfx::Rect(400, 300, 200, 100));
   1343   Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
   1344   Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
   1345   Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
   1346   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
   1347   ASSERT_EQ(3, detached_collection->num_panels());
   1348   ASSERT_EQ(4, docked_collection->num_panels());
   1349 
   1350   // Wait for active states to settle.
   1351   PanelCollectionSqueezeObserver panel7_settled(docked_collection, panel7);
   1352   panel7_settled.Wait();
   1353 
   1354   gfx::Point detached_position1 = panel1->GetBounds().origin();
   1355   gfx::Point detached_position2 = panel2->GetBounds().origin();
   1356   gfx::Point detached_position3 = panel3->GetBounds().origin();
   1357   gfx::Point docked_position4 = panel4->GetBounds().origin();
   1358   gfx::Point docked_position5 = panel5->GetBounds().origin();
   1359   gfx::Point docked_position6 = panel6->GetBounds().origin();
   1360   gfx::Point docked_position7 = panel7->GetBounds().origin();
   1361 
   1362   // Drag to attach a detached panel between 2 docked panels.
   1363   // Expect to have:
   1364   //   detached:  P1  P2
   1365   //   docked:    P4  P3  P5  P6  P7
   1366   gfx::Point drag_to_location(panel5->GetBounds().x() + 10,
   1367                               panel5->GetBounds().y());
   1368   DragPanelToMouseLocation(panel3, drag_to_location);
   1369   ASSERT_EQ(2, detached_collection->num_panels());
   1370   ASSERT_EQ(5, docked_collection->num_panels());
   1371   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1372   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1373   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1374   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
   1375   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1376   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
   1377   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
   1378   EXPECT_EQ(detached_position1, panel1->GetBounds().origin());
   1379   EXPECT_EQ(detached_position2, panel2->GetBounds().origin());
   1380 
   1381   // Wait for active states to settle.
   1382   base::MessageLoopForUI::current()->RunUntilIdle();
   1383 
   1384   // Panel positions should have shifted because of the "squeeze" mode.
   1385   EXPECT_NE(docked_position4, panel4->GetBounds().origin());
   1386   EXPECT_LT(panel4->GetBounds().width(), panel4->GetRestoredBounds().width());
   1387   EXPECT_NE(docked_position5, panel5->GetBounds().origin());
   1388   EXPECT_LT(panel5->GetBounds().width(), panel5->GetRestoredBounds().width());
   1389 
   1390 #if defined(OS_WIN)
   1391   // The panel we dragged becomes the active one.
   1392   EXPECT_EQ(true, panel3->IsActive());
   1393   EXPECT_EQ(panel3->GetBounds().width(), panel3->GetRestoredBounds().width());
   1394 
   1395   EXPECT_NE(docked_position6, panel6->GetBounds().origin());
   1396 #else
   1397   // The last panel is active so these positions do not change.
   1398   // TODO (ABurago) this is wrong behavior, a panel should activate
   1399   // when it is dragged (it does in real usage, but not when drag is
   1400   // simulated in a test). Change this test when the behavior is fixed.
   1401   EXPECT_EQ(true, panel7->IsActive());
   1402   EXPECT_EQ(panel7->GetBounds().width(), panel7->GetRestoredBounds().width());
   1403 
   1404   EXPECT_EQ(docked_position6, panel6->GetBounds().origin());
   1405 #endif
   1406   EXPECT_EQ(docked_position7, panel7->GetBounds().origin());
   1407 
   1408   // Drag to attach a detached panel to most-right.
   1409   // Expect to have:
   1410   //   detached:  P1
   1411   //   docked:    P2  P4  P3  P5  P6  P7
   1412   gfx::Point drag_to_location2(panel4->GetBounds().right() + 10,
   1413                                panel4->GetBounds().y());
   1414   DragPanelToMouseLocation(panel2, drag_to_location2);
   1415   ASSERT_EQ(1, detached_collection->num_panels());
   1416   ASSERT_EQ(6, docked_collection->num_panels());
   1417   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1418   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
   1419   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1420   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
   1421   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1422   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
   1423   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
   1424   EXPECT_EQ(detached_position1, panel1->GetBounds().origin());
   1425 
   1426   // Drag to attach a detached panel to most-left.
   1427   // Expect to have:
   1428   //   docked:    P2  P4  P1  P3  P5  P6  P7
   1429   gfx::Point drag_to_location3(panel3->GetBounds().x() - 10,
   1430                                panel3->GetBounds().y());
   1431   DragPanelToMouseLocation(panel1, drag_to_location3);
   1432   ASSERT_EQ(0, detached_collection->num_panels());
   1433   ASSERT_EQ(7, docked_collection->num_panels());
   1434   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
   1435   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
   1436   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
   1437   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
   1438   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
   1439   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
   1440   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
   1441 
   1442   panel_manager->CloseAll();
   1443 }
   1444 
   1445 // http://crbug.com/175760; several panel tests failing regularly on mac.
   1446 #if defined(OS_MACOSX)
   1447 #define MAYBE_DragDetachedPanelToTop DISABLED_DragDetachedPanelToTop
   1448 #else
   1449 #define MAYBE_DragDetachedPanelToTop DragDetachedPanelToTop
   1450 #endif
   1451 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragDetachedPanelToTop) {
   1452   // Setup the test areas to have top-aligned bar excluded from work area.
   1453   const gfx::Rect primary_display_area(0, 0, 800, 600);
   1454   const gfx::Rect primary_work_area(0, 10, 800, 590);
   1455   mock_display_settings_provider()->SetPrimaryDisplay(
   1456       primary_display_area, primary_work_area);
   1457 
   1458   PanelManager* panel_manager = PanelManager::GetInstance();
   1459   Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200));
   1460 
   1461   // Drag up the panel. Expect that the panel should not go outside the top of
   1462   // the work area.
   1463   gfx::Point drag_to_location(250, 0);
   1464   DragPanelToMouseLocation(panel, drag_to_location);
   1465   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1466   EXPECT_EQ(drag_to_location.x(), panel->GetBounds().origin().x());
   1467   EXPECT_EQ(primary_work_area.y(), panel->GetBounds().origin().y());
   1468 
   1469   // Drag down the panel. Expect that the panel can be dragged without
   1470   // constraint.
   1471   drag_to_location = gfx::Point(280, 150);
   1472   DragPanelToMouseLocation(panel, drag_to_location);
   1473   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1474   EXPECT_EQ(drag_to_location, panel->GetBounds().origin());
   1475 
   1476   panel_manager->CloseAll();
   1477 }
   1478 
   1479 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
   1480                        DragDockedPanelToSecondaryDisplay) {
   1481   // Setup 2 displays with secondary display on the right side of primary
   1482   // display.
   1483   mock_display_settings_provider()->SetPrimaryDisplay(
   1484       gfx::Rect(0, 0, 400, 600), gfx::Rect(0, 0, 400, 560));
   1485   gfx::Rect secondary_display_area(400, 100, 400, 500);
   1486   mock_display_settings_provider()->SetSecondaryDisplay(
   1487       secondary_display_area, secondary_display_area);
   1488 
   1489   // Create a docked panel.
   1490   gfx::Size panel_size(100, 100);
   1491   Panel* panel = CreateDockedPanel("1", gfx::Rect(gfx::Point(), panel_size));
   1492   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
   1493 
   1494   // Drag the panel to the secondary display horizontally.
   1495   // Expected that the panel should become detached.
   1496   gfx::Point drag_to_location(secondary_display_area.x() + 100,
   1497                               panel->GetBounds().y());
   1498   DragPanelToMouseLocation(panel, drag_to_location);
   1499   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1500   gfx::Rect expected_bounds(drag_to_location, panel_size);
   1501   EXPECT_EQ(expected_bounds, panel->GetBounds());
   1502 
   1503   PanelManager::GetInstance()->CloseAll();
   1504 }
   1505 
   1506 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
   1507                        DragDetachedPanelToSecondaryDisplay) {
   1508   // Setup 2 displays with secondary display at the bottom of primary display.
   1509   mock_display_settings_provider()->SetPrimaryDisplay(
   1510       gfx::Rect(0, 0, 800, 300), gfx::Rect(0, 0, 800, 260));
   1511   gfx::Rect secondary_display_area(100, 300, 700, 250);
   1512   mock_display_settings_provider()->SetSecondaryDisplay(
   1513       secondary_display_area, secondary_display_area);
   1514 
   1515   // Create a detached panel on the primary display.
   1516   gfx::Rect initial_panel_bounds(300, 50, 100, 100);
   1517   Panel* panel = CreateDetachedPanel("1", initial_panel_bounds);
   1518   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1519   EXPECT_EQ(initial_panel_bounds, panel->GetBounds());
   1520 
   1521   // Drag down the panel to the secondary display vertically.
   1522   // Expected that the panel should remain detached.
   1523   gfx::Point drag_to_location(initial_panel_bounds.x(),
   1524                               secondary_display_area.y() + 100);
   1525   DragPanelToMouseLocation(panel, drag_to_location);
   1526   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
   1527   gfx::Rect expected_bounds(drag_to_location, initial_panel_bounds.size());
   1528   EXPECT_EQ(expected_bounds, panel->GetBounds());
   1529 
   1530   PanelManager::GetInstance()->CloseAll();
   1531 }
   1532 
   1533 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromBottom) {
   1534   PanelManager* panel_manager = PanelManager::GetInstance();
   1535   DetachedPanelCollection* detached_collection =
   1536       panel_manager->detached_collection();
   1537 
   1538   // Create two detached panels.
   1539   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100));
   1540   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150));
   1541   ASSERT_EQ(2, detached_collection->num_panels());
   1542   ASSERT_EQ(0, panel_manager->num_stacks());
   1543   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1544   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1545 
   1546   gfx::Rect panel1_old_bounds = panel1->GetBounds();
   1547   gfx::Rect panel2_old_bounds = panel2->GetBounds();
   1548 
   1549   // Press on title-bar of P2.
   1550   scoped_ptr<NativePanelTesting> panel2_testing(
   1551       CreateNativePanelTesting(panel2));
   1552   gfx::Point mouse_location(panel2->GetBounds().origin());
   1553   gfx::Point original_mouse_location = mouse_location;
   1554   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1555 
   1556   // Drag P2 close to the bottom of P1 to trigger the stacking. Expect:
   1557   // 1) P1 and P2 form a stack.
   1558   // 2) P2 jumps vertcially to align to the bottom edge of P1.
   1559   // 3) P2 moves horizontally by the dragging delta.
   1560   // 4) The width of P2 remains unchanged.
   1561   gfx::Vector2d drag_delta_to_stack =
   1562       GetDragDeltaToStackToBottom(panel2, panel1);
   1563   mouse_location = mouse_location + drag_delta_to_stack;
   1564   panel2_testing->DragTitlebar(mouse_location);
   1565   ASSERT_EQ(0, detached_collection->num_panels());
   1566   ASSERT_EQ(1, panel_manager->num_stacks());
   1567   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1568   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1569   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1570   gfx::Rect panel2_new_bounds(panel2_old_bounds.x() + drag_delta_to_stack.x(),
   1571                               panel1_old_bounds.bottom(),
   1572                               panel2_old_bounds.width(),
   1573                               panel2_old_bounds.height());
   1574   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1575 
   1576   // Drag P2 somewhat away from the bottom of P1 to trigger the unstacking.
   1577   // Expect P1 and P2 become detached.
   1578   gfx::Vector2d drag_delta_to_unstack =
   1579       GetDragDeltaToUnstackFromBottom(panel2, panel1);
   1580   mouse_location = mouse_location + drag_delta_to_unstack;
   1581   panel2_testing->DragTitlebar(mouse_location);
   1582   ASSERT_EQ(2, detached_collection->num_panels());
   1583   ASSERT_EQ(0, panel_manager->num_stacks());
   1584   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1585   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1586   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1587   panel2_new_bounds.set_origin(panel2_old_bounds.origin());
   1588   panel2_new_bounds.Offset(mouse_location - original_mouse_location);
   1589   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1590 
   1591   // Drag P2 close to the bottom of P1 to trigger the stacking again. Expect:
   1592   // 1) P1 and P2 form a stack.
   1593   // 2) P2 jumps vertcially to align to the bottom edge of P1.
   1594   // 3) P2 moves horizontally by the dragging delta.
   1595   // 4) The width of P2 remains unchanged.
   1596   drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1);
   1597   mouse_location = mouse_location + drag_delta_to_stack;
   1598   panel2_testing->DragTitlebar(mouse_location);
   1599   ASSERT_EQ(0, detached_collection->num_panels());
   1600   ASSERT_EQ(1, panel_manager->num_stacks());
   1601   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1602   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1603   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1604   panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x());
   1605   panel2_new_bounds.set_y(panel1_old_bounds.bottom());
   1606   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1607 
   1608   // Move the mouse a little bit. Expect P2 only moves horizontally. P2 should
   1609   // not move vertically since its top edge already glues to the bottom edge
   1610   // of P1.
   1611   gfx::Vector2d small_delta(1, -1);
   1612   mouse_location = mouse_location + small_delta;
   1613   panel2_testing->DragTitlebar(mouse_location);
   1614   ASSERT_EQ(0, detached_collection->num_panels());
   1615   ASSERT_EQ(1, panel_manager->num_stacks());
   1616   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1617   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1618   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1619   panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x());
   1620   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1621 
   1622   // Finish the drag. Expect:
   1623   // 1) P1 and P2 remain stacked.
   1624   // 2) P2 moves horizontally to align with P1.
   1625   // 3) The width of P2 is adjusted to be same as the one of P1.
   1626   panel2_testing->FinishDragTitlebar();
   1627   WaitForBoundsAnimationFinished(panel2);
   1628   ASSERT_EQ(0, detached_collection->num_panels());
   1629   ASSERT_EQ(1, panel_manager->num_stacks());
   1630   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1631   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1632   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1633   panel2_new_bounds.set_x(panel1_old_bounds.x());
   1634   panel2_new_bounds.set_width(panel1_old_bounds.width());
   1635   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1636 
   1637   panel_manager->CloseAll();
   1638 }
   1639 
   1640 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromTop) {
   1641   PanelManager* panel_manager = PanelManager::GetInstance();
   1642   DetachedPanelCollection* detached_collection =
   1643       panel_manager->detached_collection();
   1644 
   1645   // Create two detached panels.
   1646   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 300, 200, 100));
   1647   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 200, 150, 150));
   1648   ASSERT_EQ(2, detached_collection->num_panels());
   1649   ASSERT_EQ(0, panel_manager->num_stacks());
   1650   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1651   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1652 
   1653   gfx::Rect panel1_old_bounds = panel1->GetBounds();
   1654   gfx::Rect panel2_old_bounds = panel2->GetBounds();
   1655 
   1656   // Press on title-bar of P2.
   1657   scoped_ptr<NativePanelTesting> panel2_testing(
   1658       CreateNativePanelTesting(panel2));
   1659   gfx::Point mouse_location(panel2->GetBounds().origin());
   1660   gfx::Point original_mouse_location = mouse_location;
   1661   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1662 
   1663   // Drag P2 close to the top of P1 to trigger the stacking. Expect:
   1664   // 1) P2 and P1 form a stack.
   1665   // 2) P2 jumps vertcially to align to the top edge of P1.
   1666   // 3) P2 moves horizontally by the dragging delta.
   1667   // 4) The width of both P1 and P2 remains unchanged.
   1668   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1);
   1669   mouse_location = mouse_location + drag_delta_to_stack;
   1670   panel2_testing->DragTitlebar(mouse_location);
   1671   ASSERT_EQ(0, detached_collection->num_panels());
   1672   ASSERT_EQ(1, panel_manager->num_stacks());
   1673   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1674   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1675   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1676   gfx::Rect panel2_new_bounds(
   1677       panel2_old_bounds.x() + drag_delta_to_stack.x(),
   1678       panel1_old_bounds.y() - panel2_old_bounds.height(),
   1679       panel2_old_bounds.width(),
   1680       panel2_old_bounds.height());
   1681   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1682 
   1683   // Drag P2 somewhat away from the top of P1 to trigger the unstacking.
   1684   // Expect P1 and P2 become detached.
   1685   gfx::Vector2d drag_delta_to_unstack =
   1686       GetDragDeltaToUnstackFromTop(panel2, panel1);
   1687   mouse_location = mouse_location + drag_delta_to_unstack;
   1688   panel2_testing->DragTitlebar(mouse_location);
   1689   ASSERT_EQ(2, detached_collection->num_panels());
   1690   ASSERT_EQ(0, panel_manager->num_stacks());
   1691   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1692   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1693   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1694   panel2_new_bounds.set_origin(panel2_old_bounds.origin());
   1695   panel2_new_bounds.Offset(mouse_location - original_mouse_location);
   1696   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1697 
   1698   // Drag P2 close to the top of P1 to trigger the stacking again. Expect:
   1699   // 1) P2 and P1 form a stack.
   1700   // 2) P2 jumps vertcially to align to the top edge of P1.
   1701   // 3) P2 moves horizontally by the dragging delta.
   1702   // 4) The width of both P1 and P2 remains unchanged.
   1703   drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1);
   1704   mouse_location = mouse_location + drag_delta_to_stack;
   1705   panel2_testing->DragTitlebar(mouse_location);
   1706   ASSERT_EQ(0, detached_collection->num_panels());
   1707   ASSERT_EQ(1, panel_manager->num_stacks());
   1708   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1709   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1710   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1711   panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x());
   1712   panel2_new_bounds.set_y(panel1_old_bounds.y() - panel2_old_bounds.height());
   1713   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1714 
   1715   // Move the mouse a little bit. Expect only P2 moves horizontally. P2 should
   1716   // not move vertically because its bottom edge already glues to the top edge
   1717   // of P1.
   1718   gfx::Vector2d small_delta(1, -1);
   1719   mouse_location = mouse_location + small_delta;
   1720   panel2_testing->DragTitlebar(mouse_location);
   1721   ASSERT_EQ(0, detached_collection->num_panels());
   1722   ASSERT_EQ(1, panel_manager->num_stacks());
   1723   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1724   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1725   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1726   panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x());
   1727   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1728 
   1729   // Finish the drag. Expect:
   1730   // 1) P2 and P1 remain stacked.
   1731   // 2) P2 moves horizontally to align with P1.
   1732   // 3) The width of P1 is adjusted to be same as the one of P2.
   1733   panel2_testing->FinishDragTitlebar();
   1734   WaitForBoundsAnimationFinished(panel1);
   1735   ASSERT_EQ(0, detached_collection->num_panels());
   1736   ASSERT_EQ(1, panel_manager->num_stacks());
   1737   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1738   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1739   gfx::Rect panel1_new_bounds = panel1_old_bounds;
   1740   panel1_new_bounds.set_width(panel2_new_bounds.width());
   1741   EXPECT_EQ(panel1_new_bounds, panel1->GetBounds());
   1742   panel2_new_bounds.set_x(panel1_new_bounds.x());
   1743   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1744 
   1745   panel_manager->CloseAll();
   1746 }
   1747 
   1748 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupAndCancel) {
   1749   PanelManager* panel_manager = PanelManager::GetInstance();
   1750   DetachedPanelCollection* detached_collection =
   1751       panel_manager->detached_collection();
   1752 
   1753   // Create two detached panels.
   1754   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100));
   1755   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150));
   1756   ASSERT_EQ(2, detached_collection->num_panels());
   1757   ASSERT_EQ(0, panel_manager->num_stacks());
   1758   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1759   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1760 
   1761   gfx::Rect panel1_old_bounds = panel1->GetBounds();
   1762   gfx::Rect panel2_old_bounds = panel2->GetBounds();
   1763 
   1764   // Press on title-bar.
   1765   scoped_ptr<NativePanelTesting> panel2_testing(
   1766       CreateNativePanelTesting(panel2));
   1767   gfx::Point mouse_location(panel2->GetBounds().origin());
   1768   gfx::Point original_mouse_location = mouse_location;
   1769   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   1770 
   1771   // Drag P2 close to the bottom of P1 to trigger the stacking.
   1772   // Expect that P2 stacks to P1 and P2's width remains unchanged.
   1773   gfx::Vector2d drag_delta_to_stack =
   1774       GetDragDeltaToStackToBottom(panel2, panel1);
   1775   mouse_location = mouse_location + drag_delta_to_stack;
   1776   panel2_testing->DragTitlebar(mouse_location);
   1777   ASSERT_EQ(0, detached_collection->num_panels());
   1778   ASSERT_EQ(1, panel_manager->num_stacks());
   1779   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   1780   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   1781   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1782   gfx::Rect panel2_new_bounds(panel1_old_bounds.x(),
   1783                               panel1_old_bounds.bottom(),
   1784                               panel2_old_bounds.width(),
   1785                               panel2_old_bounds.height());
   1786   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
   1787 
   1788   // Cancel the drag.
   1789   // Expect that the P1 and P2 become detached.
   1790   panel2_testing->CancelDragTitlebar();
   1791   ASSERT_EQ(2, detached_collection->num_panels());
   1792   ASSERT_EQ(0, panel_manager->num_stacks());
   1793   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   1794   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   1795   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
   1796   EXPECT_EQ(panel2_old_bounds, panel2->GetBounds());
   1797 
   1798   panel_manager->CloseAll();
   1799 }
   1800 
   1801 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromBottom) {
   1802   PanelManager* panel_manager = PanelManager::GetInstance();
   1803   DetachedPanelCollection* detached_collection =
   1804       panel_manager->detached_collection();
   1805 
   1806   // Create 2 stacked panels.
   1807   StackedPanelCollection* stack = panel_manager->CreateStack();
   1808   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
   1809   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   1810   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   1811   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   1812   ASSERT_EQ(0, detached_collection->num_panels());
   1813   ASSERT_EQ(1, panel_manager->num_stacks());
   1814   ASSERT_EQ(2, stack->num_panels());
   1815   EXPECT_EQ(stack, panel1->collection());
   1816   EXPECT_EQ(stack, panel2->collection());
   1817 
   1818   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   1819   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1820   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   1821       panel2_initial_bounds, panel1_expected_bounds);
   1822   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1823 
   1824   // Create 1 detached panel.
   1825   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
   1826   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   1827   ASSERT_EQ(1, detached_collection->num_panels());
   1828   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   1829   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1830 
   1831   // Drag P3 close to the bottom edge of P1 that is not the bottom panel.
   1832   // Expect no stacking.
   1833   gfx::Vector2d drag_delta_to_stack =
   1834       GetDragDeltaToStackToBottom(panel3, panel1);
   1835   DragPanelByDelta(panel3, drag_delta_to_stack);
   1836   ASSERT_EQ(1, detached_collection->num_panels());
   1837   ASSERT_EQ(2, stack->num_panels());
   1838   ASSERT_EQ(1, panel_manager->num_stacks());
   1839 
   1840   // Drag P3 close to the bottom edge of P2 that is the bottom panel.
   1841   // Expect that P3 becomes the bottom panel of the stack.
   1842   drag_delta_to_stack = GetDragDeltaToStackToBottom(panel3, panel2);
   1843   DragPanelByDelta(panel3, drag_delta_to_stack);
   1844   WaitForBoundsAnimationFinished(panel3);
   1845   ASSERT_EQ(0, detached_collection->num_panels());
   1846   ASSERT_EQ(3, stack->num_panels());
   1847   ASSERT_EQ(1, panel_manager->num_stacks());
   1848   EXPECT_EQ(stack, panel1->collection());
   1849   EXPECT_EQ(stack, panel2->collection());
   1850   EXPECT_EQ(stack, panel3->collection());
   1851   EXPECT_EQ(panel3, stack->bottom_panel());
   1852 
   1853   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1854   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1855   panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   1856       panel3_initial_bounds, panel2_expected_bounds);
   1857   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1858 
   1859   panel_manager->CloseAll();
   1860 }
   1861 
   1862 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromTop) {
   1863   PanelManager* panel_manager = PanelManager::GetInstance();
   1864   DetachedPanelCollection* detached_collection =
   1865       panel_manager->detached_collection();
   1866 
   1867   // Create 2 stacked panels.
   1868   StackedPanelCollection* stack = panel_manager->CreateStack();
   1869   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 300, 200, 150);
   1870   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   1871   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   1872   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   1873   ASSERT_EQ(0, detached_collection->num_panels());
   1874   ASSERT_EQ(1, panel_manager->num_stacks());
   1875   ASSERT_EQ(2, stack->num_panels());
   1876   EXPECT_EQ(stack, panel1->collection());
   1877   EXPECT_EQ(stack, panel2->collection());
   1878 
   1879   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   1880   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1881   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   1882       panel2_initial_bounds, panel1_expected_bounds);
   1883   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1884 
   1885   // Create 1 detached panel.
   1886   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
   1887   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   1888   ASSERT_EQ(1, detached_collection->num_panels());
   1889   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   1890   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1891 
   1892   // Drag P3 close to the top edge of P2 that is not the top panel.
   1893   // Expect no stacking.
   1894   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel2);
   1895   DragPanelByDelta(panel3, drag_delta_to_stack);
   1896   ASSERT_EQ(1, detached_collection->num_panels());
   1897   ASSERT_EQ(2, stack->num_panels());
   1898   ASSERT_EQ(1, panel_manager->num_stacks());
   1899 
   1900   // Drag P3 close to the top edge of P1 that is the top panel.
   1901   // Expect that P3 becomes the top panel of the stack.
   1902   drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel1);
   1903   DragPanelByDelta(panel3, drag_delta_to_stack);
   1904   WaitForBoundsAnimationFinished(panel1);
   1905   WaitForBoundsAnimationFinished(panel2);
   1906   ASSERT_EQ(0, detached_collection->num_panels());
   1907   ASSERT_EQ(3, stack->num_panels());
   1908   ASSERT_EQ(1, panel_manager->num_stacks());
   1909   EXPECT_EQ(stack, panel1->collection());
   1910   EXPECT_EQ(stack, panel2->collection());
   1911   EXPECT_EQ(stack, panel3->collection());
   1912   EXPECT_EQ(panel3, stack->top_panel());
   1913 
   1914   panel3_expected_bounds = GetStackedAtTopPanelBounds(
   1915       panel3_initial_bounds, panel1_expected_bounds);
   1916   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1917   panel1_expected_bounds.set_width(panel3_expected_bounds.width());
   1918   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1919   panel2_expected_bounds.set_width(panel3_expected_bounds.width());
   1920   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1921 
   1922   panel_manager->CloseAll();
   1923 }
   1924 
   1925 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromBottom) {
   1926   PanelManager* panel_manager = PanelManager::GetInstance();
   1927   DetachedPanelCollection* detached_collection =
   1928       panel_manager->detached_collection();
   1929 
   1930   // Create 2 stacked panels.
   1931   StackedPanelCollection* stack = panel_manager->CreateStack();
   1932   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
   1933   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   1934   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   1935   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   1936   ASSERT_EQ(0, detached_collection->num_panels());
   1937   ASSERT_EQ(1, panel_manager->num_stacks());
   1938   ASSERT_EQ(2, stack->num_panels());
   1939   EXPECT_EQ(stack, panel1->stack());
   1940   EXPECT_EQ(stack, panel2->stack());
   1941 
   1942   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   1943   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1944   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   1945       panel2_initial_bounds, panel1_expected_bounds);
   1946   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1947 
   1948   // Create 1 detached panel.
   1949   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
   1950   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   1951   ASSERT_EQ(1, detached_collection->num_panels());
   1952   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   1953   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1954 
   1955   // Drag P1 (together with P2) to stack to the bottom of P3.
   1956   // Expect that P1 and P2 append to the bottom of P3 and all 3 panels are in
   1957   // one stack.
   1958   gfx::Vector2d drag_delta_to_stack =
   1959       GetDragDeltaToStackToBottom(panel1, panel3);
   1960   DragPanelByDelta(panel1, drag_delta_to_stack);
   1961   WaitForBoundsAnimationFinished(panel1);
   1962   WaitForBoundsAnimationFinished(panel2);
   1963   ASSERT_EQ(0, detached_collection->num_panels());
   1964   ASSERT_EQ(1, panel_manager->num_stacks());
   1965   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   1966   ASSERT_EQ(3, final_stack->num_panels());
   1967   EXPECT_EQ(final_stack, panel1->stack());
   1968   EXPECT_EQ(final_stack, panel2->stack());
   1969   EXPECT_EQ(final_stack, panel3->stack());
   1970 
   1971   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   1972   panel1_expected_bounds = GetStackedAtBottomPanelBounds(
   1973       panel1_initial_bounds, panel3_expected_bounds);
   1974   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   1975   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   1976       panel2_initial_bounds, panel1_expected_bounds);
   1977   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   1978 
   1979   panel_manager->CloseAll();
   1980 }
   1981 
   1982 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromTop) {
   1983   PanelManager* panel_manager = PanelManager::GetInstance();
   1984   DetachedPanelCollection* detached_collection =
   1985       panel_manager->detached_collection();
   1986 
   1987   // Create 2 stacked panels.
   1988   StackedPanelCollection* stack = panel_manager->CreateStack();
   1989   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
   1990   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   1991   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   1992   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   1993   ASSERT_EQ(0, detached_collection->num_panels());
   1994   ASSERT_EQ(1, panel_manager->num_stacks());
   1995   ASSERT_EQ(2, stack->num_panels());
   1996   EXPECT_EQ(stack, panel1->stack());
   1997   EXPECT_EQ(stack, panel2->stack());
   1998 
   1999   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2000   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2001   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2002       panel2_initial_bounds, panel1_expected_bounds);
   2003   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2004 
   2005   // Create 1 detached panel.
   2006   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 450, 100, 100);
   2007   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   2008   ASSERT_EQ(1, detached_collection->num_panels());
   2009   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2010   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2011 
   2012   // Drag P1 (together with P2) to stack to the top of P3.
   2013   // Expect that P1 and P2 add to the top of P3 and all 3 panels are in
   2014   // one stack. P1 and P2 should align to top of P3 while P3 should update its
   2015   // width to be same as the width of P1 and P2.
   2016   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3);
   2017   DragPanelByDelta(panel1, drag_delta_to_stack);
   2018   WaitForBoundsAnimationFinished(panel3);
   2019   ASSERT_EQ(0, detached_collection->num_panels());
   2020   ASSERT_EQ(1, panel_manager->num_stacks());
   2021   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   2022   ASSERT_EQ(3, final_stack->num_panels());
   2023   EXPECT_EQ(final_stack, panel1->stack());
   2024   EXPECT_EQ(final_stack, panel2->stack());
   2025   EXPECT_EQ(final_stack, panel3->stack());
   2026 
   2027   panel3_expected_bounds.set_width(panel1_expected_bounds.width());
   2028   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2029   panel2_expected_bounds = GetStackedAtTopPanelBounds(
   2030       panel2_expected_bounds, panel3_expected_bounds);
   2031   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2032   panel1_expected_bounds = GetStackedAtTopPanelBounds(
   2033       panel1_expected_bounds, panel2_expected_bounds);
   2034   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2035 
   2036   panel_manager->CloseAll();
   2037 }
   2038 
   2039 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromBottom) {
   2040   PanelManager* panel_manager = PanelManager::GetInstance();
   2041   DetachedPanelCollection* detached_collection =
   2042       panel_manager->detached_collection();
   2043 
   2044   // Create 2 stacked panels.
   2045   StackedPanelCollection* stack1 = panel_manager->CreateStack();
   2046   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2047   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1);
   2048   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2049   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1);
   2050   ASSERT_EQ(0, detached_collection->num_panels());
   2051   ASSERT_EQ(1, panel_manager->num_stacks());
   2052   ASSERT_EQ(2, stack1->num_panels());
   2053   EXPECT_EQ(stack1, panel1->stack());
   2054   EXPECT_EQ(stack1, panel2->stack());
   2055 
   2056   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2057   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2058   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2059       panel2_initial_bounds, panel1_expected_bounds);
   2060   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2061 
   2062   // Create 2 more stacked panels in another stack.
   2063   StackedPanelCollection* stack2 = panel_manager->CreateStack();
   2064   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 100, 220, 120);
   2065   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2);
   2066   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 140);
   2067   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2);
   2068   ASSERT_EQ(0, detached_collection->num_panels());
   2069   ASSERT_EQ(2, panel_manager->num_stacks());
   2070   ASSERT_EQ(2, stack2->num_panels());
   2071   EXPECT_EQ(stack2, panel3->stack());
   2072   EXPECT_EQ(stack2, panel4->stack());
   2073 
   2074   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2075   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2076   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
   2077       panel4_initial_bounds, panel3_expected_bounds);
   2078   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2079 
   2080   // Drag P3 (together with P4) to stack to the bottom of the stack consisting
   2081   // P1 and P2.
   2082   // Expect that P3 and P4 append to the bottom of P2 and all 4 panels are in
   2083   // one stack.
   2084   gfx::Vector2d drag_delta_to_stack =
   2085       GetDragDeltaToStackToBottom(panel3, panel2);
   2086   DragPanelByDelta(panel3, drag_delta_to_stack);
   2087   WaitForBoundsAnimationFinished(panel3);
   2088   WaitForBoundsAnimationFinished(panel4);
   2089   ASSERT_EQ(0, detached_collection->num_panels());
   2090   ASSERT_EQ(1, panel_manager->num_stacks());
   2091   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   2092   ASSERT_EQ(4, final_stack->num_panels());
   2093   EXPECT_EQ(final_stack, panel1->stack());
   2094   EXPECT_EQ(final_stack, panel2->stack());
   2095   EXPECT_EQ(final_stack, panel3->stack());
   2096   EXPECT_EQ(final_stack, panel4->stack());
   2097 
   2098   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2099   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2100   panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   2101       panel3_initial_bounds, panel2_expected_bounds);
   2102   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2103   panel4_expected_bounds = GetStackedAtBottomPanelBounds(
   2104       panel4_initial_bounds, panel3_expected_bounds);
   2105   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2106 
   2107   panel_manager->CloseAll();
   2108 }
   2109 
   2110 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromTop) {
   2111   PanelManager* panel_manager = PanelManager::GetInstance();
   2112   DetachedPanelCollection* detached_collection =
   2113       panel_manager->detached_collection();
   2114 
   2115   // Create 2 stacked panels.
   2116   StackedPanelCollection* stack1 = panel_manager->CreateStack();
   2117   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2118   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1);
   2119   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2120   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1);
   2121   ASSERT_EQ(0, detached_collection->num_panels());
   2122   ASSERT_EQ(1, panel_manager->num_stacks());
   2123   ASSERT_EQ(2, stack1->num_panels());
   2124   EXPECT_EQ(stack1, panel1->stack());
   2125   EXPECT_EQ(stack1, panel2->stack());
   2126 
   2127   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2128   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2129   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2130       panel2_initial_bounds, panel1_expected_bounds);
   2131   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2132 
   2133   // Create 2 more stacked panels in another stack.
   2134   StackedPanelCollection* stack2 = panel_manager->CreateStack();
   2135   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 350, 220, 110);
   2136   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2);
   2137   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 100);
   2138   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2);
   2139   ASSERT_EQ(0, detached_collection->num_panels());
   2140   ASSERT_EQ(2, panel_manager->num_stacks());
   2141   ASSERT_EQ(2, stack2->num_panels());
   2142   EXPECT_EQ(stack2, panel3->stack());
   2143   EXPECT_EQ(stack2, panel4->stack());
   2144 
   2145   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2146   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2147   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
   2148       panel4_initial_bounds, panel3_expected_bounds);
   2149   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2150 
   2151   // Drag P1 (together with P2) to stack to the top of the stack consisting
   2152   // P3 and P4.
   2153   // Expect that P1 and P2 add to the top of P3 and all 4 panels are in
   2154   // one stack. P1 and P2 should align to top of P3 while P3 and P4 should
   2155   // update their width to be same as the width of P1 and P2.
   2156   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3);
   2157   DragPanelByDelta(panel1, drag_delta_to_stack);
   2158   WaitForBoundsAnimationFinished(panel3);
   2159   WaitForBoundsAnimationFinished(panel4);
   2160   ASSERT_EQ(0, detached_collection->num_panels());
   2161   ASSERT_EQ(1, panel_manager->num_stacks());
   2162   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   2163   ASSERT_EQ(4, final_stack->num_panels());
   2164   EXPECT_EQ(final_stack, panel1->stack());
   2165   EXPECT_EQ(final_stack, panel2->stack());
   2166   EXPECT_EQ(final_stack, panel3->stack());
   2167   EXPECT_EQ(final_stack, panel4->stack());
   2168 
   2169   panel4_expected_bounds.set_width(panel1_expected_bounds.width());
   2170   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2171   panel3_expected_bounds.set_width(panel1_expected_bounds.width());
   2172   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2173   panel2_expected_bounds = GetStackedAtTopPanelBounds(
   2174       panel2_expected_bounds, panel3_expected_bounds);
   2175   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2176   panel1_expected_bounds = GetStackedAtTopPanelBounds(
   2177       panel1_expected_bounds, panel2_expected_bounds);
   2178   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2179 
   2180   panel_manager->CloseAll();
   2181 }
   2182 
   2183 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupTwoPanelStack) {
   2184   PanelManager* panel_manager = PanelManager::GetInstance();
   2185   DetachedPanelCollection* detached_collection =
   2186       panel_manager->detached_collection();
   2187 
   2188   // Create 2 stacked panels.
   2189   StackedPanelCollection* stack = panel_manager->CreateStack();
   2190   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2191   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2192   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2193   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2194   ASSERT_EQ(0, detached_collection->num_panels());
   2195   ASSERT_EQ(2, stack->num_panels());
   2196   ASSERT_EQ(1, panel_manager->num_stacks());
   2197   EXPECT_EQ(stack, panel1->stack());
   2198   EXPECT_EQ(stack, panel2->stack());
   2199 
   2200   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2201   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2202   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2203       panel2_initial_bounds, panel1_expected_bounds);
   2204   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2205   gfx::Rect panel2_old_bounds = panel2_expected_bounds;
   2206 
   2207   // Press on title-bar.
   2208   scoped_ptr<NativePanelTesting> panel2_testing(
   2209       CreateNativePanelTesting(panel2));
   2210   gfx::Point mouse_location(panel2->GetBounds().origin());
   2211   gfx::Point original_mouse_location = mouse_location;
   2212   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   2213 
   2214   // Drag P2 away from the bottom of P1 to trigger the unstacking.
   2215   // Expect that P1 and P2 get detached.
   2216   gfx::Vector2d drag_delta_to_unstack =
   2217       GetDragDeltaToUnstackFromBottom(panel2, panel1);
   2218   mouse_location = mouse_location + drag_delta_to_unstack;
   2219   panel2_testing->DragTitlebar(mouse_location);
   2220   ASSERT_EQ(2, detached_collection->num_panels());
   2221   ASSERT_TRUE(stack->num_panels() == 0);
   2222   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2223   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   2224   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2225   panel2_expected_bounds.Offset(drag_delta_to_unstack);
   2226   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2227 
   2228   // Drag P2 a bit closer to the bottom of P1 to trigger the stacking.
   2229   // Expect P1 and P2 get stacked together.
   2230   gfx::Vector2d drag_delta_to_stack =
   2231       GetDragDeltaToStackToBottom(panel2, panel1);
   2232   mouse_location = mouse_location + drag_delta_to_stack;
   2233   panel2_testing->DragTitlebar(mouse_location);
   2234   ASSERT_EQ(0, detached_collection->num_panels());
   2235   // Note that the empty stack might still exist until the drag ends.
   2236   ASSERT_GE(panel_manager->num_stacks(), 1);
   2237   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   2238   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   2239   EXPECT_EQ(panel1->stack(), panel2->stack());
   2240   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2241   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2242       panel2_initial_bounds, panel1_expected_bounds);
   2243   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2244 
   2245   // Drag P2 away from the bottom of P1 to trigger the unstacking again.
   2246   // Expect that P1 and P2 get detached.
   2247   drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1);
   2248   mouse_location = mouse_location + drag_delta_to_unstack;
   2249   panel2_testing->DragTitlebar(mouse_location);
   2250   ASSERT_EQ(2, detached_collection->num_panels());
   2251   ASSERT_TRUE(stack->num_panels() == 0);
   2252   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2253   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   2254   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2255   panel2_expected_bounds = panel2_old_bounds;
   2256   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
   2257   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2258 
   2259   // Finish the drag.
   2260   // Expect that the P1 and P2 stay detached.
   2261   panel2_testing->FinishDragTitlebar();
   2262   ASSERT_EQ(2, detached_collection->num_panels());
   2263   ASSERT_EQ(0, panel_manager->num_stacks());
   2264   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2265   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   2266   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2267   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2268 
   2269   panel_manager->CloseAll();
   2270 }
   2271 
   2272 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndCancel) {
   2273   PanelManager* panel_manager = PanelManager::GetInstance();
   2274   DetachedPanelCollection* detached_collection =
   2275       panel_manager->detached_collection();
   2276 
   2277   // Create 2 stacked panels.
   2278   StackedPanelCollection* stack = panel_manager->CreateStack();
   2279   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2280   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2281   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2282   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2283   ASSERT_EQ(0, detached_collection->num_panels());
   2284   ASSERT_EQ(2, stack->num_panels());
   2285   ASSERT_EQ(1, panel_manager->num_stacks());
   2286   EXPECT_EQ(stack, panel1->stack());
   2287   EXPECT_EQ(stack, panel2->stack());
   2288 
   2289   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2290   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2291   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2292       panel2_initial_bounds, panel1_expected_bounds);
   2293   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2294   gfx::Rect panel2_old_bounds = panel2->GetBounds();
   2295 
   2296   // Press on title-bar.
   2297   scoped_ptr<NativePanelTesting> panel2_testing(
   2298       CreateNativePanelTesting(panel2));
   2299   gfx::Point mouse_location(panel2->GetBounds().origin());
   2300   gfx::Point original_mouse_location = mouse_location;
   2301   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   2302 
   2303   // Drag P2 away from the bottom of P1 to trigger the unstacking.
   2304   // Expect that P1 and P2 get detached.
   2305   gfx::Vector2d drag_delta_to_unstack =
   2306       GetDragDeltaToUnstackFromBottom(panel2, panel1);
   2307   mouse_location = mouse_location + drag_delta_to_unstack;
   2308   panel2_testing->DragTitlebar(mouse_location);
   2309   ASSERT_EQ(2, detached_collection->num_panels());
   2310   ASSERT_TRUE(stack->num_panels() == 0);
   2311   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2312   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   2313   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2314   panel2_expected_bounds.Offset(drag_delta_to_unstack);
   2315   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2316 
   2317   // Cancel the drag.
   2318   // Expect that the P1 and P2 put back to the same stack.
   2319   panel2_testing->CancelDragTitlebar();
   2320   WaitForBoundsAnimationFinished(panel2);
   2321   ASSERT_EQ(0, detached_collection->num_panels());
   2322   ASSERT_EQ(1, panel_manager->num_stacks());
   2323   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
   2324   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
   2325   EXPECT_EQ(stack, panel1->stack());
   2326   EXPECT_EQ(stack, panel2->stack());
   2327   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2328   EXPECT_EQ(panel2_old_bounds, panel2->GetBounds());
   2329 
   2330   panel_manager->CloseAll();
   2331 }
   2332 
   2333 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
   2334                        UngroupBottomPanelInThreePanelStack) {
   2335   PanelManager* panel_manager = PanelManager::GetInstance();
   2336   DetachedPanelCollection* detached_collection =
   2337       panel_manager->detached_collection();
   2338 
   2339   // Create 3 stacked panels.
   2340   StackedPanelCollection* stack = panel_manager->CreateStack();
   2341   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2342   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2343   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2344   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2345   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
   2346   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
   2347   ASSERT_EQ(0, detached_collection->num_panels());
   2348   ASSERT_EQ(1, panel_manager->num_stacks());
   2349   ASSERT_EQ(3, stack->num_panels());
   2350   EXPECT_EQ(stack, panel1->stack());
   2351   EXPECT_EQ(stack, panel2->stack());
   2352   EXPECT_EQ(stack, panel3->stack());
   2353 
   2354   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2355   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2356   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2357       panel2_initial_bounds, panel1_expected_bounds);
   2358   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2359   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   2360       panel3_initial_bounds, panel2_expected_bounds);
   2361   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2362 
   2363   // Drag P3 away to unstack from P2 and P1.
   2364   // Expect that P1 and P2 are still in the stack while P3 gets detached.
   2365   gfx::Vector2d drag_delta_to_unstack =
   2366       GetDragDeltaToUnstackFromBottom(panel3, panel2);
   2367   DragPanelByDelta(panel3, drag_delta_to_unstack);
   2368   ASSERT_EQ(1, detached_collection->num_panels());
   2369   ASSERT_EQ(1, panel_manager->num_stacks());
   2370   ASSERT_EQ(2, stack->num_panels());
   2371   EXPECT_EQ(stack, panel1->stack());
   2372   EXPECT_EQ(stack, panel2->stack());
   2373   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
   2374 
   2375   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2376   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2377   panel3_expected_bounds.Offset(drag_delta_to_unstack);
   2378   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2379 
   2380   panel_manager->CloseAll();
   2381 }
   2382 
   2383 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
   2384                        UngroupMiddlePanelInThreePanelStack) {
   2385   PanelManager* panel_manager = PanelManager::GetInstance();
   2386   DetachedPanelCollection* detached_collection =
   2387       panel_manager->detached_collection();
   2388 
   2389   // Create 3 stacked panels.
   2390   StackedPanelCollection* stack = panel_manager->CreateStack();
   2391   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2392   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2393   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2394   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2395   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
   2396   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
   2397   ASSERT_EQ(0, detached_collection->num_panels());
   2398   ASSERT_EQ(1, panel_manager->num_stacks());
   2399   ASSERT_EQ(3, stack->num_panels());
   2400   EXPECT_EQ(stack, panel1->stack());
   2401   EXPECT_EQ(stack, panel2->stack());
   2402   EXPECT_EQ(stack, panel3->stack());
   2403 
   2404   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2405   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2406   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2407       panel2_initial_bounds, panel1_expected_bounds);
   2408   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2409   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   2410       panel3_initial_bounds, panel2_expected_bounds);
   2411   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2412 
   2413   // Drag P2 (together with P3) away to unstack from P1.
   2414   // Expect that P2 and P3 are still in a stack while P1 gets detached.
   2415   gfx::Vector2d drag_delta_to_unstack =
   2416       GetDragDeltaToUnstackFromBottom(panel2, panel1);
   2417   DragPanelByDelta(panel2, drag_delta_to_unstack);
   2418   ASSERT_EQ(1, detached_collection->num_panels());
   2419   ASSERT_EQ(1, panel_manager->num_stacks());
   2420   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   2421   ASSERT_EQ(2, final_stack->num_panels());
   2422   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2423   EXPECT_EQ(final_stack, panel2->stack());
   2424   EXPECT_EQ(final_stack, panel3->stack());
   2425 
   2426   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2427   panel2_expected_bounds.Offset(drag_delta_to_unstack);
   2428   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2429   panel3_expected_bounds.Offset(drag_delta_to_unstack);
   2430   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2431 
   2432   panel_manager->CloseAll();
   2433 }
   2434 
   2435 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
   2436                        UngroupThirdPanelInFourPanelStack) {
   2437   PanelManager* panel_manager = PanelManager::GetInstance();
   2438   DetachedPanelCollection* detached_collection =
   2439       panel_manager->detached_collection();
   2440 
   2441   // Create 4 stacked panels.
   2442   StackedPanelCollection* stack = panel_manager->CreateStack();
   2443   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 120, 200, 100);
   2444   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2445   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2446   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2447   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
   2448   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
   2449   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 120, 110);
   2450   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack);
   2451   ASSERT_EQ(0, detached_collection->num_panels());
   2452   ASSERT_EQ(1, panel_manager->num_stacks());
   2453   ASSERT_EQ(4, stack->num_panels());
   2454   EXPECT_EQ(stack, panel1->stack());
   2455   EXPECT_EQ(stack, panel2->stack());
   2456   EXPECT_EQ(stack, panel3->stack());
   2457   EXPECT_EQ(stack, panel4->stack());
   2458 
   2459   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2460   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2461   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2462       panel2_initial_bounds, panel1_expected_bounds);
   2463   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2464   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   2465       panel3_initial_bounds, panel2_expected_bounds);
   2466   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2467   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
   2468       panel4_initial_bounds, panel3_expected_bounds);
   2469   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2470 
   2471   // Drag P3 (together with P4) away to unstack from P2.
   2472   // Expect that P1 and P2 are in one stack while P3 and P4 are in different
   2473   // stack.
   2474   gfx::Vector2d drag_delta_to_unstack =
   2475       GetDragDeltaToUnstackFromBottom(panel3, panel2);
   2476   DragPanelByDelta(panel3, drag_delta_to_unstack);
   2477   ASSERT_EQ(0, detached_collection->num_panels());
   2478   ASSERT_EQ(2, panel_manager->num_stacks());
   2479   StackedPanelCollection* final_stack1 = panel_manager->stacks().front();
   2480   ASSERT_EQ(2, final_stack1->num_panels());
   2481   StackedPanelCollection* final_stack2 = panel_manager->stacks().back();
   2482   ASSERT_EQ(2, final_stack2->num_panels());
   2483   EXPECT_EQ(panel1->stack(), panel2->stack());
   2484   EXPECT_EQ(panel3->stack(), panel4->stack());
   2485 
   2486   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2487   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2488   panel3_expected_bounds.Offset(drag_delta_to_unstack);
   2489   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2490   panel4_expected_bounds.Offset(drag_delta_to_unstack);
   2491   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
   2492 
   2493   panel_manager->CloseAll();
   2494 }
   2495 
   2496 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndGroup) {
   2497   PanelManager* panel_manager = PanelManager::GetInstance();
   2498   DetachedPanelCollection* detached_collection =
   2499       panel_manager->detached_collection();
   2500 
   2501   // Create 2 stacked panels.
   2502   StackedPanelCollection* stack = panel_manager->CreateStack();
   2503   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2504   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2505   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2506   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2507   ASSERT_EQ(0, detached_collection->num_panels());
   2508   ASSERT_EQ(2, stack->num_panels());
   2509   ASSERT_EQ(1, panel_manager->num_stacks());
   2510   EXPECT_EQ(stack, panel1->stack());
   2511   EXPECT_EQ(stack, panel2->stack());
   2512 
   2513   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2514   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2515   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2516       panel2_initial_bounds, panel1_expected_bounds);
   2517   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2518 
   2519   // Create 1 detached panel.
   2520   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
   2521   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   2522   ASSERT_EQ(1, detached_collection->num_panels());
   2523   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2524   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2525 
   2526   // Drag P2 to the bottom edge of P3 to trigger both unstacking and stacking.
   2527   // Expect that P3 and P2 are stacked together while P1 gets detached.
   2528   gfx::Vector2d drag_delta_to_unstack_and_stack =
   2529       GetDragDeltaToStackToBottom(panel2, panel3);
   2530   DragPanelByDelta(panel2, drag_delta_to_unstack_and_stack);
   2531   WaitForBoundsAnimationFinished(panel2);
   2532   ASSERT_EQ(1, detached_collection->num_panels());
   2533   ASSERT_EQ(1, panel_manager->num_stacks());
   2534   StackedPanelCollection* final_stack = panel_manager->stacks().front();
   2535   ASSERT_EQ(2, final_stack->num_panels());
   2536   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2537   EXPECT_EQ(final_stack, panel2->stack());
   2538   EXPECT_EQ(final_stack, panel3->stack());
   2539 
   2540   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2541   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2542       panel2_initial_bounds, panel3_expected_bounds);
   2543   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2544   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2545 
   2546   panel_manager->CloseAll();
   2547 }
   2548 
   2549 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndAttach) {
   2550   PanelManager* panel_manager = PanelManager::GetInstance();
   2551   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   2552   DetachedPanelCollection* detached_collection =
   2553       panel_manager->detached_collection();
   2554 
   2555   // Create 2 stacked panels.
   2556   StackedPanelCollection* stack = panel_manager->CreateStack();
   2557   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
   2558   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2559   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2560   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2561   ASSERT_EQ(0, docked_collection->num_panels());
   2562   ASSERT_EQ(0, detached_collection->num_panels());
   2563   ASSERT_EQ(2, stack->num_panels());
   2564   ASSERT_EQ(1, panel_manager->num_stacks());
   2565   EXPECT_EQ(stack, panel1->stack());
   2566   EXPECT_EQ(stack, panel2->stack());
   2567 
   2568   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2569   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2570   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2571       panel2_initial_bounds, panel1_expected_bounds);
   2572   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2573 
   2574   // Drag P2 close to the bottom of the work area to trigger both unstacking and
   2575   // docking for P2.
   2576   // Expect that P2 gets docked while P2 gets detached.
   2577   gfx::Vector2d drag_delta_to_unstack_and_attach = GetDragDeltaToAttach(panel2);
   2578   DragPanelByDelta(panel2, drag_delta_to_unstack_and_attach);
   2579   WaitForBoundsAnimationFinished(panel2);
   2580   ASSERT_EQ(1, docked_collection->num_panels());
   2581   ASSERT_EQ(1, detached_collection->num_panels());
   2582   ASSERT_EQ(0, panel_manager->num_stacks());
   2583   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2584   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
   2585 
   2586   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2587   panel2_expected_bounds.set_x(docked_collection->StartingRightPosition() -
   2588       panel2_expected_bounds.width());
   2589   panel2_expected_bounds.set_y(docked_collection->work_area().bottom() -
   2590       panel2_expected_bounds.height());
   2591   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2592 
   2593   panel_manager->CloseAll();
   2594 }
   2595 
   2596 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelLeft) {
   2597   PanelManager* panel_manager = PanelManager::GetInstance();
   2598   DetachedPanelCollection* detached_collection =
   2599       panel_manager->detached_collection();
   2600 
   2601   // Create 2 detached panels.
   2602   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200);
   2603   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
   2604   gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250);
   2605   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
   2606   ASSERT_EQ(2, detached_collection->num_panels());
   2607 
   2608   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2609   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2610   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
   2611   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2612 
   2613   // Press on title-bar.
   2614   scoped_ptr<NativePanelTesting> panel2_testing(
   2615       CreateNativePanelTesting(panel2));
   2616   gfx::Point mouse_location(panel2->GetBounds().origin());
   2617   gfx::Point original_mouse_location = mouse_location;
   2618   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   2619 
   2620   // Drag P2 close to the left of P1 to trigger the snapping.
   2621   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
   2622   mouse_location = mouse_location + drag_delta_to_snap;
   2623   panel2_testing->DragTitlebar(mouse_location);
   2624   ASSERT_EQ(2, detached_collection->num_panels());
   2625   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2626   panel2_expected_bounds.Offset(drag_delta_to_snap);
   2627   panel2_expected_bounds.set_x(
   2628       panel1_expected_bounds.x() - panel2_expected_bounds.width());
   2629   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2630 
   2631   // Drag P2 a bit away from the left of P1 to trigger the unsnapping.
   2632   gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1);
   2633   mouse_location = mouse_location + drag_delta_to_unsnap;
   2634   panel2_testing->DragTitlebar(mouse_location);
   2635   ASSERT_EQ(2, detached_collection->num_panels());
   2636   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2637   panel2_expected_bounds = panel2_initial_bounds;
   2638   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
   2639   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2640 
   2641   // Drag P2 close to the left of P1 to trigger the snapping again.
   2642   drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
   2643   mouse_location = mouse_location + drag_delta_to_snap;
   2644   panel2_testing->DragTitlebar(mouse_location);
   2645   ASSERT_EQ(2, detached_collection->num_panels());
   2646   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2647   panel2_expected_bounds.Offset(drag_delta_to_snap);
   2648   panel2_expected_bounds.set_x(
   2649       panel1_expected_bounds.x() - panel2_expected_bounds.width());
   2650   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2651 
   2652   // Drag P2 vertically with a little bit of horizontal movement should still
   2653   // keep the snapping.
   2654   gfx::Vector2d drag_delta_almost_vertically(2, 20);
   2655   mouse_location = mouse_location + drag_delta_almost_vertically;
   2656   panel2_testing->DragTitlebar(mouse_location);
   2657   ASSERT_EQ(2, detached_collection->num_panels());
   2658   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2659   panel2_expected_bounds.set_y(
   2660       panel2_expected_bounds.y() + drag_delta_almost_vertically.y());
   2661   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2662 
   2663   // Finish the drag.
   2664   panel2_testing->FinishDragTitlebar();
   2665   ASSERT_EQ(2, detached_collection->num_panels());
   2666   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2667   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2668 
   2669   panel_manager->CloseAll();
   2670 }
   2671 
   2672 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelRight) {
   2673   PanelManager* panel_manager = PanelManager::GetInstance();
   2674   DetachedPanelCollection* detached_collection =
   2675       panel_manager->detached_collection();
   2676 
   2677   // Create 2 detached panels.
   2678   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 200, 100, 200);
   2679   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
   2680   gfx::Rect panel2_initial_bounds = gfx::Rect(300, 100, 200, 250);
   2681   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
   2682   ASSERT_EQ(2, detached_collection->num_panels());
   2683 
   2684   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2685   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2686   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
   2687   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2688 
   2689   // Press on title-bar.
   2690   scoped_ptr<NativePanelTesting> panel2_testing(
   2691       CreateNativePanelTesting(panel2));
   2692   gfx::Point mouse_location(panel2->GetBounds().origin());
   2693   gfx::Point original_mouse_location = mouse_location;
   2694   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   2695 
   2696   // Drag P1 close to the right of P2 to trigger the snapping.
   2697   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1);
   2698   mouse_location = mouse_location + drag_delta_to_snap;
   2699   panel2_testing->DragTitlebar(mouse_location);
   2700   ASSERT_EQ(2, detached_collection->num_panels());
   2701   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2702   panel2_expected_bounds.Offset(drag_delta_to_snap);
   2703   panel2_expected_bounds.set_x(panel1_expected_bounds.right());
   2704   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2705 
   2706   // Drag P2 a bit away from the right of P1 to trigger the unsnapping.
   2707   gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1);
   2708   mouse_location = mouse_location + drag_delta_to_unsnap;
   2709   panel2_testing->DragTitlebar(mouse_location);
   2710   ASSERT_EQ(2, detached_collection->num_panels());
   2711   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2712   panel2_expected_bounds = panel2_initial_bounds;
   2713   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
   2714   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2715 
   2716   // Drag P2 close to the right of P1 to trigger the snapping again.
   2717   drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1);
   2718   mouse_location = mouse_location + drag_delta_to_snap;
   2719   panel2_testing->DragTitlebar(mouse_location);
   2720   ASSERT_EQ(2, detached_collection->num_panels());
   2721   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2722   panel2_expected_bounds.Offset(drag_delta_to_snap);
   2723   panel2_expected_bounds.set_x(panel1_expected_bounds.right());
   2724   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2725 
   2726   // Drag P2 vertically with a little bit of horizontal movement should still
   2727   // keep the snapping.
   2728   gfx::Vector2d drag_delta_almost_vertically(2, -20);
   2729   mouse_location = mouse_location + drag_delta_almost_vertically;
   2730   panel2_testing->DragTitlebar(mouse_location);
   2731   ASSERT_EQ(2, detached_collection->num_panels());
   2732   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2733   panel2_expected_bounds.set_y(
   2734       panel2_expected_bounds.y() + drag_delta_almost_vertically.y());
   2735   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2736 
   2737   // Finish the drag.
   2738   panel2_testing->FinishDragTitlebar();
   2739   ASSERT_EQ(2, detached_collection->num_panels());
   2740   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2741   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2742 
   2743   panel_manager->CloseAll();
   2744 }
   2745 
   2746 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapAndCancel) {
   2747   PanelManager* panel_manager = PanelManager::GetInstance();
   2748   DetachedPanelCollection* detached_collection =
   2749       panel_manager->detached_collection();
   2750 
   2751   // Create 2 detached panels.
   2752   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200);
   2753   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
   2754   gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250);
   2755   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
   2756   ASSERT_EQ(2, detached_collection->num_panels());
   2757 
   2758   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2759   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2760   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
   2761   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2762 
   2763   // Press on title-bar.
   2764   scoped_ptr<NativePanelTesting> panel2_testing(
   2765       CreateNativePanelTesting(panel2));
   2766   gfx::Point mouse_location(panel2->GetBounds().origin());
   2767   gfx::Point original_mouse_location = mouse_location;
   2768   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
   2769 
   2770   // Drag P2 close to the left of P1 to trigger the snapping.
   2771   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
   2772   mouse_location = mouse_location + drag_delta_to_snap;
   2773   panel2_testing->DragTitlebar(mouse_location);
   2774   ASSERT_EQ(2, detached_collection->num_panels());
   2775   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2776   panel2_expected_bounds.Offset(drag_delta_to_snap);
   2777   panel2_expected_bounds.set_x(
   2778       panel1_expected_bounds.x() - panel2_expected_bounds.width());
   2779   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2780 
   2781   // Cancel the drag.
   2782   panel2_testing->CancelDragTitlebar();
   2783   ASSERT_EQ(2, detached_collection->num_panels());
   2784   EXPECT_EQ(panel1_initial_bounds, panel1->GetBounds());
   2785   EXPECT_EQ(panel2_initial_bounds, panel2->GetBounds());
   2786 
   2787   panel_manager->CloseAll();
   2788 }
   2789 
   2790 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackLeft) {
   2791   PanelManager* panel_manager = PanelManager::GetInstance();
   2792   DetachedPanelCollection* detached_collection =
   2793       panel_manager->detached_collection();
   2794 
   2795   // Create 2 stacked panels.
   2796   StackedPanelCollection* stack = panel_manager->CreateStack();
   2797   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
   2798   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2799   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2800   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2801   ASSERT_EQ(0, detached_collection->num_panels());
   2802   ASSERT_EQ(1, panel_manager->num_stacks());
   2803   ASSERT_EQ(2, stack->num_panels());
   2804   EXPECT_EQ(stack, panel1->collection());
   2805   EXPECT_EQ(stack, panel2->collection());
   2806 
   2807   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2808   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2809   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2810       panel2_initial_bounds, panel1_expected_bounds);
   2811   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2812 
   2813   // Create 1 detached panel.
   2814   gfx::Rect panel3_initial_bounds = gfx::Rect(100, 200, 100, 100);
   2815   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   2816   ASSERT_EQ(1, detached_collection->num_panels());
   2817   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
   2818   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2819   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2820 
   2821   // Drag P3 close to the left of the stack of P1 and P2 to trigger the
   2822   // snapping.
   2823   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel3, panel1);
   2824   DragPanelByDelta(panel3, drag_delta_to_snap);
   2825   ASSERT_EQ(1, detached_collection->num_panels());
   2826   ASSERT_EQ(1, panel_manager->num_stacks());
   2827   ASSERT_EQ(2, stack->num_panels());
   2828   EXPECT_EQ(stack, panel1->collection());
   2829   EXPECT_EQ(stack, panel2->collection());
   2830   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
   2831   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2832   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2833   panel3_expected_bounds.Offset(drag_delta_to_snap);
   2834   panel3_expected_bounds.set_x(
   2835       panel1_expected_bounds.x() - panel3_expected_bounds.width());
   2836   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2837 
   2838   panel_manager->CloseAll();
   2839 }
   2840 
   2841 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackRight) {
   2842   PanelManager* panel_manager = PanelManager::GetInstance();
   2843   DetachedPanelCollection* detached_collection =
   2844       panel_manager->detached_collection();
   2845 
   2846   // Create 2 stacked panels.
   2847   StackedPanelCollection* stack = panel_manager->CreateStack();
   2848   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
   2849   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2850   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2851   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2852   ASSERT_EQ(0, detached_collection->num_panels());
   2853   ASSERT_EQ(1, panel_manager->num_stacks());
   2854   ASSERT_EQ(2, stack->num_panels());
   2855   EXPECT_EQ(stack, panel1->collection());
   2856   EXPECT_EQ(stack, panel2->collection());
   2857 
   2858   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2859   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2860   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2861       panel2_initial_bounds, panel1_expected_bounds);
   2862   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2863 
   2864   // Create 1 detached panel.
   2865   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
   2866   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
   2867   ASSERT_EQ(1, detached_collection->num_panels());
   2868   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
   2869   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
   2870   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2871 
   2872   // Drag P3 close to the right of the stack of P1 and P2 to trigger the
   2873   // snapping.
   2874   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel3, panel1);
   2875   DragPanelByDelta(panel3, drag_delta_to_snap);
   2876   ASSERT_EQ(1, detached_collection->num_panels());
   2877   ASSERT_EQ(1, panel_manager->num_stacks());
   2878   ASSERT_EQ(2, stack->num_panels());
   2879   EXPECT_EQ(stack, panel1->collection());
   2880   EXPECT_EQ(stack, panel2->collection());
   2881   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
   2882   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2883   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2884   panel3_expected_bounds.Offset(drag_delta_to_snap);
   2885   panel3_expected_bounds.set_x(panel1_expected_bounds.right());
   2886   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2887 
   2888   panel_manager->CloseAll();
   2889 }
   2890 
   2891 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAndSnap) {
   2892   PanelManager* panel_manager = PanelManager::GetInstance();
   2893   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   2894   DetachedPanelCollection* detached_collection =
   2895       panel_manager->detached_collection();
   2896 
   2897   // Create 1 detached panel.
   2898   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 100, 100));
   2899   ASSERT_EQ(0, docked_collection->num_panels());
   2900   ASSERT_EQ(1, detached_collection->num_panels());
   2901   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2902   gfx::Rect panel1_bounds = panel1->GetBounds();
   2903 
   2904   // Create 1 docked panel.
   2905   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 150, 150));
   2906   ASSERT_EQ(1, docked_collection->num_panels());
   2907   ASSERT_EQ(1, detached_collection->num_panels());
   2908   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
   2909   gfx::Rect panel2_bounds = panel2->GetBounds();
   2910 
   2911   // Drag P2 close to the right of P1 to trigger both detaching and snapping.
   2912   gfx::Vector2d drag_delta_to_detach_and_snap =
   2913       GetDragDeltaToSnapToRight(panel2, panel1);
   2914   DragPanelByDelta(panel2, drag_delta_to_detach_and_snap);
   2915   ASSERT_EQ(0, docked_collection->num_panels());
   2916   ASSERT_EQ(2, detached_collection->num_panels());
   2917   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
   2918   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
   2919   EXPECT_EQ(panel1_bounds, panel1->GetBounds());
   2920   panel2_bounds.Offset(drag_delta_to_detach_and_snap);
   2921   panel2_bounds.set_x(panel1_bounds.right());
   2922   EXPECT_EQ(panel2_bounds, panel2->GetBounds());
   2923 
   2924   panel_manager->CloseAll();
   2925 }
   2926 
   2927 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTopStackedPanel) {
   2928   PanelManager* panel_manager = PanelManager::GetInstance();
   2929 
   2930   // Create 3 stacked panels.
   2931   StackedPanelCollection* stack = panel_manager->CreateStack();
   2932   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
   2933   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   2934   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   2935   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   2936   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 150, 200);
   2937   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
   2938   ASSERT_EQ(3, stack->num_panels());
   2939   ASSERT_EQ(1, panel_manager->num_stacks());
   2940   EXPECT_EQ(stack, panel1->collection());
   2941   EXPECT_EQ(stack, panel2->collection());
   2942   EXPECT_EQ(stack, panel3->collection());
   2943 
   2944   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   2945   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2946   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   2947       panel2_initial_bounds, panel1_expected_bounds);
   2948   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2949   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
   2950       panel3_initial_bounds, panel2_expected_bounds);
   2951   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2952 
   2953   // Drag the top panel by a delta.
   2954   // Expect all panels are still in the same stack and they are all moved by the
   2955   // same delta.
   2956   gfx::Vector2d drag_delta(-50, -20);
   2957   DragPanelByDelta(panel1, drag_delta);
   2958   ASSERT_EQ(3, stack->num_panels());
   2959   ASSERT_EQ(1, panel_manager->num_stacks());
   2960   EXPECT_EQ(stack, panel1->collection());
   2961   EXPECT_EQ(stack, panel2->collection());
   2962   EXPECT_EQ(stack, panel3->collection());
   2963 
   2964   panel1_expected_bounds.Offset(drag_delta);
   2965   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   2966   panel2_expected_bounds.Offset(drag_delta);
   2967   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   2968   panel3_expected_bounds.Offset(drag_delta);
   2969   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
   2970 
   2971   panel_manager->CloseAll();
   2972 }
   2973 
   2974 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapDetachedPanelToScreenEdge) {
   2975   PanelManager* panel_manager = PanelManager::GetInstance();
   2976   int small_distance =
   2977       PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2;
   2978 
   2979   // Setup 2 displays with secondary display on the right side of primary
   2980   // display.
   2981   gfx::Rect primary_display_area(0, 0, 400, 600);
   2982   gfx::Rect primary_work_area(0, 0, 400, 560);
   2983   mock_display_settings_provider()->SetPrimaryDisplay(
   2984       primary_display_area, primary_work_area);
   2985   gfx::Rect secondary_display_area(400, 100, 400, 500);
   2986   gfx::Rect secondary_work_area(400, 140, 400, 460);
   2987   mock_display_settings_provider()->SetSecondaryDisplay(
   2988       secondary_display_area, secondary_work_area);
   2989 
   2990   // Create one detached panel on the primary display.
   2991   gfx::Rect initial_bounds = gfx::Rect(100, 100, 200, 150);
   2992   Panel* panel = CreateDetachedPanel("1", initial_bounds);
   2993   gfx::Rect expected_bounds(initial_bounds);
   2994   EXPECT_EQ(expected_bounds, panel->GetBounds());
   2995 
   2996   // Drag the panel close to the right edge of the primary display.
   2997   // Expect that the panel should snap to the right edge.
   2998   gfx::Point drag_to_location(
   2999       primary_work_area.right() - small_distance - panel->GetBounds().width(),
   3000       panel->GetBounds().y());
   3001   DragPanelToMouseLocation(panel, drag_to_location);
   3002   expected_bounds.set_x(primary_work_area.right() - panel->GetBounds().width());
   3003   EXPECT_EQ(expected_bounds, panel->GetBounds());
   3004 
   3005   // Drag the panel close to the top-left corner of the primary display.
   3006   // Expect that the panel should snap to the top-left corner.
   3007   drag_to_location = gfx::Point(
   3008       primary_work_area.x() + small_distance,
   3009       primary_work_area.y() - small_distance);
   3010   DragPanelToMouseLocation(panel, drag_to_location);
   3011   expected_bounds.set_origin(primary_work_area.origin());
   3012   EXPECT_EQ(expected_bounds, panel->GetBounds());
   3013 
   3014   // Drag the panel close to the top-right corner of the secondary display.
   3015   // Expect that the panel should snap to the top-right corner.
   3016   drag_to_location = gfx::Point(
   3017       secondary_work_area.right() - small_distance - panel->GetBounds().width(),
   3018       secondary_work_area.y() + small_distance);
   3019   DragPanelToMouseLocation(panel, drag_to_location);
   3020   expected_bounds.set_x(
   3021       secondary_work_area.right() - panel->GetBounds().width());
   3022   expected_bounds.set_y(secondary_work_area.y());
   3023   EXPECT_EQ(expected_bounds, panel->GetBounds());
   3024 
   3025   panel_manager->CloseAll();
   3026 }
   3027 
   3028 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapStackedPanelToScreenEdge) {
   3029   PanelManager* panel_manager = PanelManager::GetInstance();
   3030   int small_distance =
   3031       PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2;
   3032 
   3033   // Setup 2 displays with secondary display on the right side of primary
   3034   // display.
   3035   gfx::Rect primary_display_area(0, 0, 400, 600);
   3036   gfx::Rect primary_work_area(0, 0, 400, 560);
   3037   mock_display_settings_provider()->SetPrimaryDisplay(
   3038       primary_display_area, primary_work_area);
   3039   gfx::Rect secondary_display_area(400, 100, 400, 500);
   3040   gfx::Rect secondary_work_area(400, 140, 400, 460);
   3041   mock_display_settings_provider()->SetSecondaryDisplay(
   3042       secondary_display_area, secondary_work_area);
   3043 
   3044   // Create 2 stacked panels on the primary display.
   3045   StackedPanelCollection* stack = panel_manager->CreateStack();
   3046   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
   3047   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
   3048   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
   3049   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
   3050 
   3051   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
   3052   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   3053   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
   3054       panel2_initial_bounds, panel1_expected_bounds);
   3055   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   3056 
   3057   // Drag the stack close to the left edge of the primary display.
   3058   // Expect that the stack should snap to the left edge.
   3059   gfx::Point drag_to_location(
   3060       primary_work_area.x() + small_distance, panel1->GetBounds().y());
   3061   DragPanelToMouseLocation(panel1, drag_to_location);
   3062 
   3063   panel1_expected_bounds.set_x(primary_work_area.x());
   3064   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   3065   panel2_expected_bounds.set_x(primary_work_area.x());
   3066   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   3067 
   3068   // Drag the stack close to the bottom-right corner of the primary display.
   3069   // Expect that the stack should snap to the bottom-right corner.
   3070   drag_to_location = gfx::Point(
   3071       primary_work_area.right() + small_distance - panel1->GetBounds().width(),
   3072       primary_work_area.bottom() - small_distance -
   3073           panel1->GetBounds().height() - panel2->GetBounds().height());
   3074   DragPanelToMouseLocation(panel1, drag_to_location);
   3075 
   3076   int expected_x = primary_work_area.right() - panel1->GetBounds().width();
   3077   panel1_expected_bounds.set_x(expected_x);
   3078   panel1_expected_bounds.set_y(primary_work_area.bottom() -
   3079       panel1->GetBounds().height() - panel2->GetBounds().height());
   3080   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   3081   panel2_expected_bounds.set_x(expected_x);
   3082   panel2_expected_bounds.set_y(primary_work_area.bottom() -
   3083       panel2->GetBounds().height());
   3084   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   3085 
   3086   // Drag the stack close to the top-left corner of the secondary display.
   3087   // Expect that the stack should snap to the top-left corner.
   3088   drag_to_location = gfx::Point(
   3089       secondary_work_area.x() + small_distance,
   3090       secondary_work_area.y() + small_distance);
   3091   DragPanelToMouseLocation(panel1, drag_to_location);
   3092 
   3093   expected_x = secondary_work_area.x();
   3094   panel1_expected_bounds.set_x(expected_x);
   3095   panel1_expected_bounds.set_y(secondary_work_area.y());
   3096   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
   3097   panel2_expected_bounds.set_x(expected_x);
   3098   panel2_expected_bounds.set_y(panel1_expected_bounds.bottom());
   3099   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
   3100 
   3101   panel_manager->CloseAll();
   3102 }
   3103