summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Volkov <a.volkov@rusbitech.ru>2019-01-24 15:53:28 +0300
committerGatis Paeglis <gatis.paeglis@qt.io>2019-01-25 15:59:51 +0000
commit730cbad8824bcfcb7ab60371a6563cfb6dd5658d (patch)
tree4e1d88c0662fb1b90f55758bfed92762a484a3ec
parentc9b9a0ea2f274688da26af20102d349336fdb2a0 (diff)
xcb: Avoid repaint lags with DnD
The lags can be seen when dragged data is requested for a MIME type. This leads to calling QXcbClipboard::waitForClipboardEvent() which runs a loop in the GUI thread and processes events from QXcbEventQueue. The loop ends when a corresponding event is received, otherwise it makes a delay of 50 ms before the next iteration. Sync with QXcbEventQueue thread by QWaitCondition instead of using the delay. This way the loop will end as soon as possible and Expose events will be processed with minimal delay. Task-number: QTBUG-44849 Fixes: QTBUG-55442 Fixes: QTBUG-62344 Fixes: QTBUG-73253 Change-Id: Ie18d63b51a7260c83d53ffe1169b25e5135dd73b Reviewed-by: Mikhail Svetkin <mikhail.svetkin@qt.io> Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbeventqueue.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbeventqueue.h7
3 files changed, 19 insertions, 2 deletions
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index bc92f82d5f..ac8b029916 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -810,8 +810,9 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, i
connection()->flush();
- // sleep 50 ms, so we don't use up CPU cycles all the time.
- QThread::msleep(50);
+ const auto elapsed = timer.elapsed();
+ if (elapsed < clipboard_timeout)
+ queue->waitForNewEvents(clipboard_timeout - elapsed);
} while (timer.elapsed() < clipboard_timeout);
return nullptr;
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
index f6158d3127..acec0486c2 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp
+++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
@@ -229,6 +229,8 @@ void QXcbEventQueue::run()
enqueueEvent(event);
while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection)))
enqueueEvent(event);
+
+ m_newEventsCondition.wakeOne();
wakeUpDispatcher();
}
@@ -346,6 +348,13 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData,
return result;
}
+void QXcbEventQueue::waitForNewEvents(unsigned long time)
+{
+ m_newEventsMutex.lock();
+ m_newEventsCondition.wait(&m_newEventsMutex, time);
+ m_newEventsMutex.unlock();
+}
+
void QXcbEventQueue::sendCloseConnectionEvent() const
{
// A hack to close XCB connection. Apparently XCB does not have any APIs for this?
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h
index 235f2824be..11d0b8e963 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.h
+++ b/src/plugins/platforms/xcb/qxcbeventqueue.h
@@ -43,6 +43,8 @@
#include <QtCore/QHash>
#include <QtCore/QEventLoop>
#include <QtCore/QVector>
+#include <QtCore/QMutex>
+#include <QtCore/QWaitCondition>
#include <xcb/xcb.h>
@@ -104,6 +106,8 @@ public:
bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr,
PeekOptions option = PeekDefault, qint32 peekerId = -1);
+ void waitForNewEvents(unsigned long time = ULONG_MAX);
+
private:
QXcbEventNode *qXcbEventNodeFactory(xcb_generic_event_t *event);
void dequeueNode();
@@ -131,6 +135,9 @@ private:
// debug stats
quint64 m_nodesOnHeap = 0;
+
+ QMutex m_newEventsMutex;
+ QWaitCondition m_newEventsCondition;
};
template<typename Peeker>