Home | History | Annotate | Download | only in workspace
      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 "ash/wm/workspace/workspace_event_handler.h"
      6 
      7 #include "ash/screen_util.h"
      8 #include "ash/shell.h"
      9 #include "ash/test/ash_test_base.h"
     10 #include "ash/wm/window_state.h"
     11 #include "ash/wm/window_util.h"
     12 #include "ash/wm/wm_event.h"
     13 #include "ash/wm/workspace_controller.h"
     14 #include "ash/wm/workspace_controller_test_helper.h"
     15 #include "ui/aura/client/aura_constants.h"
     16 #include "ui/aura/test/test_window_delegate.h"
     17 #include "ui/aura/window.h"
     18 #include "ui/aura/window_tree_host.h"
     19 #include "ui/base/hit_test.h"
     20 #include "ui/events/event_processor.h"
     21 #include "ui/events/test/event_generator.h"
     22 #include "ui/gfx/screen.h"
     23 #include "ui/wm/core/window_util.h"
     24 #include "ui/wm/public/window_move_client.h"
     25 
     26 #if defined(OS_WIN)
     27 #include "base/win/windows_version.h"
     28 #endif
     29 
     30 namespace ash {
     31 
     32 class WorkspaceEventHandlerTest : public test::AshTestBase {
     33  public:
     34   WorkspaceEventHandlerTest() {}
     35   virtual ~WorkspaceEventHandlerTest() {}
     36 
     37  protected:
     38   aura::Window* CreateTestWindow(aura::WindowDelegate* delegate,
     39                                  const gfx::Rect& bounds) {
     40     aura::Window* window = new aura::Window(delegate);
     41     window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
     42     window->Init(aura::WINDOW_LAYER_TEXTURED);
     43     ParentWindowInPrimaryRootWindow(window);
     44     window->SetBounds(bounds);
     45     window->Show();
     46     return window;
     47   }
     48 
     49  private:
     50   DISALLOW_COPY_AND_ASSIGN(WorkspaceEventHandlerTest);
     51 };
     52 
     53 // Keeps track of the properties changed of a particular window.
     54 class WindowPropertyObserver : public aura::WindowObserver {
     55  public:
     56   explicit WindowPropertyObserver(aura::Window* window)
     57       : window_(window) {
     58     window->AddObserver(this);
     59   }
     60 
     61   virtual ~WindowPropertyObserver() {
     62     window_->RemoveObserver(this);
     63   }
     64 
     65   bool DidPropertyChange(const void* property) const {
     66     return std::find(properties_changed_.begin(),
     67                      properties_changed_.end(),
     68                      property) != properties_changed_.end();
     69   }
     70 
     71  private:
     72   virtual void OnWindowPropertyChanged(aura::Window* window,
     73                                        const void* key,
     74                                        intptr_t old) OVERRIDE {
     75     properties_changed_.push_back(key);
     76   }
     77 
     78   aura::Window* window_;
     79   std::vector<const void*> properties_changed_;
     80 
     81   DISALLOW_COPY_AND_ASSIGN(WindowPropertyObserver);
     82 };
     83 
     84 TEST_F(WorkspaceEventHandlerTest, DoubleClickSingleAxisResizeEdge) {
     85   // Double clicking the vertical resize edge of a window should maximize it
     86   // vertically.
     87   gfx::Rect restored_bounds(10, 10, 50, 50);
     88   aura::test::TestWindowDelegate delegate;
     89   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, restored_bounds));
     90 
     91   wm::ActivateWindow(window.get());
     92 
     93   gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
     94       window.get()).work_area();
     95 
     96   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
     97                                      window.get());
     98 
     99   // Double-click the top resize edge.
    100   delegate.set_window_component(HTTOP);
    101   // On X a double click actually generates a drag between each press/release.
    102   // Explicitly trigger this path since we had bugs in dealing with it
    103   // correctly.
    104   generator.PressLeftButton();
    105   generator.ReleaseLeftButton();
    106   generator.set_flags(ui::EF_IS_DOUBLE_CLICK);
    107   generator.PressLeftButton();
    108   generator.MoveMouseTo(generator.current_location(), 1);
    109   generator.ReleaseLeftButton();
    110   gfx::Rect bounds_in_screen = window->GetBoundsInScreen();
    111   EXPECT_EQ(restored_bounds.x(), bounds_in_screen.x());
    112   EXPECT_EQ(restored_bounds.width(), bounds_in_screen.width());
    113   EXPECT_EQ(work_area.y(), bounds_in_screen.y());
    114   EXPECT_EQ(work_area.height(), bounds_in_screen.height());
    115 
    116   wm::WindowState* window_state = wm::GetWindowState(window.get());
    117   // Single-axis maximization is not considered real maximization.
    118   EXPECT_FALSE(window_state->IsMaximized());
    119 
    120   // Restore.
    121   generator.DoubleClickLeftButton();
    122   bounds_in_screen = window->GetBoundsInScreen();
    123   EXPECT_EQ(restored_bounds.ToString(), bounds_in_screen.ToString());
    124   // Note that it should not even be restored at this point, it should have
    125   // also cleared the restore rectangle.
    126   EXPECT_FALSE(window_state->HasRestoreBounds());
    127 
    128   // Double clicking the left resize edge should maximize horizontally.
    129   delegate.set_window_component(HTLEFT);
    130   generator.DoubleClickLeftButton();
    131   bounds_in_screen = window->GetBoundsInScreen();
    132   EXPECT_EQ(restored_bounds.y(), bounds_in_screen.y());
    133   EXPECT_EQ(restored_bounds.height(), bounds_in_screen.height());
    134   EXPECT_EQ(work_area.x(), bounds_in_screen.x());
    135   EXPECT_EQ(work_area.width(), bounds_in_screen.width());
    136   // Single-axis maximization is not considered real maximization.
    137   EXPECT_FALSE(window_state->IsMaximized());
    138 
    139   // Restore.
    140   generator.DoubleClickLeftButton();
    141   EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
    142 
    143 #if defined(OS_WIN)
    144   // Multi display test does not run on Win8 bot. crbug.com/247427.
    145   if (!SupportsMultipleDisplays())
    146     return;
    147 #endif
    148 
    149   // Verify the double clicking the resize edge works on 2nd display too.
    150   UpdateDisplay("200x200,400x300");
    151   gfx::Rect work_area2 = ScreenUtil::GetSecondaryDisplay().work_area();
    152   restored_bounds.SetRect(220, 20, 50, 50);
    153   window->SetBoundsInScreen(restored_bounds, ScreenUtil::GetSecondaryDisplay());
    154   aura::Window* second_root = Shell::GetAllRootWindows()[1];
    155   EXPECT_EQ(second_root, window->GetRootWindow());
    156   ui::test::EventGenerator generator2(second_root, window.get());
    157 
    158   // Y-axis maximization.
    159   delegate.set_window_component(HTTOP);
    160   generator2.PressLeftButton();
    161   generator2.ReleaseLeftButton();
    162   generator2.set_flags(ui::EF_IS_DOUBLE_CLICK);
    163   generator2.PressLeftButton();
    164   generator2.MoveMouseTo(generator.current_location(), 1);
    165   generator2.ReleaseLeftButton();
    166   generator.DoubleClickLeftButton();
    167   bounds_in_screen = window->GetBoundsInScreen();
    168   EXPECT_EQ(restored_bounds.x(), bounds_in_screen.x());
    169   EXPECT_EQ(restored_bounds.width(), bounds_in_screen.width());
    170   EXPECT_EQ(work_area2.y(), bounds_in_screen.y());
    171   EXPECT_EQ(work_area2.height(), bounds_in_screen.height());
    172   EXPECT_FALSE(window_state->IsMaximized());
    173 
    174   // Restore.
    175   generator2.DoubleClickLeftButton();
    176   EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
    177 
    178   // X-axis maximization.
    179   delegate.set_window_component(HTLEFT);
    180   generator2.DoubleClickLeftButton();
    181   bounds_in_screen = window->GetBoundsInScreen();
    182   EXPECT_EQ(restored_bounds.y(), bounds_in_screen.y());
    183   EXPECT_EQ(restored_bounds.height(), bounds_in_screen.height());
    184   EXPECT_EQ(work_area2.x(), bounds_in_screen.x());
    185   EXPECT_EQ(work_area2.width(), bounds_in_screen.width());
    186   EXPECT_FALSE(window_state->IsMaximized());
    187 
    188   // Restore.
    189   generator2.DoubleClickLeftButton();
    190   EXPECT_EQ(restored_bounds.ToString(), window->GetBoundsInScreen().ToString());
    191 }
    192 
    193 // Tests the behavior when double clicking the border of a side snapped window.
    194 TEST_F(WorkspaceEventHandlerTest, DoubleClickSingleAxisWhenSideSnapped) {
    195   gfx::Rect restored_bounds(10, 10, 50, 50);
    196   aura::test::TestWindowDelegate delegate;
    197   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, restored_bounds));
    198 
    199   gfx::Rect work_area_in_screen = Shell::GetScreen()->GetDisplayNearestWindow(
    200       window.get()).work_area();
    201 
    202   wm::WindowState* window_state = wm::GetWindowState(window.get());
    203   const wm::WMEvent snap_event(wm::WM_EVENT_SNAP_LEFT);
    204   window_state->OnWMEvent(&snap_event);
    205 
    206   gfx::Rect snapped_bounds_in_screen = window->GetBoundsInScreen();
    207   EXPECT_EQ(work_area_in_screen.x(), snapped_bounds_in_screen.x());
    208   EXPECT_EQ(work_area_in_screen.y(), snapped_bounds_in_screen.y());
    209   EXPECT_GT(work_area_in_screen.width(), snapped_bounds_in_screen.width());
    210   EXPECT_EQ(work_area_in_screen.height(), snapped_bounds_in_screen.height());
    211 
    212   // Double clicking the top border should not do anything for side snapped
    213   // windows. (They already take up the entire workspace height and reverting
    214   // to the restored bounds would be weird).
    215   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    216                                      window.get());
    217   delegate.set_window_component(HTTOP);
    218   generator.DoubleClickLeftButton();
    219   EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
    220   EXPECT_EQ(snapped_bounds_in_screen.ToString(),
    221             window->GetBoundsInScreen().ToString());
    222 
    223   // Double clicking the right border should exit the side snapped state and
    224   // make the window take up the entire work area.
    225   delegate.set_window_component(HTRIGHT);
    226   generator.DoubleClickLeftButton();
    227   EXPECT_TRUE(window_state->IsNormalStateType());
    228   EXPECT_EQ(work_area_in_screen.ToString(),
    229             window->GetBoundsInScreen().ToString());
    230 }
    231 
    232 TEST_F(WorkspaceEventHandlerTest,
    233        DoubleClickSingleAxisDoesntResizeVerticalEdgeIfConstrained) {
    234   gfx::Rect restored_bounds(10, 10, 50, 50);
    235   aura::test::TestWindowDelegate delegate;
    236   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, restored_bounds));
    237 
    238   wm::ActivateWindow(window.get());
    239 
    240   gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
    241       window.get()).work_area();
    242 
    243   delegate.set_maximum_size(gfx::Size(0, 100));
    244 
    245   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    246                                      window.get());
    247   // Double-click the top resize edge.
    248   delegate.set_window_component(HTTOP);
    249   generator.DoubleClickLeftButton();
    250 
    251   // The size of the window should be unchanged.
    252   EXPECT_EQ(restored_bounds.y(), window->bounds().y());
    253   EXPECT_EQ(restored_bounds.height(), window->bounds().height());
    254 }
    255 
    256 TEST_F(WorkspaceEventHandlerTest,
    257        DoubleClickSingleAxisDoesntResizeHorizontalEdgeIfConstrained) {
    258   gfx::Rect restored_bounds(10, 10, 50, 50);
    259   aura::test::TestWindowDelegate delegate;
    260   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, restored_bounds));
    261 
    262   wm::ActivateWindow(window.get());
    263 
    264   gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
    265       window.get()).work_area();
    266 
    267   delegate.set_maximum_size(gfx::Size(100, 0));
    268 
    269   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    270                                      window.get());
    271   // Double-click the top resize edge.
    272   delegate.set_window_component(HTRIGHT);
    273   generator.DoubleClickLeftButton();
    274 
    275   // The size of the window should be unchanged.
    276   EXPECT_EQ(restored_bounds.x(), window->bounds().x());
    277   EXPECT_EQ(restored_bounds.width(), window->bounds().width());
    278 }
    279 
    280 TEST_F(WorkspaceEventHandlerTest,
    281        DoubleClickOrTapWithModalChildDoesntMaximize) {
    282   aura::test::TestWindowDelegate delegate1;
    283   aura::test::TestWindowDelegate delegate2;
    284   scoped_ptr<aura::Window> window(
    285       CreateTestWindow(&delegate1, gfx::Rect(10, 20, 30, 40)));
    286   scoped_ptr<aura::Window> child(
    287       CreateTestWindow(&delegate2, gfx::Rect(0, 0, 1, 1)));
    288   window->SetProperty(aura::client::kCanMaximizeKey, true);
    289   delegate1.set_window_component(HTCAPTION);
    290 
    291   child->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    292   ::wm::AddTransientChild(window.get(), child.get());
    293 
    294   wm::WindowState* window_state = wm::GetWindowState(window.get());
    295   EXPECT_FALSE(window_state->IsMaximized());
    296   aura::Window* root = Shell::GetPrimaryRootWindow();
    297   ui::test::EventGenerator generator(root, window.get());
    298   generator.DoubleClickLeftButton();
    299   EXPECT_EQ("10,20 30x40", window->bounds().ToString());
    300   EXPECT_FALSE(window_state->IsMaximized());
    301 
    302   generator.GestureTapAt(gfx::Point(25, 25));
    303   generator.GestureTapAt(gfx::Point(25, 25));
    304   RunAllPendingInMessageLoop();
    305   EXPECT_EQ("10,20 30x40", window->bounds().ToString());
    306   EXPECT_FALSE(window_state->IsMaximized());
    307 }
    308 
    309 // Test the behavior as a result of double clicking the window header.
    310 TEST_F(WorkspaceEventHandlerTest, DoubleClickCaptionTogglesMaximize) {
    311   aura::test::TestWindowDelegate delegate;
    312   scoped_ptr<aura::Window> window(
    313       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
    314   window->SetProperty(aura::client::kCanMaximizeKey, true);
    315 
    316   wm::WindowState* window_state = wm::GetWindowState(window.get());
    317   gfx::Rect restore_bounds = window->bounds();
    318   gfx::Rect work_area_in_parent = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
    319       window.get());
    320 
    321   EXPECT_FALSE(window_state->IsMaximized());
    322 
    323   // 1) Double clicking a normal window should maximize.
    324   delegate.set_window_component(HTCAPTION);
    325   aura::Window* root = Shell::GetPrimaryRootWindow();
    326   ui::test::EventGenerator generator(root, window.get());
    327   generator.ClickLeftButton();
    328   generator.DoubleClickLeftButton();
    329   EXPECT_NE(restore_bounds.ToString(), window->bounds().ToString());
    330   EXPECT_TRUE(window_state->IsMaximized());
    331 
    332   generator.ClickLeftButton();
    333   generator.DoubleClickLeftButton();
    334   EXPECT_TRUE(window_state->IsNormalStateType());
    335   EXPECT_EQ(restore_bounds.ToString(), window->bounds().ToString());
    336 
    337   // 2) Double clicking a horizontally maximized window should maximize.
    338   delegate.set_window_component(HTLEFT);
    339   generator.ClickLeftButton();
    340   generator.DoubleClickLeftButton();
    341   EXPECT_TRUE(window_state->IsNormalStateType());
    342   EXPECT_EQ(work_area_in_parent.x(), window->bounds().x());
    343   EXPECT_EQ(restore_bounds.y(), window->bounds().y());
    344   EXPECT_EQ(work_area_in_parent.width(), window->bounds().width());
    345   EXPECT_EQ(restore_bounds.height(), window->bounds().height());
    346 
    347   delegate.set_window_component(HTCAPTION);
    348   generator.ClickLeftButton();
    349   generator.DoubleClickLeftButton();
    350   EXPECT_TRUE(window_state->IsMaximized());
    351 
    352   generator.ClickLeftButton();
    353   generator.DoubleClickLeftButton();
    354   EXPECT_TRUE(window_state->IsNormalStateType());
    355   EXPECT_EQ(restore_bounds.ToString(), window->bounds().ToString());
    356 
    357   // 3) Double clicking a snapped window should maximize.
    358   const wm::WMEvent snap_event(wm::WM_EVENT_SNAP_LEFT);
    359   window_state->OnWMEvent(&snap_event);
    360   EXPECT_TRUE(window_state->IsSnapped());
    361   generator.MoveMouseTo(window->GetBoundsInRootWindow().CenterPoint());
    362   generator.ClickLeftButton();
    363   generator.DoubleClickLeftButton();
    364   EXPECT_TRUE(window_state->IsMaximized());
    365 
    366   generator.ClickLeftButton();
    367   generator.DoubleClickLeftButton();
    368   EXPECT_TRUE(window_state->IsNormalStateType());
    369   EXPECT_EQ(restore_bounds.ToString(), window->bounds().ToString());
    370 }
    371 
    372 // Test that double clicking the middle button on the window header does not
    373 // toggle the maximized state.
    374 TEST_F(WorkspaceEventHandlerTest,
    375        DoubleClickMiddleButtonDoesNotToggleMaximize) {
    376   aura::test::TestWindowDelegate delegate;
    377   scoped_ptr<aura::Window> window(
    378       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
    379   window->SetProperty(aura::client::kCanMaximizeKey, true);
    380   delegate.set_window_component(HTCAPTION);
    381   aura::Window* root = Shell::GetPrimaryRootWindow();
    382   ui::test::EventGenerator generator(root, window.get());
    383 
    384   WindowPropertyObserver observer(window.get());
    385   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, generator.current_location(),
    386                        generator.current_location(),
    387                        ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK,
    388                        ui::EF_MIDDLE_MOUSE_BUTTON);
    389   ui::EventProcessor* dispatcher = root->GetHost()->event_processor();
    390   ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
    391   ASSERT_FALSE(details.dispatcher_destroyed);
    392   ui::MouseEvent release(ui::ET_MOUSE_RELEASED, generator.current_location(),
    393                          generator.current_location(),
    394                          ui::EF_IS_DOUBLE_CLICK,
    395                          ui::EF_MIDDLE_MOUSE_BUTTON);
    396   details = dispatcher->OnEventFromSource(&release);
    397   ASSERT_FALSE(details.dispatcher_destroyed);
    398 
    399   EXPECT_FALSE(wm::GetWindowState(window.get())->IsMaximized());
    400   EXPECT_EQ("1,2 30x40", window->bounds().ToString());
    401   EXPECT_FALSE(observer.DidPropertyChange(aura::client::kShowStateKey));
    402 }
    403 
    404 TEST_F(WorkspaceEventHandlerTest, DoubleTapCaptionTogglesMaximize) {
    405   aura::test::TestWindowDelegate delegate;
    406   gfx::Rect bounds(10, 20, 30, 40);
    407   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, bounds));
    408   window->SetProperty(aura::client::kCanMaximizeKey, true);
    409   delegate.set_window_component(HTCAPTION);
    410 
    411   wm::WindowState* window_state = wm::GetWindowState(window.get());
    412   EXPECT_FALSE(window_state->IsMaximized());
    413   ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    414                                      window.get());
    415   generator.GestureTapAt(gfx::Point(25, 25));
    416   generator.GestureTapAt(gfx::Point(25, 25));
    417   RunAllPendingInMessageLoop();
    418   EXPECT_NE(bounds.ToString(), window->bounds().ToString());
    419   EXPECT_TRUE(window_state->IsMaximized());
    420 
    421   generator.GestureTapAt(gfx::Point(5, 5));
    422   generator.GestureTapAt(gfx::Point(10, 10));
    423 
    424   EXPECT_FALSE(window_state->IsMaximized());
    425   EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
    426 }
    427 
    428 // Verifies deleting the window while dragging doesn't crash.
    429 TEST_F(WorkspaceEventHandlerTest, DeleteWhenDragging) {
    430   // Create a large window in the background. This is necessary so that when we
    431   // delete |window| WorkspaceEventHandler is still the active event handler.
    432   aura::test::TestWindowDelegate delegate2;
    433   scoped_ptr<aura::Window> window2(
    434       CreateTestWindow(&delegate2, gfx::Rect(0, 0, 500, 500)));
    435 
    436   aura::test::TestWindowDelegate delegate;
    437   const gfx::Rect bounds(10, 20, 30, 40);
    438   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, bounds));
    439   delegate.set_window_component(HTCAPTION);
    440   ui::test::EventGenerator generator(window->GetRootWindow());
    441   generator.MoveMouseToCenterOf(window.get());
    442   generator.PressLeftButton();
    443   generator.MoveMouseTo(generator.current_location() + gfx::Vector2d(50, 50));
    444   DCHECK_NE(bounds.origin().ToString(), window->bounds().origin().ToString());
    445   window.reset();
    446   generator.MoveMouseTo(generator.current_location() + gfx::Vector2d(50, 50));
    447 }
    448 
    449 // Verifies deleting the window while in a run loop doesn't crash.
    450 TEST_F(WorkspaceEventHandlerTest, DeleteWhileInRunLoop) {
    451   aura::test::TestWindowDelegate delegate;
    452   const gfx::Rect bounds(10, 20, 30, 40);
    453   scoped_ptr<aura::Window> window(CreateTestWindow(&delegate, bounds));
    454   delegate.set_window_component(HTCAPTION);
    455 
    456   ASSERT_TRUE(aura::client::GetWindowMoveClient(window->GetRootWindow()));
    457   base::MessageLoop::current()->DeleteSoon(FROM_HERE, window.get());
    458   aura::client::GetWindowMoveClient(window->GetRootWindow())
    459       ->RunMoveLoop(window.release(),
    460                     gfx::Vector2d(),
    461                     aura::client::WINDOW_MOVE_SOURCE_MOUSE);
    462 }
    463 
    464 // Verifies that double clicking in the header does not maximize if the target
    465 // component has changed.
    466 TEST_F(WorkspaceEventHandlerTest,
    467     DoubleClickTwoDifferentTargetsDoesntMaximize) {
    468   aura::test::TestWindowDelegate delegate;
    469   scoped_ptr<aura::Window> window(
    470       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
    471   window->SetProperty(aura::client::kCanMaximizeKey, true);
    472 
    473   wm::WindowState* window_state = wm::GetWindowState(window.get());
    474   gfx::Rect restore_bounds = window->bounds();
    475   gfx::Rect work_area_in_parent = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
    476       window.get());
    477 
    478   EXPECT_FALSE(window_state->IsMaximized());
    479 
    480   // First click will go to a client
    481   delegate.set_window_component(HTCLIENT);
    482   aura::Window* root = Shell::GetPrimaryRootWindow();
    483   ui::test::EventGenerator generator(root, window.get());
    484   generator.ClickLeftButton();
    485   EXPECT_FALSE(window_state->IsMaximized());
    486 
    487   // Second click will go to the header
    488   delegate.set_window_component(HTCAPTION);
    489   generator.DoubleClickLeftButton();
    490   EXPECT_FALSE(window_state->IsMaximized());
    491 }
    492 
    493 // Verifies that double tapping in the header does not maximize if the target
    494 // component has changed.
    495 TEST_F(WorkspaceEventHandlerTest, DoubleTapTwoDifferentTargetsDoesntMaximize) {
    496   aura::test::TestWindowDelegate delegate;
    497   scoped_ptr<aura::Window> window(
    498       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
    499   window->SetProperty(aura::client::kCanMaximizeKey, true);
    500 
    501   wm::WindowState* window_state = wm::GetWindowState(window.get());
    502   gfx::Rect restore_bounds = window->bounds();
    503   gfx::Rect work_area_in_parent = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
    504       window.get());
    505 
    506   EXPECT_FALSE(window_state->IsMaximized());
    507 
    508   // First tap will go to a client
    509   delegate.set_window_component(HTCLIENT);
    510   aura::Window* root = Shell::GetPrimaryRootWindow();
    511   ui::test::EventGenerator generator(root, window.get());
    512   generator.GestureTapAt(gfx::Point(25, 25));
    513   EXPECT_FALSE(window_state->IsMaximized());
    514 
    515   // Second tap will go to the header
    516   delegate.set_window_component(HTCAPTION);
    517   generator.GestureTapAt(gfx::Point(25, 25));
    518   EXPECT_FALSE(window_state->IsMaximized());
    519 }
    520 
    521 TEST_F(WorkspaceEventHandlerTest,
    522     RightClickDuringDoubleClickDoesntMaximize) {
    523   aura::test::TestWindowDelegate delegate;
    524   scoped_ptr<aura::Window> window(
    525       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
    526   window->SetProperty(aura::client::kCanMaximizeKey, true);
    527 
    528   wm::WindowState* window_state = wm::GetWindowState(window.get());
    529   gfx::Rect restore_bounds = window->bounds();
    530   gfx::Rect work_area_in_parent = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
    531       window.get());
    532 
    533   EXPECT_FALSE(window_state->IsMaximized());
    534 
    535   // First click will go to a client
    536   delegate.set_window_component(HTCLIENT);
    537   aura::Window* root = Shell::GetPrimaryRootWindow();
    538   ui::test::EventGenerator generator(root, window.get());
    539   generator.ClickLeftButton();
    540   EXPECT_FALSE(window_state->IsMaximized());
    541 
    542   // Second click will go to the header
    543   delegate.set_window_component(HTCAPTION);
    544   generator.PressRightButton();
    545   generator.ReleaseRightButton();
    546   EXPECT_FALSE(window_state->IsMaximized());
    547   generator.DoubleClickLeftButton();
    548   EXPECT_FALSE(window_state->IsMaximized());
    549 }
    550 
    551 }  // namespace ash
    552