summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-05 04:00:59 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-05 04:00:59 +0000
commit7443494b88d2c04f3c07ebf98f0e6d68478eed7d (patch)
tree9211568b7d60a93dc8bf03a57a725dc8c8d967b7 /base
parent6f7e1d63f9c97c7f8f11af86f78f80934064a9a9 (diff)
downloadchromium_src-7443494b88d2c04f3c07ebf98f0e6d68478eed7d.zip
chromium_src-7443494b88d2c04f3c07ebf98f0e6d68478eed7d.tar.gz
chromium_src-7443494b88d2c04f3c07ebf98f0e6d68478eed7d.tar.bz2
A non-GTK version of menus for touchui.
For the menus to work correctly, the X messge pump also needs updating to allow nested event dispatching. BUG=None TEST=On a touchui build, non-GTK context menus in web-pages should work correctly. Review URL: http://codereview.chromium.org/5110011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68309 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/message_pump_glib_x.cc35
-rw-r--r--base/message_pump_glib_x.h4
-rw-r--r--base/message_pump_glib_x_dispatch.h15
3 files changed, 49 insertions, 5 deletions
diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc
index 78c1799..26c4b87 100644
--- a/base/message_pump_glib_x.cc
+++ b/base/message_pump_glib_x.cc
@@ -85,6 +85,8 @@ MessagePumpGlibX::~MessagePumpGlibX() {
bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
GdkDisplay* gdisp = gdk_display_get_default();
Display* display = GDK_DISPLAY_XDISPLAY(gdisp);
+ bool should_quit = false;
+
if (XPending(display)) {
XEvent xev;
XPeekEvent(display, &xev);
@@ -95,10 +97,22 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
) {
XNextEvent(display, &xev);
- bool processed = static_cast<MessagePumpGlibXDispatcher*>
+#if defined(HAVE_XINPUT2)
+ bool have_cookie = false;
+ if (xev.type == GenericEvent &&
+ XGetEventData(xev.xgeneric.display, &xev.xcookie)) {
+ have_cookie = true;
+ }
+#endif
+
+ MessagePumpGlibXDispatcher::DispatchStatus status =
+ static_cast<MessagePumpGlibXDispatcher*>
(GetDispatcher())->Dispatch(&xev);
- if (!processed) {
+ if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) {
+ should_quit = true;
+ Quit();
+ } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) {
DLOG(WARNING) << "Event (" << xev.type << ") not handled.";
// TODO(sad): It is necessary to put back the event so that the default
@@ -106,16 +120,29 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
// impossible to use the omnibox at the moment. However, this will
// eventually be removed once the omnibox code is updated for touchui.
XPutBackEvent(display, &xev);
+ if (gdksource_)
+ gdksource_->source_funcs->dispatch = gdkdispatcher_;
g_main_context_iteration(context, FALSE);
}
+
+#if defined(HAVE_XINPUT2)
+ if (have_cookie) {
+ XFreeEventData(xev.xgeneric.display, &xev.xcookie);
+ }
+#endif
} else {
// TODO(sad): A couple of extra events can still sneak in during this.
// Those should be sent back to the X queue from the dispatcher
// EventDispatcherX.
+ if (gdksource_)
+ gdksource_->source_funcs->dispatch = gdkdispatcher_;
g_main_context_iteration(context, FALSE);
}
}
+ if (should_quit)
+ return true;
+
bool retvalue;
if (gdksource_) {
// Replace the dispatch callback of the GDK event source temporarily so that
@@ -178,6 +205,9 @@ void MessagePumpGlibX::InitializeXInput2(void) {
return;
}
+ // TODO(sad): Here, we only setup so that the X windows created by GTK+ are
+ // setup for XInput2 events. We need a way to listen for XInput2 events for X
+ // windows created by other means (e.g. for context menus).
SetupGtkWidgetRealizeNotifier(this);
// Instead of asking X for the list of devices all the time, let's maintain a
@@ -242,6 +272,7 @@ void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) {
if (!pump_x->gdksource_) {
pump_x->gdksource_ = g_main_current_source();
+ pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch;
} else if (!pump_x->IsDispatchingEvent()) {
if (event->type != GDK_NOTHING &&
pump_x->capture_gdk_events_[event->type]) {
diff --git a/base/message_pump_glib_x.h b/base/message_pump_glib_x.h
index c6d98e3..fc3f3b1 100644
--- a/base/message_pump_glib_x.h
+++ b/base/message_pump_glib_x.h
@@ -60,6 +60,10 @@ class MessagePumpGlibX : public MessagePumpForUI {
// The event source for GDK events.
GSource* gdksource_;
+ // The default GDK event dispatcher. This is stored so that it can be restored
+ // when necessary during nested event dispatching.
+ gboolean (*gdkdispatcher_)(GSource*, GSourceFunc, void*);
+
// Indicates whether a GDK event was injected by chrome (when |true|) or if it
// was captured and being processed by GDK (when |false|).
bool dispatching_event_;
diff --git a/base/message_pump_glib_x_dispatch.h b/base/message_pump_glib_x_dispatch.h
index 95364a2..faee5b5 100644
--- a/base/message_pump_glib_x_dispatch.h
+++ b/base/message_pump_glib_x_dispatch.h
@@ -18,9 +18,18 @@ namespace base {
// GdkEvents. This class provides additional mechanism for dispatching XEvents.
class MessagePumpGlibXDispatcher : public MessagePumpForUI::Dispatcher {
public:
- // Dispatches the event. If true is returned processing continues as
- // normal. If false is returned, the nested loop exits immediately.
- virtual bool Dispatch(XEvent* xevent) = 0;
+
+ typedef enum {
+ EVENT_IGNORED, // The event was not processed.
+ EVENT_PROCESSED, // The event has been processed.
+ EVENT_QUIT // The event was processed and the message-loop should
+ // terminate.
+ } DispatchStatus;
+
+ // Dispatches the event. EVENT_IGNORED is returned if the event was ignored
+ // (i.e. not processed). EVENT_PROCESSED is returned if the event was
+ // processed. The nested loop exits immediately if EVENT_QUIT is returned.
+ virtual DispatchStatus Dispatch(XEvent* xevent) = 0;
};
} // namespace base