1 // Copyright 2014 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/events/platform/platform_event_source.h"
9 #include "base/message_loop/message_loop.h"
10 #include "ui/events/event.h"
11 #include "ui/events/platform/platform_event_dispatcher.h"
12 #include "ui/events/platform/platform_event_observer.h"
13 #include "ui/events/platform/scoped_event_dispatcher.h"
18 PlatformEventSource
* PlatformEventSource::instance_
= NULL
;
20 PlatformEventSource::PlatformEventSource()
21 : overridden_dispatcher_(NULL
),
22 overridden_dispatcher_restored_(false) {
23 CHECK(!instance_
) << "Only one platform event source can be created.";
27 PlatformEventSource::~PlatformEventSource() {
28 CHECK_EQ(this, instance_
);
32 PlatformEventSource
* PlatformEventSource::GetInstance() { return instance_
; }
34 void PlatformEventSource::AddPlatformEventDispatcher(
35 PlatformEventDispatcher
* dispatcher
) {
37 dispatchers_
.AddObserver(dispatcher
);
38 OnDispatcherListChanged();
41 void PlatformEventSource::RemovePlatformEventDispatcher(
42 PlatformEventDispatcher
* dispatcher
) {
43 dispatchers_
.RemoveObserver(dispatcher
);
44 OnDispatcherListChanged();
47 scoped_ptr
<ScopedEventDispatcher
> PlatformEventSource::OverrideDispatcher(
48 PlatformEventDispatcher
* dispatcher
) {
50 overridden_dispatcher_restored_
= false;
51 return make_scoped_ptr(
52 new ScopedEventDispatcher(&overridden_dispatcher_
, dispatcher
));
55 void PlatformEventSource::AddPlatformEventObserver(
56 PlatformEventObserver
* observer
) {
58 observers_
.AddObserver(observer
);
61 void PlatformEventSource::RemovePlatformEventObserver(
62 PlatformEventObserver
* observer
) {
63 observers_
.RemoveObserver(observer
);
66 uint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event
) {
67 uint32_t action
= POST_DISPATCH_PERFORM_DEFAULT
;
68 bool should_quit
= false;
70 FOR_EACH_OBSERVER(PlatformEventObserver
, observers_
,
71 WillProcessEvent(platform_event
));
72 // Give the overridden dispatcher a chance to dispatch the event first.
73 if (overridden_dispatcher_
)
74 action
= overridden_dispatcher_
->DispatchEvent(platform_event
);
75 should_quit
= !!(action
& POST_DISPATCH_QUIT_LOOP
);
77 if ((action
& POST_DISPATCH_PERFORM_DEFAULT
) &&
78 dispatchers_
.might_have_observers()) {
79 ObserverList
<PlatformEventDispatcher
>::Iterator
iter(dispatchers_
);
80 while (PlatformEventDispatcher
* dispatcher
= iter
.GetNext()) {
81 if (dispatcher
->CanDispatchEvent(platform_event
))
82 action
= dispatcher
->DispatchEvent(platform_event
);
83 if (action
& POST_DISPATCH_QUIT_LOOP
)
85 if (action
& POST_DISPATCH_STOP_PROPAGATION
)
89 FOR_EACH_OBSERVER(PlatformEventObserver
, observers_
,
90 DidProcessEvent(platform_event
));
92 // Terminate the message-loop if the dispatcher requested for it.
94 base::MessageLoop::current()->QuitNow();
95 action
|= POST_DISPATCH_QUIT_LOOP
;
98 // If an overridden dispatcher has been destroyed, then the platform
99 // event-source should halt dispatching the current stream of events, and wait
100 // until the next message-loop iteration for dispatching events. This lets any
101 // nested message-loop to unwind correctly and any new dispatchers to receive
102 // the correct sequence of events.
103 if (overridden_dispatcher_restored_
)
104 action
|= POST_DISPATCH_QUIT_LOOP
;
106 overridden_dispatcher_restored_
= false;
111 void PlatformEventSource::OnDispatcherListChanged() {
114 void PlatformEventSource::OnOverriddenDispatcherRestored() {
115 CHECK(overridden_dispatcher_
);
116 overridden_dispatcher_restored_
= true;