Chromium Code Reviews| Index: ui/events/platform/platform_event_source.cc |
| diff --git a/ui/events/platform/platform_event_source.cc b/ui/events/platform/platform_event_source.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a5101c3b4b64343b872552ef5e1e086eaf536fee |
| --- /dev/null |
| +++ b/ui/events/platform/platform_event_source.cc |
| @@ -0,0 +1,121 @@ |
| +// Copyright 2014 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/events/platform/platform_event_source.h" |
| + |
| +#include <algorithm> |
| + |
| +#include "base/message_loop/message_loop.h" |
| +#include "ui/events/event.h" |
| +#include "ui/events/platform/platform_event_dispatcher.h" |
| +#include "ui/events/platform/platform_event_observer.h" |
| +#include "ui/events/platform/scoped_event_dispatcher.h" |
| + |
| +namespace ui { |
| + |
| +// static |
| +PlatformEventSource* PlatformEventSource::instance_ = NULL; |
| + |
| +PlatformEventSource::PlatformEventSource() |
| + : overridden_dispatcher_(NULL), overridden_dispatcher_restored_(false) { |
|
sky
2014/03/25 15:51:15
nit: when you wrap one param per line.
sadrul
2014/03/25 18:33:15
Done.
|
| + CHECK(!instance_) << "Only one platform event source can be created."; |
| + instance_ = this; |
| +} |
| + |
| +PlatformEventSource::~PlatformEventSource() { |
| + CHECK_EQ(this, instance_); |
| + instance_ = NULL; |
| +} |
| + |
| +PlatformEventSource* PlatformEventSource::GetInstance() { return instance_; } |
| + |
| +void PlatformEventSource::AddPlatformEventDispatcher( |
| + PlatformEventDispatcher* dispatcher) { |
| + CHECK(dispatcher); |
|
sky
2014/03/25 15:51:15
DCHECK not already in dispatchers_?
sadrul
2014/03/25 18:33:15
Done.
|
| + dispatchers_.push_back(dispatcher); |
| +} |
| + |
| +void PlatformEventSource::RemovePlatformEventDispatcher( |
| + PlatformEventDispatcher* dispatcher) { |
| + PlatformEventDispatcherList::iterator remove = |
| + std::remove(dispatchers_.begin(), dispatchers_.end(), dispatcher); |
| + if (remove != dispatchers_.end()) |
| + dispatchers_.erase(remove); |
| +} |
| + |
| +scoped_ptr<ScopedEventDispatcher> PlatformEventSource::OverrideDispatcher( |
| + PlatformEventDispatcher* dispatcher) { |
| + CHECK(dispatcher); |
| + overridden_dispatcher_restored_ = false; |
| + return make_scoped_ptr( |
| + new ScopedEventDispatcher(&overridden_dispatcher_, dispatcher)); |
| +} |
| + |
| +void PlatformEventSource::AddPlatformEventObserver( |
| + PlatformEventObserver* observer) { |
| + CHECK(observer); |
| + observers_.AddObserver(observer); |
| +} |
| + |
| +void PlatformEventSource::RemovePlatformEventObserver( |
| + PlatformEventObserver* observer) { |
| + observers_.RemoveObserver(observer); |
| +} |
| + |
| +uint32_t PlatformEventSource::DispatchEvent(PlatformEvent platform_event) { |
| + uint32_t action = POST_DISPATCH_PERFORM_DEFAULT; |
| + bool should_quit = false; |
| + |
| + if (!WillProcessEvent(platform_event)) { |
| + // Give the overridden dispatcher a chance to dispatch the event first. |
| + if (overridden_dispatcher_) |
| + action = overridden_dispatcher_->DispatchEvent(platform_event); |
| + should_quit = !!(action & POST_DISPATCH_QUIT_LOOP); |
| + |
| + if (action & POST_DISPATCH_PERFORM_DEFAULT) { |
| + for (PlatformEventDispatcherList::iterator i = dispatchers_.begin(); |
| + i != dispatchers_.end(); |
| + ++i) { |
| + PlatformEventDispatcher* dispatcher = *(i); |
| + if (dispatcher->CanDispatchEvent(platform_event)) |
| + action = dispatcher->DispatchEvent(platform_event); |
| + if (action & POST_DISPATCH_QUIT_LOOP) |
| + should_quit = true; |
| + if (action & POST_DISPATCH_STOP_PROPAGATION) |
| + break; |
| + } |
| + } |
| + } |
| + DidProcessEvent(platform_event); |
| + if (should_quit || overridden_dispatcher_restored_) { |
|
sky
2014/03/25 15:51:15
Why does overridden_dispatcher_restored_ == true m
sadrul
2014/03/25 18:33:15
Yeah. This code was a bit misleading. I have clari
|
| + base::MessageLoop::current()->QuitNow(); |
| + action |= POST_DISPATCH_QUIT_LOOP; |
| + } |
| + overridden_dispatcher_restored_ = false; |
| + |
| + return action; |
| +} |
| + |
| +bool PlatformEventSource::WillProcessEvent(PlatformEvent event) { |
| + if (observers_.might_have_observers()) { |
| + ObserverListBase<PlatformEventObserver>::Iterator it(observers_); |
| + PlatformEventObserver* obs; |
| + while ((obs = it.GetNext()) != NULL) { |
| + if (obs->WillProcessEvent(event)) |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| +void PlatformEventSource::DidProcessEvent(PlatformEvent event) { |
| + FOR_EACH_OBSERVER(PlatformEventObserver, observers_, DidProcessEvent(event)); |
| +} |
| + |
| +void PlatformEventSource::OnOverriddenDispatcherRestored() { |
| + CHECK(overridden_dispatcher_); |
| + overridden_dispatcher_restored_ = true; |
| +} |
| + |
| +} // namespace ui |