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.
5 #include "ui/base/events/event_dispatcher.h"
13 class UI_EXPORT ScopedDispatchHelper
: public NON_EXPORTED_BASE(
14 Event::DispatcherApi
) {
16 explicit ScopedDispatchHelper(Event
* event
)
17 : Event::DispatcherApi(event
) {
18 set_result(ui::ER_UNHANDLED
);
21 virtual ~ScopedDispatchHelper() {
22 set_phase(EP_POSTDISPATCH
);
26 DISALLOW_COPY_AND_ASSIGN(ScopedDispatchHelper
);
31 EventDispatcherDelegate::EventDispatcherDelegate()
35 EventDispatcherDelegate::~EventDispatcherDelegate() {
37 dispatcher_
->OnDispatcherDelegateDestroyed();
40 Event
* EventDispatcherDelegate::current_event() {
41 return dispatcher_
? dispatcher_
->current_event() : NULL
;
44 bool EventDispatcherDelegate::DispatchEvent(EventTarget
* target
, Event
* event
) {
45 EventDispatcher
* old_dispatcher
= dispatcher_
;
46 EventDispatcher
dispatcher(this);
47 dispatcher_
= &dispatcher
;
48 dispatcher
.ProcessEvent(target
, event
);
49 if (!dispatcher
.delegate_destroyed())
50 dispatcher_
= old_dispatcher
;
51 else if (old_dispatcher
)
52 old_dispatcher
->OnDispatcherDelegateDestroyed();
54 return !dispatcher
.delegate_destroyed();
57 EventDispatcher::EventDispatcher(EventDispatcherDelegate
* delegate
)
58 : delegate_(delegate
),
59 current_event_(NULL
) {
62 EventDispatcher::~EventDispatcher() {
65 void EventDispatcher::OnHandlerDestroyed(EventHandler
* handler
) {
66 handler_list_
.erase(std::find(handler_list_
.begin(),
71 void EventDispatcher::ProcessEvent(EventTarget
* target
, Event
* event
) {
72 if (!target
|| !target
->CanAcceptEvent(*event
))
75 ScopedDispatchHelper
dispatch_helper(event
);
76 dispatch_helper
.set_target(target
);
78 handler_list_
.clear();
79 target
->GetPreTargetHandlers(&handler_list_
);
81 dispatch_helper
.set_phase(EP_PRETARGET
);
82 DispatchEventToEventHandlers(handler_list_
, event
);
86 // If the event hasn't been consumed, trigger the default handler. Note that
87 // even if the event has already been handled (i.e. return result has
88 // ER_HANDLED set), that means that the event should still be processed at
89 // this layer, however it should not be processed in the next layer of
91 if (delegate_
&& delegate_
->CanDispatchToTarget(target
)) {
92 dispatch_helper
.set_phase(EP_TARGET
);
93 DispatchEvent(target
, event
);
98 if (!delegate_
|| !delegate_
->CanDispatchToTarget(target
))
101 handler_list_
.clear();
102 target
->GetPostTargetHandlers(&handler_list_
);
103 dispatch_helper
.set_phase(EP_POSTTARGET
);
104 DispatchEventToEventHandlers(handler_list_
, event
);
107 void EventDispatcher::OnDispatcherDelegateDestroyed() {
111 ////////////////////////////////////////////////////////////////////////////////
112 // EventDispatcher, private:
114 void EventDispatcher::DispatchEventToEventHandlers(EventHandlerList
& list
,
116 for (EventHandlerList::const_iterator it
= list
.begin(),
117 end
= list
.end(); it
!= end
; ++it
) {
118 (*it
)->dispatchers_
.push(this);
121 while (!list
.empty()) {
122 EventHandler
* handler
= (*list
.begin());
123 if (delegate_
&& !event
->stopped_propagation())
124 DispatchEvent(handler
, event
);
126 if (!list
.empty() && *list
.begin() == handler
) {
127 // The handler has not been destroyed (because if it were, then it would
128 // have been removed from the list).
129 CHECK(handler
->dispatchers_
.top() == this);
130 handler
->dispatchers_
.pop();
131 list
.erase(list
.begin());
136 void EventDispatcher::DispatchEvent(EventHandler
* handler
, Event
* event
) {
137 // If the target has been invalidated or deleted, don't dispatch the event.
138 if (!delegate_
->CanDispatchToTarget(event
->target())) {
139 event
->StopPropagation();
143 base::AutoReset
<Event
*> event_reset(¤t_event_
, event
);
144 DispatchEventToSingleHandler(handler
, event
);
146 event
->StopPropagation();
149 void EventDispatcher::DispatchEventToSingleHandler(EventHandler
* handler
,
151 handler
->OnEvent(event
);