Mailbox support for texture layers.
[chromium-blink-merge.git] / ui / base / events / event_dispatcher.cc
blob79f937542993cd8c0de96ace4da098b6abc9f03f
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"
7 #include <algorithm>
9 namespace ui {
11 namespace {
13 class UI_EXPORT ScopedDispatchHelper : public NON_EXPORTED_BASE(
14 Event::DispatcherApi) {
15 public:
16 explicit ScopedDispatchHelper(Event* event)
17 : Event::DispatcherApi(event) {
18 set_result(ui::ER_UNHANDLED);
21 virtual ~ScopedDispatchHelper() {
22 set_phase(EP_POSTDISPATCH);
25 private:
26 DISALLOW_COPY_AND_ASSIGN(ScopedDispatchHelper);
29 } // namespace
31 EventDispatcherDelegate::EventDispatcherDelegate()
32 : dispatcher_(NULL) {
35 EventDispatcherDelegate::~EventDispatcherDelegate() {
36 if (dispatcher_)
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(),
67 handler_list_.end(),
68 handler));
71 void EventDispatcher::ProcessEvent(EventTarget* target, Event* event) {
72 if (!target || !target->CanAcceptEvent(*event))
73 return;
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);
83 if (event->handled())
84 return;
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
90 // abstraction.
91 if (delegate_ && delegate_->CanDispatchToTarget(target)) {
92 dispatch_helper.set_phase(EP_TARGET);
93 DispatchEvent(target, event);
94 if (event->handled())
95 return;
98 if (!delegate_ || !delegate_->CanDispatchToTarget(target))
99 return;
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() {
108 delegate_ = NULL;
111 ////////////////////////////////////////////////////////////////////////////////
112 // EventDispatcher, private:
114 void EventDispatcher::DispatchEventToEventHandlers(EventHandlerList& list,
115 Event* event) {
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();
140 return;
143 base::AutoReset<Event*> event_reset(&current_event_, event);
144 DispatchEventToSingleHandler(handler, event);
145 if (!delegate_)
146 event->StopPropagation();
149 void EventDispatcher::DispatchEventToSingleHandler(EventHandler* handler,
150 Event* event) {
151 handler->OnEvent(event);
154 } // namespace ui