From 05062e288e4b8f174a79cc698c3c97d7d12975be Mon Sep 17 00:00:00 2001 From: "sky@chromium.org" Date: Fri, 15 May 2009 22:40:05 +0000 Subject: Adds an observer callback to Linux's MessagePumpForUI. BUG=none TEST=none Review URL: http://codereview.chromium.org/112029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16204 0039d316-1c4b-4281-b951-d872f2087c98 --- base/message_pump_glib.cc | 21 +++++++++++++++++++++ base/message_pump_glib.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/base/message_pump_glib.cc b/base/message_pump_glib.cc index da40f26..0f8e197 100644 --- a/base/message_pump_glib.cc +++ b/base/message_pump_glib.cc @@ -110,9 +110,12 @@ MessagePumpForUI::MessagePumpForUI() // This is needed to allow Run calls inside Dispatch. g_source_set_can_recurse(work_source_, TRUE); g_source_attach(work_source_, context_); + gdk_event_handler_set(&EventDispatcher, this, NULL); } MessagePumpForUI::~MessagePumpForUI() { + gdk_event_handler_set(reinterpret_cast(gtk_main_do_event), + this, NULL); g_source_destroy(work_source_); g_source_unref(work_source_); close(wakeup_pipe_read_); @@ -210,6 +213,18 @@ void MessagePumpForUI::HandleDispatch() { return; } +void MessagePumpForUI::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void MessagePumpForUI::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void MessagePumpForUI::WillProcessEvent(GdkEvent* event) { + FOR_EACH_OBSERVER(Observer, observers_, WillProcessEvent(event)); +} + void MessagePumpForUI::Quit() { if (state_) { state_->should_quit = true; @@ -235,4 +250,10 @@ void MessagePumpForUI::ScheduleDelayedWork(const Time& delayed_work_time) { ScheduleWork(); } +// static +void MessagePumpForUI::EventDispatcher(GdkEvent* event, gpointer data) { + reinterpret_cast(data)->WillProcessEvent(event); + gtk_main_do_event(event); +} + } // namespace base diff --git a/base/message_pump_glib.h b/base/message_pump_glib.h index d25ae86..c8a2e0d 100644 --- a/base/message_pump_glib.h +++ b/base/message_pump_glib.h @@ -5,9 +5,11 @@ #ifndef BASE_MESSAGE_PUMP_GLIB_H_ #define BASE_MESSAGE_PUMP_GLIB_H_ +#include #include #include "base/message_pump.h" +#include "base/observer_list.h" #include "base/time.h" namespace base { @@ -16,6 +18,16 @@ namespace base { // OS_LINUX platforms using GLib. class MessagePumpForUI : public MessagePump { public: + // Observer is notified prior to a GdkEvent event being dispatched. As + // Observers are notified of every change, they have to be FAST! + class Observer { + public: + virtual ~Observer() {} + + // This method is called before processing a message. + virtual void WillProcessEvent(GdkEvent* event) = 0; + }; + MessagePumpForUI(); ~MessagePumpForUI(); @@ -32,6 +44,13 @@ class MessagePumpForUI : public MessagePump { int HandlePrepare(); void HandleDispatch(); + // Add an Observer, which will start receiving notifications immediately. + void AddObserver(Observer* observer); + + // Remove an Observer. It is safe to call this method while an Observer is + // receiving a notification callback. + void RemoveObserver(Observer* observer); + private: // We may make recursive calls to Run, so we save state that needs to be // separate between them in this structure type. @@ -49,6 +68,13 @@ class MessagePumpForUI : public MessagePump { bool more_work_is_plausible; }; + // Invoked from EventDispatcher. Notifies all observers we're about to + // process an event. + void WillProcessEvent(GdkEvent* event); + + // Callback prior to gdk dispatching an event. + static void EventDispatcher(GdkEvent* event, gpointer data); + RunState* state_; // This is a GLib structure that we can add event sources to. We use the @@ -71,6 +97,9 @@ class MessagePumpForUI : public MessagePump { int wakeup_pipe_write_; GPollFD wakeup_gpollfd_; + // List of observers. + ObserverList observers_; + DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); }; -- cgit v1.1