summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 02:52:14 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 02:52:14 +0000
commite5c49f5cb6e52f3d3f23f6f514421d3247d4c01b (patch)
tree34ab982b7e5e51285b68db48907adafcd6efbc5d
parent5f4b64f3dbc358de9b561d4874bf37a2f11bf41b (diff)
downloadchromium_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.gyp2
-rw-r--r--ui/aura/event_filter_unittest.cc62
-rw-r--r--ui/aura/test/test_event_filter.cc47
-rw-r--r--ui/aura/test/test_event_filter.h63
-rw-r--r--ui/aura_shell/desktop_event_filter.cc58
-rw-r--r--ui/aura_shell/desktop_event_filter.h22
-rw-r--r--ui/aura_shell/desktop_event_filter_unittest.cc88
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