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>
This commit is contained in:
Samuel Rødal 2012-11-12 17:02:17 +01:00 committed by The Qt Project
parent 5055183bc5
commit 4334e0fcc6
2 changed files with 60 additions and 1 deletions

View File

@ -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

View File

@ -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();
}