diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-05 04:00:59 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-05 04:00:59 +0000 |
commit | 7443494b88d2c04f3c07ebf98f0e6d68478eed7d (patch) | |
tree | 9211568b7d60a93dc8bf03a57a725dc8c8d967b7 /base | |
parent | 6f7e1d63f9c97c7f8f11af86f78f80934064a9a9 (diff) | |
download | chromium_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.cc | 35 | ||||
-rw-r--r-- | base/message_pump_glib_x.h | 4 | ||||
-rw-r--r-- | base/message_pump_glib_x_dispatch.h | 15 |
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 |