summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-01 01:01:28 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-01 01:01:28 +0100
commitf09fc1f35294827245e74ced48274387d5ed346f (patch)
tree4c07e40a13fd5be82f2afe4a38165b46dd385d34
parentcc9645f11b46aaad36658d62d38a5e44a5ba5ae5 (diff)
parentf5c0a19077989b5ac14071ecd095e29f62d05602 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--src/3rdparty/angle/qt_attribution.json4
-rw-r--r--src/corelib/global/qendian.h26
-rw-r--r--src/corelib/io/qiodevice.cpp4
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp17
-rw-r--r--src/corelib/kernel/qobject.cpp34
-rw-r--r--src/corelib/thread/qthread_win.cpp4
-rw-r--r--src/corelib/tools/qcontiguouscache.h1
-rw-r--r--src/gui/painting/qpdf.cpp26
-rw-r--r--src/gui/painting/qrgba64.qdoc2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm22
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp43
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp190
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h41
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_screens.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h1
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp4
-rw-r--r--tests/auto/corelib/global/qtendian/tst_qtendian.cpp40
-rw-r--r--tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp3
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST2
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp53
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp2
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp4
-rw-r--r--tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp3
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp79
28 files changed, 432 insertions, 204 deletions
diff --git a/src/3rdparty/angle/qt_attribution.json b/src/3rdparty/angle/qt_attribution.json
index e35e1f0eb9..b10343d945 100644
--- a/src/3rdparty/angle/qt_attribution.json
+++ b/src/3rdparty/angle/qt_attribution.json
@@ -5,6 +5,10 @@
"QDocModule": "qtgui",
"QtUsage": "Used on Windows to implement OpenGL ES on top of DirectX. Configure with -no-opengl, or -opengl desktop to exclude.",
+ "Description": "The ANGLE library translates OpenGL ES API calls to hardware-supported APIs.",
+ "Homepage": "http://angleproject.org/",
+ "Version": "chromium/3280",
+
"License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENSE",
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index 1cc8a823d9..0e67a1ab8e 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -41,6 +41,7 @@
#ifndef QENDIAN_H
#define QENDIAN_H
+#include <QtCore/qfloat16.h>
#include <QtCore/qglobal.h>
// include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems
@@ -151,6 +152,31 @@ template <> inline Q_DECL_CONSTEXPR qint8 qbswap<qint8>(qint8 source)
return source;
}
+// floating specializations
+template<typename Float>
+Float qbswapFloatHelper(Float source)
+{
+ // memcpy call in qFromUnaligned is recognized by optimizer as a correct way of type prunning
+ auto temp = qFromUnaligned<typename QIntegerForSizeof<Float>::Unsigned>(&source);
+ temp = qbswap(temp);
+ return qFromUnaligned<Float>(&temp);
+}
+
+template <> inline qfloat16 qbswap<qfloat16>(qfloat16 source)
+{
+ return qbswapFloatHelper(source);
+}
+
+template <> inline float qbswap<float>(float source)
+{
+ return qbswapFloatHelper(source);
+}
+
+template <> inline double qbswap<double>(double source)
+{
+ return qbswapFloatHelper(source);
+}
+
/*
* qbswap(const T src, const void *dest);
* Changes the byte order of \a src from big endian to little endian or vice versa
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 5dd5f8031e..86e21f0a66 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -333,7 +333,7 @@ QIODevicePrivate::~QIODevicePrivate()
allowed. This flag currently only affects QFile. Other
classes might use this flag in the future, but until then
using this flag with any classes other than QFile may
- result in undefined behavior.
+ result in undefined behavior. (since Qt 5.11)
\value ExistingOnly Fail if the file to be opened does not exist. This flag
must be specified alongside ReadOnly, WriteOnly, or
ReadWrite. Note that using this flag with ReadOnly alone
@@ -341,7 +341,7 @@ QIODevicePrivate::~QIODevicePrivate()
not exist. This flag currently only affects QFile. Other
classes might use this flag in the future, but until then
using this flag with any classes other than QFile may
- result in undefined behavior.
+ result in undefined behavior. (since Qt 5.11)
Certain flags, such as \c Unbuffered and \c Truncate, are
meaningless when used with some subclasses. Some of these
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 0109e2c658..0c57ad34b9 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -417,6 +417,23 @@ static const char *findWMstr(uint msg)
{ 0x0232, "WM_EXITSIZEMOVE" },
{ 0x0233, "WM_DROPFILES" },
{ 0x0234, "WM_MDIREFRESHMENU" },
+ { 0x0241, "WM_NCPOINTERUPDATE"},
+ { 0x0242, "WM_NCPOINTERDOWN"},
+ { 0x0243, "WM_NCPOINTERUP"},
+ { 0x0245, "WM_POINTERUPDATE"},
+ { 0x0246, "WM_POINTERDOWN"},
+ { 0x0247, "WM_POINTERUP"},
+ { 0x0249, "WM_POINTERENTER"},
+ { 0x024A, "WM_POINTERLEAVE"},
+ { 0x0248, "WM_POINTERACTIVATE"},
+ { 0x024C, "WM_POINTERCAPTURECHANGED"},
+ { 0x024D, "WM_TOUCHHITTESTING"},
+ { 0x024E, "WM_POINTERWHEEL"},
+ { 0x024F, "WM_POINTERHWHEEL"},
+ { 0x0250, "DM_POINTERHITTEST"},
+ { 0x0251, "WM_POINTERROUTEDTO"},
+ { 0x0252, "WM_POINTERROUTEDAWAY"},
+ { 0x0253, "WM_POINTERROUTEDRELEASED"},
{ 0x0281, "WM_IME_SETCONTEXT" },
{ 0x0282, "WM_IME_NOTIFY" },
{ 0x0283, "WM_IME_CONTROL" },
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 9aea4dec67..8dbccfec3d 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -421,6 +421,7 @@ void QObjectPrivate::cleanConnectionLists()
{
if (connectionLists->dirty && !connectionLists->inUse) {
// remove broken connections
+ bool allConnected = false;
for (int signal = -1; signal < connectionLists->count(); ++signal) {
QObjectPrivate::ConnectionList &connectionList =
(*connectionLists)[signal];
@@ -432,11 +433,13 @@ void QObjectPrivate::cleanConnectionLists()
QObjectPrivate::Connection **prev = &connectionList.first;
QObjectPrivate::Connection *c = *prev;
+ bool connected = false; // whether the signal is still connected somewhere
while (c) {
if (c->receiver) {
last = c;
prev = &c->nextConnectionList;
c = *prev;
+ connected = true;
} else {
QObjectPrivate::Connection *next = c->nextConnectionList;
*prev = next;
@@ -448,6 +451,14 @@ void QObjectPrivate::cleanConnectionLists()
// Correct the connection list's last pointer.
// As conectionList.last could equal last, this could be a noop
connectionList.last = last;
+
+ if (!allConnected && !connected && signal >= 0
+ && size_t(signal) < sizeof(connectedSignals) * 8) {
+ // This signal is no longer connected
+ connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f));
+ } else if (signal == -1) {
+ allConnected = connected;
+ }
}
connectionLists->dirty = false;
}
@@ -2502,19 +2513,20 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj);
- if (signalIndex < sizeof(d->connectedSignals) * 8)
+ QMutexLocker locker(signalSlotLock(this));
+ if (!d->connectionLists)
+ return false;
+
+ if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty)
return d->isSignalConnected(signalIndex);
- QMutexLocker locker(signalSlotLock(this));
- if (d->connectionLists) {
- if (signalIndex < uint(d->connectionLists->count())) {
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signalIndex).first;
- while (c) {
- if (c->receiver)
- return true;
- c = c->nextConnectionList;
- }
+ if (signalIndex < uint(d->connectionLists->count())) {
+ const QObjectPrivate::Connection *c =
+ d->connectionLists->at(signalIndex).first;
+ while (c) {
+ if (c->receiver)
+ return true;
+ c = c->nextConnectionList;
}
}
return false;
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index e04d27d7b6..e56fe2c6ae 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -465,11 +465,7 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW
void QThread::yieldCurrentThread()
{
-#if !defined(Q_OS_WINRT)
SwitchToThread();
-#else
- ::Sleep(0);
-#endif
}
#endif // QT_CONFIG(thread)
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index faa7263d6b..fdb9c6d19a 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -217,6 +217,7 @@ void QContiguousCache<T>::setCapacity(int asize)
detach();
union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
x.d = allocateData(asize);
+ x.d->ref.store(1);
x.d->alloc = asize;
x.d->count = qMin(d->count, asize);
x.d->offset = d->offset + d->count - x.d->count;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 6cabf3ccae..0811dd9918 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -954,7 +954,18 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
if (object < 0)
return;
- *d->currentPage << "q\n/GSa gs\n";
+ *d->currentPage << "q\n";
+
+ if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) {
+ int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity));
+ if (stateObject)
+ *d->currentPage << "/GState" << stateObject << "gs\n";
+ else
+ *d->currentPage << "/GSa gs\n";
+ } else {
+ *d->currentPage << "/GSa gs\n";
+ }
+
*d->currentPage
<< QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
@@ -983,7 +994,18 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q
if (object < 0)
return;
- *d->currentPage << "q\n/GSa gs\n";
+ *d->currentPage << "q\n";
+
+ if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) {
+ int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity));
+ if (stateObject)
+ *d->currentPage << "/GState" << stateObject << "gs\n";
+ else
+ *d->currentPage << "/GSa gs\n";
+ } else {
+ *d->currentPage << "/GSa gs\n";
+ }
+
*d->currentPage
<< QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
diff --git a/src/gui/painting/qrgba64.qdoc b/src/gui/painting/qrgba64.qdoc
index 26c78a5dcd..3ee8a355e6 100644
--- a/src/gui/painting/qrgba64.qdoc
+++ b/src/gui/painting/qrgba64.qdoc
@@ -35,7 +35,7 @@
QRgba64 is a 64-bit data-structure containing four 16-bit color channels: Red, green, blue and alpha.
- QRgba64 can be used a replacement for QRgb when higher precision is needed. In particular a
+ QRgba64 can be used as a replacement for QRgb when higher precision is needed. In particular a
premultiplied QRgba64 can operate on unpremultiplied QRgb without loss of precision except
for alpha 0.
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 221a8b0866..44ab16d300 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -86,6 +86,7 @@
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
+#include <qwindowdefs.h>
QT_USE_NAMESPACE
@@ -93,6 +94,7 @@ QT_USE_NAMESPACE
bool startedQuit;
NSObject <NSApplicationDelegate> *reflectionDelegate;
bool inLaunch;
+ QWindowList hiddenWindows;
}
+ (instancetype)sharedDelegate
@@ -322,12 +324,28 @@ QT_USE_NAMESPACE
// fact that the application itself is hidden, which will cause a problem when
// the application is made visible again.
const QWindowList topLevelWindows = QGuiApplication::topLevelWindows();
- for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) {
- if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible())
+ for (QWindow *topLevelWindow : topLevelWindows) {
+ if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) {
topLevelWindow->hide();
+
+ if ((topLevelWindow->type() & Qt::Tool) == Qt::Tool)
+ hiddenWindows << topLevelWindow;
+ }
}
}
+- (void)applicationDidUnhide:(NSNotification *)notification
+{
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidUnhide:)])
+ [reflectionDelegate applicationDidUnhide:notification];
+
+ for (QWindow *window : qAsConst(hiddenWindows))
+ window->show();
+
+ hiddenWindows.clear();
+}
+
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
if (reflectionDelegate
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index 23251fd610..a3fdcd1025 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -546,7 +546,7 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven
else
QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier);
- QCoreApplication::processEvents();
+ QWasmEventDispatcher::maintainTimers();
return 1;
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 21dc0cd577..2b6c696979 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -484,6 +484,9 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
case WM_POINTERHWHEEL:
case WM_POINTERWHEEL: {
+ if (!isValidWheelReceiver(window))
+ return true;
+
int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
// Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL
@@ -493,8 +496,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ?
QPoint(delta, 0) : QPoint(0, delta);
- if (isValidWheelReceiver(window))
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
return true;
}
case WM_POINTERLEAVE:
@@ -508,7 +510,6 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
MSG msg, PVOID vTouchInfo, quint32 count)
{
Q_UNUSED(hwnd);
- Q_UNUSED(et);
if (et & QtWindows::NonClientEventFlag)
return false; // Let DefWindowProc() handle Non Client messages.
@@ -707,21 +708,46 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
// Process old-style mouse messages here.
bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
- Q_UNUSED(et);
-
// Generate enqueued events.
flushTouchEvents(m_touchDevice);
flushTabletEvents();
*result = 0;
- if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
+ if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
return false;
- const QPoint localPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
- const QPoint globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, localPos);
+ const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ QPoint localPos;
+ QPoint globalPos;
+ if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) {
+ globalPos = eventPos;
+ localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos);
+ } else {
+ localPos = eventPos;
+ globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, eventPos);
+ }
+ const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+ if (et == QtWindows::MouseWheelEvent) {
+
+ if (!isValidWheelReceiver(window))
+ return true;
+
+ int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
+
+ // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL
+ if (msg.message == WM_MOUSEHWHEEL)
+ delta = -delta;
+
+ const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ?
+ QPoint(delta, 0) : QPoint(0, delta);
+
+ QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ return true;
+ }
+
if (msg.message == WM_MOUSELEAVE) {
if (window == m_currentWindow) {
QWindowSystemInterface::handleLeaveEvent(window);
@@ -762,7 +788,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
m_windowUnderPointer = currentWindowUnderPointer;
}
- const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::MouseButtons mouseButtons = queryMouseButtons();
if (!discardEvent)
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 3fd14a659e..9c7559d514 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -153,114 +153,71 @@ private:
QByteArray format_atoms;
};
-namespace {
-class INCRTransaction;
-typedef QMap<xcb_window_t,INCRTransaction*> TransactionMap;
-static TransactionMap *transactions = 0;
+QXcbClipboardTransaction::QXcbClipboardTransaction(QXcbClipboard *clipboard, xcb_window_t w,
+ xcb_atom_t p, QByteArray d, xcb_atom_t t, int f)
+ : m_clipboard(clipboard), m_window(w), m_property(p), m_data(d), m_target(t), m_format(f)
+{
+ const quint32 values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
+ xcb_change_window_attributes(m_clipboard->xcb_connection(), m_window,
+ XCB_CW_EVENT_MASK, values);
-//#define INCR_DEBUG
+ m_abortTimerId = startTimer(m_clipboard->clipboardTimeout());
+}
-class INCRTransaction : public QObject
+QXcbClipboardTransaction::~QXcbClipboardTransaction()
{
- Q_OBJECT
-public:
- INCRTransaction(QXcbConnection *c, xcb_window_t w, xcb_atom_t p,
- QByteArray d, uint i, xcb_atom_t t, int f, int to) :
- conn(c), win(w), property(p), data(d), increment(i),
- target(t), format(f), timeout(to), offset(0)
- {
- const quint32 values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
- xcb_change_window_attributes(conn->xcb_connection(), win,
- XCB_CW_EVENT_MASK, values);
- if (!transactions) {
-#ifdef INCR_DEBUG
- qDebug("INCRTransaction: creating the TransactionMap");
-#endif
- transactions = new TransactionMap;
- conn->clipboard()->setProcessIncr(true);
- }
- transactions->insert(win, this);
- abort_timer = startTimer(timeout);
- }
+ if (m_abortTimerId)
+ killTimer(m_abortTimerId);
+ m_abortTimerId = 0;
+ m_clipboard->removeTransaction(m_window);
+}
- ~INCRTransaction()
- {
- if (abort_timer)
- killTimer(abort_timer);
- abort_timer = 0;
- transactions->remove(win);
- if (transactions->isEmpty()) {
-#ifdef INCR_DEBUG
- qDebug("INCRTransaction: no more INCR transactions left in the TransactionMap");
-#endif
- delete transactions;
- transactions = 0;
- conn->clipboard()->setProcessIncr(false);
- }
- }
+bool QXcbClipboardTransaction::updateIncrementalProperty(const xcb_property_notify_event_t *event)
+{
+ if (event->atom != m_property || event->state != XCB_PROPERTY_DELETE)
+ return false;
- void updateIncrProperty(xcb_property_notify_event_t *event, bool &accepted)
- {
- xcb_connection_t *c = conn->xcb_connection();
- if (event->atom == property && event->state == XCB_PROPERTY_DELETE) {
- accepted = true;
- // restart the timer
- if (abort_timer)
- killTimer(abort_timer);
- abort_timer = startTimer(timeout);
-
- unsigned int bytes_left = data.size() - offset;
- if (bytes_left > 0) {
- unsigned int bytes_to_send = qMin(increment, bytes_left);
-#ifdef INCR_DEBUG
- qDebug("INCRTransaction: sending %d bytes, %d remaining (INCR transaction %p)",
- bytes_to_send, bytes_left - bytes_to_send, this);
-#endif
- int dataSize = bytes_to_send / (format / 8);
- xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property,
- target, format, dataSize, data.constData() + offset);
- offset += bytes_to_send;
- } else {
-#ifdef INCR_DEBUG
- qDebug("INCRTransaction: INCR transaction %p completed", this);
-#endif
- xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property,
- target, format, 0, (const void *)0);
- const quint32 values[] = { XCB_EVENT_MASK_NO_EVENT };
- xcb_change_window_attributes(conn->xcb_connection(), win,
- XCB_CW_EVENT_MASK, values);
- // self destroy
- delete this;
- }
- }
- }
+ // restart the timer
+ if (m_abortTimerId)
+ killTimer(m_abortTimerId);
+ m_abortTimerId = startTimer(m_clipboard->clipboardTimeout());
-protected:
- void timerEvent(QTimerEvent *ev) override
- {
- if (ev->timerId() == abort_timer) {
- // this can happen when the X client we are sending data
- // to decides to exit (normally or abnormally)
-#ifdef INCR_DEBUG
- qDebug("INCRTransaction: Timed out while sending data to %p", this);
-#endif
- delete this;
- }
+ uint bytes_left = uint(m_data.size()) - m_offset;
+ if (bytes_left > 0) {
+ int increment = m_clipboard->increment();
+ uint bytes_to_send = qMin(uint(increment), bytes_left);
+
+ qCDebug(lcQpaClipboard, "sending %d bytes, %d remaining, transaction: %p)",
+ bytes_to_send, bytes_left - bytes_to_send, this);
+
+ uint32_t dataSize = bytes_to_send / (m_format / 8);
+ xcb_change_property(m_clipboard->xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ m_property, m_target, m_format, dataSize, m_data.constData() + m_offset);
+ m_offset += bytes_to_send;
+ } else {
+ qCDebug(lcQpaClipboard, "transaction %p completed", this);
+
+ xcb_change_property(m_clipboard->xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ m_property, m_target, m_format, 0, nullptr);
+
+ const quint32 values[] = { XCB_EVENT_MASK_NO_EVENT };
+ xcb_change_window_attributes(m_clipboard->xcb_connection(), m_window,
+ XCB_CW_EVENT_MASK, values);
+ delete this; // self destroy
}
+ return true;
+}
-private:
- QXcbConnection *conn;
- xcb_window_t win;
- xcb_atom_t property;
- QByteArray data;
- uint increment;
- xcb_atom_t target;
- int format;
- int timeout;
- uint offset;
- int abort_timer;
-};
-} // unnamed namespace
+
+void QXcbClipboardTransaction::timerEvent(QTimerEvent *ev)
+{
+ if (ev->timerId() == m_abortTimerId) {
+ // this can happen when the X client we are sending data
+ // to decides to exit (normally or abnormally)
+ qCDebug(lcQpaClipboard, "timed out while sending data to %p", this);
+ delete this; // self destroy
+ }
+}
const int QXcbClipboard::clipboard_timeout = 5000;
@@ -282,6 +239,9 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask);
xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask);
}
+
+ // change property protocol request is 24 bytes
+ m_increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;
}
QXcbClipboard::~QXcbClipboard()
@@ -313,16 +273,17 @@ QXcbClipboard::~QXcbClipboard()
delete m_clientClipboard[QClipboard::Selection];
}
-void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted)
+bool QXcbClipboard::handlePropertyNotify(const xcb_generic_event_t *event)
{
- uint response_type = ge->response_type & ~0x80;
- if (response_type == XCB_PROPERTY_NOTIFY) {
- xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;
- TransactionMap::Iterator it = transactions->find(event->window);
- if (it != transactions->end()) {
- (*it)->updateIncrProperty(event, accepted);
- }
- }
+ if (m_transactions.isEmpty() || event->response_type != XCB_PROPERTY_NOTIFY)
+ return false;
+
+ auto propertyNotify = reinterpret_cast<const xcb_property_notify_event_t *>(event);
+ TransactionMap::Iterator it = m_transactions.find(propertyNotify->window);
+ if (it == m_transactions.constEnd())
+ return false;
+
+ return (*it)->updateIncrementalProperty(propertyNotify);
}
xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const
@@ -522,19 +483,18 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win
// This 'bool' can be removed once there is a proper fix for QTBUG-32853
if (m_clipboard_closing)
allow_incr = false;
- // X_ChangeProperty protocol request is 24 bytes
- const int increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;
- if (data.size() > increment && allow_incr) {
+
+ if (data.size() > m_increment && allow_incr) {
long bytes = data.size();
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property,
atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);
- new INCRTransaction(connection(), window, property, data, increment,
- atomFormat, dataFormat, clipboard_timeout);
+ auto transaction = new QXcbClipboardTransaction(this, window, property, data, atomFormat, dataFormat);
+ m_transactions.insert(window, transaction);
return property;
}
// make sure we can perform the XChangeProperty in a single request
- if (data.size() > increment)
+ if (data.size() > m_increment)
return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
int dataSize = data.size() / (dataFormat / 8);
// use a single request to transfer data
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index abab42a613..26d3b3b395 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -45,14 +45,41 @@
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
+#include <QtCore/QObject>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_CLIPBOARD
class QXcbConnection;
class QXcbScreen;
+class QXcbClipboard;
class QXcbClipboardMime;
+class QXcbClipboardTransaction : public QObject
+{
+ Q_OBJECT
+public:
+ QXcbClipboardTransaction(QXcbClipboard *clipboard, xcb_window_t w, xcb_atom_t p,
+ QByteArray d, xcb_atom_t t, int f);
+ ~QXcbClipboardTransaction();
+
+ bool updateIncrementalProperty(const xcb_property_notify_event_t *event);
+
+protected:
+ void timerEvent(QTimerEvent *ev) override;
+
+private:
+ QXcbClipboard *m_clipboard;
+ xcb_window_t m_window;
+ xcb_atom_t m_property;
+ QByteArray m_data;
+ xcb_atom_t m_target;
+ uint8_t m_format;
+ uint m_offset = 0;
+ int m_abortTimerId = 0;
+};
+
class QXcbClipboard : public QXcbObject, public QPlatformClipboard
{
public:
@@ -81,13 +108,16 @@ public:
QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
- void setProcessIncr(bool process) { m_incr_active = process; }
- bool processIncr() { return m_incr_active; }
- void incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted);
+ bool handlePropertyNotify(const xcb_generic_event_t *event);
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
+ int increment() const { return m_increment; }
+ int clipboardTimeout() const { return clipboard_timeout; }
+
+ void removeTransaction(xcb_window_t window) { m_transactions.remove(window); }
+
private:
xcb_generic_event_t *waitForClipboardEvent(xcb_window_t window, int type, bool checkManager = false);
@@ -107,9 +137,12 @@ private:
static const int clipboard_timeout;
- bool m_incr_active = false;
+ int m_increment = 0;
bool m_clipboard_closing = false;
xcb_timestamp_t m_incr_receive_time = 0;
+
+ using TransactionMap = QMap<xcb_window_t, QXcbClipboardTransaction *>;
+ TransactionMap m_transactions;
};
#endif // QT_NO_CLIPBOARD
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 9e857ea2ff..37ee980924 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -84,6 +84,7 @@ Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
Q_LOGGING_CATEGORY(lcQpaEventReader, "qt.qpa.events.reader")
Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker")
Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
+Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard")
Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
// this event type was added in libxcb 1.10,
@@ -105,6 +106,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
+ if (hasXRandr())
+ xrandrSelectEvents();
+
initializeScreens();
#if QT_CONFIG(xcb_xinput)
@@ -648,6 +652,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
case XCB_PROPERTY_NOTIFY:
{
+#ifndef QT_NO_CLIPBOARD
+ if (m_clipboard->handlePropertyNotify(event))
+ break;
+#endif
auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
if (propertyNotify->atom == atom(QXcbAtom::_NET_WORKAREA)) {
QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
@@ -1007,14 +1015,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
if (compressEvent(event))
continue;
-#ifndef QT_NO_CLIPBOARD
- bool accepted = false;
- if (clipboard()->processIncr())
- clipboard()->incrTransactionPeeker(event, accepted);
- if (accepted)
- continue;
-#endif
-
auto isWaitingFor = [=](PeekFunc peekFunc) {
// These callbacks return true if the event is what they were
// waiting for, remove them from the list in that case.
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 49e79ec3fd..47036ca257 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -68,6 +68,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
Q_DECLARE_LOGGING_CATEGORY(lcQpaPeeker)
Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard)
Q_DECLARE_LOGGING_CATEGORY(lcQpaXDnd)
Q_DECLARE_LOGGING_CATEGORY(lcQpaEventReader)
@@ -250,7 +251,7 @@ protected:
bool event(QEvent *e) override;
private:
- void selectXRandrEvents();
+ void xrandrSelectEvents();
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index 7bed3c8937..b8335d1240 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -308,7 +308,7 @@ void QXcbBasicConnection::initializeXRandr()
return;
}
- m_hasXRender = true;
+ m_hasXRandr = true;
m_xrenderVersion.first = xrenderQuery->major_version;
m_xrenderVersion.second = xrenderQuery->minor_version;
#endif
@@ -358,7 +358,7 @@ void QXcbBasicConnection::initializeXRender()
return;
}
- m_hasXRandr = true;
+ m_hasXRender = true;
m_xrandrFirstEvent = reply->first_event;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
index 4c380bf39f..fe9e0be86d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
@@ -46,7 +46,7 @@
#include <xcb/xinerama.h>
-void QXcbConnection::selectXRandrEvents()
+void QXcbConnection::xrandrSelectEvents()
{
xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(setup());
for (; rootIter.rem; xcb_screen_next(&rootIter)) {
@@ -270,8 +270,6 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
void QXcbConnection::initializeScreens()
{
- selectXRandrEvents();
-
xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup());
int xcbScreenNumber = 0; // screen number in the xcb sense
QXcbScreen *primaryScreen = nullptr;
@@ -284,7 +282,7 @@ void QXcbConnection::initializeScreens()
QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber);
m_virtualDesktops.append(virtualDesktop);
QList<QPlatformScreen *> siblings;
- if (hasXRender()) {
+ if (hasXRandr()) {
// RRGetScreenResourcesCurrent is fast but it may return nothing if the
// configuration is not initialized wrt to the hardware. We should call
// RRGetScreenResources in this case.
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 6667f45343..d2ca9fe0b9 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -207,7 +207,6 @@ protected:
void setTransparentForMouseEvents(bool transparent);
void updateDoesNotAcceptFocus(bool doesNotAcceptFocus);
- QRect windowToWmGeometry(QRect r) const;
void sendXEmbedMessage(xcb_window_t window, quint32 message,
quint32 detail = 0, quint32 data1 = 0, quint32 data2 = 0);
void handleXEmbedMessage(const xcb_client_message_event_t *event);
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
index cda267d24b..5e94d1558e 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -181,10 +181,10 @@ void QXdgDesktopPortalFileDialog::openPortal()
if (d->saveFile) {
if (!d->directory.isEmpty())
- options.insert(QLatin1String("current_folder"), d->directory.toLatin1());
+ options.insert(QLatin1String("current_folder"), d->directory.toLatin1().append('\0'));
if (!d->selectedFiles.isEmpty())
- options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1());
+ options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1().append('\0'));
}
// Insert filters
diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
index 7043969c2f..2345bb39c1 100644
--- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
+++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
@@ -64,6 +64,9 @@ struct TestData
quint16 data16;
quint8 data8;
+ float dataFloat;
+ double dataDouble;
+
quint8 reserved;
};
@@ -72,6 +75,7 @@ template <> quint8 getData(const TestData &d) { return d.data8; }
template <> quint16 getData(const TestData &d) { return d.data16; }
template <> quint32 getData(const TestData &d) { return d.data32; }
template <> quint64 getData(const TestData &d) { return d.data64; }
+template <> float getData(const TestData &d) { return d.dataFloat; }
union RawTestData
{
@@ -79,9 +83,39 @@ union RawTestData
TestData data;
};
-static const TestData inNativeEndian = { Q_UINT64_C(0x0123456789abcdef), 0x00c0ffee, 0xcafe, 0xcf, '\0' };
-static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" };
-static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" };
+template <typename Float>
+Float int2Float(typename QIntegerForSizeof<Float>::Unsigned i)
+{
+ Float result = 0;
+ memcpy(reinterpret_cast<char *>(&result), reinterpret_cast<const char *>(&i), sizeof (Float));
+ return result;
+}
+
+static const TestData inNativeEndian = {
+ Q_UINT64_C(0x0123456789abcdef),
+ 0x00c0ffee,
+ 0xcafe,
+ 0xcf,
+ int2Float<float>(0x00c0ffeeU),
+ int2Float<double>(Q_UINT64_C(0x0123456789abcdef)),
+ '\0'
+};
+static const RawTestData inBigEndian = {
+ "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\x00\xc0\xff\xee"
+ "\xca\xfe"
+ "\xcf"
+ "\x00\xc0\xff\xee"
+ "\x01\x23\x45\x67\x89\xab\xcd\xef"
+};
+static const RawTestData inLittleEndian = {
+ "\xef\xcd\xab\x89\x67\x45\x23\x01"
+ "\xee\xff\xc0\x00"
+ "\xfe\xca"
+ "\xcf"
+ "\xee\xff\xc0\x00"
+ "\xef\xcd\xab\x89\x67\x45\x23\x01"
+};
#define EXPAND_ENDIAN_TEST(endian) \
do { \
diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
index fed05698fd..da5327594c 100644
--- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
@@ -209,9 +209,6 @@ void tst_QIODevice::read_QByteArray()
//--------------------------------------------------------------------
void tst_QIODevice::unget()
{
-#if defined(Q_OS_MAC)
- QSKIP("The unget network test is unstable on Mac. See QTBUG-39983.");
-#endif
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
buffer.write("ZXCV");
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
index fb7e025b7c..b1590a5ccf 100644
--- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
+++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
@@ -1,7 +1,5 @@
[sendPostedEvents]
windows
-osx
[registerTimer]
windows
-osx
winrt
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 9f4419affc..936cbd3894 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -103,6 +103,7 @@ private slots:
void deleteQObjectWhenDeletingEvent();
void overloads();
void isSignalConnected();
+ void isSignalConnectedAfterDisconnection();
void qMetaObjectConnect();
void qMetaObjectDisconnectOne();
void sameName();
@@ -3837,6 +3838,58 @@ void tst_QObject::isSignalConnected()
QVERIFY(!o.isSignalConnected(QMetaMethod()));
}
+void tst_QObject::isSignalConnectedAfterDisconnection()
+{
+ ManySignals o;
+ const QMetaObject *meta = o.metaObject();
+
+ const QMetaMethod sig00 = meta->method(meta->indexOfSignal("sig00()"));
+ QVERIFY(!o.isSignalConnected(sig00));
+ QObject::connect(&o, &ManySignals::sig00, qt_noop);
+ QVERIFY(o.isSignalConnected(sig00));
+ QVERIFY(QObject::disconnect(&o, &ManySignals::sig00, 0, 0));
+ QVERIFY(!o.isSignalConnected(sig00));
+
+ const QMetaMethod sig69 = meta->method(meta->indexOfSignal("sig69()"));
+ QVERIFY(!o.isSignalConnected(sig69));
+ QObject::connect(&o, &ManySignals::sig69, qt_noop);
+ QVERIFY(o.isSignalConnected(sig69));
+ QVERIFY(QObject::disconnect(&o, &ManySignals::sig69, 0, 0));
+ QVERIFY(!o.isSignalConnected(sig69));
+
+ {
+ ManySignals o2;
+ QObject::connect(&o, &ManySignals::sig00, &o2, &ManySignals::sig00);
+ QVERIFY(o.isSignalConnected(sig00));
+ // o2 is destructed
+ }
+ QVERIFY(!o.isSignalConnected(sig00));
+
+ const QMetaMethod sig01 = meta->method(meta->indexOfSignal("sig01()"));
+ QObject::connect(&o, &ManySignals::sig00, qt_noop);
+ QObject::connect(&o, &ManySignals::sig01, qt_noop);
+ QObject::connect(&o, &ManySignals::sig69, qt_noop);
+ QVERIFY(o.isSignalConnected(sig00));
+ QVERIFY(o.isSignalConnected(sig01));
+ QVERIFY(o.isSignalConnected(sig69));
+ QVERIFY(QObject::disconnect(&o, &ManySignals::sig69, 0, 0));
+ QVERIFY(o.isSignalConnected(sig00));
+ QVERIFY(o.isSignalConnected(sig01));
+ QVERIFY(!o.isSignalConnected(sig69));
+ QVERIFY(QObject::disconnect(&o, &ManySignals::sig00, 0, 0));
+ QVERIFY(!o.isSignalConnected(sig00));
+ QVERIFY(o.isSignalConnected(sig01));
+ QVERIFY(!o.isSignalConnected(sig69));
+ QObject::connect(&o, &ManySignals::sig69, qt_noop);
+ QVERIFY(!o.isSignalConnected(sig00));
+ QVERIFY(o.isSignalConnected(sig01));
+ QVERIFY(o.isSignalConnected(sig69));
+ QVERIFY(QObject::disconnect(&o, &ManySignals::sig01, 0, 0));
+ QVERIFY(!o.isSignalConnected(sig00));
+ QVERIFY(!o.isSignalConnected(sig01));
+ QVERIFY(o.isSignalConnected(sig69));
+}
+
void tst_QObject::qMetaObjectConnect()
{
ReceiverObject r1;
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index 1b818ad152..c609aa6621 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -334,7 +334,7 @@ void tst_QCborValue::copyCompare()
QCOMPARE(v, other);
QVERIFY(!(v != other));
QVERIFY(!(v < other));
-#if QT_HAS_INCLUDE(<compare>)
+#if 0 && QT_HAS_INCLUDE(<compare>)
QVERIFY(v <= other);
QVERIFY(v >= other);
QVERIFY(!(v > other));
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
index f520e9742a..18098f16bf 100644
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
@@ -2108,12 +2108,16 @@ void tst_QRegularExpression::threadSafety_data()
QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
}
+ // pcre2 does not support JIT for winrt. As this test row takes a long time without JIT we skip
+ // it for winrt as it might time out in COIN.
+#ifndef Q_OS_WINRT
{
QString subject = "ab";
subject.append(QString(512*1024, QLatin1Char('x')));
subject.append("c");
QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
}
+#endif // Q_OS_WINRT
{
QString subject = "ab";
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index 779d55a77a..45ab275510 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -962,9 +962,6 @@ void tst_QLocalSocket::processConnection()
#if !QT_CONFIG(process)
QSKIP("No qprocess support", SkipAll);
#else
-#ifdef Q_OS_MAC
- QSKIP("The processConnection test is unstable on Mac. See QTBUG-39986.");
-#endif
#ifdef Q_OS_WIN
const QString exeSuffix = QStringLiteral(".exe");
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index d8a680881a..9ee5292fcb 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -51,10 +51,15 @@
// Will try to wait for the condition while allowing event processing
// for a maximum of 5 seconds.
-#define TRY_WAIT(expr) \
+#define TRY_WAIT(expr, timedOut) \
do { \
+ *timedOut = true; \
const int step = 50; \
- for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \
+ for (int __i = 0; __i < 5000; __i += step) { \
+ if (expr) { \
+ *timedOut = false; \
+ break; \
+ } \
QTest::qWait(step); \
} \
} while(0)
@@ -123,6 +128,8 @@ private slots:
protected:
bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList());
+ QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr,
+ QSignalSpy **spy3 = nullptr);
private:
QFileSystemModel *model;
@@ -306,7 +313,11 @@ void tst_QFileSystemModel::iconProvider()
bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs)
{
//qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
- TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
+ bool timedOut = false;
+ TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount), &timedOut);
+ if (timedOut)
+ return false;
+
for (int i = 0; i < initial_dirs.count(); ++i) {
QDir dir(test_path);
if (!dir.exists()) {
@@ -363,23 +374,45 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi
return true;
}
-void tst_QFileSystemModel::rowCount()
+QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2,
+ QSignalSpy **spy3)
{
- QString tmp = flatDirTestPath;
- QVERIFY(createFiles(tmp, QStringList()));
+ if (model->rowCount(model->index(test_path)) != 0)
+ return QModelIndex();
- QSignalSpy spy2(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ if (spy2)
+ *spy2 = new QSignalSpy(model, &QFileSystemModel::rowsInserted);
+ if (spy3)
+ *spy3 = new QSignalSpy(model, &QFileSystemModel::rowsAboutToBeInserted);
- QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g";
+ QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" };
QString l = "b,d,f,h,j,.a,.c,.e,.g";
- QVERIFY(createFiles(tmp, files));
+ if (!createFiles(test_path, files))
+ return QModelIndex();
- QModelIndex root = model->setRootPath(tmp);
- QTRY_COMPARE(model->rowCount(root), 5);
- QVERIFY(spy2.count() > 0);
- QVERIFY(spy3.count() > 0);
+ QModelIndex root = model->setRootPath(test_path);
+ if (!root.isValid())
+ return QModelIndex();
+
+ bool timedOut = false;
+ TRY_WAIT(model->rowCount(root) == 5, &timedOut);
+ if (timedOut)
+ return QModelIndex();
+
+ return root;
+}
+
+void tst_QFileSystemModel::rowCount()
+{
+ const QString tmp = flatDirTestPath;
+ QSignalSpy *spy2 = nullptr;
+ QSignalSpy *spy3 = nullptr;
+ QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3);
+ QVERIFY(root.isValid());
+
+ QVERIFY(spy2 && spy2->count() > 0);
+ QVERIFY(spy3 && spy3->count() > 0);
}
void tst_QFileSystemModel::rowsInserted_data()
@@ -401,9 +434,9 @@ static inline QString lastEntry(const QModelIndex &root)
void tst_QFileSystemModel::rowsInserted()
{
- QString tmp = flatDirTestPath;
- rowCount();
- QModelIndex root = model->index(model->rootPath());
+ const QString tmp = flatDirTestPath;
+ QModelIndex root = prepareTestModelRoot(tmp);
+ QVERIFY(root.isValid());
QFETCH(int, ascending);
QFETCH(int, count);
@@ -454,9 +487,9 @@ void tst_QFileSystemModel::rowsRemoved_data()
void tst_QFileSystemModel::rowsRemoved()
{
- QString tmp = flatDirTestPath;
- rowCount();
- QModelIndex root = model->index(model->rootPath());
+ const QString tmp = flatDirTestPath;
+ QModelIndex root = prepareTestModelRoot(tmp);
+ QVERIFY(root.isValid());
QFETCH(int, count);
QFETCH(int, ascending);
@@ -509,9 +542,9 @@ void tst_QFileSystemModel::dataChanged()
{
QSKIP("This can't be tested right now since we don't watch files, only directories.");
- QString tmp = flatDirTestPath;
- rowCount();
- QModelIndex root = model->index(model->rootPath());
+ const QString tmp = flatDirTestPath;
+ QModelIndex root = prepareTestModelRoot(tmp);
+ QVERIFY(root.isValid());
QFETCH(int, count);
QFETCH(int, assending);