Home | History | Annotate | Download | only in corewm
      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 "ui/views/corewm/compound_event_filter.h"
      6 
      7 #include "ui/aura/client/activation_client.h"
      8 #include "ui/aura/client/cursor_client.h"
      9 #include "ui/aura/env.h"
     10 #include "ui/aura/root_window.h"
     11 #include "ui/aura/test/aura_test_base.h"
     12 #include "ui/aura/test/event_generator.h"
     13 #include "ui/aura/test/test_activation_client.h"
     14 #include "ui/aura/test/test_cursor_client.h"
     15 #include "ui/aura/test/test_windows.h"
     16 #include "ui/base/events/event.h"
     17 #include "ui/base/events/event_utils.h"
     18 
     19 namespace {
     20 
     21 base::TimeDelta GetTime() {
     22   return ui::EventTimeForNow();
     23 }
     24 
     25 }
     26 
     27 namespace views {
     28 namespace corewm {
     29 
     30 namespace {
     31 
     32 // An event filter that consumes all gesture events.
     33 class ConsumeGestureEventFilter : public ui::EventHandler {
     34  public:
     35   ConsumeGestureEventFilter() {}
     36   virtual ~ConsumeGestureEventFilter() {}
     37 
     38  private:
     39   // Overridden from ui::EventHandler:
     40   virtual void OnGestureEvent(ui::GestureEvent* e) OVERRIDE {
     41     e->StopPropagation();
     42   }
     43 
     44   DISALLOW_COPY_AND_ASSIGN(ConsumeGestureEventFilter);
     45 };
     46 
     47 }  // namespace
     48 
     49 typedef aura::test::AuraTestBase CompoundEventFilterTest;
     50 
     51 TEST_F(CompoundEventFilterTest, CursorVisibilityChange) {
     52   scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter);
     53   aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
     54   aura::test::TestWindowDelegate delegate;
     55   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234,
     56       gfx::Rect(5, 5, 100, 100), root_window()));
     57   window->Show();
     58   window->SetCapture();
     59 
     60   aura::test::TestCursorClient cursor_client(root_window());
     61 
     62   // Send key event to hide the cursor.
     63   ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, true);
     64   root_window()->AsRootWindowHostDelegate()->OnHostKeyEvent(&key);
     65   EXPECT_FALSE(cursor_client.IsCursorVisible());
     66 
     67   // Synthesized mouse event should not show the cursor.
     68   ui::MouseEvent enter(ui::ET_MOUSE_ENTERED, gfx::Point(10, 10),
     69                        gfx::Point(10, 10), 0);
     70   enter.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED);
     71   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&enter);
     72   EXPECT_FALSE(cursor_client.IsCursorVisible());
     73 
     74   ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
     75                       gfx::Point(10, 10), 0);
     76   move.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED);
     77   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&move);
     78   EXPECT_FALSE(cursor_client.IsCursorVisible());
     79 
     80   ui::MouseEvent real_move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
     81                            gfx::Point(10, 10), 0);
     82   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&real_move);
     83   EXPECT_TRUE(cursor_client.IsCursorVisible());
     84 
     85   // Send key event to hide the cursor again.
     86   root_window()->AsRootWindowHostDelegate()->OnHostKeyEvent(&key);
     87   EXPECT_FALSE(cursor_client.IsCursorVisible());
     88 
     89   // Mouse synthesized exit event should not show the cursor.
     90   ui::MouseEvent exit(ui::ET_MOUSE_EXITED, gfx::Point(10, 10),
     91                       gfx::Point(10, 10), 0);
     92   exit.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED);
     93   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&exit);
     94   EXPECT_FALSE(cursor_client.IsCursorVisible());
     95 }
     96 
     97 TEST_F(CompoundEventFilterTest, TouchHidesCursor) {
     98   scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter);
     99   aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
    100   aura::test::TestWindowDelegate delegate;
    101   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234,
    102       gfx::Rect(5, 5, 100, 100), root_window()));
    103   window->Show();
    104   window->SetCapture();
    105 
    106   aura::test::TestCursorClient cursor_client(root_window());
    107 
    108   ui::MouseEvent mouse0(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
    109                         gfx::Point(10, 10), 0);
    110   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse0);
    111   EXPECT_TRUE(cursor_client.IsMouseEventsEnabled());
    112 
    113   // This press is required for the GestureRecognizer to associate a target
    114   // with kTouchId
    115   ui::TouchEvent press0(
    116       ui::ET_TOUCH_PRESSED, gfx::Point(90, 90), 1, GetTime());
    117   root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press0);
    118   EXPECT_FALSE(cursor_client.IsMouseEventsEnabled());
    119 
    120   ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), 1, GetTime());
    121   root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move);
    122   EXPECT_FALSE(cursor_client.IsMouseEventsEnabled());
    123 
    124   ui::TouchEvent release(
    125       ui::ET_TOUCH_RELEASED, gfx::Point(10, 10), 1, GetTime());
    126   root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
    127   EXPECT_FALSE(cursor_client.IsMouseEventsEnabled());
    128 
    129   ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
    130                         gfx::Point(10, 10), 0);
    131   // Move the cursor again. The cursor should be visible.
    132   root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse1);
    133   EXPECT_TRUE(cursor_client.IsMouseEventsEnabled());
    134 
    135   // Now activate the window and press on it again.
    136   ui::TouchEvent press1(
    137       ui::ET_TOUCH_PRESSED, gfx::Point(90, 90), 1, GetTime());
    138   aura::client::GetActivationClient(
    139       root_window())->ActivateWindow(window.get());
    140   root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1);
    141   EXPECT_FALSE(cursor_client.IsMouseEventsEnabled());
    142   aura::Env::GetInstance()->RemovePreTargetHandler(compound_filter.get());
    143 }
    144 
    145 // Tests that if an event filter consumes a gesture, then it doesn't focus the
    146 // window.
    147 TEST_F(CompoundEventFilterTest, FilterConsumedGesture) {
    148   scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter);
    149   scoped_ptr<ui::EventHandler> gesure_handler(new ConsumeGestureEventFilter);
    150   compound_filter->AddHandler(gesure_handler.get());
    151   aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
    152   aura::test::TestWindowDelegate delegate;
    153   DCHECK(root_window());
    154   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234,
    155       gfx::Rect(5, 5, 100, 100), root_window()));
    156   window->Show();
    157 
    158   EXPECT_TRUE(window->CanFocus());
    159   EXPECT_FALSE(window->HasFocus());
    160 
    161   // Tap on the window should not focus it since the filter will be consuming
    162   // the gestures.
    163   aura::test::EventGenerator generator(root_window(), gfx::Point(50, 50));
    164   generator.PressTouch();
    165   EXPECT_FALSE(window->HasFocus());
    166 
    167   compound_filter->RemoveHandler(gesure_handler.get());
    168   aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
    169 }
    170 
    171 // Verifies we don't attempt to hide the mouse when the mouse is down and a
    172 // touch event comes in.
    173 TEST_F(CompoundEventFilterTest, DontHideWhenMouseDown) {
    174   aura::test::EventGenerator event_generator(root_window());
    175 
    176   scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter);
    177   aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get());
    178   aura::test::TestWindowDelegate delegate;
    179   scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234,
    180       gfx::Rect(5, 5, 100, 100), root_window()));
    181   window->Show();
    182 
    183   aura::test::TestCursorClient cursor_client(root_window());
    184 
    185   // Move and press the mouse over the window.
    186   event_generator.MoveMouseTo(10, 10);
    187   EXPECT_TRUE(cursor_client.IsMouseEventsEnabled());
    188   event_generator.PressLeftButton();
    189   EXPECT_TRUE(cursor_client.IsMouseEventsEnabled());
    190   EXPECT_TRUE(aura::Env::GetInstance()->is_mouse_button_down());
    191 
    192   // Do a touch event. As the mouse button is down this should not disable mouse
    193   // events.
    194   event_generator.PressTouch();
    195   EXPECT_TRUE(cursor_client.IsMouseEventsEnabled());
    196   aura::Env::GetInstance()->RemovePreTargetHandler(compound_filter.get());
    197 }
    198 
    199 }  // namespace corewm
    200 }  // namespace views
    201