summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-11 20:50:00 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-11 20:50:00 +0000
commit5040dfab473eff732a7fd5ae0572d64f4f42626d (patch)
tree99d2625c35553f60dc8b59a4f89c8ab68b9be2da /base
parent22c071b9f2fac7cb6bb75bb4054f9acd440b43e1 (diff)
downloadchromium_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.h7
-rw-r--r--base/message_pump_glib.h2
-rw-r--r--base/message_pump_glib_x.cc36
-rw-r--r--base/message_pump_glib_x.h7
-rw-r--r--base/message_pump_glib_x_dispatch.h9
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