patch 1: --- qt-opensource-4.8.0.old/src/gui/kernel/qapplication_x11.cpp 2011-12-16 03:22:33.918428374 -0500 +++ qt-opensource-4.8.0.new/src/gui/kernel/qapplication_x11.cpp 2011-12-27 06:39:22.852191952 -0500 @@ -4244,6 +4244,12 @@ bool QETWidget::translateMouseEvent(cons && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) || (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) && (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) { + // As we may run through a significant number of a large class of non-MotionNotify + // events here, without returning to the event loop, just before processing nextEvent, + // pass it through QAbstractEventDispatcher::filterEvent(). Note that this issue may + // exist elsewhere, wherever events are compressed in a similar manner. + if (QAbstractEventDispatcher::instance()->filterEvent(&nextEvent)) + continue; qApp->x11ProcessEvent(&nextEvent); continue; } else if (nextEvent.type != MotionNotify || --- patch 2: --- qt-opensource-4.8.0.old/src/gui/kernel/qapplication_x11.cpp 2011-12-16 03:22:33.918428374 -0500 +++ qt-opensource-4.8.0.new/src/gui/kernel/qapplication_x11.cpp 2011-12-27 06:21:28.510129894 -0500 @@ -4230,28 +4230,17 @@ bool QETWidget::translateMouseEvent(cons return false; XMotionEvent lastMotion = event->xmotion; - while(XPending(X11->display)) { // compress mouse moves - XNextEvent(X11->display, &nextEvent); - if (nextEvent.type == ConfigureNotify - || nextEvent.type == PropertyNotify - || nextEvent.type == Expose - || nextEvent.type == GraphicsExpose - || nextEvent.type == NoExpose - || nextEvent.type == KeymapNotify - || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify) - && qt_button_down == this) - || (nextEvent.type == ClientMessage - && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) || - (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) && - (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) { - qApp->x11ProcessEvent(&nextEvent); - continue; - } else if (nextEvent.type != MotionNotify || - nextEvent.xmotion.window != event->xmotion.window || - nextEvent.xmotion.state != event->xmotion.state) { - XPutBackEvent(X11->display, &nextEvent); + // Compress any additional (same window, same state, contiguous) MotionNotify + // events immediately following this one. This appears to work, but may have + // negative side effects such as increased event processing due to sub-optimal + // compression: + while (XPending(X11->display)) { + XPeekEvent(X11->display, &nextEvent); + if (nextEvent.type != MotionNotify || + nextEvent.xmotion.window != event->xmotion.window || + nextEvent.xmotion.state != event->xmotion.state) break; - } + XNextEvent(X11->display, &nextEvent); if (!qt_x11EventFilter(&nextEvent) && !x11Event(&nextEvent)) // send event through filter lastMotion = nextEvent.xmotion; --- patch 3: --- qt-opensource-4.8.0.old/src/gui/kernel/qapplication_x11.cpp 2011-12-16 03:22:33.918428374 -0500 +++ qt-opensource-4.8.0.new/src/gui/kernel/qapplication_x11.cpp 2011-12-27 18:08:38.625333252 -0500 @@ -4230,27 +4230,17 @@ bool QETWidget::translateMouseEvent(cons return false; XMotionEvent lastMotion = event->xmotion; - while(XPending(X11->display)) { // compress mouse moves + // Compress any additional (same window, same state, not nessarily contiguous) + // MotionNotify events without disturbing other events. This appears to work, + // but may have negative side effects due to the out-of-order event processing + QList saved_events; + while (XPending(X11->display)) { XNextEvent(X11->display, &nextEvent); - if (nextEvent.type == ConfigureNotify - || nextEvent.type == PropertyNotify - || nextEvent.type == Expose - || nextEvent.type == GraphicsExpose - || nextEvent.type == NoExpose - || nextEvent.type == KeymapNotify - || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify) - && qt_button_down == this) - || (nextEvent.type == ClientMessage - && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) || - (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) && - (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) { - qApp->x11ProcessEvent(&nextEvent); + if (nextEvent.type != MotionNotify || + nextEvent.xmotion.window != event->xmotion.window || + nextEvent.xmotion.state != event->xmotion.state) { + saved_events.append(nextEvent); continue; - } else if (nextEvent.type != MotionNotify || - nextEvent.xmotion.window != event->xmotion.window || - nextEvent.xmotion.state != event->xmotion.state) { - XPutBackEvent(X11->display, &nextEvent); - break; } if (!qt_x11EventFilter(&nextEvent) && !x11Event(&nextEvent)) // send event through filter @@ -4258,6 +4248,10 @@ bool QETWidget::translateMouseEvent(cons else break; } + foreach (XEvent ev, saved_events) + XPutBackEvent(X11->display, (XEvent*)&ev); + saved_events.clear(); + type = QEvent::MouseMove; pos.rx() = lastMotion.x; pos.ry() = lastMotion.y;