Chromium Code Reviews| Index: base/message_pump_glib_x.cc |
| diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc |
| index 78c179933d00a7e5a70d0d94c3675fe7b9dd1379..8e340e203571b6c98a5ed33ce4d5a884977bb1aa 100644 |
| --- a/base/message_pump_glib_x.cc |
| +++ b/base/message_pump_glib_x.cc |
| @@ -85,6 +85,7 @@ MessagePumpGlibX::~MessagePumpGlibX() { |
| bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) { |
| GdkDisplay* gdisp = gdk_display_get_default(); |
| Display* display = GDK_DISPLAY_XDISPLAY(gdisp); |
| + |
| if (XPending(display)) { |
| XEvent xev; |
| XPeekEvent(display, &xev); |
| @@ -95,10 +96,21 @@ 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) { |
| + state_->should_quit = true; |
|
sadrul
2010/11/29 15:56:56
Instead of setting |should_quit| here, we can simp
|
| + } 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 +118,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 (state_->should_quit) |
| + return true; |
| + |
| bool retvalue; |
| if (gdksource_) { |
| // Replace the dispatch callback of the GDK event source temporarily so that |
| @@ -178,6 +203,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 +270,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]) { |