summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-12-16 07:05:19 +0100
committerLiang Qi <liang.qi@qt.io>2019-12-16 12:58:50 +0100
commit1d00f52fd3db908ead50167b59d5ff6091fb1688 (patch)
treedf10d394e24eb83be30516658536febe2a7996e3 /src
parent313c2b46fe2830de981c94d07c5ef5ced9cb3257 (diff)
parentee71a9ba8169b9327b8dbaf2266ebeb515c64dbb (diff)
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/VulkanMemoryAllocator/qt_attribution.json2
-rw-r--r--src/corelib/doc/src/qtcore-index.qdoc2
-rw-r--r--src/corelib/doc/src/resource-system.qdoc4
-rw-r--r--src/corelib/global/qendian.cpp6
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qlibraryinfo.cpp36
-rw-r--r--src/corelib/io/qresource.cpp4
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp17
-rw-r--r--src/corelib/thread/qatomic.cpp204
-rw-r--r--src/corelib/thread/qatomic.h6
-rw-r--r--src/corelib/time/qcalendar.cpp4
-rw-r--r--src/gui/configure.json1
-rw-r--r--src/gui/doc/src/qtgui.qdoc2
-rw-r--r--src/gui/kernel/qwindow.cpp2
-rw-r--r--src/gui/opengl/qopenglextrafunctions.h2
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp75
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.h21
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm272
-rw-r--r--src/sql/doc/src/sql-driver.qdoc11
-rw-r--r--src/testlib/doc/src/qttest-best-practices.qdoc4
-rw-r--r--src/widgets/kernel/qapplication.cpp138
-rw-r--r--src/widgets/kernel/qapplication_p.h1
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
24 files changed, 567 insertions, 257 deletions
diff --git a/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json b/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json
index 2548856ca7..0a5df738a8 100644
--- a/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json
+++ b/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json
@@ -2,7 +2,7 @@
{
"Id": "VulkanMemoryAllocator",
"Name": "Vulkan Memory Allocator",
- "QDocModule": "qtrhi",
+ "QDocModule": "qtgui",
"Description": "Vulkan Memory Allocator",
"QtUsage": "Memory management for the Vulkan backend of QRhi.",
diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc
index 40a6584af0..29fc25f69d 100644
--- a/src/corelib/doc/src/qtcore-index.qdoc
+++ b/src/corelib/doc/src/qtcore-index.qdoc
@@ -56,7 +56,7 @@
\include module-use.qdocinc using qt module
\quotefile overview/using-qt-core.cmake
- See also the \l[QtDoc]{Building with CMake} overview.
+ See also the \l[QtDoc]{Build with CMake} overview.
\section2 Building with qmake
diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc
index 69ec5e556b..f9ef317799 100644
--- a/src/corelib/doc/src/resource-system.qdoc
+++ b/src/corelib/doc/src/resource-system.qdoc
@@ -189,13 +189,13 @@
XML file to indicate a file should be most compressed, regardless of
which algorithms \c rcc supports.
- \li \c{zstd}: use the \l{Zstandard}{https://zstd.net} library to compress
+ \li \c{zstd}: use the \l{https://zstd.net}{Zstandard} library to compress
contents. Valid compression levels range from 1 to 19, 1 is least
compression (least CPU time) and 19 is the most compression (most CPU
time). The default level is 14. A special value of 0 tells the \c{zstd}
library to choose an implementation-defined default.
- \li \c{zlib}: use the \l{zlib}{https://zlib.net} library to compress
+ \li \c{zlib}: use the \l{https://zlib.net}{zlib} library to compress
contents. Valid compression levels range from 1 to 9, with 1the least
compression (least CPU time) and 9 the most compression (most CPU time).
The special value 0 means "no compression" and should not be used. The
diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp
index 7fd6e13d3b..98dc6a9a4b 100644
--- a/src/corelib/global/qendian.cpp
+++ b/src/corelib/global/qendian.cpp
@@ -137,7 +137,7 @@ QT_BEGIN_NAMESPACE
\sa qToLittleEndian()
*/
/*!
- \fn template <typename T> T qFromLittleEndian(const void *src)
+ \fn template <typename T> inline T qFromLittleEndian(const void *src)
\since 4.3
\relates <QtEndian>
@@ -159,7 +159,7 @@ QT_BEGIN_NAMESPACE
\sa qToLittleEndian()
*/
/*!
- \fn template <typename T> T qFromLittleEndian(T src)
+ \fn template <typename T> inline T qFromLittleEndian(T src)
\since 4.3
\relates <QtEndian>
\overload
@@ -171,7 +171,7 @@ QT_BEGIN_NAMESPACE
unmodified.
*/
/*!
- \fn template <typename T> T qFromLittleEndian(const void *src, qsizetype count, void *dest)
+ \fn template <typename T> inline T qFromLittleEndian(const void *src, qsizetype count, void *dest)
\since 5.12
\relates <QtEndian>
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 861f087c60..1bfe2c1615 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -944,6 +944,10 @@ QT_WARNING_POP
# define Q_DUMMY_COMPARISON_OPERATOR(C)
#endif
+QT_WARNING_PUSH
+// warning: noexcept-expression evaluates to ‘false’ because of a call to ‘void swap(..., ...)'
+QT_WARNING_DISABLE_GCC("-Wnoexcept")
+
namespace QtPrivate
{
namespace SwapExceptionTester { // insulate users from the "using std::swap" below
@@ -963,6 +967,8 @@ inline void qSwap(T &value1, T &value2)
swap(value1, value2);
}
+QT_WARNING_POP
+
#if QT_DEPRECATED_SINCE(5, 0)
Q_CORE_EXPORT QT_DEPRECATED void *qMalloc(size_t size) Q_ALLOC_SIZE(1);
Q_CORE_EXPORT QT_DEPRECATED void qFree(void *ptr);
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index ecd26233cd..fa2098c757 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -562,9 +562,39 @@ static QString getRelocatablePrefix()
HMODULE hModule = getWindowsModuleHandle();
const int kBufferSize = 4096;
wchar_t buffer[kBufferSize];
- const int pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
- if (pathSize > 0)
- prefixPath = prefixFromQtCoreLibraryHelper(QString::fromWCharArray(buffer, pathSize));
+ DWORD pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
+ const QString qtCoreFilePath = QString::fromWCharArray(buffer, int(pathSize));
+ const QString qtCoreDirPath = QFileInfo(qtCoreFilePath).absolutePath();
+ pathSize = GetModuleFileName(NULL, buffer, kBufferSize);
+ const QString exeDirPath = QFileInfo(QString::fromWCharArray(buffer, int(pathSize))).absolutePath();
+ if (QFileInfo(exeDirPath) == QFileInfo(qtCoreDirPath)) {
+ // QtCore DLL is next to the executable. This is either a windeployqt'ed executable or an
+ // executable within the QT_HOST_BIN directory. We're detecting the latter case by checking
+ // whether there's an import library corresponding to our QtCore DLL in PREFIX/lib.
+ const QString libdir = QString::fromLatin1(
+ qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]);
+ const QLatin1Char slash('/');
+#if defined(Q_CC_MINGW)
+ const QString implibPrefix = QStringLiteral("lib");
+ const QString implibSuffix = QStringLiteral(".a");
+#else
+ const QString implibPrefix;
+ const QString implibSuffix = QStringLiteral(".lib");
+#endif
+ const QString qtCoreImpLibFileName = implibPrefix
+ + QFileInfo(qtCoreFilePath).completeBaseName() + implibSuffix;
+ const QString qtCoreImpLibPath = qtCoreDirPath
+ + slash + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH)
+ + slash + libdir
+ + slash + qtCoreImpLibFileName;
+ if (!QFileInfo::exists(qtCoreImpLibPath)) {
+ // We did not find a corresponding import library and conclude that this is a
+ // windeployqt'ed executable.
+ return exeDirPath;
+ }
+ }
+ if (!qtCoreFilePath.isEmpty())
+ prefixPath = prefixFromQtCoreLibraryHelper(qtCoreFilePath);
#else
#error "The chosen platform / config does not support querying for a dynamic prefix."
#endif
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 3664a63050..bb608d8a72 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -280,9 +280,9 @@ static inline QStringList *resourceSearchPaths()
RCC tool used to compress the payload.
\value NoCompression Contents are not compressed
- \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can
+ \value ZlibCompression Contents are compressed using \l{https://zlib.net}{zlib} and can
be decompressed using the qUncompress() function.
- \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To
+ \value ZstdCompression Contents are compressed using \l{https://zstd.net}{zstd}. To
decompress, use the \c{ZSTD_decompress} function from the zstd
library.
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index f4402c88dc..e4ac5da299 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1627,10 +1627,9 @@ bool QItemSelectionModel::rowIntersectsSelection(int row, const QModelIndex &par
QItemSelection sel = d->ranges;
sel.merge(d->currentSelection, d->currentCommand);
- for (int i = 0; i < sel.count(); ++i) {
- QItemSelectionRange range = sel.at(i);
+ for (const QItemSelectionRange &range : qAsConst(sel)) {
if (range.parent() != parent)
- return false;
+ return false;
int top = range.top();
int bottom = range.bottom();
int left = range.left();
@@ -1661,11 +1660,13 @@ bool QItemSelectionModel::columnIntersectsSelection(int column, const QModelInde
QItemSelection sel = d->ranges;
sel.merge(d->currentSelection, d->currentCommand);
- for (int i = 0; i < sel.count(); ++i) {
- int left = sel.at(i).left();
- int right = sel.at(i).right();
- int top = sel.at(i).top();
- int bottom = sel.at(i).bottom();
+ for (const QItemSelectionRange &range : qAsConst(sel)) {
+ if (range.parent() != parent)
+ return false;
+ int top = range.top();
+ int bottom = range.bottom();
+ int left = range.left();
+ int right = range.right();
if (left <= column && right >= column) {
for (int j = top; j <= bottom; j++) {
const Qt::ItemFlags flags = d->model->index(j, column, parent).flags();
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index b1a7edad91..5c3ad9412f 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -234,22 +234,26 @@
\sa QAtomicPointer
*/
-/*! \fn QAtomicInt::QAtomicInt(int value)
+/*!
+ \fn QAtomicInt::QAtomicInt(int value)
Constructs a QAtomicInt with the given \a value.
*/
-/*! \fn QAtomicInteger<T>::QAtomicInteger(T value)
+/*!
+ \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(T value)
Constructs a QAtomicInteger with the given \a value.
*/
-/*! \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(const QAtomicInteger &other)
+/*!
+ \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(const QAtomicInteger &other)
Constructs a copy of \a other.
*/
-/*! \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(const QAtomicInteger &other)
+/*!
+ \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(const QAtomicInteger &other)
Assigns \a other to this QAtomicInteger and returns a reference to
this QAtomicInteger.
@@ -344,19 +348,22 @@
\sa storeRelaxed(), storeRelease()
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative()
Returns \c true if reference counting is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingWaitFree()
Returns \c true if atomic reference counting is wait-free, false
otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::ref()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::ref()
Atomically increments the value of this QAtomicInteger. Returns \c true
if the new value is non-zero, false otherwise.
@@ -394,7 +401,8 @@
\sa ref(), operator++(), operator--(int)
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::deref()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::deref()
Atomically decrements the value of this QAtomicInteger. Returns \c true
if the new value is non-zero, false otherwise.
@@ -432,18 +440,21 @@
\sa deref(), operator--(), operator++(int)
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetNative()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetNative()
Returns \c true if test-and-set is implemented using atomic processor
instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetWaitFree()
Returns \c true if atomic test-and-set is wait-free, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelaxed(T expectedValue, T newValue)
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelaxed(T expectedValue, T newValue)
Atomic test-and-set.
@@ -457,7 +468,8 @@
processor to freely reorder memory accesses.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue)
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue)
Atomic test-and-set.
@@ -472,7 +484,8 @@
be re-ordered before the atomic operation.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue)
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue)
Atomic test-and-set.
@@ -487,7 +500,8 @@
re-ordered after the atomic operation.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue)
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue)
Atomic test-and-set.
@@ -502,19 +516,22 @@
may not be re-ordered.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreNative()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreNative()
Returns \c true if fetch-and-store is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreWaitFree()
Returns \c true if atomic fetch-and-store is wait-free, false
otherwise.
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelaxed(T newValue)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelaxed(T newValue)
Atomic fetch-and-store.
@@ -526,7 +543,8 @@
processor to freely reorder memory accesses.
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreAcquire(T newValue)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreAcquire(T newValue)
Atomic fetch-and-store.
@@ -539,7 +557,8 @@
be re-ordered before the atomic operation.
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelease(T newValue)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelease(T newValue)
Atomic fetch-and-store.
@@ -552,7 +571,8 @@
re-ordered after the atomic operation.
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreOrdered(T newValue)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreOrdered(T newValue)
Atomic fetch-and-store.
@@ -565,19 +585,22 @@
may not be re-ordered.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddNative()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddNative()
Returns \c true if fetch-and-add is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddWaitFree()
Returns \c true if atomic fetch-and-add is wait-free, false
otherwise.
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelaxed(T valueToAdd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelaxed(T valueToAdd)
Atomic fetch-and-add.
@@ -591,7 +614,8 @@
\sa operator+=(), fetchAndSubRelaxed()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAddAcquire(T valueToAdd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddAcquire(T valueToAdd)
Atomic fetch-and-add.
@@ -606,7 +630,8 @@
\sa operator+=(), fetchAndSubAcquire()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelease(T valueToAdd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelease(T valueToAdd)
Atomic fetch-and-add.
@@ -621,7 +646,8 @@
\sa operator+=(), fetchAndSubRelease()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAddOrdered(T valueToAdd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddOrdered(T valueToAdd)
Atomic fetch-and-add.
@@ -636,7 +662,8 @@
\sa operator+=(), fetchAndSubOrdered()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::operator+=(T value)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::operator+=(T value)
\since 5.3
Atomic add-and-fetch.
@@ -650,7 +677,8 @@
\sa fetchAndAddOrdered(), operator-=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelaxed(T valueToSub)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelaxed(T valueToSub)
\since 5.3
Atomic fetch-and-sub.
@@ -665,7 +693,8 @@
\sa operator-=(), fetchAndAddRelaxed()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndSubAcquire(T valueToSub)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubAcquire(T valueToSub)
\since 5.3
Atomic fetch-and-sub.
@@ -681,7 +710,8 @@
\sa operator-=(), fetchAndAddAcquire()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelease(T valueToSub)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelease(T valueToSub)
\since 5.3
Atomic fetch-and-sub.
@@ -697,7 +727,8 @@
\sa operator-=(), fetchAndAddRelease()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndSubOrdered(T valueToSub)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubOrdered(T valueToSub)
\since 5.3
Atomic fetch-and-sub.
@@ -713,7 +744,8 @@
\sa operator-=(), fetchAndAddOrdered()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::operator-=(T value)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::operator-=(T value)
\since 5.3
Atomic sub-and-fetch.
@@ -727,7 +759,8 @@
\sa fetchAndSubOrdered(), operator+=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelaxed(T valueToOr)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelaxed(T valueToOr)
\since 5.3
Atomic fetch-and-or.
@@ -742,7 +775,8 @@
\sa operator|=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndOrAcquire(T valueToOr)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrAcquire(T valueToOr)
\since 5.3
Atomic fetch-and-or.
@@ -758,7 +792,8 @@
\sa operator|=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelease(T valueToOr)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelease(T valueToOr)
\since 5.3
Atomic fetch-and-or.
@@ -774,7 +809,8 @@
\sa operator|=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndOrOrdered(T valueToOr)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrOrdered(T valueToOr)
\since 5.3
Atomic fetch-and-or.
@@ -790,7 +826,8 @@
\sa operator|=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::operator|=(T value)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::operator|=(T value)
\since 5.3
Atomic or-and-fetch.
@@ -804,7 +841,8 @@
\sa fetchAndOrOrdered()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelaxed(T valueToXor)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelaxed(T valueToXor)
\since 5.3
Atomic fetch-and-xor.
@@ -819,7 +857,8 @@
\sa operator^=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndXorAcquire(T valueToXor)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorAcquire(T valueToXor)
\since 5.3
Atomic fetch-and-xor.
@@ -835,7 +874,8 @@
\sa operator^=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelease(T valueToXor)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelease(T valueToXor)
\since 5.3
Atomic fetch-and-xor.
@@ -851,7 +891,8 @@
\sa operator^=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndXorOrdered(T valueToXor)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorOrdered(T valueToXor)
\since 5.3
Atomic fetch-and-xor.
@@ -867,7 +908,8 @@
\sa operator^=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::operator^=(T value)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::operator^=(T value)
\since 5.3
Atomic xor-and-fetch.
@@ -881,7 +923,8 @@
\sa fetchAndXorOrdered()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelaxed(T valueToAnd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelaxed(T valueToAnd)
\since 5.3
Atomic fetch-and-and.
@@ -896,7 +939,8 @@
\sa operator&=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAndAcquire(T valueToAnd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndAcquire(T valueToAnd)
\since 5.3
Atomic fetch-and-and.
@@ -912,7 +956,8 @@
\sa operator&=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelease(T valueToAnd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelease(T valueToAnd)
\since 5.3
Atomic fetch-and-and.
@@ -928,7 +973,8 @@
\sa operator&=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::fetchAndAndOrdered(T valueToAnd)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndOrdered(T valueToAnd)
\since 5.3
Atomic fetch-and-and.
@@ -944,7 +990,8 @@
\sa operator&=()
*/
-/*! \fn template <typename T> T QAtomicInteger<T>::operator&=(T value)
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::operator&=(T value)
\since 5.3
Atomic add-and-fetch.
@@ -1287,17 +1334,20 @@
\sa QAtomicInteger
*/
-/*! \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(T *value)
+/*!
+ \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(T *value)
Constructs a QAtomicPointer with the given \a value.
*/
-/*! \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(const QAtomicPointer<T> &other)
+/*!
+ \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(const QAtomicPointer<T> &other)
Constructs a copy of \a other.
*/
-/*! \fn template <typename T> QAtomicPointer &QAtomicPointer<T>::operator=(const QAtomicPointer &other)
+/*!
+ \fn template <typename T> QAtomicPointer &QAtomicPointer<T>::operator=(const QAtomicPointer &other)
Assigns \a other to this QAtomicPointer and returns a reference to
this QAtomicPointer.
@@ -1369,18 +1419,21 @@
\sa storeRelaxed(), loadRelaxed()
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative()
Returns \c true if test-and-set is implemented using atomic processor
instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetWaitFree()
Returns \c true if atomic test-and-set is wait-free, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
Atomic test-and-set.
@@ -1394,7 +1447,8 @@
processor to freely reorder memory accesses.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
Atomic test-and-set.
@@ -1409,7 +1463,8 @@
be re-ordered before the atomic operation.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
Atomic test-and-set.
@@ -1424,7 +1479,8 @@
re-ordered after the atomic operation.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
Atomic test-and-set.
@@ -1439,19 +1495,22 @@
may not be re-ordered.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreNative()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreNative()
Returns \c true if fetch-and-store is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreWaitFree()
Returns \c true if atomic fetch-and-store is wait-free, false
otherwise.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
Atomic fetch-and-store.
@@ -1463,7 +1522,8 @@
processor to freely reorder memory accesses.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
Atomic fetch-and-store.
@@ -1476,7 +1536,8 @@
be re-ordered before the atomic operation.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
Atomic fetch-and-store.
@@ -1489,7 +1550,8 @@
re-ordered after the atomic operation.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
Atomic fetch-and-store.
@@ -1502,19 +1564,22 @@
may not be re-ordered.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddNative()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddNative()
Returns \c true if fetch-and-add is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddWaitFree()
+/*!
+ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddWaitFree()
Returns \c true if atomic fetch-and-add is wait-free, false
otherwise.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
Atomic fetch-and-add.
@@ -1526,7 +1591,8 @@
processor to freely reorder memory accesses.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
Atomic fetch-and-add.
@@ -1539,7 +1605,8 @@
be re-ordered before the atomic operation.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
Atomic fetch-and-add.
@@ -1552,7 +1619,8 @@
re-ordered after the atomic operation.
*/
-/*! \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+/*!
+ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
Atomic fetch-and-add.
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index a3b9be0729..aa57ddc610 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -50,6 +50,10 @@ QT_BEGIN_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wextra")
+#ifdef Q_CLANG_QDOC
+# undef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
+#endif
+
// High-level atomic integer operations
template <typename T>
class QAtomicInteger : public QBasicAtomicInteger<T>
@@ -194,7 +198,9 @@ public:
#ifdef Q_QDOC
T *load() const;
T *loadAcquire() const;
+ T *loadRelaxed() const;
void store(T *newValue);
+ void storeRelaxed(T *newValue);
void storeRelease(T *newValue);
static Q_DECL_CONSTEXPR bool isTestAndSetNative();
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index d308aeba2b..6a4623ce92 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -100,7 +100,7 @@ struct Registry {
if (id == QCalendar::System::User) {
byId.push_back(calendar);
} else {
- Q_ASSERT(byId.at(size_t(id)) == nullptr);
+ Q_ASSERT(byId[size_t(id)] == nullptr);
byId[size_t(id)] = calendar;
}
if (id == QCalendar::System::Gregorian) {
@@ -618,7 +618,7 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
if (calendarRegistry.isDestroyed() || system == QCalendar::System::User)
return nullptr;
Q_ASSERT(calendarRegistry->byId.size() >= size_t(system));
- if (auto *c = calendarRegistry->byId.at(size_t(system)))
+ if (auto *c = calendarRegistry->byId[size_t(system)])
return c;
switch (system) {
case QCalendar::System::Gregorian:
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 7f4d7cc6af..4de159d97a 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -373,6 +373,7 @@
},
"headers": "jpeglib.h",
"sources": [
+ { "type": "pkgConfig", "args": "libjpeg" },
{ "libs": "-llibjpeg", "condition": "config.msvc" },
"-ljpeg"
]
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index c4e7d32de1..392b6040cb 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -62,7 +62,7 @@
\include module-use.qdocinc using qt module
\quotefile overview/using-qt-gui.cmake
- See also the \l[QtDoc]{Building with CMake} overview.
+ See also the \l[QtDoc]{Build with CMake} overview.
\section2 Building with qmake
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 74e0e6401e..c4c7de1b2e 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1344,7 +1344,7 @@ Qt::WindowStates QWindow::windowStates() const
This is a hint to the window manager that this window is a dialog or pop-up
on behalf of the transient parent.
- In order to cause the window to be centered above its transient parent by
+ In order to cause the window to be centered above its transient \a parent by
default, depending on the window manager, it may also be necessary to call
setFlags() with a suitable \l Qt::WindowType (such as \c Qt::Dialog).
diff --git a/src/gui/opengl/qopenglextrafunctions.h b/src/gui/opengl/qopenglextrafunctions.h
index a68e269065..faac2dce4e 100644
--- a/src/gui/opengl/qopenglextrafunctions.h
+++ b/src/gui/opengl/qopenglextrafunctions.h
@@ -54,7 +54,7 @@
// GLES build without having included gl32.h -> GLDEBUGPROC is still need for the protos, define it here
#if defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_3_2)
-typedef void (QOPENGLF_APIENTRYP *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void (QOPENGLF_APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 690251727d..0828a795f1 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1543,7 +1543,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates()
+ \sa QSslConfiguration::addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index 26e72a480f..fcc08ea00d 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -72,9 +72,10 @@ static inline QString prefixedPath(QString path)
struct AssetItem {
enum class Type {
File,
- Folder
+ Folder,
+ Invalid
};
-
+ AssetItem() = default;
AssetItem (const QString &rawName)
: name(rawName)
{
@@ -92,21 +93,47 @@ using AssetItemList = QVector<AssetItem>;
class FolderIterator : public AssetItemList
{
public:
- static QSharedPointer<FolderIterator> fromCache(const QString &path)
+ static QSharedPointer<FolderIterator> fromCache(const QString &path, bool clone)
{
QMutexLocker lock(&m_assetsCacheMutex);
QSharedPointer<FolderIterator> *folder = m_assetsCache.object(path);
if (!folder) {
folder = new QSharedPointer<FolderIterator>{new FolderIterator{path}};
- if (!m_assetsCache.insert(path, folder)) {
+ if ((*folder)->empty() || !m_assetsCache.insert(path, folder)) {
QSharedPointer<FolderIterator> res = *folder;
delete folder;
return res;
}
}
- return *folder;
+ return clone ? QSharedPointer<FolderIterator>{new FolderIterator{*(*folder)}} : *folder;
+ }
+
+ static AssetItem::Type fileType(const QString &filePath)
+ {
+ const QStringList paths = filePath.split(QLatin1Char('/'));
+ QString fullPath;
+ AssetItem::Type res = AssetItem::Type::Invalid;
+ for (const auto &path: paths) {
+ auto folder = fromCache(fullPath, false);
+ auto it = std::lower_bound(folder->begin(), folder->end(), AssetItem{path}, [](const AssetItem &val, const AssetItem &assetItem) {
+ return val.name < assetItem.name;
+ });
+ if (it == folder->end() || it->name != path)
+ return AssetItem::Type::Invalid;
+ if (!fullPath.isEmpty())
+ fullPath.append(QLatin1Char('/'));
+ fullPath += path;
+ res = it->type;
+ }
+ return res;
}
+ FolderIterator(const FolderIterator &other)
+ : AssetItemList(other)
+ , m_index(-1)
+ , m_path(other.m_path)
+ {}
+
FolderIterator(const QString &path)
: m_path(path)
{
@@ -118,8 +145,12 @@ public:
QJNIEnvironmentPrivate env;
jobjectArray jFiles = static_cast<jobjectArray>(files.object());
const jint nFiles = env->GetArrayLength(jFiles);
- for (int i = 0; i < nFiles; ++i)
- push_back({QJNIObjectPrivate(env->GetObjectArrayElement(jFiles, i)).toString()});
+ for (int i = 0; i < nFiles; ++i) {
+ AssetItem item{QJNIObjectPrivate(env->GetObjectArrayElement(jFiles, i)).toString()};
+ insert(std::upper_bound(begin(), end(), item, [](const auto &a, const auto &b){
+ return a.name < b.name;
+ }), item);
+ }
}
m_path = assetsPrefix + QLatin1Char('/') + m_path + QLatin1Char('/');
m_path.replace(QLatin1String("//"), QLatin1String("/"));
@@ -169,7 +200,7 @@ public:
const QString &path)
: QAbstractFileEngineIterator(filters, nameFilters)
{
- m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path)));
+ m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path), true));
if (m_stack.last()->empty())
m_stack.pop_back();
}
@@ -215,7 +246,7 @@ public:
if (!res)
return {};
if (res->second.type == AssetItem::Type::Folder) {
- m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath())));
+ m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath()), true));
if (m_stack.last()->empty())
m_stack.pop_back();
}
@@ -257,6 +288,7 @@ public:
m_assetFile = 0;
return true;
}
+ m_isFolder = false;
return false;
}
@@ -305,12 +337,12 @@ public:
FileFlags fileFlags(FileFlags type = FileInfoAll) const override
{
- FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
+ FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
+ FileFlags flags;
if (m_assetFile)
- flags |= FileType;
+ flags = FileType | commonFlags;
else if (m_isFolder)
- flags |= DirectoryType;
-
+ flags = DirectoryType | commonFlags;
return type & flags;
}
@@ -341,9 +373,20 @@ public:
void setFileName(const QString &file) override
{
+ if (m_fileName == cleanedAssetPath(file))
+ return;
close();
m_fileName = cleanedAssetPath(file);
- m_isFolder = !open(QIODevice::ReadOnly) && !FolderIterator::fromCache(m_fileName)->empty();
+ switch (FolderIterator::fileType(m_fileName)) {
+ case AssetItem::Type::File:
+ open(QIODevice::ReadOnly);
+ break;
+ case AssetItem::Type::Folder:
+ m_isFolder = true;
+ break;
+ case AssetItem::Type::Invalid:
+ break;
+ }
}
Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override
@@ -355,9 +398,9 @@ public:
private:
AAsset *m_assetFile = nullptr;
- AAssetManager *m_assetManager;
+ AAssetManager *m_assetManager = nullptr;
QString m_fileName;
- bool m_isFolder;
+ bool m_isFolder = false;
};
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h
index 7ec9a2b5af..dcf6f1c753 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.h
+++ b/src/plugins/platforms/cocoa/qcocoascreen.h
@@ -53,9 +53,6 @@ class QCocoaIntegration;
class QCocoaScreen : public QPlatformScreen
{
public:
- static void initializeScreens();
- static void cleanupScreens();
-
~QCocoaScreen();
// ----------------------------------------------------
@@ -79,7 +76,6 @@ public:
// ----------------------------------------------------
NSScreen *nativeScreen() const;
- void updateProperties();
void requestUpdate();
void deliverUpdateRequests();
@@ -88,6 +84,7 @@ public:
static QCocoaScreen *primaryScreen();
static QCocoaScreen *get(NSScreen *nsScreen);
static QCocoaScreen *get(CGDirectDisplayID displayId);
+ static QCocoaScreen *get(CFUUIDRef uuid);
static CGPoint mapToNative(const QPointF &pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
static CGRect mapToNative(const QRectF &rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
@@ -95,11 +92,23 @@ public:
static QRectF mapFromNative(CGRect rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
private:
- QCocoaScreen(CGDirectDisplayID displayId);
+ static void initializeScreens();
+ static void updateScreens();
+ static void cleanupScreens();
+
+ static bool updateScreensIfNeeded();
+ static NSArray *s_screenConfigurationBeforeUpdate;
+
static void add(CGDirectDisplayID displayId);
+ QCocoaScreen(CGDirectDisplayID displayId);
+ void update(CGDirectDisplayID displayId);
void remove();
+ bool isOnline() const;
+ bool isMirroring() const;
+
CGDirectDisplayID m_displayId = kCGNullDirectDisplay;
+ CGDirectDisplayID displayId() const { return m_displayId; }
QRect m_geometry;
QRect m_availableGeometry;
@@ -116,6 +125,8 @@ private:
dispatch_source_t m_displayLinkSource = nullptr;
QAtomicInt m_pendingUpdates;
+ friend class QCocoaIntegration;
+ friend class QCocoaWindow;
friend QDebug operator<<(QDebug debug, const QCocoaScreen *screen);
};
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index bd5c95b9d0..e4dd4cf6c6 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
namespace CoreGraphics {
Q_NAMESPACE
enum DisplayChange {
+ ReconfiguredWithFlagsMissing = 0,
Moved = kCGDisplayMovedFlag,
SetMain = kCGDisplaySetMainFlag,
SetMode = kCGDisplaySetModeFlag,
@@ -71,73 +72,165 @@ namespace CoreGraphics {
Q_ENUM_NS(DisplayChange)
}
+NSArray *QCocoaScreen::s_screenConfigurationBeforeUpdate = nil;
+
void QCocoaScreen::initializeScreens()
{
- uint32_t displayCount = 0;
- if (CGGetActiveDisplayList(0, nullptr, &displayCount) != kCGErrorSuccess)
- qFatal("Failed to get number of active displays");
-
- CGDirectDisplayID activeDisplays[displayCount];
- if (CGGetActiveDisplayList(displayCount, &activeDisplays[0], &displayCount) != kCGErrorSuccess)
- qFatal("Failed to get active displays");
-
- for (CGDirectDisplayID displayId : activeDisplays)
- QCocoaScreen::add(displayId);
+ updateScreens();
CGDisplayRegisterReconfigurationCallback([](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) {
- if (flags & kCGDisplayBeginConfigurationFlag)
- return; // Wait for changes to apply
-
Q_UNUSED(userInfo);
- qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display reconfiguration"
- << " (" << QFlags<CoreGraphics::DisplayChange>(flags) << ")"
- << " for displayId=" << displayId;
-
- QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId);
+ // Displays are reconfigured in batches, and we want to update our screens
+ // once a batch ends, so that all the states of the displays are up to date.
+ static int displayReconfigurationsInProgress = 0;
+
+ const bool beforeReconfigure = flags & kCGDisplayBeginConfigurationFlag;
+ qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display " << displayId
+ << (beforeReconfigure ? " about to reconfigure" : " was ")
+ << QFlags<CoreGraphics::DisplayChange>(flags)
+ << " with " << displayReconfigurationsInProgress
+ << " display configuration(s) in progress";
+
+ if (!flags) {
+ // CGDisplayRegisterReconfigurationCallback has been observed to be called
+ // with flags unset. This seems like a bug. The callback is not paired with
+ // a matching "completion" callback either, so we don't know whether to treat
+ // it as a begin or end of reconfigure.
+ return;
+ }
- if ((flags & kCGDisplayAddFlag) || !cocoaScreen) {
- if (!CGDisplayIsActive(displayId)) {
- qCDebug(lcQpaScreen) << "Not adding inactive display" << displayId;
- return; // Will be added when activated
+ if (beforeReconfigure) {
+ if (!displayReconfigurationsInProgress++) {
+ // There might have been a screen reconfigure before this that
+ // we didn't process yet, so do that now if that's the case.
+ updateScreensIfNeeded();
+
+ Q_ASSERT(!s_screenConfigurationBeforeUpdate);
+ s_screenConfigurationBeforeUpdate = NSScreen.screens;
+ qCDebug(lcQpaScreen, "Display reconfigure transaction started"
+ " with screen configuration %p", s_screenConfigurationBeforeUpdate);
+
+ static void (^tryScreenUpdate)();
+ tryScreenUpdate = ^void () {
+ qCDebug(lcQpaScreen) << "Attempting screen update from runloop block";
+ if (!updateScreensIfNeeded())
+ CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, tryScreenUpdate);
+ };
+ CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, tryScreenUpdate);
}
- QCocoaScreen::add(displayId);
- } else if ((flags & kCGDisplayRemoveFlag) || !CGDisplayIsActive(displayId)) {
- cocoaScreen->remove();
} else {
- // Detect changes to the primary screen immediately, instead of
- // waiting for a display reconfigure with kCGDisplaySetMainFlag.
- // This ensures that any property updates to the other screens
- // will be in reference to the correct primary screen.
- QCocoaScreen *mainDisplay = QCocoaScreen::get(CGMainDisplayID());
- if (QGuiApplication::primaryScreen()->handle() != mainDisplay) {
- mainDisplay->updateProperties();
- qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay;
- QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay);
- if (cocoaScreen == mainDisplay)
- return; // Already reconfigured
- }
+ Q_ASSERT_X(displayReconfigurationsInProgress, "QCococaScreen",
+ "Display configuration transactions are expected to be balanced");
- cocoaScreen->updateProperties();
- qCInfo(lcQpaScreen).nospace() << "Reconfigured " <<
- (primaryScreen() == cocoaScreen ? "primary " : "")
- << cocoaScreen;
+ if (!--displayReconfigurationsInProgress) {
+ qCDebug(lcQpaScreen) << "Display reconfigure transaction completed";
+ // We optimistically update now, in case the NSScreens have changed
+ updateScreensIfNeeded();
+ }
}
}, nullptr);
+
+ static QMacNotificationObserver screenParameterObserver(NSApplication.sharedApplication,
+ NSApplicationDidChangeScreenParametersNotification, [&]() {
+ qCDebug(lcQpaScreen) << "Received screen parameter change notification";
+ updateScreensIfNeeded(); // As a last resort we update screens here
+ });
+}
+
+bool QCocoaScreen::updateScreensIfNeeded()
+{
+ if (!s_screenConfigurationBeforeUpdate) {
+ qCDebug(lcQpaScreen) << "QScreens have already been updated, all good";
+ return true;
+ }
+
+ if (s_screenConfigurationBeforeUpdate == NSScreen.screens) {
+ qCDebug(lcQpaScreen) << "Still waiting for NSScreen configuration change";
+ return false;
+ }
+
+ qCDebug(lcQpaScreen, "NSScreen configuration changed to %p", NSScreen.screens);
+ updateScreens();
+
+ s_screenConfigurationBeforeUpdate = nil;
+ return true;
+}
+
+/*
+ Update the list of available QScreens, and the properties of existing screens.
+
+ At this point we rely on the NSScreen.screens to be up to date.
+*/
+void QCocoaScreen::updateScreens()
+{
+ uint32_t displayCount = 0;
+ if (CGGetOnlineDisplayList(0, nullptr, &displayCount) != kCGErrorSuccess)
+ qFatal("Failed to get number of online displays");
+
+ QVector<CGDirectDisplayID> onlineDisplays(displayCount);
+ if (CGGetOnlineDisplayList(displayCount, onlineDisplays.data(), &displayCount) != kCGErrorSuccess)
+ qFatal("Failed to get online displays");
+
+ qCInfo(lcQpaScreen) << "Updating screens with" << displayCount
+ << "online displays:" << onlineDisplays;
+
+ // TODO: Verify whether we can always assume the main display is first
+ int mainDisplayIndex = onlineDisplays.indexOf(CGMainDisplayID());
+ if (mainDisplayIndex < 0) {
+ qCWarning(lcQpaScreen) << "Main display not in list of online displays!";
+ } else if (mainDisplayIndex > 0) {
+ qCWarning(lcQpaScreen) << "Main display not first display, making sure it is";
+ onlineDisplays.move(mainDisplayIndex, 0);
+ }
+
+ for (CGDirectDisplayID displayId : onlineDisplays) {
+ Q_ASSERT(CGDisplayIsOnline(displayId));
+
+ if (CGDisplayMirrorsDisplay(displayId))
+ continue;
+
+ // A single physical screen can map to multiple displays IDs,
+ // depending on which GPU is in use or which physical port the
+ // screen is connected to. By mapping the display ID to a UUID,
+ // which are shared between displays that target the same screen,
+ // we can pick an existing QScreen to update instead of needlessly
+ // adding and removing QScreens.
+ QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(displayId);
+ Q_ASSERT(uuid);
+
+ if (QCocoaScreen *existingScreen = QCocoaScreen::get(uuid)) {
+ existingScreen->update(displayId);
+ qCInfo(lcQpaScreen) << "Updated" << existingScreen;
+ if (CGDisplayIsMain(displayId) && existingScreen != qGuiApp->primaryScreen()->handle()) {
+ qCInfo(lcQpaScreen) << "Primary screen changed to" << existingScreen;
+ QWindowSystemInterface::handlePrimaryScreenChanged(existingScreen);
+ }
+ } else {
+ QCocoaScreen::add(displayId);
+ }
+ }
+
+ for (QScreen *screen : QGuiApplication::screens()) {
+ QCocoaScreen *platformScreen = static_cast<QCocoaScreen*>(screen->handle());
+ if (!platformScreen->isOnline() || platformScreen->isMirroring())
+ platformScreen->remove();
+ }
}
void QCocoaScreen::add(CGDirectDisplayID displayId)
{
const bool isPrimary = CGDisplayIsMain(displayId);
QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId);
- qCInfo(lcQpaScreen).nospace() << "Adding " << (isPrimary ? "new primary " : "") << cocoaScreen;
+ qCInfo(lcQpaScreen) << "Adding" << cocoaScreen
+ << (isPrimary ? "as new primary screen" : "");
QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary);
}
QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId)
: QPlatformScreen(), m_displayId(displayId)
{
- updateProperties();
+ update(m_displayId);
m_cursor = new QCocoaCursor;
}
@@ -150,8 +243,6 @@ void QCocoaScreen::cleanupScreens()
void QCocoaScreen::remove()
{
- m_displayId = kCGNullDirectDisplay; // Prevent stale references during removal
-
// This may result in the application responding to QGuiApplication::screenRemoved
// by moving the window to another screen, either by setGeometry, or by setScreen.
// If the window isn't moved by the application, Qt will as a fallback move it to
@@ -163,7 +254,7 @@ void QCocoaScreen::remove()
// QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have
// already changed its screen, but that's only true if comparing the Qt screens,
// not when comparing the NSScreens.
- qCInfo(lcQpaScreen).nospace() << "Removing " << (primaryScreen() == this ? "current primary " : "") << this;
+ qCInfo(lcQpaScreen) << "Removing " << this;
QWindowSystemInterface::handleScreenRemoved(this);
}
@@ -210,9 +301,14 @@ static QString displayName(CGDirectDisplayID displayID)
return QString();
}
-void QCocoaScreen::updateProperties()
+void QCocoaScreen::update(CGDirectDisplayID displayId)
{
- Q_ASSERT(m_displayId);
+ if (displayId != m_displayId) {
+ qCDebug(lcQpaScreen) << "Reconnecting" << this << "as display" << displayId;
+ m_displayId = displayId;
+ }
+
+ Q_ASSERT(isOnline());
const QRect previousGeometry = m_geometry;
const QRect previousAvailableGeometry = m_availableGeometry;
@@ -350,8 +446,8 @@ struct DeferredDebugHelper
void QCocoaScreen::deliverUpdateRequests()
{
- if (!m_displayId)
- return; // Screen removed
+ if (!isOnline())
+ return;
QMacAutoReleasePool pool;
@@ -562,6 +658,29 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height)
return windowPixmap;
}
+bool QCocoaScreen::isOnline() const
+{
+ // When a display is disconnected CGDisplayIsOnline and other CGDisplay
+ // functions that take a displayId will not return false, but will start
+ // returning -1 to signal that the displayId is invalid. Some functions
+ // will also assert or even crash in this case, so it's important that
+ // we double check if a display is online before calling other functions.
+ auto isOnline = CGDisplayIsOnline(m_displayId);
+ static const uint32_t kCGDisplayIsDisconnected = int32_t(-1);
+ return isOnline != kCGDisplayIsDisconnected && isOnline;
+}
+
+/*
+ Returns true if a screen is mirroring another screen
+*/
+bool QCocoaScreen::isMirroring() const
+{
+ if (!isOnline())
+ return false;
+
+ return CGDisplayMirrorsDisplay(m_displayId);
+}
+
/*!
The screen used as a reference for global window geometry
*/
@@ -586,6 +705,12 @@ QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const
QCocoaScreen *QCocoaScreen::get(NSScreen *nsScreen)
{
+ if (s_screenConfigurationBeforeUpdate) {
+ qCWarning(lcQpaScreen) << "Trying to resolve screen while waiting for screen reconfigure!";
+ if (!updateScreensIfNeeded())
+ qCWarning(lcQpaScreen) << "Failed to do last minute screen update. Expect crashes.";
+ }
+
return get(nsScreen.qt_displayId);
}
@@ -600,23 +725,34 @@ QCocoaScreen *QCocoaScreen::get(CGDirectDisplayID displayId)
return nullptr;
}
+QCocoaScreen *QCocoaScreen::get(CFUUIDRef uuid)
+{
+ for (QScreen *screen : QGuiApplication::screens()) {
+ auto *platformScreen = static_cast<QCocoaScreen*>(screen->handle());
+ if (!platformScreen->isOnline())
+ continue;
+
+ auto displayId = platformScreen->displayId();
+ QCFType<CFUUIDRef> candidateUuid(CGDisplayCreateUUIDFromDisplayID(displayId));
+ Q_ASSERT(candidateUuid);
+
+ if (candidateUuid == uuid)
+ return platformScreen;
+ }
+
+ return nullptr;
+}
+
NSScreen *QCocoaScreen::nativeScreen() const
{
if (!m_displayId)
return nil; // The display has been disconnected
- // A single display may have different displayIds depending on
- // which GPU is in use or which physical port the display is
- // connected to. By comparing UUIDs instead of display IDs we
- // ensure that we always pick up the appropriate NSScreen.
- QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId);
-
- for (NSScreen *screen in [NSScreen screens]) {
- if (QCFType<CFUUIDRef>(CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId)) == uuid)
+ for (NSScreen *screen in NSScreen.screens) {
+ if (screen.qt_displayId == m_displayId)
return screen;
}
- qCWarning(lcQpaScreen) << "Could not find NSScreen for display ID" << m_displayId;
return nil;
}
@@ -651,11 +787,21 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen)
debug.nospace();
debug << "QCocoaScreen(" << (const void *)screen;
if (screen) {
- debug << ", geometry=" << screen->geometry();
+ debug << ", " << screen->name();
+ if (screen->isOnline()) {
+ if (CGDisplayIsAsleep(screen->displayId()))
+ debug << ", Sleeping";
+ if (auto mirroring = CGDisplayMirrorsDisplay(screen->displayId()))
+ debug << ", mirroring=" << mirroring;
+ } else {
+ debug << ", Offline";
+ }
+ debug << ", " << screen->geometry();
debug << ", dpr=" << screen->devicePixelRatio();
- debug << ", name=" << screen->name();
- debug << ", displayId=" << screen->m_displayId;
- debug << ", native=" << screen->nativeScreen();
+ debug << ", displayId=" << screen->displayId();
+
+ if (auto nativeScreen = screen->nativeScreen())
+ debug << ", " << nativeScreen;
}
debug << ')';
return debug;
diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc
index 9c26c4089c..3a0fcfa1e7 100644
--- a/src/sql/doc/src/sql-driver.qdoc
+++ b/src/sql/doc/src/sql-driver.qdoc
@@ -171,7 +171,8 @@
\section3 How to Build the QMYSQL Plugin on Windows
You need to get the MySQL installation files (e.g.
- \e{mysql-installer-web-community-8.0.18.0.msi}). Run the installer,
+ \l {https://dev.mysql.com/downloads/installer/}{mysql-installer-web-community-8.0.18.0.msi}).
+ Run the installer,
select custom installation and install the MySQL C Connector
which matches your Qt installation (x86 or x64).
After installation make sure that the needed files are there:
@@ -192,9 +193,9 @@
When you distribute your application, remember to include libmysql.dll
in your installation package. It must be placed in the same folder
- as the application executable. libmysql.dll additionally needs the
+ as the application executable. \e libmysql.dll additionally needs the
MSVC runtime libraries which can be installed with vcredist.exe
- (\l {https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads}(vcredist.exe)
+ (\l {https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads}{vcredist.exe}
\target QOCI
\section2 QOCI for the Oracle Call Interface (OCI)
@@ -356,10 +357,6 @@
Windows NT based systems, this is the default. Note that the ODBC
driver and the DBMS must also support Unicode.
- Some driver managers and drivers do not support UNICODE. To use the
- QODBC plugin with such drivers, it has to be compiled with
- Q_ODBC_VERSION_2 defined.
-
For the Oracle 9 ODBC driver (Windows), it is necessary to check
"SQL_WCHAR support" in the ODBC driver manager otherwise Oracle
will convert all Unicode strings to local 8-bit.
diff --git a/src/testlib/doc/src/qttest-best-practices.qdoc b/src/testlib/doc/src/qttest-best-practices.qdoc
index c7fee93c80..8ad67acce6 100644
--- a/src/testlib/doc/src/qttest-best-practices.qdoc
+++ b/src/testlib/doc/src/qttest-best-practices.qdoc
@@ -278,8 +278,8 @@
\section2 Avoid Fixed Timeouts
Avoid using hard-coded timeouts, such as QTest::qWait() to wait for some
- conditions to become true. Consider using the \l QtSignalSpy class,
- the \l QTRY_VERIFY() or \l QTRY_COMPARE() macros, or the \c QtSignalSpy
+ conditions to become true. Consider using the \l QSignalSpy class,
+ the \l QTRY_VERIFY() or \l QTRY_COMPARE() macros, or the \c QSignalSpy
class in conjunction with the \c QTRY_ macro variants.
The \c qWait() function can be used to set a delay for a fixed period
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 57771b3e12..3577414713 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -142,16 +142,19 @@ QApplicationPrivate *QApplicationPrivate::self = nullptr;
static void initSystemPalette()
{
- if (!QApplicationPrivate::sys_pal) {
- QPalette defaultPlatte;
- if (QApplicationPrivate::app_style)
- defaultPlatte = QApplicationPrivate::app_style->standardPalette();
- if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette()) {
- QApplicationPrivate::setSystemPalette(themePalette->resolve(defaultPlatte));
- QApplicationPrivate::initializeWidgetPaletteHash();
- } else {
- QApplicationPrivate::setSystemPalette(defaultPlatte);
- }
+ if (QApplicationPrivate::sys_pal)
+ return; // Already initialized
+
+ QPalette defaultPalette;
+ if (QApplicationPrivate::app_style)
+ defaultPalette = QApplicationPrivate::app_style->standardPalette();
+
+ auto *platformTheme = QGuiApplicationPrivate::platformTheme();
+ if (const QPalette *themePalette = platformTheme ? platformTheme->palette() : nullptr) {
+ QApplicationPrivate::setSystemPalette(themePalette->resolve(defaultPalette));
+ QApplicationPrivate::initializeWidgetPaletteHash();
+ } else {
+ QApplicationPrivate::setSystemPalette(defaultPalette);
}
}
@@ -379,7 +382,6 @@ QString QApplicationPrivate::styleSheet; // default application styles
QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = nullptr;
QPalette *QApplicationPrivate::sys_pal = nullptr; // default system palette
-QPalette *QApplicationPrivate::set_pal = nullptr; // default palette set by programmer
QFont *QApplicationPrivate::sys_font = nullptr; // default system font
QFont *QApplicationPrivate::set_font = nullptr; // default font set by programmer
@@ -431,13 +433,6 @@ void QApplicationPrivate::process_cmdline()
if (styleOverride.isEmpty() && qEnvironmentVariableIsSet("QT_STYLE_OVERRIDE"))
styleOverride = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
- if (!styleOverride.isEmpty()) {
- if (app_style) {
- delete app_style;
- app_style = nullptr;
- }
- }
-
// process platform-indep command line
if (!qt_is_gui_used || !argc)
return;
@@ -552,6 +547,12 @@ void QApplicationPrivate::init()
// Must be called before initialize()
QColormap::initialize();
+ if (sys_pal) {
+ // Now that we have a platform theme we need to reset
+ // the system palette to pick up the theme colors.
+ clearSystemPalette();
+ initSystemPalette();
+ }
qt_init_tooltip_palette();
QApplicationPrivate::initializeWidgetFontHash();
@@ -597,8 +598,20 @@ void QApplicationPrivate::initialize()
// needed for widgets in QML
QAbstractDeclarativeData::setWidgetParent = QWidgetPrivate::setWidgetParentHelper;
- if (application_type != QApplicationPrivate::Tty)
- (void) QApplication::style(); // trigger creation of application style
+ if (application_type != QApplicationPrivate::Tty) {
+ if (!styleOverride.isEmpty()) {
+ if (auto *style = QStyleFactory::create(styleOverride.toLower())) {
+ QApplication::setStyle(style);
+ } else {
+ qWarning("QApplication: invalid style override '%s' passed, ignoring it.\n"
+ "\tAvailable styles: %s", qPrintable(styleOverride),
+ qPrintable(QStyleFactory::keys().join(QLatin1String(", "))));
+ }
+ }
+
+ // Trigger default style if none was set already
+ Q_UNUSED(QApplication::style());
+ }
#if QT_CONFIG(statemachine)
// trigger registering of QStateMachine's GUI types
qRegisterGuiStateMachine();
@@ -789,8 +802,6 @@ QApplication::~QApplication()
delete QApplicationPrivate::app_pal;
QApplicationPrivate::app_pal = nullptr;
clearSystemPalette();
- delete QApplicationPrivate::set_pal;
- QApplicationPrivate::set_pal = nullptr;
app_palettes()->clear();
delete QApplicationPrivate::sys_font;
@@ -1016,55 +1027,45 @@ void QApplication::setStyleSheet(const QString& styleSheet)
*/
QStyle *QApplication::style()
{
- if (QApplicationPrivate::app_style)
- return QApplicationPrivate::app_style;
- if (!qobject_cast<QApplication *>(QCoreApplication::instance())) {
- Q_ASSERT(!"No style available without QApplication!");
- return nullptr;
- }
-
if (!QApplicationPrivate::app_style) {
- // Compile-time search for default style
- //
- QStyle *&app_style = QApplicationPrivate::app_style;
-
- if (!QApplicationPrivate::styleOverride.isEmpty()) {
- const QString style = QApplicationPrivate::styleOverride.toLower();
- app_style = QStyleFactory::create(style);
- if (Q_UNLIKELY(!app_style)) {
- qWarning("QApplication: invalid style override passed, ignoring it.\n"
- " Available styles: %s", qPrintable(QStyleFactory::keys().join(QLatin1String(", "))));
- }
+ // Create default style
+ if (!qobject_cast<QApplication *>(QCoreApplication::instance())) {
+ Q_ASSERT(!"No style available without QApplication!");
+ return nullptr;
}
- if (!app_style)
- app_style = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
- if (!app_style) {
+ auto &defaultStyle = QApplicationPrivate::app_style;
+
+ defaultStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
+ if (!defaultStyle) {
const QStringList styles = QStyleFactory::keys();
for (const auto &style : styles) {
- if ((app_style = QStyleFactory::create(style)))
+ if ((defaultStyle = QStyleFactory::create(style)))
break;
}
}
- if (!app_style) {
+ if (!defaultStyle) {
Q_ASSERT(!"No styles available!");
return nullptr;
}
- }
- // take ownership of the style
- QApplicationPrivate::app_style->setParent(qApp);
- initSystemPalette();
+ // Take ownership of the style
+ defaultStyle->setParent(qApp);
+
+ initSystemPalette();
- if (QApplicationPrivate::set_pal) // repolish set palette with the new style
- QApplication::setPalette(*QApplicationPrivate::set_pal);
+ if (testAttribute(Qt::AA_SetPalette))
+ defaultStyle->polish(*QGuiApplicationPrivate::app_pal);
#ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty()) {
- qApp->setStyleSheet(QApplicationPrivate::styleSheet);
- } else
+ if (!QApplicationPrivate::styleSheet.isEmpty()) {
+ qApp->setStyleSheet(QApplicationPrivate::styleSheet);
+ } else
#endif
- QApplicationPrivate::app_style->polish(qApp);
+ {
+ defaultStyle->polish(qApp);
+ }
+ }
return QApplicationPrivate::app_style;
}
@@ -1128,17 +1129,21 @@ void QApplication::setStyle(QStyle *style)
// take care of possible palette requirements of certain gui
// styles. Do it before polishing the application since the style
// might call QApplication::setPalette() itself
- if (QApplicationPrivate::set_pal) {
- QApplication::setPalette(*QApplicationPrivate::set_pal);
- } else if (QApplicationPrivate::sys_pal) {
- clearSystemPalette();
+ if (testAttribute(Qt::AA_SetPalette)) {
+ QApplicationPrivate::app_style->polish(*QGuiApplicationPrivate::app_pal);
+ } else {
+ if (QApplicationPrivate::sys_pal)
+ clearSystemPalette();
initSystemPalette();
- QApplicationPrivate::initializeWidgetFontHash();
- } else if (!QApplicationPrivate::sys_pal) {
- // Initialize the sys_pal if it hasn't happened yet...
- QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
}
+ // The default widget font hash is based on the platform theme,
+ // not the style, but the widget fonts could in theory have been
+ // affected by polish of the previous style, without a proper
+ // cleanup in unpolish, so reset it now before polishing the
+ // new style.
+ QApplicationPrivate::initializeWidgetFontHash();
+
// initialize the application with the new style
QApplicationPrivate::app_style->polish(qApp);
@@ -1389,11 +1394,8 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char*
// Send ApplicationPaletteChange to qApp itself, and to the widgets.
qApp->d_func()->sendApplicationPaletteChange(all, className);
}
+
if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
- if (!QApplicationPrivate::set_pal)
- QApplicationPrivate::set_pal = new QPalette(palette);
- else
- *QApplicationPrivate::set_pal = palette;
QCoreApplication::setAttribute(Qt::AA_SetPalette);
emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
}
@@ -1436,7 +1438,7 @@ void QApplicationPrivate::setSystemPalette(const QPalette &pal)
else
*sys_pal = pal;
- if (!QApplicationPrivate::set_pal)
+ if (!testAttribute(Qt::AA_SetPalette))
QApplication::setPalette(*sys_pal);
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 3167bd423f..79d06ed98c 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -162,7 +162,6 @@ public:
static QWidgetList *popupWidgets;
static QStyle *app_style;
static QPalette *sys_pal;
- static QPalette *set_pal;
protected:
void notifyThemeChanged() override;
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 1af839c841..5292d971ea 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1453,7 +1453,7 @@ QStyleOptionTab::QStyleOptionTab(int version)
\value None A normal tab button.
\value HasFrame The tab button is positioned on a tab frame
- \sa features
+ \sa QStyleOptionToolBar::features
*/
/*!