diff options
author | Samuel Rødal <samuel.rodal@digia.com> | 2012-11-12 17:02:17 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-14 10:36:38 +0100 |
commit | 4334e0fcc60497da73671063deb68fb1661f864c (patch) | |
tree | c5dad9e23c375e4fb8879e645c7603f2aa903add /src/plugins | |
parent | 5055183bc5a8288976f58c65b52276ad17491cad (diff) |
Added expose and configure event compression in xcb platform plugin.
We had this in 4.x to prevend swamping the event queue and causing a lot
of needless processing of stale events.
Task-number: QTBUG-27734
Change-Id: I020fe44885569f5a68c07220fcb44bea3e138089
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 45 |
2 files changed, 60 insertions, 1 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 78f1efb745..405a16d488 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -969,6 +969,22 @@ void QXcbConnection::processXcbEvents() continue; } + if (response_type == XCB_CONFIGURE_NOTIFY) { + // compress multiple configure notify events for the same window + bool found = false; + for (int j = i; j < eventqueue->size(); ++j) { + xcb_generic_event_t *other = eventqueue->at(j); + if (other && (other->response_type & ~0x80) == XCB_CONFIGURE_NOTIFY + && ((xcb_configure_notify_event_t *)other)->event == ((xcb_configure_notify_event_t *)event)->event) + { + found = true; + break; + } + } + if (found) + continue; + } + QVector<PeekFunc>::iterator it = m_peekFuncs.begin(); while (it != m_peekFuncs.end()) { // These callbacks return true if the event is what they were diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index b6bbbdcc30..e0f5dbc435 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1303,6 +1303,42 @@ QXcbEGLSurface *QXcbWindow::eglSurface() const } #endif +class ExposeCompressor +{ +public: + ExposeCompressor(xcb_window_t window, QRegion *region) + : m_window(window) + , m_region(region) + , m_pending(true) + { + } + + bool checkEvent(xcb_generic_event_t *event) + { + if (!event) + return false; + if ((event->response_type & ~0x80) != XCB_EXPOSE) + return false; + xcb_expose_event_t *expose = (xcb_expose_event_t *)event; + if (expose->window != m_window) + return false; + if (expose->count == 0) + m_pending = false; + *m_region |= QRect(expose->x, expose->y, expose->width, expose->height); + return true; + } + + bool pending() const + { + return m_pending; + } + +private: + xcb_window_t m_window; + QRegion *m_region; + bool m_pending; +}; + void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { QRect rect(event->x, event->y, event->width, event->height); @@ -1312,8 +1348,15 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) else m_exposeRegion |= rect; + ExposeCompressor compressor(m_window, &m_exposeRegion); + xcb_generic_event_t *filter = 0; + do { + filter = connection()->checkEvent(compressor); + free(filter); + } while (filter); + // if count is non-zero there are more expose events pending - if (event->count == 0) { + if (event->count == 0 || !compressor.pending()) { QWindowSystemInterface::handleExposeEvent(window(), m_exposeRegion); m_exposeRegion = QRegion(); } |