diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 02:52:14 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 02:52:14 +0000 |
commit | e5c49f5cb6e52f3d3f23f6f514421d3247d4c01b (patch) | |
tree | 34ab982b7e5e51285b68db48907adafcd6efbc5d | |
parent | 5f4b64f3dbc358de9b561d4874bf37a2f11bf41b (diff) | |
download | chromium_src-e5c49f5cb6e52f3d3f23f6f514421d3247d4c01b.zip chromium_src-e5c49f5cb6e52f3d3f23f6f514421d3247d4c01b.tar.gz chromium_src-e5c49f5cb6e52f3d3f23f6f514421d3247d4c01b.tar.bz2 |
[Aura] Support additonal event filters in DesktopEventFilter.
BUG=none.
TEST=DesktopEventFilter.AddtionalFilters test should pass.
Review URL: http://codereview.chromium.org/8565018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110022 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/aura/aura.gyp | 2 | ||||
-rw-r--r-- | ui/aura/event_filter_unittest.cc | 62 | ||||
-rw-r--r-- | ui/aura/test/test_event_filter.cc | 47 | ||||
-rw-r--r-- | ui/aura/test/test_event_filter.h | 63 | ||||
-rw-r--r-- | ui/aura_shell/desktop_event_filter.cc | 58 | ||||
-rw-r--r-- | ui/aura_shell/desktop_event_filter.h | 22 | ||||
-rw-r--r-- | ui/aura_shell/desktop_event_filter_unittest.cc | 88 |
7 files changed, 271 insertions, 71 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index 66c4375..45c8709 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -69,6 +69,8 @@ 'test/aura_test_base.h', 'test/event_generator.cc', 'test/event_generator.h', + 'test/test_event_filter.cc', + 'test/test_event_filter.h', 'test/test_stacking_client.cc', 'test/test_stacking_client.h', 'test/test_windows.cc', diff --git a/ui/aura/event_filter_unittest.cc b/ui/aura/event_filter_unittest.cc index 03f01db..2e7ea79 100644 --- a/ui/aura/event_filter_unittest.cc +++ b/ui/aura/event_filter_unittest.cc @@ -10,6 +10,7 @@ #include "ui/aura/event.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/event_generator.h" +#include "ui/aura/test/test_event_filter.h" #include "ui/aura/test/test_window_delegate.h" #if defined(OS_WIN) @@ -74,67 +75,6 @@ Window* CreateWindow(int id, Window* parent, WindowDelegate* delegate) { return window; } -class TestEventFilter : public EventFilter { - public: - explicit TestEventFilter(Window* owner) - : EventFilter(owner), - key_event_count_(0), - mouse_event_count_(0), - touch_event_count_(0), - consumes_key_events_(false), - consumes_mouse_events_(false), - consumes_touch_events_(false) { - } - virtual ~TestEventFilter() {} - - void ResetCounts() { - key_event_count_ = 0; - mouse_event_count_ = 0; - touch_event_count_ = 0; - } - - int key_event_count() const { return key_event_count_; } - int mouse_event_count() const { return mouse_event_count_; } - int touch_event_count() const { return touch_event_count_; } - - void set_consumes_key_events(bool consumes_key_events) { - consumes_key_events_ = consumes_key_events; - } - void set_consumes_mouse_events(bool consumes_mouse_events) { - consumes_mouse_events_ = consumes_mouse_events; - } - void set_consumes_touch_events(bool consumes_touch_events) { - consumes_touch_events_ = consumes_touch_events; - } - - // Overridden from EventFilter: - virtual bool PreHandleKeyEvent(Window* target, KeyEvent* event) OVERRIDE { - ++key_event_count_; - return consumes_key_events_; - } - virtual bool PreHandleMouseEvent(Window* target, MouseEvent* event) OVERRIDE { - ++mouse_event_count_; - return consumes_mouse_events_; - } - virtual ui::TouchStatus PreHandleTouchEvent(Window* target, - TouchEvent* event) OVERRIDE { - ++touch_event_count_; - // TODO(sadrul): ! - return ui::TOUCH_STATUS_UNKNOWN; - } - - private: - int key_event_count_; - int mouse_event_count_; - int touch_event_count_; - - bool consumes_key_events_; - bool consumes_mouse_events_; - bool consumes_touch_events_; - - DISALLOW_COPY_AND_ASSIGN(TestEventFilter); -}; - // Creates this hierarchy: // // Desktop Window (EF) diff --git a/ui/aura/test/test_event_filter.cc b/ui/aura/test/test_event_filter.cc new file mode 100644 index 0000000..de99689 --- /dev/null +++ b/ui/aura/test/test_event_filter.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/aura/test/test_event_filter.h" + +namespace aura { +namespace test { + +TestEventFilter::TestEventFilter(Window* owner) + : EventFilter(owner), + key_event_count_(0), + mouse_event_count_(0), + touch_event_count_(0), + consumes_key_events_(false), + consumes_mouse_events_(false), + consumes_touch_events_(false) { +} + +TestEventFilter::~TestEventFilter() { +} + +void TestEventFilter::ResetCounts() { + key_event_count_ = 0; + mouse_event_count_ = 0; + touch_event_count_ = 0; +} + +bool TestEventFilter::PreHandleKeyEvent(Window* target, KeyEvent* event) { + ++key_event_count_; + return consumes_key_events_; +} + +bool TestEventFilter::PreHandleMouseEvent(Window* target, MouseEvent* event) { + ++mouse_event_count_; + return consumes_mouse_events_; +} + +ui::TouchStatus TestEventFilter::PreHandleTouchEvent(Window* target, + TouchEvent* event) { + ++touch_event_count_; + // TODO(sadrul): ! + return ui::TOUCH_STATUS_UNKNOWN; +} + +} // namespace test +} // namespace aura diff --git a/ui/aura/test/test_event_filter.h b/ui/aura/test/test_event_filter.h new file mode 100644 index 0000000..9529826 --- /dev/null +++ b/ui/aura/test/test_event_filter.h @@ -0,0 +1,63 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_AURA_TEST_TEST_EVENT_FILTER_H_ +#define UI_AURA_TEST_TEST_EVENT_FILTER_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "ui/aura/event_filter.h" + +namespace aura { + +class Window; + +namespace test { + +// TestEventFilter counts the key, mouse and touch events it receives and can +// optinally be set to consume those events. +class TestEventFilter : public EventFilter { + public: + explicit TestEventFilter(Window* owner); + virtual ~TestEventFilter(); + + // Resets all event counters. + void ResetCounts(); + + int key_event_count() const { return key_event_count_; } + int mouse_event_count() const { return mouse_event_count_; } + int touch_event_count() const { return touch_event_count_; } + + void set_consumes_key_events(bool consumes_key_events) { + consumes_key_events_ = consumes_key_events; + } + void set_consumes_mouse_events(bool consumes_mouse_events) { + consumes_mouse_events_ = consumes_mouse_events; + } + void set_consumes_touch_events(bool consumes_touch_events) { + consumes_touch_events_ = consumes_touch_events; + } + + // Overridden from EventFilter: + virtual bool PreHandleKeyEvent(Window* target, KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(Window* target, MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(Window* target, + TouchEvent* event) OVERRIDE; + + private: + int key_event_count_; + int mouse_event_count_; + int touch_event_count_; + + bool consumes_key_events_; + bool consumes_mouse_events_; + bool consumes_touch_events_; + + DISALLOW_COPY_AND_ASSIGN(TestEventFilter); +}; + +} // namespace test +} // namespace aura + +#endif // UI_AURA_TEST_TEST_EVENT_FILTER_H_ diff --git a/ui/aura_shell/desktop_event_filter.cc b/ui/aura_shell/desktop_event_filter.cc index 3d17865..d69ead1 100644 --- a/ui/aura_shell/desktop_event_filter.cc +++ b/ui/aura_shell/desktop_event_filter.cc @@ -47,6 +47,17 @@ DesktopEventFilter::DesktopEventFilter() } DesktopEventFilter::~DesktopEventFilter() { + // Additional filters are not owned by DesktopEventFilter and they + // should all be removed when running here. |filters_| has + // check_empty == true and will DCHECK failure if it is not empty. +} + +void DesktopEventFilter::AddFilter(aura::EventFilter* filter) { + filters_.AddObserver(filter); +} + +void DesktopEventFilter::RemoveFilter(aura::EventFilter* filter) { + filters_.RemoveObserver(filter); } //////////////////////////////////////////////////////////////////////////////// @@ -54,11 +65,14 @@ DesktopEventFilter::~DesktopEventFilter() { bool DesktopEventFilter::PreHandleKeyEvent(aura::Window* target, aura::KeyEvent* event) { - return false; + return FilterKeyEvent(target, event); } bool DesktopEventFilter::PreHandleMouseEvent(aura::Window* target, aura::MouseEvent* event) { + if (FilterMouseEvent(target, event)) + return true; + switch (event->type()) { case ui::ET_MOUSE_PRESSED: ActivateIfNecessary(target, event); @@ -75,6 +89,10 @@ bool DesktopEventFilter::PreHandleMouseEvent(aura::Window* target, ui::TouchStatus DesktopEventFilter::PreHandleTouchEvent( aura::Window* target, aura::TouchEvent* event) { + ui::TouchStatus status = FilterTouchEvent(target, event); + if (status != ui::TOUCH_STATUS_UNKNOWN) + return status; + if (event->type() == ui::ET_TOUCH_PRESSED) ActivateIfNecessary(target, event); return ui::TOUCH_STATUS_UNKNOWN; @@ -105,5 +123,43 @@ void DesktopEventFilter::HandleMouseMoved(aura::Window* target, aura::Desktop::GetInstance()->SetCursor(cursor); } +bool DesktopEventFilter::FilterKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + bool handled = false; + if (filters_.might_have_observers()) { + ObserverListBase<aura::EventFilter>::Iterator it(filters_); + aura::EventFilter* filter; + while (!handled && (filter = it.GetNext()) != NULL) + handled = filter->PreHandleKeyEvent(target, event); + } + return handled; +} + +bool DesktopEventFilter::FilterMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + bool handled = false; + if (filters_.might_have_observers()) { + ObserverListBase<aura::EventFilter>::Iterator it(filters_); + aura::EventFilter* filter; + while (!handled && (filter = it.GetNext()) != NULL) + handled = filter->PreHandleMouseEvent(target, event); + } + return handled; +} + +ui::TouchStatus DesktopEventFilter::FilterTouchEvent(aura::Window* target, + aura::TouchEvent* event) { + ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; + if (filters_.might_have_observers()) { + ObserverListBase<aura::EventFilter>::Iterator it(filters_); + aura::EventFilter* filter; + while (status == ui::TOUCH_STATUS_UNKNOWN && + (filter = it.GetNext()) != NULL) { + status = filter->PreHandleTouchEvent(target, event); + } + } + return status; +} + } // namespace internal } // namespace aura_shell diff --git a/ui/aura_shell/desktop_event_filter.h b/ui/aura_shell/desktop_event_filter.h index 1ad0438..a5cb2c8 100644 --- a/ui/aura_shell/desktop_event_filter.h +++ b/ui/aura_shell/desktop_event_filter.h @@ -7,17 +7,29 @@ #pragma once #include "base/compiler_specific.h" +#include "base/observer_list.h" #include "ui/aura/event_filter.h" #include "ui/aura_shell/aura_shell_export.h" namespace aura_shell { namespace internal { +// DesktopEventFilter gets all desktop events first and can provide actions to +// those events. It implements desktop features such as click to activate a +// window and cursor change when moving mouse. +// Additional event filters can be added to DesktopEventFilter. Events will +// pass through those additional filters in their addition order and could be +// consumed by any of those filters. If an event is consumed by a filter, the +// rest of the filter(s) and DesktopEventFilter will not see the consumed event. class AURA_SHELL_EXPORT DesktopEventFilter : public aura::EventFilter { public: DesktopEventFilter(); virtual ~DesktopEventFilter(); + // Adds/removes additional event filters. + void AddFilter(aura::EventFilter* filter); + void RemoveFilter(aura::EventFilter* filter); + // Overridden from EventFilter: virtual bool PreHandleKeyEvent(aura::Window* target, aura::KeyEvent* event) OVERRIDE; @@ -34,6 +46,16 @@ class AURA_SHELL_EXPORT DesktopEventFilter : public aura::EventFilter { // default resize cursors for window edges. void HandleMouseMoved(aura::Window* target, aura::MouseEvent* event); + // Dispatches event to addtional filters. Returns false or + // ui::TOUCH_STATUS_UNKNOWN if event is consumed. + bool FilterKeyEvent(aura::Window* target, aura::KeyEvent* event); + bool FilterMouseEvent(aura::Window* target, aura::MouseEvent* event); + ui::TouchStatus FilterTouchEvent(aura::Window* target, + aura::TouchEvent* event); + + // Additional event filters that pre-handles events. + ObserverList<aura::EventFilter, true> filters_; + DISALLOW_COPY_AND_ASSIGN(DesktopEventFilter); }; diff --git a/ui/aura_shell/desktop_event_filter_unittest.cc b/ui/aura_shell/desktop_event_filter_unittest.cc index 498dbda..504f1ec 100644 --- a/ui/aura_shell/desktop_event_filter_unittest.cc +++ b/ui/aura_shell/desktop_event_filter_unittest.cc @@ -10,6 +10,7 @@ #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/event_generator.h" #include "ui/aura/test/test_windows.h" +#include "ui/aura/test/test_event_filter.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_stacking_client.h" #include "ui/aura_shell/shell_window_ids.h" @@ -19,9 +20,9 @@ namespace aura_shell { namespace test { -class DefaultEventFilterTest : public aura::test::AuraTestBase { +class DesktopEventFilterTest : public aura::test::AuraTestBase { public: - DefaultEventFilterTest() { + DesktopEventFilterTest() { aura::Desktop::GetInstance()->SetEventFilter( new internal::DesktopEventFilter); @@ -31,12 +32,12 @@ class DefaultEventFilterTest : public aura::test::AuraTestBase { stacking_client->default_container()->set_id( internal::kShellWindowId_DefaultContainer); } - virtual ~DefaultEventFilterTest() { + virtual ~DesktopEventFilterTest() { aura::Desktop::GetInstance()->SetEventFilter(NULL); } private: - DISALLOW_COPY_AND_ASSIGN(DefaultEventFilterTest); + DISALLOW_COPY_AND_ASSIGN(DesktopEventFilterTest); }; class HitTestWindowDelegate : public aura::test::TestWindowDelegate { @@ -58,7 +59,7 @@ class HitTestWindowDelegate : public aura::test::TestWindowDelegate { DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate); }; -TEST_F(DefaultEventFilterTest, Focus) { +TEST_F(DesktopEventFilterTest, Focus) { aura::Desktop* desktop = aura::Desktop::GetInstance(); desktop->SetBounds(gfx::Rect(0, 0, 510, 510)); @@ -120,7 +121,7 @@ TEST_F(DefaultEventFilterTest, Focus) { } // Various assertion testing for activating windows. -TEST_F(DefaultEventFilterTest, ActivateOnMouse) { +TEST_F(DesktopEventFilterTest, ActivateOnMouse) { aura::Desktop* desktop = aura::Desktop::GetInstance(); aura::test::ActivateWindowDelegate d1; @@ -186,7 +187,7 @@ TEST_F(DefaultEventFilterTest, ActivateOnMouse) { } // Essentially the same as ActivateOnMouse, but for touch events. -TEST_F(DefaultEventFilterTest, ActivateOnTouch) { +TEST_F(DesktopEventFilterTest, ActivateOnTouch) { aura::Desktop* desktop = aura::Desktop::GetInstance(); aura::test::ActivateWindowDelegate d1; @@ -252,7 +253,7 @@ TEST_F(DefaultEventFilterTest, ActivateOnTouch) { EXPECT_EQ(0, d1.lost_active_count()); } -TEST_F(DefaultEventFilterTest, MouseEventCursors) { +TEST_F(DesktopEventFilterTest, MouseEventCursors) { aura::Desktop* desktop = aura::Desktop::GetInstance(); // Create a window. @@ -316,7 +317,7 @@ TEST_F(DefaultEventFilterTest, MouseEventCursors) { EXPECT_EQ(aura::kCursorNull, desktop->last_cursor()); } -TEST_F(DefaultEventFilterTest, TransformActivate) { +TEST_F(DesktopEventFilterTest, TransformActivate) { aura::Desktop* desktop = aura::Desktop::GetInstance(); gfx::Size size = desktop->GetHostSize(); EXPECT_EQ(gfx::Rect(size), @@ -355,5 +356,74 @@ TEST_F(DefaultEventFilterTest, TransformActivate) { EXPECT_EQ(w1.get(), w1->GetFocusManager()->GetFocusedWindow()); } +TEST_F(DesktopEventFilterTest, AdditionalFilters) { + aura::Desktop* desktop = aura::Desktop::GetInstance(); + + // Creates a window and make it active + scoped_ptr<aura::Window> w1(aura::test::CreateTestWindow( + SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100), NULL)); + desktop->SetActiveWindow(w1.get(), NULL); + + // Creates two addition filters + scoped_ptr<aura::test::TestEventFilter> f1( + new aura::test::TestEventFilter(NULL)); + scoped_ptr<aura::test::TestEventFilter> f2( + new aura::test::TestEventFilter(NULL)); + + // Adds them to desktop event filter. + internal::DesktopEventFilter* desktop_filter = + static_cast<internal::DesktopEventFilter*>(desktop->event_filter()); + desktop_filter->AddFilter(f1.get()); + desktop_filter->AddFilter(f2.get()); + + // Dispatches mouse and keyboard events. + aura::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); + desktop->DispatchKeyEvent(&key_event); + aura::MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), 0x0); + desktop->DispatchMouseEvent(&mouse_pressed); + + // Both filters should get the events. + EXPECT_EQ(1, f1->key_event_count()); + EXPECT_EQ(1, f1->mouse_event_count()); + EXPECT_EQ(1, f2->key_event_count()); + EXPECT_EQ(1, f2->mouse_event_count()); + + f1->ResetCounts(); + f2->ResetCounts(); + + // Makes f1 consume events. + f1->set_consumes_key_events(true); + f1->set_consumes_mouse_events(true); + + // Dispatches events. + desktop->DispatchKeyEvent(&key_event); + aura::MouseEvent mouse_released(ui::ET_MOUSE_RELEASED, gfx::Point(0, 0), 0x0); + desktop->DispatchMouseEvent(&mouse_released); + + // f1 should still get the events but f2 no longer gets them. + EXPECT_EQ(1, f1->key_event_count()); + EXPECT_EQ(1, f1->mouse_event_count()); + EXPECT_EQ(0, f2->key_event_count()); + EXPECT_EQ(0, f2->mouse_event_count()); + + f1->ResetCounts(); + f2->ResetCounts(); + + // Remove f1 from additonal filters list. + desktop_filter->RemoveFilter(f1.get()); + + // Dispatches events. + desktop->DispatchKeyEvent(&key_event); + desktop->DispatchMouseEvent(&mouse_pressed); + + // f1 should get no events since it's out and f2 should get them. + EXPECT_EQ(0, f1->key_event_count()); + EXPECT_EQ(0, f1->mouse_event_count()); + EXPECT_EQ(1, f2->key_event_count()); + EXPECT_EQ(1, f2->mouse_event_count()); + + desktop_filter->RemoveFilter(f2.get()); +} + } // namespace test } // namespace aura_shell |