summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 05:56:51 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 05:56:51 +0000
commit1eeb971326a2a38b782443ae1857f37f5d74eb07 (patch)
tree8ed8afb1c8c044717d6dcedbd4ac407ee47cda1c /ui
parent8af40c7f4612fab5e348ef866d93a05b79e2d035 (diff)
downloadchromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.zip
chromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.tar.gz
chromium_src-1eeb971326a2a38b782443ae1857f37f5d74eb07.tar.bz2
events: Inlcude the event-phase and event-result in Event.
An event-handler can be installed on a target as both a pre-target and a post-target handler. In such cases, it will be necessary to know the phase of the event-dispatch. So add EventPhase. Also, from a handler, it may be necessary to know whether the event has been handled by any other handlers before this. So include EventResult in the event too. BUG=none. Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=155825 Review URL: https://chromiumcodereview.appspot.com/10916210 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155957 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/base/events/event.cc12
-rw-r--r--ui/base/events/event.h9
-rw-r--r--ui/base/events/event_constants.h9
-rw-r--r--ui/base/events/event_dispatcher.cc11
-rw-r--r--ui/base/events/event_dispatcher.h19
-rw-r--r--ui/base/events/event_dispatcher_unittest.cc79
6 files changed, 106 insertions, 33 deletions
diff --git a/ui/base/events/event.cc b/ui/base/events/event.cc
index f288107..a2190ff 100644
--- a/ui/base/events/event.cc
+++ b/ui/base/events/event.cc
@@ -74,7 +74,9 @@ Event::Event(EventType type, int flags)
time_stamp_(base::Time::NowFromSystemTime() - base::Time()),
flags_(flags),
delete_native_event_(false),
- target_(NULL) {
+ target_(NULL),
+ phase_(EP_PREDISPATCH),
+ result_(ER_UNHANDLED) {
Init();
}
@@ -85,7 +87,9 @@ Event::Event(const base::NativeEvent& native_event,
time_stamp_(EventTimeFromNative(native_event)),
flags_(flags),
delete_native_event_(false),
- target_(NULL) {
+ target_(NULL),
+ phase_(EP_PREDISPATCH),
+ result_(ER_UNHANDLED) {
InitWithNativeEvent(native_event);
}
@@ -95,7 +99,9 @@ Event::Event(const Event& copy)
time_stamp_(copy.time_stamp_),
flags_(copy.flags_),
delete_native_event_(false),
- target_(NULL) {
+ target_(NULL),
+ phase_(EP_PREDISPATCH),
+ result_(ER_UNHANDLED) {
#if defined(USE_X11)
if (native_event_)
delete_native_event_ = true;
diff --git a/ui/base/events/event.h b/ui/base/events/event.h
index 89831f2..4d8ad63 100644
--- a/ui/base/events/event.h
+++ b/ui/base/events/event.h
@@ -33,6 +33,11 @@ class UI_EXPORT Event {
event_->target_ = target;
}
+ void set_phase(EventPhase phase) { event_->phase_ = phase; }
+ void set_result(int result) {
+ event_->result_ = static_cast<EventResult>(result);
+ }
+
private:
DispatcherApi();
Event* event_;
@@ -65,6 +70,8 @@ class UI_EXPORT Event {
void set_flags(int flags) { flags_ = flags; }
EventTarget* target() const { return target_; }
+ EventPhase phase() const { return phase_; }
+ EventResult result() const { return result_; }
// The following methods return true if the respective keys were pressed at
// the time the event was created.
@@ -171,6 +178,8 @@ class UI_EXPORT Event {
int flags_;
bool delete_native_event_;
EventTarget* target_;
+ EventPhase phase_;
+ EventResult result_;
};
class UI_EXPORT LocatedEvent : public Event {
diff --git a/ui/base/events/event_constants.h b/ui/base/events/event_constants.h
index 91d0be5..43a0e90 100644
--- a/ui/base/events/event_constants.h
+++ b/ui/base/events/event_constants.h
@@ -105,6 +105,15 @@ enum EventResult {
// propagated to other handlers.
};
+// Phase of the event dispatch.
+enum EventPhase {
+ EP_PREDISPATCH,
+ EP_PRETARGET,
+ EP_TARGET,
+ EP_POSTTARGET,
+ EP_POSTDISPATCH
+};
+
enum TouchStatus {
TOUCH_STATUS_UNKNOWN = 0, // Unknown touch status. This is used to indicate
// that the touch event was not handled.
diff --git a/ui/base/events/event_dispatcher.cc b/ui/base/events/event_dispatcher.cc
index ec9c5ac..23bad57 100644
--- a/ui/base/events/event_dispatcher.cc
+++ b/ui/base/events/event_dispatcher.cc
@@ -44,4 +44,15 @@ EventResult EventDispatcher::DispatchEventToSingleHandler(EventHandler* handler,
return handler->OnGestureEvent(event);
}
+////////////////////////////////////////////////////////////////////////////////
+// EventDispatcher::ScopedDispatchHelper
+
+EventDispatcher::ScopedDispatchHelper::ScopedDispatchHelper(Event* event)
+ : Event::DispatcherApi(event) {
+}
+
+EventDispatcher::ScopedDispatchHelper::~ScopedDispatchHelper() {
+ set_phase(EP_POSTDISPATCH);
+}
+
} // namespace ui
diff --git a/ui/base/events/event_dispatcher.h b/ui/base/events/event_dispatcher.h
index 48aa5d4..55cab11 100644
--- a/ui/base/events/event_dispatcher.h
+++ b/ui/base/events/event_dispatcher.h
@@ -33,12 +33,13 @@ class UI_EXPORT EventDispatcher {
if (!target || !target->CanAcceptEvents())
return ER_UNHANDLED;
- Event::DispatcherApi dispatcher(event);
- dispatcher.set_target(target);
+ ScopedDispatchHelper dispatch_helper(event);
+ dispatch_helper.set_target(target);
EventHandlerList list;
target->GetPreTargetHandlers(&list);
ProcessPreTargetList(&list);
+ dispatch_helper.set_phase(EP_PRETARGET);
int result = DispatchEventToEventHandlers(list, event);
if (result & ER_CONSUMED)
return result;
@@ -49,7 +50,9 @@ class UI_EXPORT EventDispatcher {
// this layer, however it should not be processed in the next layer of
// abstraction.
if (CanDispatchToTarget(target)) {
+ dispatch_helper.set_phase(EP_TARGET);
result |= DispatchEventToSingleHandler(target, event);
+ dispatch_helper.set_result(event->result() | result);
if (result & ER_CONSUMED)
return result;
}
@@ -60,17 +63,29 @@ class UI_EXPORT EventDispatcher {
list.clear();
target->GetPostTargetHandlers(&list);
ProcessPostTargetList(&list);
+ dispatch_helper.set_phase(EP_POSTTARGET);
result |= DispatchEventToEventHandlers(list, event);
return result;
}
private:
+ class UI_EXPORT ScopedDispatchHelper : public NON_EXPORTED_BASE(
+ Event::DispatcherApi) {
+ public:
+ explicit ScopedDispatchHelper(Event* event);
+ virtual ~ScopedDispatchHelper();
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedDispatchHelper);
+ };
+
template<class T>
int DispatchEventToEventHandlers(EventHandlerList& list, T* event) {
int result = ER_UNHANDLED;
+ Event::DispatcherApi dispatch_helper(event);
for (EventHandlerList::const_iterator it = list.begin(),
end = list.end(); it != end; ++it) {
result |= DispatchEventToSingleHandler((*it), event);
+ dispatch_helper.set_result(event->result() | result);
if (result & ER_CONSUMED)
return result;
}
diff --git a/ui/base/events/event_dispatcher_unittest.cc b/ui/base/events/event_dispatcher_unittest.cc
index 3cdeccfd..4f7b1a7 100644
--- a/ui/base/events/event_dispatcher_unittest.cc
+++ b/ui/base/events/event_dispatcher_unittest.cc
@@ -10,26 +10,6 @@ namespace ui {
namespace {
-class TestEventDispatcher : public EventDispatcher {
- public:
- TestEventDispatcher() {}
- virtual ~TestEventDispatcher() {}
-
- private:
- // Overridden from EventDispatcher:
- virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE {
- return true;
- }
-
- virtual void ProcessPreTargetList(EventHandlerList* list) OVERRIDE {
- }
-
- virtual void ProcessPostTargetList(EventHandlerList* list) OVERRIDE {
- }
-
- DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
-};
-
class TestTarget : public EventTarget {
public:
TestTarget() : parent_(NULL) {}
@@ -67,50 +47,80 @@ class TestEventHandler : public EventHandler {
public:
TestEventHandler(int id)
: id_(id),
- event_result_(ER_UNHANDLED) {
+ event_result_(ER_UNHANDLED),
+ expected_phase_(EP_PREDISPATCH) {
}
virtual ~TestEventHandler() {}
- void ReceivedEventForTarget(EventTarget* target) {
- static_cast<TestTarget*>(target)->AddHandlerId(id_);
+ void ReceivedEvent(Event* event) {
+ EXPECT_EQ(expected_phase_, event->phase());
+ static_cast<TestTarget*>(event->target())->AddHandlerId(id_);
}
void set_event_result(EventResult result) { event_result_ = result; }
+ void set_expected_phase(EventPhase phase) { expected_phase_ = phase; }
private:
// Overridden from EventHandler:
virtual EventResult OnKeyEvent(KeyEvent* event) OVERRIDE {
- ReceivedEventForTarget(event->target());
+ ReceivedEvent(event);
return event_result_;
}
virtual EventResult OnMouseEvent(MouseEvent* event) OVERRIDE {
- ReceivedEventForTarget(event->target());
+ ReceivedEvent(event);
return event_result_;
}
virtual EventResult OnScrollEvent(ScrollEvent* event) OVERRIDE {
- ReceivedEventForTarget(event->target());
+ ReceivedEvent(event);
return event_result_;
}
virtual TouchStatus OnTouchEvent(TouchEvent* event) OVERRIDE {
- ReceivedEventForTarget(event->target());
+ ReceivedEvent(event);
return ui::TOUCH_STATUS_UNKNOWN;
}
virtual EventResult OnGestureEvent(GestureEvent* event) OVERRIDE {
- ReceivedEventForTarget(event->target());
+ ReceivedEvent(event);
return event_result_;
}
int id_;
EventResult event_result_;
+ EventPhase expected_phase_;
DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
};
+class TestEventDispatcher : public EventDispatcher {
+ public:
+ TestEventDispatcher() {}
+ virtual ~TestEventDispatcher() {}
+
+ private:
+ // Overridden from EventDispatcher:
+ virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE {
+ return true;
+ }
+
+ virtual void ProcessPreTargetList(EventHandlerList* list) OVERRIDE {
+ for (EventHandlerList::iterator i = list->begin(); i != list->end(); ++i) {
+ static_cast<TestEventHandler*>(*i)->set_expected_phase(EP_PRETARGET);
+ }
+ }
+
+ virtual void ProcessPostTargetList(EventHandlerList* list) OVERRIDE {
+ for (EventHandlerList::iterator i = list->begin(); i != list->end(); ++i) {
+ static_cast<TestEventHandler*>(*i)->set_expected_phase(EP_POSTTARGET);
+ }
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
+};
+
} // namespace
TEST(EventDispatcherTest, EventDispatchOrder) {
@@ -135,6 +145,7 @@ TEST(EventDispatcherTest, EventDispatchOrder) {
MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4),
gfx::Point(3, 4), 0);
+ Event::DispatcherApi event_mod(&mouse);
int result = dispatcher.ProcessEvent(&child, &mouse);
EXPECT_FALSE(result & ER_CONSUMED);
EXPECT_FALSE(result & ER_HANDLED);
@@ -145,9 +156,13 @@ TEST(EventDispatcherTest, EventDispatchOrder) {
child.handler_list());
child.Reset();
+ event_mod.set_phase(EP_PREDISPATCH);
+ event_mod.set_result(ER_UNHANDLED);
h1.set_event_result(ER_HANDLED);
result = dispatcher.ProcessEvent(&child, &mouse);
+ EXPECT_EQ(result, mouse.result());
+ EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
EXPECT_FALSE(result & ER_CONSUMED);
EXPECT_TRUE(result & ER_HANDLED);
EXPECT_EQ(
@@ -155,10 +170,14 @@ TEST(EventDispatcherTest, EventDispatchOrder) {
child.handler_list());
child.Reset();
+ event_mod.set_phase(EP_PREDISPATCH);
+ event_mod.set_result(ER_UNHANDLED);
int nexpected[] = { 1, 2, 3, 4, 5 };
h5.set_event_result(ER_CONSUMED);
result = dispatcher.ProcessEvent(&child, &mouse);
+ EXPECT_EQ(result, mouse.result());
+ EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
EXPECT_TRUE(result & ER_CONSUMED);
EXPECT_TRUE(result & ER_HANDLED);
EXPECT_EQ(
@@ -166,10 +185,14 @@ TEST(EventDispatcherTest, EventDispatchOrder) {
child.handler_list());
child.Reset();
+ event_mod.set_phase(EP_PREDISPATCH);
+ event_mod.set_result(ER_UNHANDLED);
int exp[] = { 1 };
h1.set_event_result(ER_CONSUMED);
result = dispatcher.ProcessEvent(&child, &mouse);
+ EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
+ EXPECT_EQ(result, mouse.result());
EXPECT_TRUE(result & ER_CONSUMED);
EXPECT_FALSE(result & ER_HANDLED);
EXPECT_EQ(