Home | History | Annotate | Download | only in wm
      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/shell.h"
      6 #include "ash/shell_window_ids.h"
      7 #include "ash/test/ash_test_base.h"
      8 #include "ash/test/shell_test_api.h"
      9 #include "ash/test/test_activation_delegate.h"
     10 #include "ash/wm/activation_controller.h"
     11 #include "ash/wm/window_util.h"
     12 #include "ui/aura/client/activation_client.h"
     13 #include "ui/aura/client/activation_delegate.h"
     14 #include "ui/aura/client/cursor_client_observer.h"
     15 #include "ui/aura/client/focus_client.h"
     16 #include "ui/aura/env.h"
     17 #include "ui/aura/root_window.h"
     18 #include "ui/aura/test/aura_test_base.h"
     19 #include "ui/aura/test/event_generator.h"
     20 #include "ui/aura/test/test_event_handler.h"
     21 #include "ui/aura/test/test_window_delegate.h"
     22 #include "ui/aura/test/test_windows.h"
     23 #include "ui/base/cursor/cursor.h"
     24 #include "ui/base/events/event.h"
     25 #include "ui/base/events/event_utils.h"
     26 #include "ui/base/hit_test.h"
     27 #include "ui/gfx/screen.h"
     28 #include "ui/views/corewm/compound_event_filter.h"
     29 #include "ui/views/corewm/corewm_switches.h"
     30 #include "ui/views/corewm/input_method_event_filter.h"
     31 
     32 namespace {
     33 
     34 class TestingCursorClientObserver : public aura::client::CursorClientObserver {
     35  public:
     36   TestingCursorClientObserver()
     37       : cursor_visibility_(false),
     38         did_visibility_change_(false) {}
     39   void reset() { cursor_visibility_ = did_visibility_change_ = false; }
     40   bool is_cursor_visible() const { return cursor_visibility_; }
     41   bool did_visibility_change() const { return did_visibility_change_; }
     42 
     43   // Overridden from aura::client::CursorClientObserver:
     44   virtual void OnCursorVisibilityChanged(bool is_visible) OVERRIDE {
     45     cursor_visibility_ = is_visible;
     46     did_visibility_change_ = true;
     47   }
     48 
     49  private:
     50   bool cursor_visibility_;
     51   bool did_visibility_change_;
     52 
     53   DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver);
     54 };
     55 
     56 base::TimeDelta getTime() {
     57   return ui::EventTimeForNow();
     58 }
     59 
     60 // A slightly changed TestEventHandler which can be configured to return a
     61 // specified value for key/mouse event handling.
     62 class CustomEventHandler : public aura::test::TestEventHandler {
     63  public:
     64   CustomEventHandler()
     65       : key_result_(ui::ER_UNHANDLED),
     66         mouse_result_(ui::ER_UNHANDLED) {
     67   }
     68 
     69   virtual ~CustomEventHandler() {}
     70 
     71   void set_key_event_handling_result(ui::EventResult result) {
     72     key_result_ = result;
     73   }
     74 
     75   void set_mouse_event_handling_result(ui::EventResult result) {
     76     mouse_result_ = result;
     77   }
     78 
     79   // Overridden from ui::EventHandler:
     80   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
     81     aura::test::TestEventHandler::OnKeyEvent(event);
     82     if (key_result_ & ui::ER_HANDLED)
     83       event->SetHandled();
     84     if (key_result_ & ui::ER_CONSUMED)
     85       event->StopPropagation();
     86   }
     87 
     88   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
     89     aura::test::TestEventHandler::OnMouseEvent(event);
     90     if (mouse_result_ & ui::ER_HANDLED)
     91       event->SetHandled();
     92     if (mouse_result_ & ui::ER_CONSUMED)
     93       event->StopPropagation();
     94   }
     95 
     96  private:
     97   ui::EventResult key_result_;
     98   ui::EventResult mouse_result_;
     99 
    100   DISALLOW_COPY_AND_ASSIGN(CustomEventHandler);
    101 };
    102 
    103 }  // namespace
    104 
    105 namespace ash {
    106 
    107 typedef test::AshTestBase WindowManagerTest;
    108 
    109 class NonFocusableDelegate : public aura::test::TestWindowDelegate {
    110  public:
    111   NonFocusableDelegate() {}
    112 
    113  private:
    114   virtual bool CanFocus() OVERRIDE {
    115     return false;
    116   }
    117 
    118   DISALLOW_COPY_AND_ASSIGN(NonFocusableDelegate);
    119 };
    120 
    121 class HitTestWindowDelegate : public aura::test::TestWindowDelegate {
    122  public:
    123   HitTestWindowDelegate()
    124       : hittest_code_(HTNOWHERE) {
    125   }
    126   virtual ~HitTestWindowDelegate() {}
    127   void set_hittest_code(int hittest_code) { hittest_code_ = hittest_code; }
    128 
    129  private:
    130   // Overridden from TestWindowDelegate:
    131   virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
    132     return hittest_code_;
    133   }
    134 
    135   int hittest_code_;
    136 
    137   DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate);
    138 };
    139 
    140 TEST_F(WindowManagerTest, Focus) {
    141   // The IME event filter interferes with the basic key event propagation we
    142   // attempt to do here, so we remove it.
    143   test::ShellTestApi shell_test(Shell::GetInstance());
    144   Shell::GetInstance()->RemovePreTargetHandler(
    145       shell_test.input_method_event_filter());
    146 
    147   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    148   root_window->SetBounds(gfx::Rect(0, 0, 510, 510));
    149 
    150   // Supplied ids are negative so as not to collide with shell ids.
    151   // TODO(beng): maybe introduce a MAKE_SHELL_ID() macro that generates a safe
    152   //             id beyond shell id max?
    153   scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
    154       SK_ColorWHITE, -1, gfx::Rect(10, 10, 500, 500)));
    155   scoped_ptr<aura::Window> w11(aura::test::CreateTestWindow(
    156       SK_ColorGREEN, -11, gfx::Rect(5, 5, 100, 100), w1.get()));
    157   scoped_ptr<aura::Window> w111(aura::test::CreateTestWindow(
    158       SK_ColorCYAN, -111, gfx::Rect(5, 5, 75, 75), w11.get()));
    159   scoped_ptr<aura::Window> w1111(aura::test::CreateTestWindow(
    160       SK_ColorRED, -1111, gfx::Rect(5, 5, 50, 50), w111.get()));
    161   scoped_ptr<aura::Window> w12(aura::test::CreateTestWindow(
    162       SK_ColorMAGENTA, -12, gfx::Rect(10, 420, 25, 25), w1.get()));
    163   aura::test::ColorTestWindowDelegate* w121delegate =
    164       new aura::test::ColorTestWindowDelegate(SK_ColorYELLOW);
    165   scoped_ptr<aura::Window> w121(aura::test::CreateTestWindowWithDelegate(
    166       w121delegate, -121, gfx::Rect(5, 5, 5, 5), w12.get()));
    167   aura::test::ColorTestWindowDelegate* w122delegate =
    168       new aura::test::ColorTestWindowDelegate(SK_ColorRED);
    169   scoped_ptr<aura::Window> w122(aura::test::CreateTestWindowWithDelegate(
    170       w122delegate, -122, gfx::Rect(10, 5, 5, 5), w12.get()));
    171   aura::test::ColorTestWindowDelegate* w123delegate =
    172       new aura::test::ColorTestWindowDelegate(SK_ColorRED);
    173   scoped_ptr<aura::Window> w123(aura::test::CreateTestWindowWithDelegate(
    174       w123delegate, -123, gfx::Rect(15, 5, 5, 5), w12.get()));
    175   scoped_ptr<aura::Window> w13(aura::test::CreateTestWindow(
    176       SK_ColorGRAY, -13, gfx::Rect(5, 470, 50, 50), w1.get()));
    177 
    178   // Click on a sub-window (w121) to focus it.
    179   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    180                                        w121.get());
    181   generator.ClickLeftButton();
    182 
    183   aura::client::FocusClient* focus_client =
    184       aura::client::GetFocusClient(w121.get());
    185   EXPECT_EQ(w121.get(), focus_client->GetFocusedWindow());
    186 
    187   // The key press should be sent to the focused sub-window.
    188   ui::KeyEvent keyev(ui::ET_KEY_PRESSED, ui::VKEY_E, 0, false);
    189   root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&keyev);
    190   EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code());
    191 
    192   // Touch on a sub-window (w122) to focus it.
    193   gfx::Point click_point = w122->bounds().CenterPoint();
    194   aura::Window::ConvertPointToTarget(w122->parent(), root_window, &click_point);
    195   ui::TouchEvent touchev(ui::ET_TOUCH_PRESSED, click_point, 0, getTime());
    196   root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&touchev);
    197   focus_client = aura::client::GetFocusClient(w122.get());
    198   EXPECT_EQ(w122.get(), focus_client->GetFocusedWindow());
    199 
    200   // The key press should be sent to the focused sub-window.
    201   root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&keyev);
    202   EXPECT_EQ(ui::VKEY_E, w122delegate->last_key_code());
    203 
    204   // Hiding the focused window will set the focus to its parent if
    205   // it's focusable.
    206   w122->Hide();
    207   EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
    208             aura::client::GetFocusClient(w122.get()));
    209   EXPECT_EQ(w12.get(),
    210             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    211 
    212   // Sets the focus back to w122.
    213   w122->Show();
    214   w122->Focus();
    215   EXPECT_EQ(w122.get(),
    216             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    217 
    218   // Removing the focused window from parent should set the focus to
    219   // its parent if it's focusable.
    220   w12->RemoveChild(w122.get());
    221   EXPECT_EQ(NULL, aura::client::GetFocusClient(w122.get()));
    222   EXPECT_EQ(w12.get(),
    223             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    224 
    225   // Set the focus to w123, but make the w1 not activatable.
    226   test::TestActivationDelegate activation_delegate(false);
    227   w123->Focus();
    228   EXPECT_EQ(w123.get(),
    229             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    230   aura::client::SetActivationDelegate(w1.get(), &activation_delegate);
    231 
    232   // Hiding the focused window will set the focus to NULL because
    233   // parent window is not focusable.
    234   w123->Hide();
    235   EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
    236             aura::client::GetFocusClient(w123.get()));
    237   EXPECT_EQ(NULL, aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    238   EXPECT_FALSE(root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&keyev));
    239 
    240   // Set the focus back to w123
    241   aura::client::SetActivationDelegate(w1.get(), NULL);
    242   w123->Show();
    243   w123->Focus();
    244   EXPECT_EQ(w123.get(),
    245             aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
    246   aura::client::SetActivationDelegate(w1.get(), &activation_delegate);
    247 
    248   // Removing the focused window will set the focus to NULL because
    249   // parent window is not focusable.
    250   w12->RemoveChild(w123.get());
    251   EXPECT_EQ(NULL, aura::client::GetFocusClient(w123.get()));
    252   EXPECT_FALSE(root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&keyev));
    253 }
    254 
    255 // Various assertion testing for activating windows.
    256 TEST_F(WindowManagerTest, ActivateOnMouse) {
    257   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    258 
    259   test::TestActivationDelegate d1;
    260   aura::test::TestWindowDelegate wd;
    261   scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
    262       &wd, -1, gfx::Rect(10, 10, 50, 50)));
    263   d1.SetWindow(w1.get());
    264   test::TestActivationDelegate d2;
    265   scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
    266       &wd, -2, gfx::Rect(70, 70, 50, 50)));
    267   d2.SetWindow(w2.get());
    268 
    269   aura::client::FocusClient* focus_client =
    270       aura::client::GetFocusClient(w1.get());
    271 
    272   d1.Clear();
    273   d2.Clear();
    274 
    275   // Activate window1.
    276   wm::ActivateWindow(w1.get());
    277   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    278   EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    279   EXPECT_EQ(1, d1.activated_count());
    280   EXPECT_EQ(0, d1.lost_active_count());
    281   d1.Clear();
    282 
    283   {
    284     // Click on window2.
    285     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    286                                          w2.get());
    287     generator.ClickLeftButton();
    288 
    289     // Window2 should have become active.
    290     EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    291     EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    292     EXPECT_EQ(0, d1.activated_count());
    293     EXPECT_EQ(1, d1.lost_active_count());
    294     EXPECT_EQ(1, d2.activated_count());
    295     EXPECT_EQ(0, d2.lost_active_count());
    296     d1.Clear();
    297     d2.Clear();
    298   }
    299 
    300   {
    301     // Click back on window1, but set it up so w1 doesn't activate on click.
    302     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    303                                          w1.get());
    304     d1.set_activate(false);
    305     generator.ClickLeftButton();
    306 
    307     // Window2 should still be active and focused.
    308     EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    309     EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    310     EXPECT_EQ(0, d1.activated_count());
    311     EXPECT_EQ(0, d1.lost_active_count());
    312     EXPECT_EQ(0, d2.activated_count());
    313     EXPECT_EQ(0, d2.lost_active_count());
    314     d1.Clear();
    315     d2.Clear();
    316   }
    317 
    318   // Destroy window2, this should make window1 active.
    319   d1.set_activate(true);
    320   w2.reset();
    321   EXPECT_EQ(0, d2.activated_count());
    322   EXPECT_EQ(views::corewm::UseFocusController() ? 1 : 0,
    323             d2.lost_active_count());
    324   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    325   EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    326   EXPECT_EQ(1, d1.activated_count());
    327   EXPECT_EQ(0, d1.lost_active_count());
    328 
    329   // Clicking an active window with a child shouldn't steal the
    330   // focus from the child.
    331   {
    332     scoped_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
    333           &wd, -11, gfx::Rect(10, 10, 10, 10), w1.get()));
    334     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    335                                          w11.get());
    336     // First set the focus to the child |w11|.
    337     generator.ClickLeftButton();
    338     EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
    339     EXPECT_EQ(w1.get(), wm::GetActiveWindow());
    340 
    341     // Then click the parent active window. The focus shouldn't move.
    342     gfx::Point left_top = w1->bounds().origin();
    343     aura::Window::ConvertPointToTarget(w1->parent(), root_window, &left_top);
    344     left_top.Offset(1, 1);
    345     generator.MoveMouseTo(left_top);
    346     generator.ClickLeftButton();
    347     EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
    348     EXPECT_EQ(w1.get(), wm::GetActiveWindow());
    349   }
    350 
    351   // Clicking on a non-focusable window inside a background window should still
    352   // give focus to the background window.
    353   {
    354     NonFocusableDelegate nfd;
    355     scoped_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
    356           &nfd, -1, gfx::Rect(10, 10, 10, 10), w1.get()));
    357     // Move focus to |w2| first.
    358     scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
    359           &wd, -1, gfx::Rect(70, 70, 50, 50)));
    360     aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    361                                          w2.get());
    362     generator.ClickLeftButton();
    363     EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    364     EXPECT_FALSE(w11->CanFocus());
    365 
    366     // Click on |w11|. This should focus w1.
    367     generator.MoveMouseToCenterOf(w11.get());
    368     generator.ClickLeftButton();
    369     EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    370   }
    371 }
    372 
    373 TEST_F(WindowManagerTest, PanelActivation) {
    374   aura::test::TestWindowDelegate wd;
    375   scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
    376       &wd, -1, gfx::Rect(10, 10, 50, 50)));
    377   aura::test::TestWindowDelegate pd;
    378   scoped_ptr<aura::Window> p1(CreateTestWindowInShellWithDelegateAndType(
    379       &pd, aura::client::WINDOW_TYPE_PANEL, -1, gfx::Rect(10, 10, 50, 50)));
    380   aura::client::FocusClient* focus_client =
    381       aura::client::GetFocusClient(w1.get());
    382 
    383   // Activate w1.
    384   wm::ActivateWindow(w1.get());
    385   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    386 
    387   // Activate p1.
    388   wm::ActivateWindow(p1.get());
    389   EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
    390   EXPECT_EQ(p1.get(), focus_client->GetFocusedWindow());
    391 
    392   // Activate w1.
    393   wm::ActivateWindow(w1.get());
    394   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    395   EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    396 
    397   // Clicking on a non-activatable window should not change the active window.
    398   {
    399     NonFocusableDelegate nfd;
    400     scoped_ptr<aura::Window> w3(CreateTestWindowInShellWithDelegate(
    401           &nfd, -1, gfx::Rect(70, 70, 50, 50)));
    402     aura::test::EventGenerator generator3(Shell::GetPrimaryRootWindow(),
    403                                          w3.get());
    404     wm::ActivateWindow(p1.get());
    405     EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
    406     generator3.ClickLeftButton();
    407     EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
    408   }
    409 }
    410 
    411 // Essentially the same as ActivateOnMouse, but for touch events.
    412 TEST_F(WindowManagerTest, ActivateOnTouch) {
    413   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    414 
    415   test::TestActivationDelegate d1;
    416   aura::test::TestWindowDelegate wd;
    417   scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
    418       &wd, -1, gfx::Rect(10, 10, 50, 50)));
    419   d1.SetWindow(w1.get());
    420   test::TestActivationDelegate d2;
    421   scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
    422       &wd, -2, gfx::Rect(70, 70, 50, 50)));
    423   d2.SetWindow(w2.get());
    424 
    425   aura::client::FocusClient* focus_client =
    426       aura::client::GetFocusClient(w1.get());
    427 
    428   d1.Clear();
    429   d2.Clear();
    430 
    431   // Activate window1.
    432   wm::ActivateWindow(w1.get());
    433   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    434   EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    435   EXPECT_EQ(1, d1.activated_count());
    436   EXPECT_EQ(0, d1.lost_active_count());
    437   d1.Clear();
    438 
    439   // Touch window2.
    440   gfx::Point press_point = w2->bounds().CenterPoint();
    441   aura::Window::ConvertPointToTarget(w2->parent(), root_window, &press_point);
    442   ui::TouchEvent touchev1(ui::ET_TOUCH_PRESSED, press_point, 0, getTime());
    443   root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&touchev1);
    444 
    445   // Window2 should have become active.
    446   EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    447   EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    448   EXPECT_EQ(0, d1.activated_count());
    449   EXPECT_EQ(1, d1.lost_active_count());
    450   EXPECT_EQ(1, d2.activated_count());
    451   EXPECT_EQ(0, d2.lost_active_count());
    452   d1.Clear();
    453   d2.Clear();
    454 
    455   // Touch window1, but set it up so w1 doesn't activate on touch.
    456   press_point = w1->bounds().CenterPoint();
    457   aura::Window::ConvertPointToTarget(w1->parent(), root_window, &press_point);
    458   d1.set_activate(false);
    459   ui::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 1, getTime());
    460   root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&touchev2);
    461 
    462   // Window2 should still be active and focused.
    463   EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    464   EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    465   EXPECT_EQ(0, d1.activated_count());
    466   EXPECT_EQ(0, d1.lost_active_count());
    467   EXPECT_EQ(0, d2.activated_count());
    468   EXPECT_EQ(0, d2.lost_active_count());
    469   d1.Clear();
    470   d2.Clear();
    471 
    472   // Destroy window2, this should make window1 active.
    473   d1.set_activate(true);
    474   w2.reset();
    475   EXPECT_EQ(0, d2.activated_count());
    476   EXPECT_EQ(views::corewm::UseFocusController() ? 1 : 0,
    477             d2.lost_active_count());
    478   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    479   EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
    480   EXPECT_EQ(1, d1.activated_count());
    481   EXPECT_EQ(0, d1.lost_active_count());
    482 }
    483 
    484 TEST_F(WindowManagerTest, MouseEventCursors) {
    485   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    486 
    487   // Create a window.
    488   const int kWindowLeft = 123;
    489   const int kWindowTop = 45;
    490   HitTestWindowDelegate window_delegate;
    491   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
    492     &window_delegate,
    493     -1,
    494     gfx::Rect(kWindowLeft, kWindowTop, 640, 480)));
    495 
    496   // Create two mouse movement events we can switch between.
    497   gfx::Point point1(kWindowLeft, kWindowTop);
    498   aura::Window::ConvertPointToTarget(window->parent(), root_window, &point1);
    499 
    500   gfx::Point point2(kWindowLeft + 1, kWindowTop + 1);
    501   aura::Window::ConvertPointToTarget(window->parent(), root_window, &point2);
    502 
    503   // Cursor starts as a pointer (set during Shell::Init()).
    504   EXPECT_EQ(ui::kCursorPointer, root_window->last_cursor().native_type());
    505 
    506   {
    507     // Resize edges and corners show proper cursors.
    508     window_delegate.set_hittest_code(HTBOTTOM);
    509     ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0x0);
    510     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move1);
    511     EXPECT_EQ(ui::kCursorSouthResize, root_window->last_cursor().native_type());
    512   }
    513 
    514   {
    515     window_delegate.set_hittest_code(HTBOTTOMLEFT);
    516     ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0x0);
    517     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move2);
    518     EXPECT_EQ(ui::kCursorSouthWestResize,
    519               root_window->last_cursor().native_type());
    520   }
    521 
    522   {
    523     window_delegate.set_hittest_code(HTBOTTOMRIGHT);
    524     ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0x0);
    525     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move1);
    526     EXPECT_EQ(ui::kCursorSouthEastResize,
    527               root_window->last_cursor().native_type());
    528   }
    529 
    530   {
    531     window_delegate.set_hittest_code(HTLEFT);
    532     ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0x0);
    533     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move2);
    534     EXPECT_EQ(ui::kCursorWestResize, root_window->last_cursor().native_type());
    535   }
    536 
    537   {
    538     window_delegate.set_hittest_code(HTRIGHT);
    539     ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0x0);
    540     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move1);
    541     EXPECT_EQ(ui::kCursorEastResize, root_window->last_cursor().native_type());
    542   }
    543 
    544   {
    545     window_delegate.set_hittest_code(HTTOP);
    546     ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0x0);
    547     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move2);
    548     EXPECT_EQ(ui::kCursorNorthResize, root_window->last_cursor().native_type());
    549   }
    550 
    551   {
    552     window_delegate.set_hittest_code(HTTOPLEFT);
    553     ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0x0);
    554     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move1);
    555     EXPECT_EQ(ui::kCursorNorthWestResize,
    556               root_window->last_cursor().native_type());
    557   }
    558 
    559   {
    560     window_delegate.set_hittest_code(HTTOPRIGHT);
    561     ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0x0);
    562     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move2);
    563     EXPECT_EQ(ui::kCursorNorthEastResize,
    564               root_window->last_cursor().native_type());
    565   }
    566 
    567   {
    568     // Client area uses null cursor.
    569     window_delegate.set_hittest_code(HTCLIENT);
    570     ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0x0);
    571     root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&move1);
    572     EXPECT_EQ(ui::kCursorNull, root_window->last_cursor().native_type());
    573   }
    574 }
    575 
    576 #if defined(OS_MACOSX) || defined(OS_WIN)
    577 #define MAYBE_TransformActivate DISABLED_TransformActivate
    578 #else
    579 #define MAYBE_TransformActivate TransformActivate
    580 #endif
    581 TEST_F(WindowManagerTest, MAYBE_TransformActivate) {
    582   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    583   gfx::Size size = root_window->bounds().size();
    584   EXPECT_EQ(gfx::Rect(size).ToString(),
    585             Shell::GetScreen()->GetDisplayNearestPoint(
    586                 gfx::Point()).bounds().ToString());
    587 
    588   // Rotate it clock-wise 90 degrees.
    589   gfx::Transform transform;
    590   transform.Translate(size.width(), 0);
    591   transform.Rotate(90.0f);
    592   root_window->SetTransform(transform);
    593 
    594   test::TestActivationDelegate d1;
    595   aura::test::TestWindowDelegate wd;
    596   scoped_ptr<aura::Window> w1(
    597       CreateTestWindowInShellWithDelegate(&wd, 1, gfx::Rect(0, 10, 50, 50)));
    598   d1.SetWindow(w1.get());
    599   w1->Show();
    600 
    601   gfx::Point miss_point(5, 5);
    602   transform.TransformPoint(miss_point);
    603   ui::MouseEvent mouseev1(ui::ET_MOUSE_PRESSED,
    604                           miss_point,
    605                           miss_point,
    606                           ui::EF_LEFT_MOUSE_BUTTON);
    607   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouseev1);
    608   EXPECT_EQ(NULL, aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
    609   ui::MouseEvent mouseup(ui::ET_MOUSE_RELEASED,
    610                          miss_point,
    611                          miss_point,
    612                          ui::EF_LEFT_MOUSE_BUTTON);
    613   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouseup);
    614 
    615   gfx::Point hit_point(5, 15);
    616   transform.TransformPoint(hit_point);
    617   ui::MouseEvent mouseev2(ui::ET_MOUSE_PRESSED,
    618                           hit_point,
    619                           hit_point,
    620                           ui::EF_LEFT_MOUSE_BUTTON);
    621   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouseev2);
    622   EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
    623   EXPECT_EQ(w1.get(),
    624             aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
    625 }
    626 
    627 TEST_F(WindowManagerTest, AdditionalFilters) {
    628   // The IME event filter interferes with the basic key event propagation we
    629   // attempt to do here, so we remove it.
    630   test::ShellTestApi shell_test(Shell::GetInstance());
    631   Shell::GetInstance()->RemovePreTargetHandler(
    632       shell_test.input_method_event_filter());
    633 
    634   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
    635 
    636   // Creates a window and make it active
    637   scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
    638       SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100)));
    639   wm::ActivateWindow(w1.get());
    640 
    641   // Creates two addition filters
    642   scoped_ptr<CustomEventHandler> f1(new CustomEventHandler);
    643   scoped_ptr<CustomEventHandler> f2(new CustomEventHandler);
    644 
    645   // Adds them to root window event filter.
    646   views::corewm::CompoundEventFilter* env_filter =
    647       Shell::GetInstance()->env_filter();
    648   env_filter->AddHandler(f1.get());
    649   env_filter->AddHandler(f2.get());
    650 
    651   // Dispatches mouse and keyboard events.
    652   ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, false);
    653   root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&key_event);
    654   ui::MouseEvent mouse_pressed(
    655       ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0), 0x0);
    656   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_pressed);
    657 
    658   // Both filters should get the events.
    659   EXPECT_EQ(1, f1->num_key_events());
    660   EXPECT_EQ(1, f1->num_mouse_events());
    661   EXPECT_EQ(1, f2->num_key_events());
    662   EXPECT_EQ(1, f2->num_mouse_events());
    663 
    664   f1->Reset();
    665   f2->Reset();
    666 
    667   // Makes f1 consume events.
    668   f1->set_key_event_handling_result(ui::ER_CONSUMED);
    669   f1->set_mouse_event_handling_result(ui::ER_CONSUMED);
    670 
    671   // Dispatches events.
    672   root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&key_event);
    673   ui::MouseEvent mouse_released(
    674       ui::ET_MOUSE_RELEASED, gfx::Point(0, 0), gfx::Point(0, 0), 0x0);
    675   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_released);
    676 
    677   // f1 should still get the events but f2 no longer gets them.
    678   EXPECT_EQ(1, f1->num_key_events());
    679   EXPECT_EQ(1, f1->num_mouse_events());
    680   EXPECT_EQ(0, f2->num_key_events());
    681   EXPECT_EQ(0, f2->num_mouse_events());
    682 
    683   f1->Reset();
    684   f2->Reset();
    685 
    686   // Remove f1 from additonal filters list.
    687   env_filter->RemoveHandler(f1.get());
    688 
    689   // Dispatches events.
    690   root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&key_event);
    691   root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_pressed);
    692 
    693   // f1 should get no events since it's out and f2 should get them.
    694   EXPECT_EQ(0, f1->num_key_events());
    695   EXPECT_EQ(0, f1->num_mouse_events());
    696   EXPECT_EQ(1, f2->num_key_events());
    697   EXPECT_EQ(1, f2->num_mouse_events());
    698 
    699   env_filter->RemoveHandler(f2.get());
    700 }
    701 
    702 // We should show and hide the cursor in response to mouse and touch events as
    703 // requested.
    704 TEST_F(WindowManagerTest, UpdateCursorVisibility) {
    705   aura::test::EventGenerator& generator = GetEventGenerator();
    706   views::corewm::CursorManager* cursor_manager =
    707       ash::Shell::GetInstance()->cursor_manager();
    708 
    709   generator.MoveMouseTo(gfx::Point(0, 0));
    710   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    711   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    712   generator.PressTouch();
    713   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    714   EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
    715   generator.MoveMouseTo(gfx::Point(0, 0));
    716   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    717   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    718   generator.ReleaseTouch();
    719   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    720   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    721 
    722   // If someone else made cursor invisible keep it invisible even after it
    723   // received mouse events.
    724   cursor_manager->EnableMouseEvents();
    725   cursor_manager->HideCursor();
    726   generator.MoveMouseTo(gfx::Point(0, 0));
    727   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    728   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    729   generator.PressTouch();
    730   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    731   EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
    732   generator.MoveMouseTo(gfx::Point(0, 0));
    733   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    734   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    735   generator.ReleaseTouch();
    736   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    737   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    738 
    739   // Back to normal.
    740   cursor_manager->EnableMouseEvents();
    741   cursor_manager->ShowCursor();
    742   generator.MoveMouseTo(gfx::Point(0, 0));
    743   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    744   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    745   generator.PressTouch();
    746   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    747   EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
    748   generator.MoveMouseTo(gfx::Point(0, 0));
    749   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    750   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    751   generator.ReleaseTouch();
    752   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    753   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    754 }
    755 
    756 TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
    757   aura::test::EventGenerator& generator = GetEventGenerator();
    758   views::corewm::CursorManager* cursor_manager =
    759       ash::Shell::GetInstance()->cursor_manager();
    760 
    761   // Pressing a key hides the cursor but does not disable mouse events.
    762   generator.PressKey(ui::VKEY_A, ui::EF_NONE);
    763   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    764   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    765   // Moving mouse shows the cursor.
    766   generator.MoveMouseTo(gfx::Point(0, 0));
    767   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    768   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    769   // Releasing a key also hides the cursor but does not disable mouse events.
    770   generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
    771   EXPECT_FALSE(cursor_manager->IsCursorVisible());
    772   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    773   // Moving mouse shows the cursor again.
    774   generator.MoveMouseTo(gfx::Point(0, 0));
    775   EXPECT_TRUE(cursor_manager->IsCursorVisible());
    776   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
    777 }
    778 
    779 TEST_F(WindowManagerTest, TestCursorClientObserver) {
    780   aura::test::EventGenerator& generator = GetEventGenerator();
    781   views::corewm::CursorManager* cursor_manager =
    782       ash::Shell::GetInstance()->cursor_manager();
    783 
    784   scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
    785       SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100)));
    786   wm::ActivateWindow(w1.get());
    787 
    788   // Add two observers. Both should have OnCursorVisibilityChanged()
    789   // invoked when an event changes the visibility of the cursor.
    790   TestingCursorClientObserver observer_a;
    791   TestingCursorClientObserver observer_b;
    792   cursor_manager->AddObserver(&observer_a);
    793   cursor_manager->AddObserver(&observer_b);
    794 
    795   // Initial state before any events have been sent.
    796   observer_a.reset();
    797   observer_b.reset();
    798   EXPECT_FALSE(observer_a.did_visibility_change());
    799   EXPECT_FALSE(observer_b.did_visibility_change());
    800   EXPECT_FALSE(observer_a.is_cursor_visible());
    801   EXPECT_FALSE(observer_b.is_cursor_visible());
    802 
    803   // Keypress should hide the cursor.
    804   generator.PressKey(ui::VKEY_A, ui::EF_NONE);
    805   EXPECT_TRUE(observer_a.did_visibility_change());
    806   EXPECT_TRUE(observer_b.did_visibility_change());
    807   EXPECT_FALSE(observer_a.is_cursor_visible());
    808   EXPECT_FALSE(observer_b.is_cursor_visible());
    809 
    810   // Mouse move should show the cursor.
    811   observer_a.reset();
    812   observer_b.reset();
    813   generator.MoveMouseTo(50, 50);
    814   EXPECT_TRUE(observer_a.did_visibility_change());
    815   EXPECT_TRUE(observer_b.did_visibility_change());
    816   EXPECT_TRUE(observer_a.is_cursor_visible());
    817   EXPECT_TRUE(observer_b.is_cursor_visible());
    818 
    819   // Remove observer_b. Its OnCursorVisibilityChanged() should
    820   // not be invoked past this point.
    821   cursor_manager->RemoveObserver(&observer_b);
    822 
    823   // Gesture tap should hide the cursor.
    824   observer_a.reset();
    825   observer_b.reset();
    826   generator.GestureTapAt(gfx::Point(25, 25));
    827   EXPECT_TRUE(observer_a.did_visibility_change());
    828   EXPECT_FALSE(observer_b.did_visibility_change());
    829   EXPECT_FALSE(observer_a.is_cursor_visible());
    830 
    831   // Mouse move should show the cursor.
    832   observer_a.reset();
    833   observer_b.reset();
    834   generator.MoveMouseTo(50, 50);
    835   EXPECT_TRUE(observer_a.did_visibility_change());
    836   EXPECT_FALSE(observer_b.did_visibility_change());
    837   EXPECT_TRUE(observer_a.is_cursor_visible());
    838 }
    839 
    840 }  // namespace ash
    841