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