diff --git a/configure b/configure index a034d5b908..1d73443c0f 100755 --- a/configure +++ b/configure @@ -3372,14 +3372,6 @@ if [ "$OPT_SHADOW" = "yes" ]; then mkdir -p "$outpath/mkspecs" fi -# symlink fonts to be able to run application from build directory -if [ ! -d "${outpath}/lib/fonts" ]; then - if [ "$PLATFORM" = "$XPLATFORM" ]; then - mkdir -p "${outpath}/lib" - ln -s "${relpath}/lib/fonts" "${outpath}/lib/fonts" - fi -fi - # detect build style if [ "$CFG_DEBUG" = "auto" ]; then if [ "$XPLATFORM_MAC" = "yes" -o "$XPLATFORM_MINGW" = "yes" ]; then diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index abc6198bc7..c5f6353d39 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -105,7 +105,7 @@ QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2 QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain QMAKE_IDL = midl -QMAKE_LIB = $${CROSS_COMPILE}ar -ru +QMAKE_LIB = $${CROSS_COMPILE}ar -rc QMAKE_RC = $${CROSS_COMPILE}windres QMAKE_STRIP = $${CROSS_COMPILE}strip diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 858ed2e4ca..721abb90d0 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -364,6 +364,8 @@ class ProFunctionDef { public: ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } + ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW + : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } ~ProFunctionDef() { m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) { @@ -375,6 +377,18 @@ public: } return *this; } + ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW + { + ProFunctionDef moved(std::move(other)); + swap(moved); + return *this; + } + void swap(ProFunctionDef &other) Q_DECL_NOTHROW + { + qSwap(m_pro, other.m_pro); + qSwap(m_offset, other.m_offset); + } + ProFile *pro() const { return m_pro; } const ushort *tokPtr() const { return m_pro->tokPtr() + m_offset; } private: diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 2441de16cd..5e340dbd27 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -252,10 +252,11 @@ static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const cha if (len + 1 > space) { const size_t skip = len - space + 4; // 4 for "..." + '\0' s += skip; + len -= skip; for (int i = 0; i < 3; ++i) *d++ = L'.'; } - while (*s) + while (len--) *d++ = *s++; *d++ = 0; } diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index b6d8e6fdc8..3cd3f52cff 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1635,7 +1635,8 @@ public: }; enum ScrollPhase { - ScrollBegin = 1, + NoScrollPhase = 0, // Make public in 5.7 or asap + ScrollBegin, ScrollUpdate, ScrollEnd }; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index b17a1ab48b..aa3fc63833 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -3089,6 +3089,8 @@ This enum describes the phase of scrolling. + \omitvalue NoScrollPhase The input device doesn't support scroll phase. + \value ScrollBegin Scrolling is about to begin, but the scrolling distance did not yet change. diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 0303933de8..ad24b43568 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1185,6 +1185,7 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot) return false; } +#if !defined(QT_BOOTSTRAPPED) //resource engine class QResourceFileEnginePrivate : public QAbstractFileEnginePrivate { @@ -1490,5 +1491,6 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr) Q_UNUSED(ptr); return true; } +#endif // !defined(QT_BOOTSTRAPPED) QT_END_NAMESPACE diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index e84ad03353..a50bbbdaca 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -44,6 +44,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 7d80cb0e2b..02b1e1c306 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -1845,7 +1845,7 @@ bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMaptimerList.timerWait(wait_tm))) tm = &wait_tm; + d->pollfds.clear(); d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0)); - d->pollfds.resize(0); if (include_notifiers) for (auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it) diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index fd67193302..f8f3347786 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -2335,7 +2335,7 @@ QRegExpCharClass::QRegExpCharClass() void QRegExpCharClass::clear() { c = 0; - r.resize(0); + r.clear(); n = false; } diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index b3247b8af5..ef1c9c17b0 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -502,8 +502,19 @@ /*! \fn void QVector::clear() - Removes all the elements from the vector and releases the memory used by - the vector. + Removes all the elements from the vector. + + \note Until Qt 5.6, this also released the memory used by + the vector. From Qt 5.7, the capacity is preserved. To shed + all capacity, swap with a default-constructed vector: + \code + QVector v ...; + QVector().swap(v); + Q_ASSERT(v.capacity() == 0); + \endcode + or call squeeze(). + + \sa squeeze() */ /*! \fn const T &QVector::at(int i) const diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index d60be78ade..13ae121450 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -419,7 +419,7 @@ void QVector::resize(int asize) } template inline void QVector::clear() -{ *this = QVector(); } +{ resize(0); } template inline const T &QVector::at(int i) const { Q_ASSERT_X(i >= 0 && i < d->size, "QVector::at", "index out of range"); diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 4c6c206bf3..ab0bbba413 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -1020,10 +1020,8 @@ bool QXmlStreamReaderPrivate::parse() prefix.clear(); qualifiedName.clear(); namespaceUri.clear(); - if (publicNamespaceDeclarations.size()) - publicNamespaceDeclarations.clear(); - if (attributes.size()) - attributes.resize(0); + publicNamespaceDeclarations.clear(); + attributes.clear(); if (isEmptyElement) { setType(QXmlStreamReader::EndElement); Tag &tag = tagStack_pop(); diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index e34347b801..027d2663de 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -33,6 +33,7 @@ depends += \ qtmultimedia \ qtnetwork \ qtopengl \ + qtplatformheaders \ qtsvg \ qtqml \ qtquick \ diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index cabcf656c3..09d23c0084 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -487,7 +487,7 @@ QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h) bool QPixmap::isQBitmap() const { - return data->type == QPlatformPixmap::BitmapType; + return data && data->type == QPlatformPixmap::BitmapType; } /*! diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 479a4283b0..9b0c6163b4 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -57,6 +57,11 @@ QT_BEGIN_NAMESPACE +static inline QString qStandardItemModelDataListMimeType() +{ + return QStringLiteral("application/x-qstandarditemmodeldatalist"); +} + class QStandardItemModelLessThan { public: @@ -2977,7 +2982,7 @@ void QStandardItemModel::sort(int column, Qt::SortOrder order) */ QStringList QStandardItemModel::mimeTypes() const { - return QAbstractItemModel::mimeTypes() << QLatin1String("application/x-qstandarditemmodeldatalist"); + return QAbstractItemModel::mimeTypes() << qStandardItemModelDataListMimeType(); } /*! @@ -2989,7 +2994,7 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const if(!data) return 0; - QString format = QLatin1String("application/x-qstandarditemmodeldatalist"); + const QString format = qStandardItemModelDataListMimeType(); if (!mimeTypes().contains(format)) return data; QByteArray encoded; @@ -3084,7 +3089,7 @@ bool QStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction acti if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction)) return false; // check if the format is supported - QString format = QLatin1String("application/x-qstandarditemmodeldatalist"); + const QString format = qStandardItemModelDataListMimeType(); if (!data->hasFormat(format)) return QAbstractItemModel::dropMimeData(data, action, row, column, parent); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index d84cbeddf2..34387d95d8 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -733,7 +733,8 @@ QHoverEvent::~QHoverEvent() QWheelEvent::QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient) - : QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons) + : QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons), + ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized) { g = QCursor::pos(); if (orient == Qt::Vertical) @@ -767,7 +768,8 @@ QWheelEvent::~QWheelEvent() QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient) - : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons) + : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons), + ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized) { if (orient == Qt::Vertical) angleD = QPoint(0, delta); @@ -803,7 +805,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta), - angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Qt::ScrollUpdate) + angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Qt::NoScrollPhase), + src(Qt::MouseEventNotSynthesized) {} /*! diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index eca5e6951d..2f31566b23 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -224,6 +224,8 @@ protected: uint ph : 2; uint src: 2; int reserved : 28; + + friend class QApplication; }; #endif diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index a48ad3180d..a871fe0024 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -168,7 +168,7 @@ inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) { - return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin); + return fromNative(rect, QHighDpiScaling::factor(screen), screenOrigin); } inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 1d444f94c9..347d02d616 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -492,8 +492,9 @@ QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) co QPlatformScreen *fallback = currentScreen; // QRect::center can return a value outside the rectangle if it's empty. // Apply mapToGlobal() in case it is a foreign/embedded window. - const QPoint center = - mapToGlobal(newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center()); + QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); + if (window()->type() == Qt::ForeignWindow) + center = mapToGlobal(center - newGeometry.topLeft()); if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { const auto screens = currentScreen->virtualSiblings(); diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 0e17b2d803..bc4a25a65f 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -46,6 +46,7 @@ #include #include +#include "qhighdpiscaling_p.h" QT_BEGIN_NAMESPACE @@ -692,7 +693,19 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height) qWarning("invoked with handle==0"); return QPixmap(); } - return platformScreen->grabWindow(window, x, y, width, height); + const qreal factor = QHighDpiScaling::factor(this); + if (qFuzzyCompare(factor, 1)) + return platformScreen->grabWindow(window, x, y, width, height); + + const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor); + QSize nativeSize(width, height); + if (nativeSize.isValid()) + nativeSize = QHighDpi::toNative(nativeSize, factor); + QPixmap result = + platformScreen->grabWindow(window, nativePos.x(), nativePos.y(), + nativeSize.width(), nativeSize.height()); + result.setDevicePixelRatio(factor); + return result; } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 5eb216d58e..3b40aba49e 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -375,7 +375,7 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) QKeySequence::SequenceMatch result = QKeySequence::NoMatch; // We start fresh each time.. - d->identicals.resize(0); + d->identicals.clear(); result = find(e); if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) { @@ -448,7 +448,7 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier } // Looking for new identicals, scrap old - d->identicals.resize(0); + d->identicals.clear(); bool partialFound = false; bool identicalDisabledFound = false; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 44fa88e7cf..f43ef43c6c 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1002,7 +1002,7 @@ QRegion QWindow::mask() const /*! Requests the window to be activated, i.e. receive keyboard focus. - \sa isActive(), QGuiApplication::focusWindow() + \sa isActive(), QGuiApplication::focusWindow(), QWindowsWindowFunctions::setWindowActivationBehavior() */ void QWindow::requestActivate() { @@ -2335,7 +2335,7 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { - return d->platformWindow->mapToGlobal(pos); + return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos + d->globalPosition(); } @@ -2355,7 +2355,7 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { - return d->platformWindow->mapFromGlobal(pos); + return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos - d->globalPosition(); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 0aec2cec07..66a4afb085 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -100,8 +100,16 @@ public: quint32 nativeModifiers, const QString& text = QString(), bool autorep = false, ushort count = 1, bool tryShortcutOverride = true); - static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); - static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, + QPoint pixelDelta, QPoint angleDelta, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::ScrollPhase phase = Qt::NoScrollPhase, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, + QPoint pixelDelta, QPoint angleDelta, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::ScrollPhase phase = Qt::NoScrollPhase, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); // Wheel event compatibility functions. Will be removed: do not use. static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 35e036dc62..523aa984a9 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -242,7 +242,7 @@ public: class WheelEvent : public InputEvent { public: WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O, - Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::ScrollUpdate, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized) + Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::NoScrollPhase, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized) : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src) { } QPoint pixelDelta; QPoint angleDelta; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 1143123717..112dbd4738 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -961,7 +961,7 @@ const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { fetchPixels // BPP32 }; -const StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { +StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { 0, // BPPNone storePixels, // BPP1MSB storePixels, // BPP1LSB @@ -6375,10 +6375,12 @@ static void qInitDrawhelperFunctions() int w, int h, int const_alpha); + extern void QT_FASTCALL storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count); qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; + qStorePixels[QPixelLayout::BPP24] = storePixelsBPP24_ssse3; } #endif // SSSE3 diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index af52ed0b43..21af6039f8 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1213,7 +1213,7 @@ typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int in extern QPixelLayout qPixelLayouts[QImage::NImageFormats]; extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount]; -extern const StorePixelsFunc qStorePixels[QPixelLayout::BPPCount]; +extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount]; diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp index 09b25d30fd..e0d1bac6b1 100644 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ b/src/gui/painting/qdrawhelper_ssse3.cpp @@ -176,6 +176,63 @@ void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, } } +static inline void store_uint24_ssse3(uchar *dst, const uint *src, int len) +{ + int i = 0; + + quint24 *dst24 = reinterpret_cast(dst); + // Align dst on 16 bytes + for (; i < len && (reinterpret_cast(dst24) & 0xf); ++i) + *dst24++ = quint24(*src++); + + // Shuffle masks for first and second half of every output, all outputs are aligned so the shuffled ends are not used. + const __m128i shuffleMask1 = _mm_setr_epi8(char(0x80), char(0x80), char(0x80), char(0x80), 2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12); + const __m128i shuffleMask2 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, char(0x80), char(0x80), char(0x80), char(0x80)); + + const __m128i *inVectorPtr = (const __m128i *)src; + __m128i *dstVectorPtr = (__m128i *)dst24; + + for (; i < (len - 15); i += 16) { + // Load four vectors, store three. + // Create each output vector by combining two shuffled input vectors. + __m128i srcVector1 = _mm_loadu_si128(inVectorPtr); + ++inVectorPtr; + __m128i srcVector2 = _mm_loadu_si128(inVectorPtr); + ++inVectorPtr; + __m128i outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1); + __m128i outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2); + __m128i outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 4); + _mm_store_si128(dstVectorPtr, outputVector); + ++dstVectorPtr; + + srcVector1 = _mm_loadu_si128(inVectorPtr); + ++inVectorPtr; + outputVector1 = _mm_shuffle_epi8(srcVector2, shuffleMask1); + outputVector2 = _mm_shuffle_epi8(srcVector1, shuffleMask2); + outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 8); + _mm_store_si128(dstVectorPtr, outputVector); + ++dstVectorPtr; + + srcVector2 = _mm_loadu_si128(inVectorPtr); + ++inVectorPtr; + outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1); + outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2); + outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 12); + _mm_store_si128(dstVectorPtr, outputVector); + ++dstVectorPtr; + } + dst24 = reinterpret_cast(dstVectorPtr); + src = reinterpret_cast(inVectorPtr); + + for (; i < len; ++i) + *dst24++ = quint24(*src++); +} + +void QT_FASTCALL storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count) +{ + store_uint24_ssse3(dest + index * 3, src, count); +} + QT_END_NAMESPACE #endif // QT_COMPILER_SUPPORTS_SSSE3 diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index fceb11959a..b9e05e726e 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -2166,7 +2166,7 @@ void Parser::init(const QString &css, bool isFile) } hasEscapeSequences = false; - symbols.resize(0); + symbols.clear(); symbols.reserve(8); Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols); index = 0; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 348fa83756..93071aaf59 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1128,7 +1128,7 @@ void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToCle delete c.custom; } undoState = 0; - undoStack.resize(0); + undoStack.clear(); if (emitSignals && undoCommandsAvailable) emitUndoAvailable(false); if (emitSignals && redoCommandsAvailable) diff --git a/src/network/kernel/qnetworkdatagram_p.h b/src/network/kernel/qnetworkdatagram_p.h index 55a0937ceb..4941d8c94b 100644 --- a/src/network/kernel/qnetworkdatagram_p.h +++ b/src/network/kernel/qnetworkdatagram_p.h @@ -34,6 +34,17 @@ #ifndef QNETWORKDATAGRAM_P_H #define QNETWORKDATAGRAM_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + #include QT_BEGIN_NAMESPACE diff --git a/src/platformheaders/doc/qtplatformheaders.qdocconf b/src/platformheaders/doc/qtplatformheaders.qdocconf index fc8a9d8731..989df524e6 100644 --- a/src/platformheaders/doc/qtplatformheaders.qdocconf +++ b/src/platformheaders/doc/qtplatformheaders.qdocconf @@ -27,6 +27,7 @@ qhp.QtPlatformHeaders.subprojects.classes.sortPages = true depends += \ qtcore \ qtgui \ + qtwidgets \ qtdoc headerdirs += .. diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h index 2b1efcdd6d..d0826bdb50 100644 --- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h +++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h @@ -57,6 +57,11 @@ public: Q_DECLARE_FLAGS(TouchWindowTouchTypes, TouchWindowTouchType) + enum WindowActivationBehavior { + DefaultActivateWindow, + AlwaysActivateWindow + }; + typedef void (*SetTouchWindowTouchType)(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchType); static const QByteArray setTouchWindowTouchTypeIdentifier() { return QByteArrayLiteral("WindowsSetTouchWindowTouchType"); } @@ -75,6 +80,16 @@ public: if (func) func(window, border); } + + typedef void (*SetWindowActivationBehaviorType)(WindowActivationBehavior); + static const QByteArray setWindowActivationBehaviorIdentifier() { return QByteArrayLiteral("WindowsSetWindowActivationBehavior"); } + + static void setWindowActivationBehavior(WindowActivationBehavior behavior) + { + SetWindowActivationBehaviorType func = reinterpret_cast(QGuiApplication::platformFunction(setWindowActivationBehaviorIdentifier())); + if (func) + func(behavior); + } }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsWindowFunctions::TouchWindowTouchTypes) diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc index d6b8764e7b..196f9f22ce 100644 --- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc +++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc @@ -95,3 +95,52 @@ See also \l [QtDoc] {Fullscreen OpenGL Based Windows} */ + +/*! + \enum QWindowsWindowFunctions::WindowActivationBehavior + + This enum specifies the behavior of QWidget::activateWindow() and + QWindow::requestActivate(). + + \value DefaultActivateWindow The window is activated according to the default + behavior of the Windows operating system. This means the window will not + be activated in some circumstances (most notably when the calling process + is not the active process); only the taskbar entry will be flashed. + \value AlwaysActivateWindow The window is always activated, even when the + calling process is not the active process. + + \sa QWidget::activateWindow(), QWindow::requestActivate() + \since 5.7 +*/ + +/*! + \typedef QWindowsWindowFunctions::SetWindowActivationBehaviorType + + This is the typedef for the function returned by QGuiApplication::platformFunction() + when passed setWindowActivationBehaviorIdentifier(). + + \sa QWidget::activateWindow(), QWindow::requestActivate() + \since 5.7 +*/ + +/*! + \fn QByteArray setWindowActivationBehaviorIdentifier() + + This function returns a bytearray that can be used to query + QGuiApplication::platformFunction() to retrieve the SetWindowActivationBehaviorType + function. + + \sa QWidget::activateWindow(), QWindow::requestActivate() + \since 5.7 +*/ + +/*! + \fn void QWindowsWindowFunctions::setWindowActivationBehavior(WindowActivationBehavior behavior) + + This is a convenience function that can be used directly instead of resolving + the function pointer. \a behavior will be relayed to the function retrieved + by QGuiApplication. + + \sa QWidget::activateWindow(), QWindow::requestActivate() + \since 5.7 +*/ diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 5e4cf113e0..e2bde442af 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -274,7 +274,7 @@ void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const { - return m_items.at(position); + return m_items.value(position); } QPlatformMenuItem *QDBusPlatformMenu::menuItemForTag(quintptr tag) const diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm index 250f3f3bf7..ebe547f64b 100644 --- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm +++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm @@ -390,6 +390,11 @@ bool QCocoaKeyMapper::updateKeyboard() keyboardInputLocale = QLocale::c(); keyboardInputDirection = Qt::LeftToRight; } + + const auto newMode = keyboard_mode; + deleteLayouts(); + keyboard_mode = newMode; + return true; } @@ -412,10 +417,8 @@ void QCocoaKeyMapper::clearMappings() void QCocoaKeyMapper::updateKeyMap(unsigned short macVirtualKey, QChar unicodeKey) { - if (updateKeyboard()) { - // ### Qt 4 did this: - // QKeyMapper::changeKeyboard(); - } + updateKeyboard(); + if (keyLayout[macVirtualKey]) return; @@ -471,9 +474,8 @@ QList QCocoaKeyMapper::possibleKeys(const QKeyEvent *event) const for (int i = 1; i < 8; ++i) { Qt::KeyboardModifiers neededMods = ModsTbl[i]; int key = kbItem->qtKey[i]; - if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) { - ret << int(key + (keyMods & ~neededMods)); - } + if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) + ret << int(key + neededMods); } return ret; } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index e0163e441e..0e84e1f8ed 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1410,6 +1410,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled) { ph = Qt::ScrollEnd; m_scrolling = false; + } else if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { + ph = Qt::NoScrollPhase; } QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph, source); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 339b9b56ce..3d0c91c36c 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -476,7 +476,6 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va d->embedFonts = value.toBool(); break; case PPK_Resolution: { - // TODO It appears the old code didn't actually set the resolution??? Can we delete all this??? int bestResolution = 0; int dpi = value.toInt(); int bestDistance = INT_MAX; @@ -492,7 +491,17 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va } } } - PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean); + PMResolution resolution; + resolution.hRes = resolution.vRes = bestResolution; + if (PMPrinterSetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &resolution) == noErr) { + // Setting the resolution succeeded. + // Now try to read the actual resolution selected by the OS. + if (PMPrinterGetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &d->resolution) != noErr) { + // Reading the resolution somehow failed; d->resolution is in undefined state. + // So use the value which was acceptable to PMPrinterSetOutputResolution. + d->resolution = resolution; + } + } break; } case PPK_CollateCopies: diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp index ac3683f4d5..7655bdf622 100644 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ b/src/plugins/platforms/windows/accessible/comutils.cpp @@ -64,15 +64,15 @@ static DATE QDateTimeToDATE(const QDateTime &dt) QDate date = dt.date(); QTime time = dt.time(); if (date.isValid() && !date.isNull()) { - stime.wDay = date.day(); - stime.wMonth = date.month(); - stime.wYear = date.year(); + stime.wDay = WORD(date.day()); + stime.wMonth = WORD(date.month()); + stime.wYear = WORD(date.year()); } if (time.isValid() && !time.isNull()) { - stime.wMilliseconds = time.msec(); - stime.wSecond = time.second(); - stime.wMinute = time.minute(); - stime.wHour = time.hour(); + stime.wMilliseconds = WORD(time.msec()); + stime.wSecond = WORD(time.second()); + stime.wMinute = WORD(time.minute()); + stime.wHour = WORD(time.hour()); } double vtime; @@ -98,8 +98,8 @@ bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeN proptype = QVariant::Double; } if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) { - if (qvar.canConvert(proptype)) - qvar.convert(proptype); + if (qvar.canConvert(int(proptype))) + qvar.convert(int(proptype)); else qvar = QVariant(proptype); } diff --git a/src/plugins/platforms/windows/accessible/comutils.h b/src/plugins/platforms/windows/accessible/comutils.h index 468bc0e45c..b1e6183a0f 100644 --- a/src/plugins/platforms/windows/accessible/comutils.h +++ b/src/plugins/platforms/windows/accessible/comutils.h @@ -53,14 +53,9 @@ class QVariant; // Originally QVariantToVARIANT copied from ActiveQt - renamed to avoid conflicts in static builds. bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out); -inline QString BSTRToQString(const BSTR &bstr) -{ - return QString((QChar*)bstr); -} - inline BSTR QStringToBSTR(const QString &str) { - return SysAllocStringLen((OLECHAR*)str.unicode(), str.length()); + return SysAllocStringLen(reinterpret_cast(str.unicode()), UINT(str.length())); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index d81044cdda..f34649e327 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -47,8 +47,16 @@ #include #include +#include + QT_BEGIN_NAMESPACE +template +static inline T *coTaskMemAllocArray(int size) +{ + return static_cast(::CoTaskMemAlloc(sizeof(T) * size_t(size))); +} + /**************************************************************\ * AccessibleApplication * **************************************************************/ @@ -58,7 +66,7 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOI *iface = 0; if (id == IID_IUnknown) { qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IUnknown"; - *iface = (IUnknown*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleApplication) { qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IAccessibleApplication"; *iface = static_cast(this); @@ -128,7 +136,7 @@ HRESULT STDMETHODCALLTYPE AccessibleRelation::QueryInterface(REFIID id, LPVOID * { *iface = 0; if (id == IID_IUnknown || id == IID_IAccessibleRelation) - *iface = (IUnknown*)this; + *iface = static_cast(this); if (*iface) { AddRef(); @@ -206,7 +214,7 @@ HRESULT STDMETHODCALLTYPE AccessibleRelation::get_targets( /* [retval][out] */ long *nTargets) { - const int numTargets = qMin((int)maxTargets, m_targets.count()); + const int numTargets = qMin(int(maxTargets), m_targets.count()); for (int i = 0; i < numTargets; ++i) { QAccessibleInterface *iface = m_targets.at(i); IAccessible *iacc = QWindowsAccessibility::wrap(iface); @@ -235,42 +243,40 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOI HRESULT hr = QWindowsMsaaAccessible::QueryInterface(id, iface); if (!SUCCEEDED(hr)) { if (id == IID_IServiceProvider) { - *iface = (IServiceProvider*)this; + *iface = static_cast(this); } else if (id == IID_IAccessible2) { - *iface = (IAccessible2*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleAction) { if (accessible->actionInterface()) - *iface = (IAccessibleAction*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleComponent) { - *iface = (IAccessibleComponent*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleEditableText) { if (accessible->editableTextInterface() || accessible->role() == QAccessible::EditableText) { - *iface = (IAccessibleEditableText*)this; + *iface = static_cast(this); } } else if (id == IID_IAccessibleHyperlink) { - //*iface = (IAccessibleHyperlink*)this; + //*iface = static_cast(this); } else if (id == IID_IAccessibleHypertext) { - //*iface = (IAccessibleHypertext*)this; + //*iface = static_cast(this); } else if (id == IID_IAccessibleImage) { - //*iface = (IAccessibleImage*)this; - } else if (id == IID_IAccessibleRelation) { - *iface = (IAccessibleRelation*)this; + //*iface = static_cast(this); } else if (id == IID_IAccessibleTable) { - //*iface = (IAccessibleTable*)this; // not supported + //*iface = static_cast(this); // not supported } else if (id == IID_IAccessibleTable2) { if (accessible->tableInterface()) - *iface = (IAccessibleTable2*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleTableCell) { if (accessible->tableCellInterface()) - *iface = (IAccessibleTableCell*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleText) { if (accessible->textInterface()) - *iface = (IAccessibleText*)this; + *iface = static_cast(this); } else if (id == IID_IAccessibleValue) { if (accessible->valueInterface()) - *iface = (IAccessibleValue*)this; + *iface = static_cast(this); } if (*iface) { AddRef(); @@ -599,9 +605,9 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex numBindings = keyBindings.count(); if (numBindings > 0) { // The IDL documents that the client must free with CoTaskMemFree - arrayOfBindingsToReturn = (BSTR*)::CoTaskMemAlloc(sizeof(BSTR) * numBindings); - for (int i = 0; i < numBindings; ++i) - arrayOfBindingsToReturn[i] = QStringToBSTR(keyBindings.at(i)); + arrayOfBindingsToReturn = coTaskMemAllocArray(numBindings); + std::transform(keyBindings.constBegin(), keyBindings.constEnd(), + arrayOfBindingsToReturn, QStringToBSTR); } } *keyBindings = arrayOfBindingsToReturn; @@ -674,7 +680,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_foreground(IA2Color *foregr return E_FAIL; // IA2Color is a typedef for long - *foreground = (IA2Color)accessible->foregroundColor().rgb(); + *foreground = static_cast(accessible->foregroundColor().rgb()); return S_OK; } @@ -686,7 +692,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_background(IA2Color *backgr return E_FAIL; // IA2Color is a typedef for long - *background = (IA2Color)accessible->backgroundColor().rgb(); + *background = static_cast(accessible->backgroundColor().rgb()); return S_OK; } @@ -760,7 +766,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::insertText(long offset, BSTR *t { QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); - const QString txt(BSTRToQString(*text)); + const QString txt = QString::fromWCharArray(*text); if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) editableTextIface->insertText(offset, txt); else @@ -805,7 +811,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::replaceText(long startOffset, l { QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); - const QString txt(BSTRToQString(*text)); + const QString txt = QString::fromWCharArray(*text); if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) editableTextIface->replaceText(startOffset, endOffset, txt); else @@ -978,12 +984,13 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele if (QAccessibleTableInterface *tableIface = tableInterface()) { const QList selectedIndices = tableIface->selectedColumns(); - const int &count = selectedIndices.count(); - long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0); - for (int i = 0; i < count; ++i) - selected[i] = selectedIndices.at(i); - *selectedColumns = selected; + const int count = selectedIndices.count(); *nColumns = count; + *selectedColumns = Q_NULLPTR; + if (count) { + *selectedColumns = coTaskMemAllocArray(count); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns); + } return count ? S_OK : S_FALSE; } return E_FAIL; @@ -999,12 +1006,13 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte if (QAccessibleTableInterface *tableIface = tableInterface()) { const QList selectedIndices = tableIface->selectedRows(); - const int &count = selectedIndices.count(); - long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0); - for (int i = 0; i < count; ++i) - selected[i] = selectedIndices.at(i); - *selectedRows = selected; + const int count = selectedIndices.count(); *nRows = count; + *selectedRows = Q_NULLPTR; + if (count) { + *selectedRows = coTaskMemAllocArray(count); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows); + } return count ? S_OK : S_FALSE; } return E_FAIL; @@ -1204,10 +1212,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row, if (!accessible || !tableCellInterface()) return E_FAIL; - *row = (long)tableCellInterface()->rowIndex(); - *column = (long)tableCellInterface()->columnIndex(); - *rowExtents = (long)tableCellInterface()->rowExtent(); - *columnExtents = (long)tableCellInterface()->columnExtent(); + *row = tableCellInterface()->rowIndex(); + *column = tableCellInterface()->columnIndex(); + *rowExtents = tableCellInterface()->rowExtent(); + *columnExtents = tableCellInterface()->columnExtent(); *isSelected = tableCellInterface()->isSelected(); return S_OK; } @@ -1248,7 +1256,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(long offset, QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *text = textInterface()) { - const QString attrs = text->attributes(offset, (int*)startOffset, (int*)endOffset); + const QString attrs = text->attributes(offset, reinterpret_cast(startOffset), + reinterpret_cast(endOffset)); *textAttributes = QStringToBSTR(attrs); return S_OK; } @@ -1320,7 +1329,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selection(long selectionInd QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *text = textInterface()) { - text->selection(selectionIndex, (int*)startOffset, (int*)endOffset); + text->selection(selectionIndex, reinterpret_cast(startOffset), + reinterpret_cast(endOffset)); return S_OK; } return E_FAIL; @@ -1352,7 +1362,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textBeforeOffset(long offse QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textBeforeOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textBeforeOffset(offset, static_cast(boundaryType), + reinterpret_cast(startOffset), + reinterpret_cast(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1372,7 +1385,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAfterOffset( QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textAfterOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textAfterOffset(offset, static_cast(boundaryType), + reinterpret_cast(startOffset), + reinterpret_cast(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1391,7 +1407,10 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAtOffset(long offset, QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = textIface->textAtOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset); + const QString txt = + textIface->textAtOffset(offset, static_cast(boundaryType), + reinterpret_cast(startOffset), + reinterpret_cast(endOffset)); if (!txt.isEmpty()) { *text = QStringToBSTR(txt); return S_OK; @@ -1630,7 +1649,7 @@ HRESULT QWindowsIA2Accessible::getRelationsHelper(IAccessibleRelation **relation QList keys = relationMap.keys(); const int numRelations = keys.count(); if (relations) { - for (int i = startIndex; i < qMin(startIndex + (int)maxRelations, numRelations); ++i) { + for (int i = startIndex; i < qMin(startIndex + int(maxRelations), numRelations); ++i) { QAccessible::Relation relation = keys.at(i); QList targets = relationMap.values(relation); AccessibleRelation *rel = new AccessibleRelation(targets, relation); @@ -1656,12 +1675,13 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList(count); + std::transform(inputCells.constBegin(), inputCells.constEnd(), + *outputAccessibles, QWindowsAccessibility::wrap); + } return count > 0 ? S_OK : S_FALSE; } diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index f91e57ae2f..4a3f0ccb2b 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -173,7 +173,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface(); if (!window->handle()) // Called before show(), no native window yet. return; - HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window); + const HWND hWnd = reinterpret_cast(platform->nativeResourceForWindow("handle", window)); if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked event->type() != QAccessible::ObjectDestroyed) { @@ -220,7 +220,7 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc); # endif IAccessible *iacc = 0; - wacc->QueryInterface(IID_IAccessible, (void**)&iacc); + wacc->QueryInterface(IID_IAccessible, reinterpret_cast(&iacc)); return iacc; #endif // defined(Q_OS_WINCE) } @@ -230,7 +230,7 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W #if !defined(Q_OS_WINCE) if (static_cast(lParam) == static_cast(UiaRootObjectId)) { /* For UI Automation */ - } else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) { + } else if (DWORD(lParam) == DWORD(OBJID_CLIENT)) { // Start handling accessibility internally QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); // Ignoring all requests while starting up @@ -244,7 +244,7 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W if (!oleaccChecked) { oleaccChecked = true; - ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject"); + ptrLresultFromObject = reinterpret_cast(QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject")); } if (ptrLresultFromObject) { diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 0d3914d2ed..0fff804e29 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -100,9 +100,9 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::QueryInterface(REFIID id, LPVOID *i { *iface = 0; if (id == IID_IUnknown) - *iface = (IUnknown*)this; + *iface = static_cast(this); else if (id == IID_IEnumVARIANT) - *iface = (IEnumVARIANT*)this; + *iface = static_cast(this); if (*iface) { AddRef(); @@ -150,13 +150,13 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Next(unsigned long celt, VARIANT F ULONG l; for (l = 0; l < celt; l++) { VariantInit(&rgVar[l]); - if ((current+1) > (ULONG)array.size()) { + if (current + 1 > ULONG(array.size())) { *pCeltFetched = l; return S_FALSE; } rgVar[l].vt = VT_I4; - rgVar[l].lVal = array[(int)current]; + rgVar[l].lVal = array[int(current)]; ++current; } *pCeltFetched = l; @@ -172,8 +172,8 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Reset() HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt) { current += celt; - if (current > (ULONG)array.size()) { - current = array.size(); + if (current > ULONG(array.size())) { + current = ULONG(array.size()); return S_FALSE; } return S_OK; @@ -201,13 +201,13 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVO << strIID << ", iface:" << accessibleInterface(); } if (id == IID_IUnknown) { - *iface = (IUnknown*)(IDispatch*)this; + *iface = static_cast(static_cast(this)); } else if (id == IID_IDispatch) { - *iface = (IDispatch*)this; + *iface = static_cast(this); } else if (id == IID_IAccessible) { - *iface = (IAccessible*)this; + *iface = static_cast(this); } else if (id == IID_IOleWindow) { - *iface = (IOleWindow*)this; + *iface = static_cast(this); } if (*iface) { diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 5ae5ae3129..78fff65d84 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -430,7 +430,7 @@ bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND, int delta; if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL) - delta = HIWORD (msg.wParam); + delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); else delta = int(msg.wParam); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index ac7c22fb7e..babca35149 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -84,6 +84,9 @@ static int resourceType(const QByteArray &key) return int(result - names); } +QWindowsWindowFunctions::WindowActivationBehavior QWindowsNativeInterface::m_windowActivationBehavior = + QWindowsWindowFunctions::DefaultActivateWindow; + void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window) { if (!window || !window->handle()) { @@ -253,6 +256,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic); else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier()) return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic); + else if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier()) + return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior); return Q_NULLPTR; } diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index 3a0d3398d9..9fc43ddcce 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -42,6 +42,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -96,7 +97,15 @@ public: QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE; void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) Q_DECL_OVERRIDE; + static QWindowsWindowFunctions::WindowActivationBehavior windowActivationBehavior() + { return QWindowsNativeInterface::m_windowActivationBehavior; } + static void setWindowActivationBehavior(QWindowsWindowFunctions::WindowActivationBehavior b) + { QWindowsNativeInterface::m_windowActivationBehavior = b; } + QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + +private: + static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index a7f00d5f6d..c64955be80 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -128,6 +128,41 @@ static inline QColor getSysColor(int index) return COLORREFToQColor(GetSysColor(index)); } +#ifndef QT_NO_WINCE_SHELLSDK +// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system +// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the +// behavior by running it in a thread. +class ShGetFileInfoFunction +{ +public: + explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) : + m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {} + + void operator()() const { *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); } + +private: + const wchar_t *m_fileName; + const DWORD m_attributes; + const UINT m_flags; + SHFILEINFO *const m_info; + bool *m_result; +}; + +static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r, + const wchar_t *fileName, DWORD attributes, + SHFILEINFO *info, UINT flags, + unsigned long timeOutMSecs = 5000) +{ + bool result = false; + if (!r.run(ShGetFileInfoFunction(fileName, attributes, info, flags, &result), timeOutMSecs)) { + qWarning().noquote() << "ShGetFileInfoBackground() timed out for " + << QString::fromWCharArray(fileName); + return false; + } + return result; +} +#endif // !QT_NO_WINCE_SHELLSDK + // from QStyle::standardPalette static inline QPalette standardPalette() { @@ -725,23 +760,22 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s } SHFILEINFO info; - unsigned int flags = + const unsigned int flags = #ifndef Q_OS_WINCE SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX; #else iconSize|SHGFI_SYSICONINDEX; #endif // Q_OS_WINCE - unsigned long val = 0; + + #if !defined(QT_NO_WINCE_SHELLSDK) - if (cacheableDirIcon && useDefaultFolderIcon) { - flags |= SHGFI_USEFILEATTRIBUTES; - val = SHGetFileInfo(L"dummy", - FILE_ATTRIBUTE_DIRECTORY, - &info, sizeof(SHFILEINFO), flags); - } else { - val = SHGetFileInfo(reinterpret_cast(filePath.utf16()), 0, - &info, sizeof(SHFILEINFO), flags); - } + const bool val = cacheableDirIcon && useDefaultFolderIcon + ? shGetFileInfoBackground(m_threadPoolRunner, L"dummy", FILE_ATTRIBUTE_DIRECTORY, + &info, flags | SHGFI_USEFILEATTRIBUTES) + : shGetFileInfoBackground(m_threadPoolRunner, reinterpret_cast(filePath.utf16()), 0, + &info, flags); +#else + const bool val = false; #endif // !QT_NO_WINCE_SHELLSDK // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 45db934e47..acf89306c2 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -40,6 +40,7 @@ #ifndef QWINDOWSTHEME_H #define QWINDOWSTHEME_H +#include "qwindowsthreadpoolrunner.h" #include QT_BEGIN_NAMESPACE @@ -80,6 +81,7 @@ private: static QWindowsTheme *m_instance; QPalette *m_palettes[NPalettes]; QFont *m_fonts[NFonts]; + mutable QWindowsThreadPoolRunner m_threadPoolRunner; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h new file mode 100644 index 0000000000..0361aa90f5 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSTHREADPOOLRUNNER_H +#define QWINDOWSTHREADPOOLRUNNER_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QWindowsThreadPoolRunner + \brief Runs a task in the global instance of QThreadPool + + QThreadPool does not provide a method to wait on a single task, so this needs + to be done by using QWaitCondition/QMutex. + + \internal + \ingroup qt-lighthouse-win +*/ +class QWindowsThreadPoolRunner +{ + Q_DISABLE_COPY(QWindowsThreadPoolRunner) + +#ifndef QT_NO_THREAD + template // nested class implementing QRunnable to execute a function. + class Runnable : public QRunnable + { + public: + explicit Runnable(QMutex *m, QWaitCondition *c, RunnableFunction f) + : m_mutex(m), m_condition(c), m_function(f) {} + + void run() Q_DECL_OVERRIDE + { + m_function(); + m_mutex->lock(); + m_condition->wakeAll(); + m_mutex->unlock(); + } + + private: + QMutex *m_mutex; + QWaitCondition *m_condition; + RunnableFunction m_function; + }; // class Runnable + +public: + QWindowsThreadPoolRunner() {} + + template + bool run(Function f, unsigned long timeOutMSecs = 5000) + { + QThreadPool *pool = QThreadPool::globalInstance(); + Q_ASSERT(pool); + Runnable *runnable = new Runnable(&m_mutex, &m_condition, f); + m_mutex.lock(); + pool->start(runnable); + const bool ok = m_condition.wait(&m_mutex, timeOutMSecs); + m_mutex.unlock(); + if (!ok) + pool->cancel(runnable); + return ok; + } + +private: + QMutex m_mutex; + QWaitCondition m_condition; +#else // !QT_NO_THREAD +public: + QWindowsThreadPoolRunner() {} + + template + bool run(Function f, unsigned long /* timeOutMSecs */ = 5000) + { + f(); + return true; + } +#endif // QT_NO_THREAD +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSTHREADPOOLRUNNER_H diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 4c503a2c48..d9a7586096 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -43,6 +43,7 @@ #include "qwindowsdrag.h" #include "qwindowsscreen.h" #include "qwindowsintegration.h" +#include "qwindowsnativeinterface.h" #include "qwindowsopenglcontext.h" #ifdef QT_NO_CURSOR # include "qwindowscursor.h" @@ -2083,8 +2084,30 @@ void QWindowsWindow::requestActivateWindow() // 'Active' state handling is based in focus since it needs to work for // child windows as well. if (m_data.hwnd) { +#ifndef Q_OS_WINCE + const DWORD currentThread = GetCurrentThreadId(); + bool attached = false; + DWORD foregroundThread = 0; + + // QTBUG-14062, QTBUG-37435: Windows normally only flashes the taskbar entry + // when activating windows of inactive applications. Attach to the input of the + // currently active window while setting the foreground window to always activate + // the window when desired. + if (QGuiApplication::applicationState() != Qt::ApplicationActive + && QWindowsNativeInterface::windowActivationBehavior() == QWindowsWindowFunctions::AlwaysActivateWindow) { + if (const HWND foregroundWindow = GetForegroundWindow()) { + foregroundThread = GetWindowThreadProcessId(foregroundWindow, NULL); + if (foregroundThread && foregroundThread != currentThread) + attached = AttachThreadInput(foregroundThread, currentThread, TRUE) == TRUE; + } + } +#endif // !Q_OS_WINCE SetForegroundWindow(m_data.hwnd); SetFocus(m_data.hwnd); +#ifndef Q_OS_WINCE + if (attached) + AttachThreadInput(foregroundThread, currentThread, FALSE); +#endif // !Q_OS_WINCE } } @@ -2180,14 +2203,15 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const // Documentation of MINMAXINFO states that it will only work for the primary screen if (screen && screen == QGuiApplication::primaryScreen()) { - mmi->ptMaxSize.y = screen->availableGeometry().height(); + const QRect availableGeometry = QHighDpi::toNativePixels(screen->availableGeometry(), screen); + mmi->ptMaxSize.y = availableGeometry.height(); // Width, because you can have the taskbar on the sides too. - mmi->ptMaxSize.x = screen->availableGeometry().width(); + mmi->ptMaxSize.x = availableGeometry.width(); // If you have the taskbar on top, or on the left you don't want it at (0,0): - mmi->ptMaxPosition.x = screen->availableGeometry().x(); - mmi->ptMaxPosition.y = screen->availableGeometry().y(); + mmi->ptMaxPosition.x = availableGeometry.x(); + mmi->ptMaxPosition.y = availableGeometry.y(); } else if (!screen){ qWarning() << "window()->screen() returned a null screen"; } diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 766168ccb8..d46cfbc43a 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -62,7 +62,8 @@ HEADERS += \ $$PWD/qplatformfunctions_wince.h \ $$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeinterface.h \ - $$PWD/qwindowsopengltester.h + $$PWD/qwindowsopengltester.h \ + $$PWD/qwindowsthreadpoolrunner.h INCLUDEPATH += $$PWD diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index ac51941f43..ad5207cf6e 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -472,6 +472,17 @@ QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType ty This method can be used to manipulate tables without having to worry about database-dependent SQL dialects. For non-prepared statements, the values will be properly escaped. + + In the WHERE statement, each non-null field of \a rec specifies a + filter condition of equality to the field value, or if prepared, a + placeholder. However, prepared or not, a null field specifies the + condition IS NULL and never introduces a placeholder. The + application must not attempt to bind data for the null field during + execution. The field must be set to some non-null value if a + placeholder is desired. Furthermore, since non-null fields specify + equality conditions and SQL NULL is not equal to anything, even + itself, it is generally not useful to bind a null to a placeholder. + */ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, const QSqlRecord &rec, bool preparedStatement) const diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp index af500722c6..1de149258d 100644 --- a/src/testlib/qbenchmarkvalgrind.cpp +++ b/src/testlib/qbenchmarkvalgrind.cpp @@ -115,13 +115,13 @@ QString QBenchmarkValgrindUtils::getNewestFileName() Q_ASSERT(!base.isEmpty()); nameFilters << QString::fromLatin1("%1.*").arg(base); - QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable); + const QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable); Q_ASSERT(!fiList.empty()); int hiSuffix = -1; QFileInfo lastFileInfo; const QString pattern = QString::fromLatin1("%1.(\\d+)").arg(base); QRegExp rx(pattern); - foreach (const QFileInfo &fileInfo, fiList) { + for (const QFileInfo &fileInfo : fiList) { const int index = rx.indexIn(fileInfo.fileName()); Q_ASSERT(index == 0); Q_UNUSED(index); @@ -151,8 +151,8 @@ void QBenchmarkValgrindUtils::cleanup() nameFilters << base // overall summary << QString::fromLatin1("%1.*").arg(base); // individual dumps - QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable); - foreach (const QFileInfo &fileInfo, fiList) { + const QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable); + for (const QFileInfo &fileInfo : fiList) { const bool removeOk = QFile::remove(fileInfo.fileName()); Q_ASSERT(removeOk); Q_UNUSED(removeOk); diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h index b6d8d6028c..c4c79b7deb 100644 --- a/src/testlib/qtestaccessible.h +++ b/src/testlib/qtestaccessible.h @@ -151,7 +151,7 @@ public: return res; } static bool containsEvent(QAccessibleEvent *event) { - Q_FOREACH (const QAccessibleEvent *ev, eventList()) { + for (const QAccessibleEvent *ev : qAsConst(eventList())) { if (*ev == *event) return true; } @@ -285,7 +285,7 @@ private: QDebug str = QDebug(&rc).nospace(); str << "Event " << *needle << " not found at head of event list of size " << haystack.size() << " :"; - Q_FOREACH (const QAccessibleEvent *e, haystack) + for (const QAccessibleEvent *e : haystack) str << ' ' << *e; return rc; } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 7b567674e4..d5b4ae218f 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1694,8 +1694,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) handler.reset(new FatalSignalHandler); #endif TestMethods::MetaMethods commandLineMethods; - if (!QTest::testFunctions.isEmpty()) { - foreach (const QString &tf, QTest::testFunctions) { + for (const QString &tf : qAsConst(QTest::testFunctions)) { const QByteArray tfB = tf.toLatin1(); const QByteArray signature = tfB + QByteArrayLiteral("()"); QMetaMethod m = TestMethods::findMethod(testObject, signature.constData()); @@ -1706,7 +1705,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) exit(1); } commandLineMethods.push_back(m); - } } TestMethods test(testObject, commandLineMethods); test.invokeTests(testObject); @@ -2296,12 +2294,58 @@ TO_STRING_IMPL(qint64, %lld) TO_STRING_IMPL(quint64, %llu) #endif TO_STRING_IMPL(bool, %d) -TO_STRING_IMPL(char, %c) TO_STRING_IMPL(signed char, %hhd) TO_STRING_IMPL(unsigned char, %hhu) TO_STRING_IMPL(float, %g) TO_STRING_IMPL(double, %lg) +template <> Q_TESTLIB_EXPORT char *QTest::toString(const char &t) +{ + unsigned char c = static_cast(t); + char *msg = new char[16]; + switch (c) { + case 0x00: + qstrcpy(msg, "'\\0'"); + break; + case 0x07: + qstrcpy(msg, "'\\a'"); + break; + case 0x08: + qstrcpy(msg, "'\\b'"); + break; + case 0x09: + qstrcpy(msg, "'\\t'"); + break; + case 0x0a: + qstrcpy(msg, "'\\n'"); + break; + case 0x0b: + qstrcpy(msg, "'\\v'"); + break; + case 0x0c: + qstrcpy(msg, "'\\f'"); + break; + case 0x0d: + qstrcpy(msg, "'\\r'"); + break; + case 0x22: + qstrcpy(msg, "'\\\"'"); + break; + case 0x27: + qstrcpy(msg, "'\\\''"); + break; + case 0x5c: + qstrcpy(msg, "'\\\\'"); + break; + default: + if (c < 0x20 || c >= 0x7F) + qsnprintf(msg, 16, "'\\x%02x'", c); + else + qsnprintf(msg, 16, "'%c'" , c); + } + return msg; +} + /*! \internal */ char *QTest::toString(const char *str) diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 4f2456cf79..522e13b17b 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -54,6 +54,7 @@ SOURCES += \ ../../corelib/io/qfsfileengine_iterator.cpp \ ../../corelib/io/qiodevice.cpp \ ../../corelib/io/qfiledevice.cpp \ + ../../corelib/io/qresource.cpp \ ../../corelib/io/qtemporaryfile.cpp \ ../../corelib/io/qtextstream.cpp \ ../../corelib/io/qstandardpaths.cpp \ diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 3bcd6f7c4b..defc0539c9 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2689,7 +2689,7 @@ void QFileDialogPrivate::saveSettings() settings.beginGroup(QLatin1String("FileDialog")); if (usingWidgets()) { - settings.setValue(QLatin1String("sidebarWidth"), qFileDialogUi->splitter->sizes().first()); + settings.setValue(QLatin1String("sidebarWidth"), qFileDialogUi->splitter->sizes().constFirst()); settings.setValue(QLatin1String("shortcuts"), QUrl::toStringList(qFileDialogUi->sidebar->urls())); settings.setValue(QLatin1String("treeViewHeader"), qFileDialogUi->treeView->header()->saveState()); } @@ -3001,9 +3001,9 @@ void QFileDialogPrivate::createWidgets() q->selectNameFilter(options->initiallySelectedNameFilter()); q->setDefaultSuffix(options->defaultSuffix()); q->setHistory(options->history()); - if (options->initiallySelectedFiles().count() == 1) - q->selectFile(options->initiallySelectedFiles().first().fileName()); const auto initiallySelectedFiles = options->initiallySelectedFiles(); + if (initiallySelectedFiles.size() == 1) + q->selectFile(initiallySelectedFiles.first().fileName()); for (const QUrl &url : initiallySelectedFiles) q->selectUrl(url); lineEdit()->selectAll(); @@ -4095,7 +4095,7 @@ QStringList QFSCompleter::splitPath(const QString &path) const parts.removeFirst(); currentLocationList.removeLast(); } - if (!currentLocationList.isEmpty() && currentLocationList.last().isEmpty()) + if (!currentLocationList.isEmpty() && currentLocationList.constLast().isEmpty()) currentLocationList.removeLast(); return currentLocationList + parts; } diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index 48ae5f1fc4..b20db8fc7c 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -217,9 +217,9 @@ void QFileInfoGatherer::run() condition.wait(&mutex); if (abort.load()) return; - const QString thisPath = path.front(); + const QString thisPath = qAsConst(path).front(); path.pop_front(); - const QStringList thisList = files.front(); + const QStringList thisList = qAsConst(files).front(); files.pop_front(); locker.unlock(); diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index bfa40317eb..c72761f2ae 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -374,7 +374,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS QModelIndex index = QModelIndex(); // start with "My Computer" #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path - QString host = QLatin1String("\\\\") + pathElements.first(); + QString host = QLatin1String("\\\\") + pathElements.constFirst(); if (absolutePath == QDir::fromNativeSeparators(host)) absolutePath.append(QLatin1Char('/')); if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/'))) diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index 2e884e238d..1b1eb6472e 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -127,7 +127,7 @@ QMimeData *QUrlModel::mimeData(const QModelIndexList &indexes) const */ bool QUrlModel::canDrop(QDragEnterEvent *event) { - if (!event->mimeData()->formats().contains(mimeTypes().first())) + if (!event->mimeData()->formats().contains(mimeTypes().constFirst())) return false; const QList list = event->mimeData()->urls(); @@ -145,7 +145,7 @@ bool QUrlModel::canDrop(QDragEnterEvent *event) bool QUrlModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { - if (!data->formats().contains(mimeTypes().first())) + if (!data->formats().contains(mimeTypes().constFirst())) return false; Q_UNUSED(action); Q_UNUSED(column); diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index aa10f65389..53f947354c 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -850,9 +850,9 @@ void QWizardPrivate::switchToPage(int newId, Direction direction) q->cleanupPage(oldId); initialized.remove(oldId); } - Q_ASSERT(history.last() == oldId); + Q_ASSERT(history.constLast() == oldId); history.removeLast(); - Q_ASSERT(history.last() == newId); + Q_ASSERT(history.constLast() == newId); } } diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 8160396ca2..75bbb99579 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -26,7 +26,7 @@ qhp.QtWidgets.subprojects.classes.sortPages = true tagfile = ../../../doc/qtwidgets/qtwidgets.tags -depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtsvg +depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtplatformheaders qtsvg headerdirs += .. diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 714f09e893..e045d60fc8 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -2016,8 +2016,8 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co if (viewportRect.intersects(rangeRect)) selectionRegion += rangeRect; if (d->hasSpans()) { - foreach (QSpanCollection::Span *s, - d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) { + const auto spansInRect = d->spans.spansInRect(range.left(), range.top(), range.width(), range.height()); + for (QSpanCollection::Span *s : spansInRect) { if (range.contains(s->top(), s->left(), range.parent())) { const QRect &visualSpanRect = d->visualSpanRect(*s); if (viewportRect.intersects(visualSpanRect)) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ebdbdbd3e6..2d23bb61a2 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -424,6 +424,7 @@ QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard inpu QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus #ifndef QT_NO_WHEELEVENT int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll +QWidget *QApplicationPrivate::wheel_widget = Q_NULLPTR; #endif bool qt_in_tab_key_event = false; int qt_antialiasing_threshold = -1; @@ -786,7 +787,7 @@ void QApplicationPrivate::initializeWidgetFontHash() QWidget *QApplication::activePopupWidget() { return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ? - QApplicationPrivate::popupWidgets->last() : 0; + QApplicationPrivate::popupWidgets->constLast() : nullptr; } @@ -1718,9 +1719,11 @@ QString QApplicationPrivate::desktopStyleKey() // first valid one. if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { const QStringList availableKeys = QStyleFactory::keys(); - foreach (const QString &style, theme->themeHint(QPlatformTheme::StyleNames).toStringList()) + const auto styles = theme->themeHint(QPlatformTheme::StyleNames).toStringList(); + for (const QString &style : styles) { if (availableKeys.contains(style, Qt::CaseInsensitive)) return style; + } } return QString(); } @@ -2225,10 +2228,13 @@ QWidget *qt_tlw_for_window(QWindow *wnd) else break; } - if (wnd) - foreach (QWidget *tlw, qApp->topLevelWidgets()) + if (wnd) { + const auto tlws = qApp->topLevelWidgets(); + for (QWidget *tlw : tlws) { if (tlw->windowHandle() == wnd) return tlw; + } + } return 0; } @@ -2391,7 +2397,7 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con const QPoint globalPos = qIsInf(globalPosF.x()) ? QPoint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) : globalPosF.toPoint(); - const QPoint windowPos = enterList.back()->window()->mapFromGlobal(globalPos); + const QPoint windowPos = qAsConst(enterList).back()->window()->mapFromGlobal(globalPos); for (auto it = enterList.crbegin(), end = enterList.crend(); it != end; ++it) { auto *w = *it; if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) { @@ -3302,7 +3308,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) case QEvent::Wheel: { QWidget* w = static_cast(receiver); - QWheelEvent* wheel = static_cast(e); // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open. if (const QWidget *popup = QApplication::activePopupWidget()) { @@ -3310,27 +3315,61 @@ bool QApplication::notify(QObject *receiver, QEvent *e) return true; } - QPoint relpos = wheel->pos(); - bool eventAccepted = wheel->isAccepted(); + QWheelEvent* wheel = static_cast(e); + const bool spontaneous = wheel->spontaneous(); + const Qt::ScrollPhase phase = wheel->phase(); - if (e->spontaneous() && wheel->phase() == Qt::ScrollUpdate) - QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); + if (phase == Qt::NoScrollPhase || phase == Qt::ScrollBegin + || (phase == Qt::ScrollUpdate && !QApplicationPrivate::wheel_widget)) { + + if (spontaneous && phase == Qt::ScrollBegin) + QApplicationPrivate::wheel_widget = Q_NULLPTR; + + const QPoint &relpos = wheel->pos(); + + if (spontaneous && (phase == Qt::NoScrollPhase || phase == Qt::ScrollUpdate)) + QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); - while (w) { QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), - wheel->modifiers(), wheel->phase(), wheel->source()); - we.spont = wheel->spontaneous(); - res = d->notify_helper(w, w == receiver ? wheel : &we); - eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted(); - e->spont = false; - if ((res && eventAccepted) - || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) - break; + wheel->modifiers(), phase, wheel->source()); + bool eventAccepted; + while (w) { + we.spont = spontaneous && w == receiver; + we.ignore(); + res = d->notify_helper(w, &we); + eventAccepted = we.isAccepted(); + if (res && eventAccepted) { + if (spontaneous && phase != Qt::NoScrollPhase) + QApplicationPrivate::wheel_widget = w; + break; + } + if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) + break; - relpos += w->pos(); - w = w->parentWidget(); + we.p += w->pos(); + w = w->parentWidget(); + } + wheel->setAccepted(eventAccepted); + } else if (QApplicationPrivate::wheel_widget) { + if (!spontaneous) { + // wheel_widget may forward the wheel event to a delegate widget, + // either directly or indirectly (e.g. QAbstractScrollArea will + // forward to its QScrollBars through viewportEvent()). In that + // case, the event will not be spontaneous but synthesized, so + // we can send it straigth to the receiver. + d->notify_helper(w, wheel); + } else { + const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos()); + QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), + wheel->modifiers(), wheel->phase(), wheel->source()); + we.spont = true; + we.ignore(); + d->notify_helper(QApplicationPrivate::wheel_widget, &we); + wheel->setAccepted(we.isAccepted()); + if (phase == Qt::ScrollEnd) + QApplicationPrivate::wheel_widget = Q_NULLPTR; + } } - wheel->setAccepted(eventAccepted); } break; #endif @@ -3795,7 +3834,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) } else { // A popup was closed, so the previous popup gets the focus. - QWidget* aw = QApplicationPrivate::popupWidgets->last(); + QWidget* aw = QApplicationPrivate::popupWidgets->constLast(); if (QWidget *fw = aw->focusWidget()) fw->setFocus(Qt::PopupFocusReason); @@ -3942,7 +3981,8 @@ void QApplication::alert(QWidget *widget, int duration) if (QWindow *window= QApplicationPrivate::windowForWidget(widget)) window->alert(duration); } else { - foreach (QWidget *topLevel, topLevelWidgets()) + const auto topLevels = topLevelWidgets(); + for (QWidget *topLevel : topLevels) QApplication::alert(topLevel, duration); } } diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index b884b32016..0482f83a8a 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -208,6 +208,7 @@ public: static QWidget *active_window; #ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; + static QWidget *wheel_widget; #endif static int enabledAnimations; // Combination of QPlatformTheme::UiEffect diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 4c85be33f5..9a3e9291bf 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -219,7 +219,8 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni } // check if the QGesture for this recognizer has already been created - foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) { + const auto states = m_objectGestures.value(QGestureManager::ObjectGesture(object, type)); + for (QGesture *state : states) { if (m_gestureToRecognizer.value(state) == recognizer) return state; } @@ -684,7 +685,8 @@ void QGestureManager::deliverEvents(const QSet &gestures, QApplication::sendEvent(receiver, &event); bool eventAccepted = event.isAccepted(); - foreach(QGesture *gesture, event.gestures()) { + const auto eventGestures = event.gestures(); + for (QGesture *gesture : eventGestures) { if (eventAccepted || event.isAccepted(gesture)) { QWidget *w = event.m_targetWidgets.value(gesture->gestureType(), 0); Q_ASSERT(w); @@ -710,7 +712,8 @@ void QGestureManager::deliverEvents(const QSet &gestures, QGestureEvent event(it.value()); QApplication::sendEvent(it.key(), &event); bool eventAccepted = event.isAccepted(); - foreach (QGesture *gesture, event.gestures()) { + const auto eventGestures = event.gestures(); + for (QGesture *gesture : eventGestures) { if (gesture->state() == Qt::GestureStarted && (eventAccepted || event.isAccepted(gesture))) { QWidget *w = event.m_targetWidgets.value(gesture->gestureType(), 0); diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index b69ca54159..66b622911a 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -375,11 +375,9 @@ class QWhatsThisPrivate : public QObject void QWhatsThisPrivate::notifyToplevels(QEvent *e) { - QWidgetList toplevels = QApplication::topLevelWidgets(); - for (int i = 0; i < toplevels.count(); ++i) { - QWidget *w = toplevels.at(i); + const QWidgetList toplevels = QApplication::topLevelWidgets(); + for (auto *w : toplevels) QApplication::sendEvent(w, e); - } } QWhatsThisPrivate *QWhatsThisPrivate::instance = 0; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 7e2e02b58e..ec5a68eeef 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1417,7 +1417,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win = topData()->window; } - foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) { + const auto dynamicPropertyNames = q->dynamicPropertyNames(); + for (const QByteArray &propertyName : dynamicPropertyNames) { if (!qstrncmp(propertyName, "_q_platform_", 12)) win->setProperty(propertyName, q->property(propertyName)); } @@ -11984,7 +11985,9 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) QWidget *targetWidget = 0; int shortestDistance = INT_MAX; - foreach(QWidget *targetCandidate, QApplication::allWidgets()) { + + const auto targetCandidates = QApplication::allWidgets(); + for (QWidget *targetCandidate : targetCandidates) { const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint())); @@ -12689,7 +12692,7 @@ QWidget *QWidget::keyboardGrabber() does not allow an application to interrupt what the user is currently doing in another application. - \sa isActiveWindow(), window(), show() + \sa isActiveWindow(), window(), show(), QWindowsWindowFunctions::setWindowActivationBehavior() */ void QWidget::activateWindow() { diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index cda7dff509..c33e4167c1 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -406,10 +406,12 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) return hwnd; // Find top level with native window (there might be dialogs that do not have one). - foreach (const QWidget *toplevel, QApplication::topLevelWidgets()) + const auto topLevels = QApplication::topLevelWidgets(); + for (const QWidget *toplevel : topLevels) { if (toplevel->windowHandle() && toplevel->windowHandle()->handle()) if (const HWND topLevelHwnd = QApplicationPrivate::getHWNDForWidget(toplevel)) return topLevelHwnd; + } if (QDesktopWidget *desktop = qApp->desktop()) if (const HWND desktopHwnd = QApplicationPrivate::getHWNDForWidget(desktop)) diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 9c61a3a263..9f167f5924 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -755,9 +755,9 @@ void QUnsortedModelEngine::filterOnDemand(int n) const QAbstractItemModel *model = c->proxy->sourceModel(); int lastRow = model->rowCount(curParent) - 1; QIndexMapper im(curMatch.indices.last() + 1, lastRow); - int lastIndex = buildIndices(curParts.last(), curParent, n, im, &curMatch); + int lastIndex = buildIndices(curParts.constLast(), curParent, n, im, &curMatch); curMatch.partial = (lastRow != lastIndex); - saveInCache(curParts.last(), curParent, curMatch); + saveInCache(curParts.constLast(), curParent, curMatch); } QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& parent, int n) diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index 3d1971db8e..933db1711b 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -581,7 +581,8 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, // Check for an active scroller at globalPos if (inputType == QScroller::InputPress) { - foreach (QScroller *as, QScroller::activeScrollers()) { + const auto activeScrollers = QScroller::activeScrollers(); + for (QScroller *as : activeScrollers) { if (as != scroller) { QRegion scrollerRegion; @@ -589,11 +590,13 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size()); #ifndef QT_NO_GRAPHICSVIEW } else if (QGraphicsObject *go = qobject_cast(as->target())) { - if (go->scene()) { + if (const auto *scene = go->scene()) { const auto goBoundingRectMappedToScene = go->mapToScene(go->boundingRect()); - foreach (QGraphicsView *gv, go->scene()->views()) + const auto views = scene->views(); + for (QGraphicsView *gv : views) { scrollerRegion |= gv->mapFromScene(goBoundingRectMappedToScene) .translated(gv->mapToGlobal(QPoint(0, 0))); + } } #endif } diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 2d6bcf72c6..02e3c2b82a 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -575,8 +575,11 @@ QPointF QScroller::pixelPerMeter() const if (QGraphicsObject *go = qobject_cast(d->target)) { QTransform viewtr; //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - viewtr = go->scene()->views().first()->viewportTransform(); + if (const auto *scene = go->scene()) { + const auto views = scene->views(); + if (!views.isEmpty()) + viewtr = views.first()->viewportTransform(); + } QTransform tr = go->deviceTransform(viewtr); if (tr.isScaling()) { QPointF p0 = tr.map(QPointF(0, 0)); @@ -1121,12 +1124,15 @@ void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal stopP return; ScrollSegment s; - if (orientation == Qt::Horizontal && !xSegments.isEmpty()) - s.startTime = xSegments.last().startTime + xSegments.last().deltaTime * xSegments.last().stopProgress; - else if (orientation == Qt::Vertical && !ySegments.isEmpty()) - s.startTime = ySegments.last().startTime + ySegments.last().deltaTime * ySegments.last().stopProgress; - else + if (orientation == Qt::Horizontal && !xSegments.isEmpty()) { + const auto &lastX = xSegments.constLast(); + s.startTime = lastX.startTime + lastX.deltaTime * lastX.stopProgress; + } else if (orientation == Qt::Vertical && !ySegments.isEmpty()) { + const auto &lastY = ySegments.constLast(); + s.startTime = lastY.startTime + lastY.deltaTime * lastY.stopProgress; + } else { s.startTime = monotonicTimer.elapsed(); + } s.startPos = startPos; s.deltaPos = deltaPos; @@ -1463,8 +1469,11 @@ bool QScrollerPrivate::prepareScrolling(const QPointF &position) #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsObject *go = qobject_cast(target)) { //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - setDpiFromWidget(go->scene()->views().first()); + if (const auto *scene = go->scene()) { + const auto views = scene->views(); + if (!views.isEmpty()) + setDpiFromWidget(views.first()); + } } #endif diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 6643b4429c..6f733f99d5 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -588,9 +588,9 @@ void QUndoStack::push(QUndoCommand *cmd) QUndoCommand *cur = 0; if (macro) { - QUndoCommand *macro_cmd = d->macro_stack.last(); + QUndoCommand *macro_cmd = d->macro_stack.constLast(); if (!macro_cmd->d->child_list.isEmpty()) - cur = macro_cmd->d->child_list.last(); + cur = macro_cmd->d->child_list.constLast(); } else { if (d->index > 0) cur = d->command_list.at(d->index - 1); @@ -616,7 +616,7 @@ void QUndoStack::push(QUndoCommand *cmd) } } else { if (macro) { - d->macro_stack.last()->d->child_list.append(cmd); + d->macro_stack.constLast()->d->child_list.append(cmd); } else { d->command_list.append(cmd); d->checkUndoLimit(); @@ -963,7 +963,7 @@ void QUndoStack::beginMacro(const QString &text) d->clean_index = -1; // we've deleted the clean state d->command_list.append(cmd); } else { - d->macro_stack.last()->d->child_list.append(cmd); + d->macro_stack.constLast()->d->child_list.append(cmd); } d->macro_stack.append(cmd); diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 6fc8cb5e26..2b68c308ec 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -964,7 +964,8 @@ bool QDialogButtonBox::event(QEvent *event) break; } - foreach (QPushButton *pb, (dialog ? dialog : this)->findChildren()) { + const auto pbs = (dialog ? dialog : this)->findChildren(); + for (QPushButton *pb : pbs) { if (pb->isDefault() && pb != firstAcceptButton) { hasDefault = true; break; diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 29089311c6..c14fd5a942 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -3096,7 +3096,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) { - QList path = indexOf(first); + const QList path = indexOf(first); if (path.isEmpty()) return; @@ -3133,7 +3133,7 @@ void QDockAreaLayout::resizeDocks(const QList &docks, while (path.size() > 1) { QDockAreaLayoutInfo *info = this->info(path); if (!info->tabbed && info->o == o) { - info->item_list[path.last()].size = size; + info->item_list[path.constLast()].size = size; int totalSize = 0; foreach (const QDockAreaLayoutItem &item, info->item_list) { if (!item.skip()) { @@ -3147,7 +3147,7 @@ void QDockAreaLayout::resizeDocks(const QList &docks, path.removeLast(); } - const int dockNum = path.first(); + const int dockNum = path.constFirst(); Q_ASSERT(dockNum < QInternal::DockCount); QRect &r = this->docks[dockNum].rect; QSize s = r.size(); diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 8410568cc1..b646e82209 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -427,7 +427,7 @@ QIcon QLineEditPrivate::clearButtonIcon() const void QLineEditPrivate::setClearButtonEnabled(bool enabled) { - foreach (const SideWidgetEntry &e, trailingSideWidgets) { + for (const SideWidgetEntry &e : trailingSideWidgets) { if (e.flags & SideWidgetClearButton) { e.action->setEnabled(enabled); break; @@ -443,13 +443,13 @@ void QLineEditPrivate::positionSideWidgets() const QSize iconSize = QLineEditPrivate::iconSize(); const int delta = QLineEditIconButton::IconMargin + iconSize.width(); QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize); - foreach (const SideWidgetEntry &e, leftSideWidgetList()) { + for (const SideWidgetEntry &e : leftSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); } widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin); - foreach (const SideWidgetEntry &e, rightSideWidgetList()) { + for (const SideWidgetEntry &e : rightSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() - delta); diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index ae87ea526d..63a6c718bc 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -1163,7 +1163,7 @@ void QMainWindowLayout::insertToolBar(QToolBar *before, QToolBar *toolbar) // copy the toolbar also in the saved state savedState.toolBarAreaLayout.insertItem(before, item); } - if (!currentGapPos.isEmpty() && currentGapPos.first() == 0) { + if (!currentGapPos.isEmpty() && currentGapPos.constFirst() == 0) { currentGapPos = layoutState.toolBarAreaLayout.currentGapIndex(); if (!currentGapPos.isEmpty()) { currentGapPos.prepend(0); @@ -1501,7 +1501,7 @@ void QMainWindowLayout::splitDockWidget(QDockWidget *after, Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QWidget *widget) const { - QList pathToWidget = layoutState.dockAreaLayout.indexOf(widget); + const QList pathToWidget = layoutState.dockAreaLayout.indexOf(widget); if (pathToWidget.isEmpty()) return Qt::NoDockWidgetArea; return toDockWidgetArea(pathToWidget.first()); @@ -1783,7 +1783,7 @@ QLayoutItem *QMainWindowLayout::takeAt(int index) } #ifndef QT_NO_TOOLBAR - if (!currentGapPos.isEmpty() && currentGapPos.first() == 0) { + if (!currentGapPos.isEmpty() && currentGapPos.constFirst() == 0) { currentGapPos = layoutState.toolBarAreaLayout.currentGapIndex(); if (!currentGapPos.isEmpty()) { currentGapPos.prepend(0); @@ -2057,7 +2057,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) if (parentInfo->tabbed) { // merge the two tab widgets - int idx = path.last(); + int idx = path.constLast(); Q_ASSERT(parentInfo->item_list[idx].widgetItem->widget() == dwgw); delete parentInfo->item_list[idx].widgetItem; parentInfo->item_list.removeAt(idx); @@ -2283,7 +2283,7 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) #ifndef QT_NO_DOCKWIDGET if (QDockWidget *dw = qobject_cast(widget)) { - Q_ASSERT(path.first() == 1); + Q_ASSERT(path.constFirst() == 1); bool actualGroup = false; #ifndef QT_NO_TABBAR if (group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3) { @@ -2386,7 +2386,7 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) } } } - foreach (QWidget *w, candidates) { + for (QWidget *w : candidates) { QWindow *handle1 = widget->windowHandle(); QWindow *handle2 = w->windowHandle(); if (handle1 && handle2 && handle1->screen() != handle2->screen()) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index 2b734b603f..b42ebe7e48 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -516,7 +516,7 @@ QVector MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const Q if (overlap >= maxOverlap || maxOverlap == -1) { if (overlap > maxOverlap) { maxOverlap = overlap; - result.resize(0); + result.clear(); } result << srcRect; } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 514cb1a8c9..1b9e31968a 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -117,7 +117,7 @@ public: { Q_D(QTornOffMenu); // make the torn-off menu a sibling of p (instead of a child) - QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.last(); + QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.constLast(); if (parentWidget->parentWidget()) parentWidget = parentWidget->parentWidget(); setParent(parentWidget, Qt::Window | Qt::Tool); @@ -1270,14 +1270,17 @@ void QMenuPrivate::_q_platformMenuAboutToShow() Q_Q(QMenu); #ifdef Q_OS_OSX - if (platformMenu) - Q_FOREACH (QAction *action, q->actions()) + if (platformMenu) { + const auto actions = q->actions(); + for (QAction *action : actions) { if (QWidget *widget = widgetItems.value(action)) if (widget->parent() == q) { QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast(action)); moveWidgetToPlatformItem(widget, menuItem); platformMenu->syncMenuItem(menuItem); } + } + } #endif emit q->aboutToShow(); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index f15ce06e23..261ff0bca3 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -200,7 +200,7 @@ void QMenuBarPrivate::updateGeometries() if(itemsDirty) { for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); - shortcutIndexMap.resize(0); // faster than clear + shortcutIndexMap.clear(); const int actionsCount = actions.count(); shortcutIndexMap.reserve(actionsCount); for (int i = 0; i < actionsCount; i++) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index cf485974f6..ba3fc2fcd7 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -590,7 +590,7 @@ QRect QTabBarPrivate::normalizedScrollRect(int index) } bool tearTopVisible = index != 0 && topEdge != -scrollOffset; - bool tearBottomVisible = index != tabList.size() - 1 && bottomEdge != tabList.last().rect.bottom() + 1 - scrollOffset; + bool tearBottomVisible = index != tabList.size() - 1 && bottomEdge != tabList.constLast().rect.bottom() + 1 - scrollOffset; if (tearTopVisible && !tearLeftRect.isNull()) topEdge = tearLeftRect.bottom() + 1; if (tearBottomVisible && !tearRightRect.isNull()) @@ -621,7 +621,7 @@ QRect QTabBarPrivate::normalizedScrollRect(int index) } bool tearLeftVisible = index != 0 && leftEdge != -scrollOffset; - bool tearRightVisible = index != tabList.size() - 1 && rightEdge != tabList.last().rect.right() + 1 - scrollOffset; + bool tearRightVisible = index != tabList.size() - 1 && rightEdge != tabList.constLast().rect.right() + 1 - scrollOffset; if (tearLeftVisible && !tearLeftRect.isNull()) leftEdge = tearLeftRect.right() + 1; if (tearRightVisible && !tearRightRect.isNull()) @@ -642,7 +642,7 @@ void QTabBarPrivate::makeVisible(int index) const bool horiz = !verticalTabs(shape); const int tabStart = horiz ? tabRect.left() : tabRect.top(); const int tabEnd = horiz ? tabRect.right() : tabRect.bottom(); - const int lastTabEnd = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom(); + const int lastTabEnd = horiz ? tabList.constLast().rect.right() : tabList.constLast().rect.bottom(); const QRect scrollRect = normalizedScrollRect(index); const int scrolledTabBarStart = qMax(1, scrollRect.left() + scrollOffset); const int scrolledTabBarEnd = qMin(lastTabEnd - 1, scrollRect.right() + scrollOffset); diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index d8a7b27d60..db66d39089 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -1141,7 +1141,7 @@ void QTextBrowser::clearHistory() d->forwardStack.clear(); if (!d->stack.isEmpty()) { QTextBrowserPrivate::HistoryEntry historyEntry = d->stack.top(); - d->stack.resize(0); + d->stack.clear(); d->stack.push(historyEntry); d->home = historyEntry.url; } diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp index 2e79b502ea..05564bb6b1 100644 --- a/src/widgets/widgets/qtoolbararealayout.cpp +++ b/src/widgets/widgets/qtoolbararealayout.cpp @@ -347,7 +347,7 @@ void QToolBarAreaLayoutInfo::removeToolBar(QToolBar *toolBar) void QToolBarAreaLayoutInfo::insertToolBarBreak(QToolBar *before) { if (before == 0) { - if (!lines.isEmpty() && lines.last().toolBarItems.isEmpty()) + if (!lines.isEmpty() && lines.constLast().toolBarItems.isEmpty()) return; lines.append(QToolBarAreaLayoutLine(o)); return; diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 0d690312e4..e5195000aa 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -40,15 +40,7 @@ #include #include -#ifndef QT_NO_PROCESS # include // only so we get QPROCESS_USE_SPAWN -# if defined(Q_OS_WIN) -# include -# endif - -Q_DECLARE_METATYPE(QProcess::ExitStatus); -Q_DECLARE_METATYPE(QProcess::ProcessState); -#endif typedef void (QProcess::*QProcessFinishedSignal1)(int); typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus); @@ -1052,24 +1044,33 @@ private: void tst_QProcess::softExitInSlots_data() { QTest::addColumn("appName"); + QTest::addColumn("signalToConnect"); + QByteArray dataTagPrefix("gui app "); #ifndef QT_NO_WIDGETS - QTest::newRow("gui app") << "testGuiProcess/testGuiProcess"; + for (int i = 0; i < 6; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testGuiProcess/testGuiProcess" << i; + } #endif - QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2"; + + dataTagPrefix = "console app "; + for (int i = 0; i < 6; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testProcessEcho2/testProcessEcho2" << i; + } } void tst_QProcess::softExitInSlots() { QFETCH(QString, appName); + QFETCH(int, signalToConnect); - for (int i = 0; i < 6; ++i) { - SoftExitProcess proc(i); - proc.writeAfterStart("OLEBOLE", 8); // include the \0 - proc.start(appName); - QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); - QCOMPARE(proc.state(), QProcess::NotRunning); - } + SoftExitProcess proc(signalToConnect); + proc.writeAfterStart("OLEBOLE", 8); // include the \0 + proc.start(appName); + QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); + QCOMPARE(proc.state(), QProcess::NotRunning); } #endif diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index b1b94a3c5f..540cd66715 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -5813,9 +5813,9 @@ class DispatcherWatcher : public QObject Q_OBJECT public: DispatcherWatcher(QEventLoop &e, int *statusAwake, int *statusAboutToBlock) : - m_statusAboutToBlock(statusAboutToBlock), - m_statusAwake(statusAwake), m_eventLoop(&e), + m_statusAwake(statusAwake), + m_statusAboutToBlock(statusAboutToBlock), m_aboutToBlocks(0), m_awakes(0) { diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index ff049b7600..cfec327319 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -714,8 +714,6 @@ void tst_QDateTime::fromMSecsSinceEpoch() QCOMPARE(dtLocal.toLocalTime(), cet); QCOMPARE(dtUtc.toLocalTime(), cet); QCOMPARE(dtOffset.toLocalTime(), cet); - } else { - QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); } // LocalTime will overflow for max diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 8fad672f42..eb37d6b8e6 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -734,10 +734,11 @@ void tst_QVector::clear() const QVector myvec; myvec << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2); - QVERIFY(myvec.size() == 3); + const auto oldCapacity = myvec.capacity(); + QCOMPARE(myvec.size(), 3); myvec.clear(); - QVERIFY(myvec.size() == 0); - QVERIFY(myvec.capacity() == 0); + QCOMPARE(myvec.size(), 0); + QCOMPARE(myvec.capacity(), oldCapacity); } void tst_QVector::clearInt() const @@ -1945,7 +1946,7 @@ void tst_QVector::resizePOD() const const int capacity = vector.capacity(); - vector.resize(0); + vector.clear(); QCOMPARE(vector.size(), 0); QVERIFY(vector.capacity() <= capacity); } diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 0219738a70..6adfe05fb0 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -96,6 +96,7 @@ private slots: void drawBitmap(); void isNull(); void task_246446(); + void task_51271(); void convertFromImageNoDetach(); void convertFromImageDetach(); @@ -1425,6 +1426,14 @@ void tst_QPixmap::task_246446() QVERIFY(pm.mask().isNull()); } +void tst_QPixmap::task_51271() +{ + QPixmap pm; + QBitmap bm; + QVERIFY(!pm.isQBitmap()); // Should not crash ! + QVERIFY(bm.isQBitmap()); +} + void tst_QPixmap::preserveDepth() { QPixmap target(64, 64); diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp index 0ffb0ea45f..8002303723 100644 --- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp +++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp @@ -341,11 +341,11 @@ struct TypeAlignment void tst_QGuiMetaType::flags_data() { QTest::addColumn("type"); - QTest::addColumn("isMovable"); + QTest::addColumn("isRelocatable"); QTest::addColumn("isComplex"); #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ - QTest::newRow(#RealType) << MetaTypeId << bool(!QTypeInfo::isStatic) << bool(QTypeInfo::isComplex); + QTest::newRow(#RealType) << MetaTypeId << bool(QTypeInfoQuery::isRelocatable) << bool(QTypeInfoQuery::isComplex); QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW } @@ -353,12 +353,12 @@ QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) void tst_QGuiMetaType::flags() { QFETCH(int, type); - QFETCH(bool, isMovable); + QFETCH(bool, isRelocatable); QFETCH(bool, isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex); QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex); - QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable); + QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isRelocatable); } diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index 9d9ca6fb43..eb056475d1 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -1623,7 +1623,24 @@ void tst_QPrinter::resolution() // Test set/get int expected = 333; #ifdef Q_OS_MAC - // Set resolution does nothing on OSX, see QTBUG-7000 + // QMacPrintEngine chooses the closest supported resolution. + const QList all_supported = native.supportedResolutions(); + foreach (int supported, all_supported) { + // Test setting a supported resolution + int requested = supported; + native.setResolution(requested); + QCOMPARE(native.resolution(), requested); + + // Test setting an unsupported resolution + do { + requested += 5; + } while (all_supported.contains(requested)); + native.setResolution(requested); + int result = native.resolution(); + QVERIFY(all_supported.contains(result)); + QVERIFY(qAbs(result - requested) <= qAbs(supported - requested)); + } + expected = native.resolution(); #endif // Q_OS_MAC native.setResolution(expected); diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index 63be3de3ab..6528c24c1a 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -555,6 +555,11 @@ void tst_QDialog::reject() QCOMPARE(dialog.called, 4); } +static QByteArray formatPoint(QPoint p) +{ + return QByteArray::number(p.x()) + ", " + QByteArray::number(p.y()); +} + void tst_QDialog::snapToDefaultButton() { #ifdef QT_NO_CURSOR @@ -563,9 +568,9 @@ void tst_QDialog::snapToDefaultButton() if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: Wayland does not support setting the cursor position."); - QPoint topLeftPos = QApplication::desktop()->availableGeometry().topLeft(); - topLeftPos = QPoint(topLeftPos.x() + 100, topLeftPos.y() + 100); - QPoint startingPos(topLeftPos.x() + 250, topLeftPos.y() + 250); + const QRect dialogGeometry(QApplication::desktop()->availableGeometry().topLeft() + + QPoint(100, 100), QSize(200, 200)); + const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100); QCursor::setPos(startingPos); #ifdef Q_OS_OSX // On OS X we use CGEventPost to move the cursor, it needs at least @@ -576,17 +581,14 @@ void tst_QDialog::snapToDefaultButton() QDialog dialog; QPushButton *button = new QPushButton(&dialog); button->setDefault(true); - dialog.setGeometry(QRect(topLeftPos, QSize(200, 200))); + dialog.setGeometry(dialogGeometry); dialog.show(); QVERIFY(QTest::qWaitForWindowExposed(&dialog)); - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - if (theme->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool()) { - QPoint localPos = button->mapFromGlobal(QCursor::pos()); - QVERIFY(button->rect().contains(localPos)); - } else { - QCOMPARE(startingPos, QCursor::pos()); - } - } + const QPoint localPos = button->mapFromGlobal(QCursor::pos()); + if (QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool()) + QVERIFY2(button->rect().contains(localPos), formatPoint(localPos).constData()); + else + QVERIFY2(!button->rect().contains(localPos), formatPoint(localPos).constData()); #endif // !QT_NO_CURSOR } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index afee548c9b..515ddf480f 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -4974,7 +4974,9 @@ static inline QByteArray msgRgbMismatch(unsigned actual, unsigned expected) static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height) { QScreen *screen = window->screen(); - return screen ? screen->grabWindow(window->winId(), x, y, width, height) : QPixmap(); + Q_ASSERT(screen); + QPixmap result = screen->grabWindow(window->winId(), x, y, width, height); + return result.devicePixelRatio() > 1 ? result.scaled(width, height) : result; } #define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__) @@ -8500,7 +8502,7 @@ void tst_QWidget::translucentWidget() #ifdef Q_OS_WIN QWidget *desktopWidget = QApplication::desktop()->screen(0); if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) - widgetSnapshot = qApp->primaryScreen()->grabWindow(desktopWidget->winId(), labelPos.x(), labelPos.y(), label.width(), label.height()); + widgetSnapshot = grabWindow(desktopWidget->windowHandle(), labelPos.x(), labelPos.y(), label.width(), label.height()); else #endif widgetSnapshot = label.grab(QRect(QPoint(0, 0), label.size())); diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index f631688870..31c5520b55 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -90,10 +90,8 @@ void tst_QImageConversion::convertRgb888ToRgb32() QFETCH(QImage, inputImage); QBENCHMARK { - volatile QImage output = inputImage.convertToFormat(QImage::Format_RGB32); - // we need the volatile and the following to make sure the compiler does not do - // anything stupid :) - (void)output; + QImage output = inputImage.convertToFormat(QImage::Format_RGB32); + output.constBits(); } } @@ -107,10 +105,8 @@ void tst_QImageConversion::convertRgb888ToRgbx8888() QFETCH(QImage, inputImage); QBENCHMARK { - volatile QImage output = inputImage.convertToFormat(QImage::Format_RGBX8888); - // we need the volatile and the following to make sure the compiler does not do - // anything stupid :) - (void)output; + QImage output = inputImage.convertToFormat(QImage::Format_RGBX8888); + output.constBits(); } } @@ -140,10 +136,8 @@ void tst_QImageConversion::convertRgb32ToRgb888() QFETCH(QImage, inputImage); QBENCHMARK { - volatile QImage output = inputImage.convertToFormat(QImage::Format_RGB888); - // we need the volatile and the following to make sure the compiler does not do - // anything stupid :) - (void)output; + QImage output = inputImage.convertToFormat(QImage::Format_RGB888); + output.constBits(); } } @@ -157,6 +151,8 @@ void tst_QImageConversion::convertRgb16_data() QTest::newRow("rgb888") << rgb16 << QImage::Format_RGB888; QTest::newRow("rgb666") << rgb16 << QImage::Format_RGB666; QTest::newRow("rgb555") << rgb16 << QImage::Format_RGB555; + QTest::newRow("argb8565") << rgb16 << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("argb8555") << rgb16 << QImage::Format_ARGB8555_Premultiplied; } void tst_QImageConversion::convertRgb16() @@ -189,6 +185,7 @@ void tst_QImageConversion::convertRgb32_data() QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888; QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666; QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555; + QTest::newRow("rgb32 -> argb8565pm") << rgb32 << QImage::Format_ARGB8565_Premultiplied; QTest::newRow("argb32 -> rgb16") << argb32 << QImage::Format_RGB16; QTest::newRow("argb32 -> rgb32") << argb32 << QImage::Format_RGB32; @@ -237,12 +234,14 @@ void tst_QImageConversion::convertGeneric_data() QImage rgba32 = argb32.convertToFormat(QImage::Format_RGBA8888); QImage bgr30 = rgb32.convertToFormat(QImage::Format_BGR30); QImage a2rgb30 = argb32.convertToFormat(QImage::Format_A2RGB30_Premultiplied); + QImage rgb666 = rgb32.convertToFormat(QImage::Format_RGB666); QTest::newRow("rgba8888 -> rgb32") << rgba32 << QImage::Format_RGB32; QTest::newRow("rgba8888 -> argb32") << rgba32 << QImage::Format_ARGB32; QTest::newRow("rgba8888 -> argb32pm") << rgba32 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("rgba8888 -> rgbx8888") << rgba32 << QImage::Format_RGBX8888; QTest::newRow("rgba8888 -> rgba8888pm") << rgba32 << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("rgba8888 -> rgb888") << rgba32 << QImage::Format_RGB888; QTest::newRow("rgba8888 -> rgb30") << rgba32 << QImage::Format_RGB30; QTest::newRow("rgba8888 -> a2bgr30") << rgba32 << QImage::Format_A2BGR30_Premultiplied; @@ -264,6 +263,14 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("a2rgb30 -> rgb30") << a2rgb30 << QImage::Format_RGB30; QTest::newRow("a2rgb30 -> bgr30") << a2rgb30 << QImage::Format_BGR30; QTest::newRow("a2rgb30 -> a2bgr30") << a2rgb30 << QImage::Format_A2BGR30_Premultiplied; + + QTest::newRow("rgb666 -> rgb32") << rgb666 << QImage::Format_RGB32; + QTest::newRow("rgb666 -> argb32") << rgb666 << QImage::Format_ARGB32; + QTest::newRow("rgb666 -> argb32pm") << rgb666 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("rgb666 -> rgb888") << rgb666 << QImage::Format_RGB888; + QTest::newRow("rgb666 -> rgb16") << rgb666 << QImage::Format_RGB16; + QTest::newRow("rgb666 -> rgb555") << rgb666 << QImage::Format_RGB555; + QTest::newRow("rgb666 -> rgb30") << rgb666 << QImage::Format_RGB30; } void tst_QImageConversion::convertGeneric() @@ -285,6 +292,9 @@ void tst_QImageConversion::convertGenericInplace_data() QImage argb32 = generateImageArgb32(1000, 1000); QImage argb32pm = argb32.convertToFormat(QImage::Format_ARGB32_Premultiplied); QImage rgba8888 = argb32.convertToFormat(QImage::Format_RGBA8888); + QImage argb6666 = argb32.convertToFormat(QImage::Format_ARGB6666_Premultiplied); + QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied); + QImage rgb16 = argb32.convertToFormat(QImage::Format_RGB16); QTest::newRow("argb32 -> argb32pm -> argb32") << argb32 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("argb32 -> rgb32 -> argb32") << argb32 << QImage::Format_RGB32; @@ -301,6 +311,16 @@ void tst_QImageConversion::convertGenericInplace_data() QTest::newRow("rgba8888 -> rgb32 -> rgba8888") << rgba8888 << QImage::Format_RGB32; QTest::newRow("rgba8888 -> argb32pm -> rgba8888") << rgba8888 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("rgba8888 -> rgba8888pm -> rgba8888") << rgba8888 << QImage::Format_RGBA8888_Premultiplied; + + QTest::newRow("argb6666pm -> argb8565pm -> argb6666pm") << argb6666 << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("argb6666pm -> rgb888 -> argb6666pm") << argb6666 << QImage::Format_RGB888; + + QTest::newRow("argb4444pm -> rgb16 -> argb4444pm") << argb4444 << QImage::Format_RGB16; + QTest::newRow("argb4444pm -> rgb444 -> argb4444pm") << argb4444 << QImage::Format_RGB444; + + QTest::newRow("rgb16 -> rgb555 -> rgb16") << rgb16 << QImage::Format_RGB555; + QTest::newRow("rgb16 -> rgb444 -> rgb16") << rgb16 << QImage::Format_RGB444; + QTest::newRow("rgb16 -> argb4444pm -> rgb16") << rgb16 << QImage::Format_ARGB4444_Premultiplied; } void tst_QImageConversion::convertGenericInplace()