From 4334e0fcc60497da73671063deb68fb1661f864c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 12 Nov 2012 17:02:17 +0100 Subject: 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 --- src/plugins/platforms/xcb/qxcbconnection.cpp | 16 ++++++++++ src/plugins/platforms/xcb/qxcbwindow.cpp | 45 +++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) (limited to 'src') 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::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(); } -- cgit v1.2.3