diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-11 20:50:00 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-11 20:50:00 +0000 |
commit | 5040dfab473eff732a7fd5ae0572d64f4f42626d (patch) | |
tree | 99d2625c35553f60dc8b59a4f89c8ab68b9be2da /base | |
parent | 22c071b9f2fac7cb6bb75bb4054f9acd440b43e1 (diff) | |
download | chromium_src-5040dfab473eff732a7fd5ae0572d64f4f42626d.zip chromium_src-5040dfab473eff732a7fd5ae0572d64f4f42626d.tar.gz chromium_src-5040dfab473eff732a7fd5ae0572d64f4f42626d.tar.bz2 |
X message pump: Allow adding observers for XEvents.
These observers are slightly different from the normal observers, as in they can
return a value to indicate if the XEvent should be dispatched or not. This will
allow the event observers to act on an event (e.g. SystemKeyEventListener) and
stop the event to be dispatched any farther. This is currently done using
gdk_window_event_filter, but since the X message pump dispatches the X events
before the event reaches GDK, that technique does not work. This is a fix for
that. A future CL will add that support in SystemKeyEventListener using this
observer.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/7013003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/message_loop.h | 7 | ||||
-rw-r--r-- | base/message_pump_glib.h | 2 | ||||
-rw-r--r-- | base/message_pump_glib_x.cc | 36 | ||||
-rw-r--r-- | base/message_pump_glib_x.h | 7 | ||||
-rw-r--r-- | base/message_pump_glib_x_dispatch.h | 9 |
5 files changed, 48 insertions, 13 deletions
diff --git a/base/message_loop.h b/base/message_loop.h index a64196ce..c747947 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -80,12 +80,11 @@ class BASE_API MessageLoop : public base::MessagePump::Delegate { #if defined(OS_WIN) typedef base::MessagePumpWin::Dispatcher Dispatcher; typedef base::MessagePumpForUI::Observer Observer; -#elif !defined(OS_MACOSX) -#if defined(TOUCH_UI) +#elif defined(TOUCH_UI) typedef base::MessagePumpGlibXDispatcher Dispatcher; -#else + typedef base::MessagePumpXObserver Observer; +#elif !defined(OS_MACOSX) typedef base::MessagePumpForUI::Dispatcher Dispatcher; -#endif typedef base::MessagePumpForUI::Observer Observer; #endif diff --git a/base/message_pump_glib.h b/base/message_pump_glib.h index 7d7d8da..32d0d8f 100644 --- a/base/message_pump_glib.h +++ b/base/message_pump_glib.h @@ -93,6 +93,8 @@ class MessagePumpForUI : public MessagePump { // Returns the dispatcher for the current run state (|state_->dispatcher|). Dispatcher* GetDispatcher(); + ObserverList<Observer>& observers() { return observers_; } + private: // We may make recursive calls to Run, so we save state that needs to be // separate between them in this structure type. diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc index dcb3e2c..b4d677e 100644 --- a/base/message_pump_glib_x.cc +++ b/base/message_pump_glib_x.cc @@ -70,15 +70,17 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { } #endif - MessagePumpGlibXDispatcher::DispatchStatus status = - static_cast<MessagePumpGlibXDispatcher*> - (GetDispatcher())->DispatchX(&xev); - - if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) { - should_quit = true; - Quit(); - } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) { - DLOG(WARNING) << "Event (" << xev.type << ") not handled."; + if (!WillProcessXEvent(&xev)) { + MessagePumpGlibXDispatcher::DispatchStatus status = + static_cast<MessagePumpGlibXDispatcher*> + (GetDispatcher())->DispatchX(&xev); + + if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) { + should_quit = true; + Quit(); + } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) { + DLOG(WARNING) << "Event (" << xev.type << ") not handled."; + } } #if defined(HAVE_XINPUT2) @@ -119,6 +121,18 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { return retvalue; } +bool MessagePumpGlibX::WillProcessXEvent(XEvent* xevent) { + ObserverListBase<Observer>::Iterator it(observers()); + Observer* obs; + while ((obs = it.GetNext()) != NULL) { + MessagePumpXObserver* xobs = + static_cast<MessagePumpXObserver*>(obs); + if (xobs->WillProcessXEvent(xevent)) + return true; + } + return false; +} + void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { MessagePumpGlibX* pump_x = reinterpret_cast<MessagePumpGlibX*>(data); @@ -186,4 +200,8 @@ void MessagePumpGlibX::InitializeXInput2(void) { } #endif // HAVE_XINPUT2 +bool MessagePumpXObserver::WillProcessXEvent(XEvent* xev) { + return false; +} + } // namespace base diff --git a/base/message_pump_glib_x.h b/base/message_pump_glib_x.h index 60e3b5d..6bd29c9 100644 --- a/base/message_pump_glib_x.h +++ b/base/message_pump_glib_x.h @@ -14,6 +14,8 @@ #include <gtk/gtk.h> #include <X11/X.h> +typedef union _XEvent XEvent; + namespace base { class MessagePumpGlibX : public MessagePumpForUI { @@ -31,6 +33,11 @@ class MessagePumpGlibX : public MessagePumpForUI { private: static void EventDispatcherX(GdkEvent* event, gpointer data); + // Sends the event to the observers. If an observer returns true, then it does + // not send the event to any other observers and returns true. Returns false + // if no observer returns true. + bool WillProcessXEvent(XEvent* xevent); + // Update the lookup table and flag the events that should be captured and // processed so that GDK doesn't get to them. void InitializeEventsToCapture(void); diff --git a/base/message_pump_glib_x_dispatch.h b/base/message_pump_glib_x_dispatch.h index 4c44cab..28f59e1 100644 --- a/base/message_pump_glib_x_dispatch.h +++ b/base/message_pump_glib_x_dispatch.h @@ -31,6 +31,15 @@ class MessagePumpGlibXDispatcher : public MessagePumpForUI::Dispatcher { virtual DispatchStatus DispatchX(XEvent* xevent) = 0; }; +class MessagePumpXObserver : public MessagePumpForUI::Observer { + public: + // This method is called before processing an XEvent. If the method returns + // true, it indicates the event has already been handled, so the event is not + // processed any farther. If the method returns false, the event dispatching + // proceeds as normal. + virtual bool WillProcessXEvent(XEvent* xevent); +}; + } // namespace base #endif // BASE_MESSAGE_PUMP_GLIB_X_DISPATCH_H |