Flush xcb connection before EventDispatcher is going to block

The non-threaded QXcbEventReader invokes processXcbEvents when the
EventDispatcher is about to block. This method ensures that the xcb
connection is going to flush. Applications can use low level xcb code
in that case without having to ensure to flush the connection before
going to block again.

With the threaded QXcbEventReader this didn't work and applications
which for example changed a window property and waited for the matching
property notify event were stalled.

This change ensures that also in the threaded case the connection gets
flushed when the EventDispatcher is going to block.

Change-Id: If1dc5eb96e2f1bde10b7a40af550b0608c62f70c
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
This commit is contained in:
Martin Gräßlin 2014-05-19 08:58:37 +02:00 committed by Shawn Rutledge
parent acd0dae3f4
commit a461bb1ff5
3 changed files with 18 additions and 2 deletions

View File

@ -1028,6 +1028,15 @@ void QXcbEventReader::registerForEvents()
connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents()));
}
void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher)
{
// flush the xcb connection before the EventDispatcher is going to block
// In the non-threaded case processXcbEvents is called before going to block,
// which flushes the connection.
if (m_xcb_poll_for_queued_event)
connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush()));
}
void QXcbEventReader::run()
{
xcb_generic_event_t *event;

View File

@ -311,6 +311,8 @@ public:
void start();
void registerEventDispatcher(QAbstractEventDispatcher *dispatcher);
signals:
void eventPending();
@ -410,7 +412,6 @@ public:
void sync();
void flush() { xcb_flush(m_connection); }
void handleXcbError(xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event);
@ -464,8 +465,11 @@ public:
void handleEnterEvent(const xcb_enter_notify_event_t *);
#endif
QXcbEventReader *eventReader() const { return m_reader; }
public slots:
void syncWindow(QXcbWindow *window);
void flush() { xcb_flush(m_connection); }
private slots:
void processXcbEvents();

View File

@ -303,7 +303,10 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{
return createUnixEventDispatcher();
QAbstractEventDispatcher *dispatcher = createUnixEventDispatcher();
for (int i = 0; i < m_connections.size(); i++)
m_connections[i]->eventReader()->registerEventDispatcher(dispatcher);
return dispatcher;
}
void QXcbIntegration::initialize()