| Index: base/message_pump_glib_x.cc
|
| diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc
|
| index b4d677ef25effef3f03bbcabe3f5708b9d7d2f51..c694114d2933b97253723f4921ff5919a2f56fd1 100644
|
| --- a/base/message_pump_glib_x.cc
|
| +++ b/base/message_pump_glib_x.cc
|
| @@ -33,6 +33,7 @@ MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(),
|
| dispatching_event_(false),
|
| capture_x_events_(0),
|
| capture_gdk_events_(0) {
|
| + gdk_window_add_filter(NULL, &GdkEventFilter, this);
|
| gdk_event_handler_set(&EventDispatcherX, this, NULL);
|
|
|
| #if defined(HAVE_XINPUT2)
|
| @@ -44,50 +45,63 @@ MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(),
|
| MessagePumpGlibX::~MessagePumpGlibX() {
|
| }
|
|
|
| -bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
|
| - GdkDisplay* gdisp = gdk_display_get_default();
|
| - if (!gdisp || !GetDispatcher())
|
| - return MessagePumpForUI::RunOnce(context, block);
|
| +bool MessagePumpGlibX::ShouldCaptureXEvent(XEvent* xev) {
|
| + return capture_x_events_[xev->type]
|
| +#if defined(HAVE_XINPUT2)
|
| + && (xev->type != GenericEvent || xev->xcookie.extension == xiopcode_)
|
| +#endif
|
| + ;
|
| +}
|
|
|
| - Display* display = GDK_DISPLAY_XDISPLAY(gdisp);
|
| +
|
| +bool MessagePumpGlibX::ProcessXEvent(XEvent* xev) {
|
| bool should_quit = false;
|
|
|
| - if (XPending(display)) {
|
| - XEvent xev;
|
| - XPeekEvent(display, &xev);
|
| - if (capture_x_events_[xev.type]
|
| #if defined(HAVE_XINPUT2)
|
| - && (xev.type != GenericEvent || xev.xcookie.extension == xiopcode_)
|
| + bool have_cookie = false;
|
| + if (xev->type == GenericEvent &&
|
| + XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
|
| + have_cookie = true;
|
| + }
|
| #endif
|
| - ) {
|
| - XNextEvent(display, &xev);
|
| +
|
| + 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)
|
| - bool have_cookie = false;
|
| - if (xev.type == GenericEvent &&
|
| - XGetEventData(xev.xgeneric.display, &xev.xcookie)) {
|
| - have_cookie = true;
|
| - }
|
| + if (have_cookie) {
|
| + XFreeEventData(xev->xgeneric.display, &xev->xcookie);
|
| + }
|
| #endif
|
|
|
| - if (!WillProcessXEvent(&xev)) {
|
| - MessagePumpGlibXDispatcher::DispatchStatus status =
|
| - static_cast<MessagePumpGlibXDispatcher*>
|
| - (GetDispatcher())->DispatchX(&xev);
|
| + return should_quit;
|
| +}
|
|
|
| - if (status == MessagePumpGlibXDispatcher::EVENT_QUIT) {
|
| - should_quit = true;
|
| - Quit();
|
| - } else if (status == MessagePumpGlibXDispatcher::EVENT_IGNORED) {
|
| - DLOG(WARNING) << "Event (" << xev.type << ") not handled.";
|
| - }
|
| - }
|
| +bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
|
| + GdkDisplay* gdisp = gdk_display_get_default();
|
| + if (!gdisp || !GetDispatcher())
|
| + return MessagePumpForUI::RunOnce(context, block);
|
|
|
| -#if defined(HAVE_XINPUT2)
|
| - if (have_cookie) {
|
| - XFreeEventData(xev.xgeneric.display, &xev.xcookie);
|
| - }
|
| -#endif
|
| + Display* display = GDK_DISPLAY_XDISPLAY(gdisp);
|
| +
|
| + if (XPending(display)) {
|
| + XEvent xev;
|
| + XPeekEvent(display, &xev);
|
| +
|
| + if (ShouldCaptureXEvent(&xev)) {
|
| + XNextEvent(display, &xev);
|
| + if (ProcessXEvent(&xev))
|
| + return true;
|
| } 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
|
| @@ -98,9 +112,6 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
|
| }
|
| }
|
|
|
| - if (should_quit)
|
| - return true;
|
| -
|
| bool retvalue;
|
| if (gdksource_) {
|
| // Replace the dispatch callback of the GDK event source temporarily so that
|
| @@ -121,6 +132,20 @@ bool MessagePumpGlibX::RunOnce(GMainContext* context, bool block) {
|
| return retvalue;
|
| }
|
|
|
| +GdkFilterReturn MessagePumpGlibX::GdkEventFilter(GdkXEvent* gxevent,
|
| + GdkEvent* gevent,
|
| + gpointer data) {
|
| + MessagePumpGlibX* pump = static_cast<MessagePumpGlibX*>(data);
|
| + XEvent* xev = static_cast<XEvent*>(gxevent);
|
| +
|
| + if (pump->ShouldCaptureXEvent(xev) && pump->GetDispatcher()) {
|
| + pump->ProcessXEvent(xev);
|
| + return GDK_FILTER_REMOVE;
|
| + }
|
| +
|
| + return GDK_FILTER_CONTINUE;
|
| +}
|
| +
|
| bool MessagePumpGlibX::WillProcessXEvent(XEvent* xevent) {
|
| ObserverListBase<Observer>::Iterator it(observers());
|
| Observer* obs;
|
| @@ -143,10 +168,7 @@ void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) {
|
| } else if (!pump_x->IsDispatchingEvent()) {
|
| if (event->type != GDK_NOTHING &&
|
| pump_x->capture_gdk_events_[event->type]) {
|
| - // TODO(sad): An X event is caught by the GDK handler. Put it back in the
|
| - // X queue so that we catch it in the next iteration. When done, the
|
| - // following DLOG statement will be removed.
|
| - DLOG(WARNING) << "GDK received an event it shouldn't have";
|
| + NOTREACHED() << "GDK received an event it shouldn't have";
|
| }
|
| }
|
|
|
|
|