diff --git a/configure b/configure index 5d028278905d0fba8e2e62e7a6398a61f1562b38..f4555a746b7bf4dc2cf631226832e26e38c9db08 100755 --- a/configure +++ b/configure @@ -4051,12 +4051,6 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(QMAKE_CXXFLAGS_DEBUG)" fi - if [ -n "$RPATH_FLAGS" ] && [ -n "`getQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then - setBootstrapVariable "QMAKE_(LFLAGS_)?RPATH" QMAKE_LFLAGS_RPATH - for rpath in $RPATH_FLAGS; do - EXTRA_LFLAGS="\$(QMAKE_LFLAGS_RPATH)\"$rpath\" $EXTRA_LFLAGS" - done - fi if [ "$BUILD_ON_MSYS" = "yes" ]; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DUNICODE" EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -DUNICODE" @@ -4104,9 +4098,6 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; \"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm\"" fi - if [ '!' -z "$D_FLAGS" ]; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $D_FLAGS" - fi echo >>"$mkfile" adjrelpath=`echo "$relpath" | sed 's/ /\\\\\\\\ /g'` adjoutpath=`echo "$outpath" | sed 's/ /\\\\\\\\ /g'` diff --git a/examples/widgets/itemviews/dirview/main.cpp b/examples/widgets/itemviews/dirview/main.cpp index abca413325559873e36f578b9037e9e33021ad10..2f030643ca97a3d690af43e01901c3dc8d26d686 100644 --- a/examples/widgets/itemviews/dirview/main.cpp +++ b/examples/widgets/itemviews/dirview/main.cpp @@ -41,6 +41,7 @@ #include <QApplication> #include <QDesktopWidget> #include <QFileSystemModel> +#include <QFileIconProvider> #include <QTreeView> #include <QCommandLineParser> #include <QCommandLineOption> @@ -54,6 +55,8 @@ int main(int argc, char *argv[]) parser.setApplicationDescription("Qt Dir View Example"); parser.addHelpOption(); parser.addVersionOption(); + QCommandLineOption dontUseCustomDirectoryIconsOption("c", "Set QFileIconProvider::DontUseCustomDirectoryIcons"); + parser.addOption(dontUseCustomDirectoryIconsOption); parser.addPositionalArgument("directory", "The directory to start in."); parser.process(app); const QString rootPath = parser.positionalArguments().isEmpty() @@ -61,6 +64,8 @@ int main(int argc, char *argv[]) QFileSystemModel model; model.setRootPath(""); + if (parser.isSet(dontUseCustomDirectoryIconsOption)) + model.iconProvider()->setOptions(QFileIconProvider::DontUseCustomDirectoryIcons); QTreeView tree; tree.setModel(&model); if (!rootPath.isEmpty()) { diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 5bb1ce77bd3585cec8a516e5d867471216dceead..a7183cb983aec6a6719128a369a2138c404e3e61 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -55,6 +55,9 @@ #include <QtCore/qfeatures.h> #endif +// The QT_SUPPORTS macro is deprecated. Don't use it in new code. +// Instead, use #ifdef/ndef QT_NO_feature. +// ### Qt6: remove macro #ifdef _MSC_VER # define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE) #else diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index e365d8d7e6f2a9d3eaeaa241e7f2e84064623947..1d1b2907b7d4d9cbe8637ae31936e9796b13768c 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -102,25 +102,6 @@ QT_BEGIN_NAMESPACE -static bool isPseudoFs(const QString &mountDir, const QByteArray &type) -{ - if (mountDir.startsWith(QLatin1String("/dev")) - || mountDir.startsWith(QLatin1String("/proc")) - || mountDir.startsWith(QLatin1String("/sys")) - || mountDir.startsWith(QLatin1String("/var/run")) - || mountDir.startsWith(QLatin1String("/var/lock"))) { - return true; - } - if (type == "tmpfs") - return true; -#if defined(Q_OS_LINUX) - if (type == "rootfs" || type == "rpc_pipefs") - return true; -#endif - - return false; -} - class QStorageIterator { public: @@ -158,6 +139,39 @@ private: #endif }; +template <typename String> +static bool isParentOf(const String &parent, const QString &dirName) +{ + return dirName.startsWith(parent) && + (dirName.size() == parent.size() || dirName.at(parent.size()) == QLatin1Char('/') || + parent.size() == 1); +} + +static bool isPseudoFs(const QStorageIterator &it) +{ + QString mountDir = it.rootPath(); + if (isParentOf(QLatin1String("/dev"), mountDir) + || isParentOf(QLatin1String("/proc"), mountDir) + || isParentOf(QLatin1String("/sys"), mountDir) + || isParentOf(QLatin1String("/var/run"), mountDir) + || isParentOf(QLatin1String("/var/lock"), mountDir)) { + return true; + } + + QByteArray type = it.fileSystemType(); + if (type == "tmpfs") + return false; +#if defined(Q_OS_LINUX) + if (type == "rootfs" || type == "rpc_pipefs") + return true; +#endif + + if (!it.device().startsWith('/')) + return true; + + return false; +} + #if defined(Q_OS_BSD4) inline QStorageIterator::QStorageIterator() @@ -444,10 +458,8 @@ void QStorageInfoPrivate::initRootPath() while (it.next()) { const QString mountDir = it.rootPath(); const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) - continue; // we try to find most suitable entry - if (oldRootPath.startsWith(mountDir) && maxLength < mountDir.length()) { + if (isParentOf(mountDir, oldRootPath) && maxLength < mountDir.length()) { maxLength = mountDir.length(); rootPath = mountDir; device = it.device(); @@ -461,11 +473,14 @@ static inline QString retrieveLabel(const QByteArray &device) #ifdef Q_OS_LINUX static const char pathDiskByLabel[] = "/dev/disk/by-label"; + QFileInfo devinfo(QFile::decodeName(device)); + QString devicePath = devinfo.canonicalFilePath(); + QDirIterator it(QLatin1String(pathDiskByLabel), QDir::NoDotAndDotDot); while (it.hasNext()) { it.next(); QFileInfo fileInfo(it.fileInfo()); - if (fileInfo.isSymLink() && fileInfo.symLinkTarget().toLocal8Bit() == device) + if (fileInfo.isSymLink() && fileInfo.symLinkTarget() == devicePath) return fileInfo.fileName(); } #elif defined Q_OS_HAIKU @@ -536,11 +551,10 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes() QList<QStorageInfo> volumes; while (it.next()) { - const QString mountDir = it.rootPath(); - const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) + if (isPseudoFs(it)) continue; + const QString mountDir = it.rootPath(); volumes.append(QStorageInfo(mountDir)); } diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index c29b80d3d0eb9fa2e90244b7db64a35525e143d6..7960174277e56b17d3863026b5380585d435e77d 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -249,8 +249,8 @@ public: AtomicType _q_value; - Type load() const Q_DECL_NOTHROW { return _q_value; } - void store(Type newValue) Q_DECL_NOTHROW { _q_value = newValue; } + Type load() const Q_DECL_NOTHROW { return Ops::load(_q_value); } + void store(Type newValue) Q_DECL_NOTHROW { Ops::store(_q_value, newValue); } operator Type() const Q_DECL_NOTHROW { return loadAcquire(); } Type operator=(Type newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; } diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index fa6556f7d9ef6fd14cb9cd1598e07bf7ce4ae122..eb6ce212828ef0711dc11d1e1103a61a121e4552 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -65,7 +65,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, // Don't allocate empty headers if (!(options & RawData) && !capacity) { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (options & Unsharable) return const_cast<QArrayData *>(&qt_array_unsharable_empty); #endif @@ -110,7 +110,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1) & ~(alignment - 1); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) header->ref.atomic.store(bool(!(options & Unsharable))); #else header->ref.atomic.store(1); @@ -132,7 +132,7 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize, && !(alignment & (alignment - 1))); Q_UNUSED(objectSize) Q_UNUSED(alignment) -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (data == &qt_array_unsharable_empty) return; #endif diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 865bd4325d5e8a7e8e79b047a987b2c78cd96cf4..cbbfe1bea2eb4045290d3db4608e3d620ff40da7 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -72,7 +72,7 @@ struct Q_CORE_EXPORT QArrayData enum AllocationOption { CapacityReserved = 0x1, -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Unsharable = 0x2, #endif RawData = 0x4, @@ -249,7 +249,7 @@ struct QTypedArrayData return allocate(/* capacity */ 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) static QTypedArrayData *unsharableEmpty() { Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData)); diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 9804d2c2d57ef546747944ce51fbd143fb1d264f..615d7c5f806a0996fe429ce8ef26198b69b60a6e 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -127,7 +127,7 @@ public: return (!d->isMutable() || d->ref.isShared()); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) void setSharable(bool sharable) { if (needsDetach()) { diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 41d198f9bc3684bef8f550542bcc50cba2861679..d546e949c204ad0c07f6e17cddb01695ab257c56 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -96,7 +96,7 @@ public: inline void detach() { if (d->ref.load() != 1) detach_helper(); } inline bool isDetached() const { return d->ref.load() == 1; } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } #endif diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index a18dd747069b306bbcacbdda0cce86c8ef564170..a5bde40fb85e1e52e728337c30ada3ecece5a367 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -266,7 +266,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; } #endif bool isSharedWith(const QHash &other) const { return d == other.d; } diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index 110529d84360b886dcc1437a1bab02c2e5fd09af..710bf5a9f2e0b181dbf5e730cb00b045adb6aeba 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -99,7 +99,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper2(this->e); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; } #endif inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index e04a6be1abf7f788ee922e69abc9d3fac6c9aa7b..381875e96f04da751d11a2a8944e347a6b862157 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -169,7 +169,7 @@ public: } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index ed49e70f4e088f176625ef3cd08971f3a9d7b0fa..7b5a643a1e79a8d86e4cf09d660a1dc111116524 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -359,7 +359,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h index a390989e7624cbd251efe64ba35cde2371aa0449..bff6885d650e55f12a609e7a4ba7a131b4b69bed 100644 --- a/src/corelib/tools/qrefcount.h +++ b/src/corelib/tools/qrefcount.h @@ -47,7 +47,7 @@ class RefCount public: inline bool ref() Q_DECL_NOTHROW { int count = atomic.load(); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; #endif @@ -58,7 +58,7 @@ public: inline bool deref() Q_DECL_NOTHROW { int count = atomic.load(); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; #endif @@ -67,7 +67,7 @@ public: return atomic.deref(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) bool setSharable(bool sharable) Q_DECL_NOTHROW { Q_ASSERT(!isShared()); diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 3f4208e8b3603345debedb1b793b7427b53d4245..7e7eb5210c01de5686a2808894046e933052a602 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -79,7 +79,7 @@ public: inline void detach() { q_hash.detach(); } inline bool isDetached() const { return q_hash.isDetached(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { q_hash.setSharable(sharable); } #endif diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 691872cb3664fe04abd6773e270a6e41e604b907..31542206340122ada8a4aa27b0b5f29bbc21b23e 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -100,7 +100,7 @@ public: inline void detach(); inline bool isDetached() const { return !d->ref.isShared(); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -376,7 +376,7 @@ template <typename T> void QVector<T>::detach() { if (!isDetached()) { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) if (!d->alloc) d = Data::unsharableEmpty(); else @@ -533,7 +533,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo x = Data::allocate(aalloc, options); Q_CHECK_PTR(x); // aalloc is bigger then 0 so it is not [un]sharedEmpty -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); #endif Q_ASSERT(!x->ref.isStatic()); @@ -601,7 +601,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo Q_ASSERT(d->data()); Q_ASSERT(uint(d->size) <= d->alloc); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(d != Data::unsharableEmpty()); #endif Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull()); diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index b733a688563ce0841591fafa3cf3d5c66e34270e..fff9f29b0318c5d3eacc566941b12b47ec3036f5 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -254,7 +254,7 @@ private: const QVector<int> &metaTypes, int slotIdx); SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); - void disconnectObjectTree(ObjectTreeNode &node); + void collectAllObjects(ObjectTreeNode &node, QSet<QObject *> &set); bool isServiceRegisteredByThread(const QString &serviceName); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index d0468f4af0eb2ee02634281d6feb7982184623f2..147966b9b094814016b418cbb5880db2148b1135 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1071,17 +1071,18 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() } } -void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack) +void QDBusConnectionPrivate::collectAllObjects(QDBusConnectionPrivate::ObjectTreeNode &haystack, + QSet<QObject *> &set) { QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); while (it != haystack.children.end()) { - disconnectObjectTree(*it); + collectAllObjects(*it, set); it++; } if (haystack.obj) - haystack.obj->disconnect(this); + set.insert(haystack.obj); } void QDBusConnectionPrivate::closeConnection() @@ -1110,15 +1111,23 @@ void QDBusConnectionPrivate::closeConnection() // Disconnect all signals from signal hooks and from the object tree to // avoid QObject::destroyed being sent to dbus daemon thread which has - // already quit. - SignalHookHash::iterator sit = signalHooks.begin(); - while (sit != signalHooks.end()) { - sit.value().obj->disconnect(this); - sit++; + // already quit. We need to make sure we disconnect exactly once per + // object, because if we tried a second time, we might be hitting a + // dangling pointer. + QSet<QObject *> allObjects; + collectAllObjects(rootNode, allObjects); + SignalHookHash::const_iterator sit = signalHooks.constBegin(); + while (sit != signalHooks.constEnd()) { + allObjects.insert(sit.value().obj); + ++sit; + } + + // now disconnect ourselves + QSet<QObject *>::const_iterator oit = allObjects.constBegin(); + while (oit != allObjects.constEnd()) { + (*oit)->disconnect(this); + ++oit; } - - disconnectObjectTree(rootNode); - rootNode.children.clear(); // free resources } void QDBusConnectionPrivate::handleDBusDisconnection() diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 33d5e76e52bf324024d4d1847dd0c57e84ba0865..defdcfb4ad59549df5fd99d78546834c338950c9 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -226,7 +226,8 @@ void QPlatformTextureList::clear() Flushes the given \a region from the specified \a window onto the screen. - Note that the \a offset parameter is currently unused. + The \a offset parameter is relative to the origin of the backing + store image. */ #ifndef QT_NO_OPENGL diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index fc344dc3ac4960d054f5cc9f8224cb5614469a32..f6c899a81544b339c4337b5f2ec8aeae99d9fd46 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -422,7 +422,7 @@ void QStroker::processCurrentSubpath() bool fwclosed = qt_stroke_side(&fwit, this, false, &fwStartTangent); bool bwclosed = qt_stroke_side(&bwit, this, !fwclosed, &bwStartTangent); - if (!bwclosed) + if (!bwclosed && !fwStartTangent.isNull()) joinPoints(m_elements.at(0).x, m_elements.at(0).y, fwStartTangent, m_capStyle); } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 28553e19e6575b60fe38e54ac12db9413b50af05..d023228fd2d9608f371d22a38fdb8e105580bf57 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -474,6 +474,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) // connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); + connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration &)), + SLOT(_q_configurationChanged(const QNetworkConfiguration &))); + #endif } @@ -1564,6 +1567,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); } //switch to new session (null if config was invalid) @@ -1571,7 +1576,6 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co networkSessionWeakRef = networkSessionStrongRef.toWeakRef(); if (!networkSessionStrongRef) { - online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); @@ -1587,6 +1591,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); + QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); _q_networkSessionStateChanged(networkSessionStrongRef->state()); } @@ -1603,6 +1609,9 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); + networkSessionStrongRef.clear(); networkSessionWeakRef.clear(); } @@ -1611,46 +1620,56 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); - + bool reallyOnline = false; //Do not emit the networkSessionConnected signal here, except for roaming -> connected //transition, otherwise it is emitted twice in a row when opening a connection. - if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming) + if (state == QNetworkSession::Connected && lastSessionState != QNetworkSession::Roaming) emit q->networkSessionConnected(); lastSessionState = state; - if (online) { + if (online && state == QNetworkSession::Disconnected) { + Q_FOREACH (const QNetworkConfiguration &cfg, networkConfigurationManager.allConfigurations()) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + reallyOnline = true; + } + } + } else if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { + reallyOnline = true; + } + + if (!reallyOnline) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { - online = false; if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; emit q->networkAccessibleChanged(networkAccessible); } } } else { - if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { - online = true; - if (defaultAccessControl) - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } + if (defaultAccessControl) + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + online = reallyOnline; + if (online && (state != QNetworkSession::Connected && state != QNetworkSession::Roaming)) { + _q_networkSessionClosed(); + createSession(q->configuration()); } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { if (online != isOnline) { - if (isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); - } + _q_networkSessionClosed(); + createSession(q->configuration()); online = isOnline; } } @@ -1661,11 +1680,6 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) emit q->networkAccessibleChanged(networkAccessible); } } - } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { - if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { - networkAccessible = QNetworkAccessManager::UnknownAccessibility; - emit q->networkAccessibleChanged(networkAccessible); - } } else { if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; @@ -1674,6 +1688,49 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) } } +void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfiguration &configuration) +{ + const QString id = configuration.identifier(); + if (configuration.state().testFlag(QNetworkConfiguration::Active)) { + if (!onlineConfigurations.contains(id)) { + + QSharedPointer<QNetworkSession> session(getNetworkSession()); + if (session) { + if (online && session->configuration().identifier() + != networkConfigurationManager.defaultConfiguration().identifier()) { + + onlineConfigurations.insert(id); + //this one disconnected but another one is online, + // close and create new session + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + } + } + } + + } else if (onlineConfigurations.contains(id)) { + //this one is disconnecting + onlineConfigurations.remove(id); + if (!onlineConfigurations.isEmpty()) { + _q_networkSessionClosed(); + createSession(configuration); + } + } +} + + +void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::SessionError) +{ + Q_FOREACH (const QNetworkConfiguration &cfg, networkConfigurationManager.allConfigurations()) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + online = true; + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + return; + } + } +} + #endif // QT_NO_BEARERMANAGEMENT QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart) diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index c8df213eadfceac1f15d299bc3516ef9b4cb46db..908d327e637fb7895a39267e40f3c752bc6ae36f 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -176,6 +176,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void _q_configurationChanged(const QNetworkConfiguration &)) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed(QNetworkSession::SessionError)) #endif }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 3fc33b5c152e7e44829a87c613f56a34192f1f32..2528249d17b36c271c455cd0765c90ffb86f80c8 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -143,6 +143,11 @@ public: bool isSeamless); void _q_networkSessionStateChanged(QNetworkSession::State state); void _q_onlineStateChanged(bool isOnline); + void _q_configurationChanged(const QNetworkConfiguration &configuration); + void _q_networkSessionFailed(QNetworkSession::SessionError error); + + QSet<QString> onlineConfigurations; + #endif QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart); diff --git a/src/platformsupport/fbconvenience/qfbbackingstore.cpp b/src/platformsupport/fbconvenience/qfbbackingstore.cpp index 2800a8150702d274df3e88cbc2462529df6bbe0b..5eddf71145b8bf1018300ee5f78e39eedce77cdd 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore.cpp +++ b/src/platformsupport/fbconvenience/qfbbackingstore.cpp @@ -37,6 +37,7 @@ #include <qpa/qplatformwindow.h> #include <QtGui/qscreen.h> +#include <QtGui/qpainter.h> QT_BEGIN_NAMESPACE @@ -84,9 +85,17 @@ void QFbBackingStore::unlock() mImageMutex.unlock(); } -void QFbBackingStore::beginPaint(const QRegion &) +void QFbBackingStore::beginPaint(const QRegion ®ion) { lock(); + + if (mImage.hasAlphaChannel()) { + QPainter p(&mImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + const QVector<QRect> rects = region.rects(); + for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) + p.fillRect(*it, Qt::transparent); + } } void QFbBackingStore::endPaint() diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index d00954375d526e09c92b0269b5683f5ae05131a0..ad4c62f4a65b4225e8c96afece2dcb6282571a29 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -233,6 +233,7 @@ QRegion QFbScreen::doRedraw() if (!mCompositePainter) mCompositePainter = new QPainter(mScreenImage); + for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) { QRegion rectRegion = rects[rectIndex]; @@ -250,7 +251,8 @@ QRegion QFbScreen::doRedraw() foreach (const QRect &rect, intersect.rects()) { bool firstLayer = true; if (layer == -1) { - mCompositePainter->fillRect(rect, Qt::black); + mCompositePainter->setCompositionMode(QPainter::CompositionMode_Source); + mCompositePainter->fillRect(rect, mScreenImage->hasAlphaChannel() ? Qt::transparent : Qt::black); firstLayer = false; layer = mWindowStack.size() - 1; } @@ -283,6 +285,7 @@ QRegion QFbScreen::doRedraw() QRect cursorRect; if (mCursor && (mCursor->isDirty() || mRepaintRegion.intersects(mCursor->lastPainted()))) { + mCompositePainter->setCompositionMode(QPainter::CompositionMode_SourceOver); cursorRect = mCursor->drawCursor(*mCompositePainter); touchedRegion += cursorRect; } diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 91bf00d1a7409ea74f8ba4bbba76add10c6719d6..703ec3a8b82424db200892ae37ff704131eb253f 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -41,6 +41,49 @@ #include <cmath> +#if defined(Q_OS_OSX) && !QT_OSX_DEPLOYMENT_TARGET_BELOW(__MAC_10_11) +#import <AppKit/AppKit.h> +#endif + +#if defined(Q_OS_IOS) && !QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_8_2) +#import <UIKit/UIKit.h> +#endif + +// These are available cross platform, exported as kCTFontWeightXXX from CoreText.framework, +// but they are not documented and are not in public headers so are private API and exposed +// only through the NSFontWeightXXX and UIFontWeightXXX aliases in AppKit and UIKit (rdar://26109857) +#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_11, __IPHONE_8_2) +#define kCTFontWeightUltraLight -0.8 +#define kCTFontWeightThin -0.6 +#define kCTFontWeightLight -0.4 +#define kCTFontWeightRegular 0 +#define kCTFontWeightMedium 0.23 +#define kCTFontWeightSemibold 0.3 +#define kCTFontWeightBold 0.4 +#define kCTFontWeightHeavy 0.56 +#define kCTFontWeightBlack 0.62 +#elif defined(Q_OS_OSX) +#define kCTFontWeightUltraLight NSFontWeightUltraLight +#define kCTFontWeightThin NSFontWeightThin +#define kCTFontWeightLight NSFontWeightLight +#define kCTFontWeightRegular NSFontWeightRegular +#define kCTFontWeightMedium NSFontWeightMedium +#define kCTFontWeightSemibold NSFontWeightSemibold +#define kCTFontWeightBold NSFontWeightBold +#define kCTFontWeightHeavy NSFontWeightHeavy +#define kCTFontWeightBlack NSFontWeightBlack +#elif defined(Q_OS_IOS) +#define kCTFontWeightUltraLight UIFontWeightUltraLight +#define kCTFontWeightThin UIFontWeightThin +#define kCTFontWeightLight UIFontWeightLight +#define kCTFontWeightRegular UIFontWeightRegular +#define kCTFontWeightMedium UIFontWeightMedium +#define kCTFontWeightSemibold UIFontWeightSemibold +#define kCTFontWeightBold UIFontWeightBold +#define kCTFontWeightHeavy UIFontWeightHeavy +#define kCTFontWeightBlack UIFontWeightBlack +#endif + QT_BEGIN_NAMESPACE static float SYNTHETIC_ITALIC_SKEW = std::tan(14.f * std::acos(0.f) / 90.f); @@ -63,23 +106,23 @@ bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buff QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value) { - if (value >= 0.62) + if (value >= kCTFontWeightBlack) return QFont::Black; - if (value >= 0.5) + if (value >= kCTFontWeightHeavy) return QFont::ExtraBold; - if (value >= 0.4) + if (value >= kCTFontWeightBold) return QFont::Bold; - if (value >= 0.3) + if (value >= kCTFontWeightSemibold) return QFont::DemiBold; - if (value >= 0.2) + if (value >= kCTFontWeightMedium) return QFont::Medium; - if (value == 0.0) + if (value == kCTFontWeightRegular) return QFont::Normal; - if (value <= -0.8) + if (value <= kCTFontWeightUltraLight) return QFont::Thin; - if (value <= -0.6) + if (value <= kCTFontWeightThin) return QFont::ExtraLight; - if (value <= -0.4) + if (value <= kCTFontWeightLight) return QFont::Light; return QFont::Normal; } diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index ac48a0e31014215ad7a3eaaacf5ae2788ee5ee97..a534d2064e8b54f75ffb256685d3145058422077 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -173,7 +173,9 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) } } - nativeItemForMenu(cocoaMenu).hidden = shouldHide; + NSMenuItem *nativeMenuItem = nativeItemForMenu(cocoaMenu); + nativeMenuItem.title = cocoaMenu->nsMenu().title; + nativeMenuItem.hidden = shouldHide; } NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index e60ca196acdb4ee9f086b5863a70de6c6008019b..9fcb221d374ee1bab49cb358bf2e1888e9096664 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -38,6 +38,7 @@ #include <qpa/qplatformwindow.h> #include <QRect> +#include <QPointer> #ifndef QT_NO_OPENGL #include "qcocoaglcontext.h" @@ -47,6 +48,32 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) +QT_BEGIN_NAMESPACE + +class QCocoaWindowPointer +{ +public: + void assign(QCocoaWindow *w); + void clear(); + + QCocoaWindow *data() const + { return watcher.isNull() ? Q_NULLPTR : window; } + bool isNull() const + { return watcher.isNull(); } + operator QCocoaWindow*() const + { return data(); } + QCocoaWindow *operator->() const + { return data(); } + QCocoaWindow &operator*() const + { return *data(); } + +private: + QPointer<QObject> watcher; + QCocoaWindow *window; +}; + +QT_END_NAMESPACE + @class QT_MANGLE_NAMESPACE(QNSWindowHelper); @protocol QNSWindowProtocol @@ -63,14 +90,13 @@ typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow; @interface QT_MANGLE_NAMESPACE(QNSWindowHelper) : NSObject { QCocoaNSWindow *_window; - QCocoaWindow *_platformWindow; + QCocoaWindowPointer _platformWindow; BOOL _grabbingMouse; BOOL _releaseOnMouseUp; - QPointer<QObject> _watcher; } @property (nonatomic, readonly) QCocoaNSWindow *window; -@property (nonatomic, readonly) QCocoaWindow *platformWindow; +@property (nonatomic, readonly) QCocoaWindowPointer platformWindow; @property (nonatomic) BOOL grabbingMouse; @property (nonatomic) BOOL releaseOnMouseUp; @@ -254,7 +280,7 @@ public: // for QNSView NSView *m_contentView; QNSView *m_qtView; QCocoaNSWindow *m_nsWindow; - QCocoaWindow *m_forwardWindow; + QCocoaWindowPointer m_forwardWindow; // TODO merge to one variable if possible bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy @@ -317,9 +343,8 @@ public: // for QNSView QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false) - // This object is tracked by a 'watcher' - // object in a window helper, preventing use of dangling - // pointers. + // This object is tracked by QCocoaWindowPointer, + // preventing the use of dangling pointers. QObject sentinel; }; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 12e85c52054f2f804219b0b03b1141e46a22a544..c5519995b66b88fd73d089de1829948892a4b65e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -85,7 +85,7 @@ static bool isMouseEvent(NSEvent *ev) self = [super init]; if (self) { _window = window; - _platformWindow = platformWindow; + _platformWindow.assign(platformWindow); _window.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:_platformWindow]; @@ -94,7 +94,6 @@ static bool isMouseEvent(NSEvent *ev) // make sure that m_nsWindow stays valid until the // QCocoaWindow is deleted by Qt. [_window setReleasedWhenClosed:NO]; - _watcher = &_platformWindow->sentinel; } return self; @@ -103,19 +102,19 @@ static bool isMouseEvent(NSEvent *ev) - (void)handleWindowEvent:(NSEvent *)theEvent { QCocoaWindow *pw = self.platformWindow; - if (_watcher && pw && pw->m_forwardWindow) { + if (pw && pw->m_forwardWindow) { if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) { QNSView *forwardView = pw->m_qtView; if (theEvent.type == NSLeftMouseUp) { [forwardView mouseUp:theEvent]; - pw->m_forwardWindow = 0; + pw->m_forwardWindow.clear(); } else { [forwardView mouseDragged:theEvent]; } } if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) { - pw->m_forwardWindow = 0; + pw->m_forwardWindow.clear(); } } @@ -142,7 +141,7 @@ static bool isMouseEvent(NSEvent *ev) if (!self.window.delegate) return; // Already detached, pending NSAppKitDefined event - if (_watcher && pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { NSPoint loc = [theEvent locationInWindow]; NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]]; NSRect contentFrame = [[self.window contentView] frame]; @@ -157,8 +156,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)detachFromPlatformWindow { - _platformWindow = 0; - _watcher.clear(); + self.platformWindow.clear(); [self.window.delegate release]; self.window.delegate = nil; } @@ -179,7 +177,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)dealloc { _window = nil; - _platformWindow = 0; + self.platformWindow.clear(); [super dealloc]; } @@ -331,6 +329,18 @@ static bool isMouseEvent(NSEvent *ev) @end +void QCocoaWindowPointer::assign(QCocoaWindow *w) +{ + window = w; + watcher = &w->sentinel; +} + +void QCocoaWindowPointer::clear() +{ + window = Q_NULLPTR; + watcher.clear(); +} + const int QCocoaWindow::NoAlertRequest = -1; QCocoaWindow::QCocoaWindow(QWindow *tlw) @@ -338,7 +348,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_contentView(nil) , m_qtView(nil) , m_nsWindow(0) - , m_forwardWindow(0) , m_contentViewIsEmbedded(false) , m_contentViewIsToBeEmbedded(false) , m_parentCocoaWindow(0) @@ -1126,8 +1135,7 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; - else if (!grab && [m_nsWindow isKeyWindow]) - [m_nsWindow resignKeyWindow]; + return true; } @@ -1138,8 +1146,7 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab) if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; - else if (!grab && [m_nsWindow isKeyWindow]) - [m_nsWindow resignKeyWindow]; + return true; } @@ -1320,7 +1327,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) if (oldParentCocoaWindow) { if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow) oldParentCocoaWindow->removeChildWindow(this); - m_forwardWindow = oldParentCocoaWindow; + m_forwardWindow.assign(oldParentCocoaWindow); } setNSWindow(m_nsWindow); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4b7b50a265ff33cb1bf0b5a9b8a954f0e86dba75..0d58faa5bf03efe072c62bd610a6df18434ab4cc 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -284,6 +284,7 @@ static bool _q_dontOverrideCtrlLMB = false; - (void)viewDidMoveToWindow { + m_backingStore = Q_NULLPTR; m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"]; if (self.window) { // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. @@ -740,7 +741,7 @@ QT_WARNING_POP if (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp) targetView = m_platformWindow->m_forwardWindow->m_qtView; else - m_platformWindow->m_forwardWindow = 0; + m_platformWindow->m_forwardWindow.clear(); } // Popups implicitly grap mouse events; forward to the active popup if there is one diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index 97ea3f1eca04d5da9a507e243607ba505667adea..830e270eeb6ba7abfae0e133d8d0d000b48d6820 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -41,6 +41,7 @@ #include <QtCore/QJsonArray> #include <QtCore/QLoggingCategory> #include <QtGui/QPainter> +#include <QtGui/private/qguiapplication_p.h> #include <xf86drm.h> #include <xf86drmMode.h> @@ -62,13 +63,13 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below , m_bo(Q_NULLPTR) , m_cursorImage(0, 0, 0, 0, 0, 0) - , m_visible(true) + , m_state(CursorPendingVisible) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - m_visible = hideCursorVal.toInt() == 0; - if (!m_visible) + if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) { + m_state = CursorDisabled; return; + } uint64_t width, height; if ((drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &width) == 0) @@ -85,6 +86,12 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) initCursorAtlas(); } + m_deviceListener = new QEglFSKmsCursorDeviceListener(this); + connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, + m_deviceListener, &QEglFSKmsCursorDeviceListener::onDeviceListChanged); + if (!m_deviceListener->hasMouse()) + m_state = CursorPendingHidden; + #ifndef QT_NO_CURSOR QCursor cursor(Qt::ArrowCursor); changeCursor(&cursor, 0); @@ -94,6 +101,8 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) QEglFSKmsCursor::~QEglFSKmsCursor() { + delete m_deviceListener; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); @@ -106,6 +115,31 @@ QEglFSKmsCursor::~QEglFSKmsCursor() } } +void QEglFSKmsCursor::updateMouseStatus() +{ + const bool wasVisible = m_state == CursorVisible; + const bool visible = m_deviceListener->hasMouse(); + if (visible == wasVisible) + return; + + m_state = visible ? CursorPendingVisible : CursorPendingHidden; + +#ifndef QT_NO_CURSOR + changeCursor(nullptr, m_screen->topLevelAt(pos())); +#endif +} + +bool QEglFSKmsCursorDeviceListener::hasMouse() const +{ + return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; +} + +void QEglFSKmsCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +{ + if (type == QInputDeviceManager::DeviceTypePointer) + m_cursor->updateMouseStatus(); +} + void QEglFSKmsCursor::pointerEvent(const QMouseEvent &event) { setPos(event.screenPos().toPoint()); @@ -119,7 +153,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) if (!m_bo) return; - if (!m_visible) + if (m_state == CursorPendingHidden) { + m_state = CursorHidden; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + } + } + + if (m_state == CursorHidden || m_state == CursorDisabled) return; const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; @@ -159,6 +201,9 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) uint32_t handle = gbm_bo_get_handle(m_bo).u32; + if (m_state == CursorPendingVisible) + m_state = CursorVisible; + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen); @@ -206,7 +251,7 @@ void QEglFSKmsCursor::initCursorAtlas() drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); } - m_visible = false; + m_state = CursorDisabled; return; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h index 68bc72a03f5cdde6a654a31b419b0fc151a57789..f26df91be5b18f070c3ff9f3276b9a1c4394b6d1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.h @@ -37,12 +37,29 @@ #include <qpa/qplatformcursor.h> #include <QtCore/QList> #include <QtGui/QImage> +#include <QtGui/private/qinputdevicemanager_p.h> #include <gbm.h> QT_BEGIN_NAMESPACE class QEglFSKmsScreen; +class QEglFSKmsCursor; + +class QEglFSKmsCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QEglFSKmsCursorDeviceListener(QEglFSKmsCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QEglFSKmsCursor *m_cursor; +}; class QEglFSKmsCursor : public QPlatformCursor { @@ -60,15 +77,26 @@ public: QPoint pos() const Q_DECL_OVERRIDE; void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + void updateMouseStatus(); + private: void initCursorAtlas(); + enum CursorState { + CursorDisabled, + CursorPendingHidden, + CursorHidden, + CursorPendingVisible, + CursorVisible + }; + QEglFSKmsScreen *m_screen; QSize m_cursorSize; gbm_bo *m_bo; QPoint m_pos; QPlatformCursorImage m_cursorImage; - bool m_visible; + CursorState m_state; + QEglFSKmsCursorDeviceListener *m_deviceListener; // cursor atlas information struct CursorAtlas { diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 8c3e73fd808f1d0b0a74bbae6f7010eca2cce23e..13e06ef104e10c49383d78d4fd9dfb3b2e81a0cc 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -405,9 +405,12 @@ QRegion QLinuxFbScreen::doRedraw() if (!mBlitter) mBlitter = new QPainter(&mFbScreenImage); - QVector<QRect> rects = touched.rects(); - for (int i = 0; i < rects.size(); i++) + const QVector<QRect> rects = touched.rects(); + mBlitter->setCompositionMode(QPainter::CompositionMode_Source); + + for (int i = 0; i < rects.size(); ++i) mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); + return touched; } diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 5ca83fa9f22fac4ab1939bef18ed66c4e3166dc9..5550dd4efd17f73dfcbcdc1fb177ae8a0dea99fc 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -498,7 +498,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT if (!accessible) return E_FAIL; - const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window()); + const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), + QWindowsAccessibility::windowHelper(accessible)); QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y()); if (child == 0) { // no child found, return this item if it contains the coordinates @@ -541,7 +542,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long QAccessibleInterface *acc = childPointer(accessible, varID); if (!acc || !acc->isValid()) return E_FAIL; - const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window()); + const QRect rect = QHighDpi::toNativePixels(acc->rect(), + QWindowsAccessibility::windowHelper(accessible)); *pxLeft = rect.x(); *pyTop = rect.y(); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 3966a4cd77b99d9c6d12d0d21aed549d56aa9bc2..968ef7bd3b28d14a1a442f0124c92a8490fcadf6 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -139,7 +139,8 @@ struct QWindowsIntegrationPrivate # endif #endif #ifndef QT_NO_OPENGL - QSharedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext; + QMutex m_staticContextLock; + QScopedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext; #endif // QT_NO_OPENGL QScopedPointer<QPlatformInputContext> m_inputContext; #ifndef QT_NO_ACCESSIBILITY @@ -435,8 +436,9 @@ QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext() if (!integration) return 0; QWindowsIntegrationPrivate *d = integration->d.data(); + QMutexLocker lock(&d->m_staticContextLock); if (d->m_staticOpenGLContext.isNull()) - d->m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create()); + d->m_staticOpenGLContext.reset(QWindowsStaticOpenGLContext::create()); return d->m_staticOpenGLContext.data(); } #endif // !QT_NO_OPENGL diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index eba0593d7567ba3a7c4570dd2e81546f4ac5af13..aee692733891df6c1c39f82f1c76252de04476a0 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -124,6 +124,7 @@ contains(QT_CONFIG, freetype) { SOURCES += \ $$PWD/qwindowsfontdatabase_ft.cpp } else:contains(QT_CONFIG, system-freetype) { + CONFIG += qpa/basicunixfontdatabase include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri) HEADERS += \ $$PWD/qwindowsfontdatabase_ft.h diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index f5407f87797dc6719957055cd0ee210c80d34a42..75b43205b7b8716f4185199ec471a78ee02a1afe 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -108,9 +108,6 @@ QWinRTWindow::QWinRTWindow(QWindow *window) d->surface = EGL_NO_SURFACE; d->display = EGL_NO_DISPLAY; d->screen = static_cast<QWinRTScreen *>(screen()); - setWindowFlags(window->flags()); - setWindowState(window->windowState()); - setWindowTitle(window->title()); handleContentOrientationChange(window->contentOrientation()); d->surfaceFormat.setAlphaBufferSize(0); @@ -158,6 +155,10 @@ QWinRTWindow::QWinRTWindow(QWindow *window) }); Q_ASSERT_SUCCEEDED(hr); + setWindowFlags(window->flags()); + setWindowState(window->windowState()); + setWindowTitle(window->title()); + setGeometry(window->geometry()); } diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 529f91e1ec05f6bad374da45b09975719cee2264..6fa5dfa48316bfaa05b7e2682122323ce2d9a0a3 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -50,6 +50,7 @@ #include <qpa/qwindowsysteminterface.h> +#include <private/qguiapplication_p.h> #include <private/qshapedpixmapdndwindow_p.h> #include <private/qsimpledrag_p.h> #include <private/qhighdpiscaling_p.h> @@ -170,6 +171,17 @@ QMimeData *QXcbDrag::platformDropData() return dropData; } +bool QXcbDrag::eventFilter(QObject *o, QEvent *e) +{ + /* We are setting a mouse grab on the QShapedPixmapWindow in order not to + * lose the grab when the virtual desktop changes, but + * QBasicDrag::eventFilter() expects the events to be coming from the + * window where the drag was started. */ + if (initiatorWindow && o == shapedPixmapWindow()) + o = initiatorWindow.data(); + return QBasicDrag::eventFilter(o, e); +} + void QXcbDrag::startDrag() { // #fixme enableEventFilter(); @@ -194,6 +206,7 @@ void QXcbDrag::startDrag() setUseCompositing(current_virtual_desktop->compositingActive()); setScreen(current_virtual_desktop->screens().constFirst()->screen()); + initiatorWindow = QGuiApplicationPrivate::currentMouseWindow; QBasicDrag::startDrag(); if (connection()->mouseGrabber() == Q_NULLPTR) shapedPixmapWindow()->setMouseGrabEnabled(true); @@ -202,6 +215,7 @@ void QXcbDrag::startDrag() void QXcbDrag::endDrag() { QBasicDrag::endDrag(); + initiatorWindow.clear(); } static xcb_translate_coordinates_reply_t * diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index c9d257906faf4d7acae312982b4d42c80d8d6051..738da1268d9ad280091c8e87ddffdbb74a3d4666 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -69,6 +69,7 @@ public: ~QXcbDrag(); virtual QMimeData *platformDropData() Q_DECL_OVERRIDE; + bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; void startDrag() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; @@ -106,6 +107,7 @@ private: Qt::DropAction toDropAction(xcb_atom_t atom) const; xcb_atom_t toXdndAction(Qt::DropAction a) const; + QPointer<QWindow> initiatorWindow; QPointer<QWindow> currentWindow; QPoint currentPosition; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 226507f7a0170e1e6e89742e2402f992da17815c..429ba8df717f5045c9894f6b4405f1fdf0228740 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2351,9 +2351,14 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i QPoint local(event_x, event_y); QPoint global(root_x, root_y); - // "mousePressWindow" can be NULL i.e. if a window will be grabbed or umnapped, so set it again here - if (connection()->buttons() != Qt::NoButton && connection()->mousePressWindow() == Q_NULLPTR) + // "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here. + // Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive. + const bool isMouseButtonPressed = (connection()->buttons() != Qt::NoButton); + const bool hasMousePressWindow = (connection()->mousePressWindow() != Q_NULLPTR); + if (isMouseButtonPressed && !hasMousePressWindow) connection()->setMousePressWindow(this); + else if (hasMousePressWindow && !isMouseButtonPressed) + connection()->setMousePressWindow(Q_NULLPTR); handleMouseEvent(timestamp, local, global, modifiers, source); } diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 740c1b9b5db0321cdde91bec0e1f764e0fe64382..6aa2eeb07270984e4d865030d1e7e854c44afa31 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -494,7 +494,7 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in \since 5.0 Returns \c true if the model contains modified values that have not been - committed to the datase, otherwise false. + committed to the database, otherwise false. */ bool QSqlTableModel::isDirty() const { diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 9d79439e049eefb56ef60997933d67910dfd6ff3..14ee0865eb4a1a507b0302f9cbe566eecad3fed6 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -238,7 +238,7 @@ namespace QTest inline typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(T e) { QMetaEnum me = QMetaEnum::fromType<T>(); - return qstrdup(me.key(int(e))); // int cast is necessary to support enum classes + return qstrdup(me.valueToKey(int(e))); // int cast is necessary to support enum classes } template <typename T> // Fallback diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 726d1972f16e4f71e76900abee3ac13b7962e7ac..7dd94cdca7e69c901b9a3f2b07053d18b6f200c2 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -378,8 +378,8 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) def->isVirtual = false; def->isStatic = false; //skip modifiers and attributes - while (test(INLINE) || (test(STATIC) && (def->isStatic = true)) || - (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + while (test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) || + (test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual || testFunctionAttribute(def) || testFunctionRevision(def)) {} bool templateFunction = (lookup() == TEMPLATE); def->type = parseType(); @@ -473,8 +473,8 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) def->isVirtual = false; def->isStatic = false; //skip modifiers and attributes - while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true)) || - (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) || + (test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual || testFunctionAttribute(def) || testFunctionRevision(def)) {} bool tilde = test(TILDE); def->type = parseType(); diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp index a0a7852851d50df6cf7dc4898299151cd38a69f9..106f7244640e6a0256f961acb55c7dfe3e0e5c2c 100644 --- a/src/widgets/accessible/qaccessiblemenu.cpp +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -225,6 +225,20 @@ QObject *QAccessibleMenuItem::object() const return m_action; } +/*! \reimp */ +QWindow *QAccessibleMenuItem::window() const +{ + QWindow *result = Q_NULLPTR; + if (!m_owner.isNull()) { + result = m_owner->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = m_owner->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + } + return result; +} + QRect QAccessibleMenuItem::rect() const { QRect rect; diff --git a/src/widgets/accessible/qaccessiblemenu_p.h b/src/widgets/accessible/qaccessiblemenu_p.h index b42c852ff19e8c568843c2456319ce339ad2a8d4..c51597bf1f22850bc62498c77325677f999b301f 100644 --- a/src/widgets/accessible/qaccessiblemenu_p.h +++ b/src/widgets/accessible/qaccessiblemenu_p.h @@ -108,6 +108,8 @@ public: QAccessibleInterface *parent() const Q_DECL_OVERRIDE; QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; QObject * object() const Q_DECL_OVERRIDE; + QWindow *window() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; QAccessible::Role role() const Q_DECL_OVERRIDE; void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 3a9422cc26f5cea3e88d1095e7d3810c4388a9f6..beff27ad64b1fe30a235f59abb2c549b67729053 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -206,8 +206,14 @@ bool QAccessibleWidget::isValid() const /*! \reimp */ QWindow *QAccessibleWidget::window() const { - Q_ASSERT(widget()); - return widget()->windowHandle(); + const QWidget *w = widget(); + Q_ASSERT(w); + QWindow *result = w->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = w->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + return result; } /*! diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 9bf5a502c39e1f2172158b9b557221548d0070a9..0e2eee3b473bd8491b5a03a1984922ed454e2e5f 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -351,6 +351,9 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS ) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QModelIndex index = QModelIndex(); // start with "My Computer" + QString elementPath; + QChar separator = QLatin1Char('/'); + QString trailingSeparator; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path QString host = QLatin1String("\\\\") + pathElements.first(); @@ -358,6 +361,8 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS absolutePath.append(QLatin1Char('/')); if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/'))) absolutePath.append(QLatin1Char('/')); + if (absolutePath.endsWith(QLatin1Char('/'))) + trailingSeparator = QLatin1String("\\"); int r = 0; QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); if (!root.children.contains(host.toLower())) { @@ -374,11 +379,10 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS r = translateVisibleLocation(rootNode, r); index = q->index(r, 0, QModelIndex()); pathElements.pop_front(); - } else -#endif - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - { + separator = QLatin1Char('\\'); + elementPath = host; + elementPath.append(separator); + } else { if (!pathElements.at(0).contains(QLatin1Char(':'))) { QString rootPath = QDir(longPath).rootPath(); pathElements.prepend(rootPath); @@ -396,6 +400,11 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS for (int i = 0; i < pathElements.count(); ++i) { QString element = pathElements.at(i); + if (i != 0) + elementPath.append(separator); + elementPath.append(element); + if (i == pathElements.count() - 1) + elementPath.append(trailingSeparator); #ifdef Q_OS_WIN // On Windows, "filename " and "filename" are equivalent and // "filename . " and "filename" are equivalent @@ -427,7 +436,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (!alreadyExisted) { // Someone might call ::index("file://cookie/monster/doesn't/like/veggies"), // a path that doesn't exists, I.E. don't blindly create directories. - QFileInfo info(absolutePath); + QFileInfo info(elementPath); if (!info.exists()) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index ee0d41ce15050f987d541a029370cc278f38333a..b68c105abaf22ae9053d2263bbaadda3bbceea5d 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -3249,13 +3249,12 @@ void QTableViewPrivate::selectRow(int row, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(qMin(rowSectionAnchor, row), logicalColumn(0), root); - QModelIndex br = model->index(qMax(rowSectionAnchor, row), logicalColumn(model->columnCount(root) - 1), root); - if ((verticalHeader->sectionsMoved() && tl.row() != br.row()) - || horizontalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root); + QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root); + if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) { + q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows); } } } @@ -3289,14 +3288,12 @@ void QTableViewPrivate::selectColumn(int column, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(logicalRow(0), qMin(columnSectionAnchor, column), root); - QModelIndex br = model->index(logicalRow(model->rowCount(root) - 1), - qMax(columnSectionAnchor, column), root); - if ((horizontalHeader->sectionsMoved() && tl.column() != br.column()) - || verticalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root); + QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root); + if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) { + q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns); } } } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index a459a57482c8c1e1e8686ca1c65f7e15d3ca8f29..fcc195f6010fa0b06a6fc9c9b633198cea69d6b6 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2249,10 +2249,10 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); // QTBUG-37126, Active X controls may set the focus on native child widgets. if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) { - if (widgetWindow->widget()->inherits("QAxHostWidget")) - widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); - } + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + if (QWidget *widget = widgetWindow->widget()) + if (widget->inherits("QAxHostWidget")) + widget->setFocus(Qt::ActiveWindowFocusReason); } } diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 967ef6b40ccad48cbb152b412b77b7fca10c9a7e..89ed6922b5892c553ea290e16265e44fdfc8ce32 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -545,7 +545,7 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) // filter method. QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(receiver); - if (widgetWindow) + if (widgetWindow && widgetWindow->widget()) return filterEvent(widgetWindow->widget(), event); QGesture *state = qobject_cast<QGesture *>(receiver); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index b638c6c377da355deb2c3ea6ce8a45b5924ab531..5290d79d9e8bf9c37d349078c5cb3a256da30cee 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -87,7 +87,7 @@ QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const { Q_Q(const QWidgetWindow); const QWidget *widget = q->widget(); - if (!widget->isWindow() || !widget->hasHeightForWidth()) + if (!widget || !widget->isWindow() || !widget->hasHeightForWidth()) return QRect(); const QSize oldSize = rect.size().toSize(); const QSize newSize = QLayout::closestAcceptableSize(widget, oldSize); @@ -123,7 +123,7 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) && !QApplication::testAttribute(Qt::AA_ForceRasterWidgets)) { setSurfaceType(QSurface::RasterGLSurface); } - connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); + connect(widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChange())); } @@ -142,16 +142,18 @@ QAccessibleInterface *QWidgetWindow::accessibleRoot() const QObject *QWidgetWindow::focusObject() const { - QWidget *widget = m_widget->focusWidget(); + QWidget *windowWidget = m_widget; + if (!windowWidget) + return Q_NULLPTR; + + QWidget *widget = windowWidget->focusWidget(); if (!widget) - widget = m_widget; + widget = windowWidget; - if (widget) { - QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); - if (focusObj) - return focusObj; - } + QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); + if (focusObj) + return focusObj; return widget; } @@ -174,6 +176,9 @@ static inline bool shouldBePropagatedToWidget(QEvent *event) bool QWidgetWindow::event(QEvent *event) { + if (!m_widget) + return QWindow::event(event); + if (m_widget->testAttribute(Qt::WA_DontShowOnScreen)) { // \a event is uninteresting for QWidgetWindow, the event was probably // generated before WA_DontShowOnScreen was set @@ -201,7 +206,7 @@ bool QWidgetWindow::event(QEvent *event) #ifndef QT_NO_ACCESSIBILITY QAccessible::State state; state.active = true; - QAccessibleStateChangeEvent ev(widget(), state); + QAccessibleStateChangeEvent ev(m_widget, state); QAccessible::updateAccessibility(&ev); #endif return false; } @@ -375,7 +380,7 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) } else { const QEnterEvent *ee = static_cast<QEnterEvent *>(event); QWidget *child = m_widget->childAt(ee->pos()); - QWidget *receiver = child ? child : m_widget; + QWidget *receiver = child ? child : m_widget.data(); QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos()); qt_last_mouse_receiver = receiver; } diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index ca4bac8d865ead842e2844833443244d7d23266d..7fafb01b3d64013a544c738367436d6b2b1963c7 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -119,7 +119,7 @@ private: }; QWidget *getFocusWidget(FocusWidgets fw); - QWidget *m_widget; + QPointer<QWidget> m_widget; QPointer<QWidget> m_implicit_mouse_grabber; #ifndef QT_NO_DRAGANDDROP QPointer<QWidget> m_dragTarget; diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 5bcfa57b3774077fc5918110851851cd1c13b9bd..bd41fb60c12081f21bc57f30f687ca31e32f24f9 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -623,6 +623,8 @@ void QUndoStack::push(QUndoCommand *cmd) Marks the stack as clean and emits cleanChanged() if the stack was not already clean. + This is typically called when a document is saved, for example. + Whenever the stack returns to this state through the use of undo/redo commands, it emits the signal cleanChanged(). This signal is also emitted when the stack leaves the clean state. diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp index efbcdc78e0bc1b9c2b434434f78b7fef53a5aab8..1afcf05135637dc859d877e0fa8a5a6bbaf05bf9 100644 --- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp +++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp @@ -162,6 +162,7 @@ void tst_QStorageInfo::tempFile() #endif qint64 free = storage1.bytesFree(); + QVERIFY(free != -1); file.write(QByteArray(1024*1024, '1')); file.flush(); @@ -185,6 +186,7 @@ void tst_QStorageInfo::caching() qint64 free = storage1.bytesFree(); QStorageInfo storage2(storage1); QVERIFY(free == storage2.bytesFree()); + QVERIFY(free != -1); file.write(QByteArray(1024*1024, '\0')); file.flush(); diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 091d871e823bec1cde3c82995e390caad8fd12d7..9c7e1ae228903f340e93419411f0e4eb2fcedca0 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -93,7 +93,7 @@ public: bool isStatic() const { return d->ref.isStatic(); } bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) bool isSharable() const { return d->ref.isSharable(); } void setSharable(bool sharable) { d.setSharable(sharable); } #endif diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 31e44bc3aee27b54c3e1d367cf2cc751176c101e..31ade2606707375dedccbfc243bda7487ba9de08 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -44,7 +44,7 @@ struct SharedNullVerifier { Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) Q_ASSERT(QArrayData::shared_null[0].ref.isSharable()); #endif } @@ -101,7 +101,7 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); #endif @@ -123,7 +123,7 @@ void tst_QArrayData::referenceCounting() // Now would be a good time to free/release allocated data } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { // Reference counting initialized to 0 (non-sharable) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; @@ -151,7 +151,7 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); #endif @@ -178,7 +178,7 @@ void tst_QArrayData::sharedNullEmpty() QCOMPARE(null->ref.atomic.load(), -1); QCOMPARE(empty->ref.atomic.load(), -1); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(null->ref.isSharable()); QVERIFY(empty->ref.isSharable()); #endif @@ -309,7 +309,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v7.isShared()); QVERIFY(!v8.isShared()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v1.isSharable()); QVERIFY(v2.isSharable()); QVERIFY(v3.isSharable()); @@ -502,7 +502,7 @@ void tst_QArrayData::simpleVector() for (int i = 0; i < 120; ++i) QCOMPARE(v1[i], v8[i % 10]); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { v7.setSharable(true); QVERIFY(v7.isSharable()); @@ -672,7 +672,7 @@ void tst_QArrayData::allocate_data() QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); QVERIFY(shared_empty); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QVERIFY(unsharable_empty); #endif @@ -686,7 +686,7 @@ void tst_QArrayData::allocate_data() } options[] = { { "Default", QArrayData::Default, false, true, shared_empty }, { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty }, -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { "Reserved | Unsharable", QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, unsharable_empty }, @@ -736,7 +736,7 @@ void tst_QArrayData::allocate() else QCOMPARE(data->alloc, uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(bool, isSharable); QCOMPARE(data->ref.isSharable(), isSharable); #endif @@ -1316,7 +1316,7 @@ static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array, void tst_QArrayData::setSharable_data() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QTest::addColumn<QArrayDataPointer<int> >("array"); QTest::addColumn<size_t>("size"); QTest::addColumn<size_t>("capacity"); @@ -1362,7 +1362,7 @@ void tst_QArrayData::setSharable_data() void tst_QArrayData::setSharable() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(QArrayDataPointer<int>, array); QFETCH(size_t, size); QFETCH(size_t, capacity); @@ -1492,7 +1492,7 @@ void fromRawData_impl() QVERIFY((const T *)raw.constBegin() != array); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) { // Immutable, unsharable SimpleVector<T> raw = SimpleVector<T>::fromRawData(array, @@ -1578,7 +1578,7 @@ void tst_QArrayData::literals() QVERIFY(v.isStatic()); #endif -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); #endif QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd()); @@ -1629,7 +1629,7 @@ void tst_QArrayData::variadicLiterals() QVERIFY(v.isStatic()); -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); #endif QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd()); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 6a5c6b5670643e1acd34e311f9f459e8353d40f6..d485040a14c0fbdbf1dabb5d57c32e58ea383707 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1191,7 +1191,7 @@ void tst_QHash::noNeedlessRehashes() void tst_QHash::const_shared_null() { QHash<int, QString> hash2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QHash<int, QString> hash1; hash1.setSharable(false); QVERIFY(hash1.isDetached()); diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index d3ace4016461103471398716b6db9937e703fb40..848fdae445b443e6a7952e03899a4aad7c80d40a 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -1027,7 +1027,7 @@ template<typename T> void tst_QLinkedList::constSharedNull() const { QLinkedList<T> list2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QLinkedList<T> list1; list1.setSharable(false); QVERIFY(list1.isDetached()); @@ -1059,7 +1059,7 @@ void tst_QLinkedList::constSharedNullComplex() const void tst_QLinkedList::setSharableInt() const { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QLinkedList<int> orglist; orglist << 0 << 1 << 2 << 3 << 4 << 5; int size = 6; diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index 1bb31afa9cde3d226cc09f26667c9d978863ae2c..87f0012002b7a38e9838c1917a9977fe91ac8b70 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -1892,7 +1892,7 @@ template<typename T> void tst_QList::constSharedNull() const { QList<T> list2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QList<T> list1; list1.setSharable(false); QVERIFY(list1.isDetached()); @@ -1926,7 +1926,7 @@ void tst_QList::constSharedNullComplex() const template <class T> void generateSetSharableData() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QTest::addColumn<QList<T> >("list"); QTest::addColumn<int>("size"); @@ -1938,7 +1938,7 @@ void generateSetSharableData() template <class T> void runSetSharableTest() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QFETCH(QList<T>, list); QFETCH(int, size); diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index bb6535b6350c2865df6af147ab76ab60d920b792..1fb9dc6d7d4690d8051f4eb98421f87a7a67037c 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -1012,7 +1012,7 @@ void tst_QMap::qmultimap_specific() void tst_QMap::const_shared_null() { QMap<int, QString> map2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QMap<int, QString> map1; map1.setSharable(false); QVERIFY(map1.isDetached()); @@ -1109,7 +1109,7 @@ const T &const_(const T &t) void tst_QMap::setSharable() { -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) QMap<int, QString> map; map.insert(1, "um"); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 87822bca6f853bed7a946bbb9315c35713cf033f..edcf4c72b61ecda35c2e0e8642c11c991c5e4c94 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -431,7 +431,7 @@ void tst_QVector::copyConstructor() const QVector<T> v2(v1); QCOMPARE(v1, v2); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v1; @@ -595,7 +595,7 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0)); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v(2); @@ -930,7 +930,7 @@ void tst_QVector::eraseEmpty() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v; @@ -969,7 +969,7 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v; @@ -1085,7 +1085,7 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue<T>::vector(12), *svc.copy); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v = SimpleValue<T>::vector(10); @@ -1172,7 +1172,7 @@ template<typename T> void tst_QVector::eraseReserved() const v.erase(v.begin() + 1, v.end() - 1); QCOMPARE(v.size(), 2); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section { QVector<T> v(10); @@ -1907,7 +1907,7 @@ void tst_QVector::resizePOD_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<int> nullNotShared; QVector<int> emptyNotShared(0, 5); @@ -1982,7 +1982,7 @@ void tst_QVector::resizeComplexMovable_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<Movable> nullNotShared; QVector<Movable> emptyNotShared(0, 'Q'); @@ -2061,7 +2061,7 @@ void tst_QVector::resizeComplex_data() const QTest::newRow("nonEmpty") << nonEmpty << 10; QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<Custom> nullNotShared; QVector<Custom> emptyNotShared(0, '0'); @@ -2500,7 +2500,7 @@ void tst_QVector::initializeListCustom() void tst_QVector::const_shared_null() { QVector<int> v2; -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section QVector<int> v1; v1.setSharable(false); @@ -2511,7 +2511,7 @@ void tst_QVector::const_shared_null() QVERIFY(!v2.isDetached()); } -#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) // ### Qt6 remove this section template<typename T> void tst_QVector::setSharable_data() const diff --git a/tests/auto/dbus/dbus.pro b/tests/auto/dbus/dbus.pro index 67cbc4bfef3a81f9e322fd7c82cbb7a93a0def3d..c5cddee5f5cf8b3749a6860139c8e9db10de993f 100644 --- a/tests/auto/dbus/dbus.pro +++ b/tests/auto/dbus/dbus.pro @@ -11,6 +11,7 @@ SUBDIRS+=\ qdbusconnection_no_app \ qdbusconnection_no_bus \ qdbusconnection_no_libdbus \ + qdbusconnection_spyhook \ qdbuscontext \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index f378091c58556d2663e56b47964e327cc804d271..9b16cf74a559c98cd5399afa305a6d0a077e01b9 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2015 Intel Corporation. +** Copyright (C) 2016 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -55,6 +55,31 @@ void MyObjectWithoutInterface::method(const QDBusMessage &msg) //qDebug() << msg; } +int tst_QDBusConnection::hookCallCount; +tst_QDBusConnection::tst_QDBusConnection() +{ +#ifdef HAS_HOOKSETUPFUNCTION +# define QCOMPARE_HOOKCOUNT(n) QCOMPARE(hookCallCount, n); hookCallCount = 0 +# define QVERIFY_HOOKCALLED() QCOMPARE(hookCallCount, 1); hookCallCount = 0 + hookSetupFunction(); +#else +# define QCOMPARE_HOOKCOUNT(n) qt_noop() +# define QVERIFY_HOOKCALLED() qt_noop() +#endif +} + +// called before each testcase +void tst_QDBusConnection::init() +{ + hookCallCount = 0; +} + +void tst_QDBusConnection::cleanup() +{ + QVERIFY2(!hookCallCount, "Unchecked call"); +} + + void tst_QDBusConnection::noConnection() { QDBusConnection con = QDBusConnection::connectToBus("unix:path=/dev/null", "testconnection"); @@ -359,9 +384,11 @@ void tst_QDBusConnection::registerObject() QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); QVERIFY(callMethod(con, path)); QCOMPARE(obj.path, path); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, path)); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerObjectWithInterface_data() @@ -393,9 +420,11 @@ void tst_QDBusConnection::registerObjectWithInterface() QVERIFY(callMethod(con, path, interface)); QCOMPARE(obj.path, path); QCOMPARE(obj.interface, interface); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, path, interface)); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerObjectPeer_data() @@ -432,6 +461,7 @@ void tst_QDBusConnection::registerObjectPeer() MyObject obj; QVERIFY(callMethodPeer(con, path)); QCOMPARE(obj.path, path); + QVERIFY_HOOKCALLED(); } QDBusConnection::connectToPeer(server.address(), "afterFoo"); @@ -441,6 +471,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } server.unregisterObject(); @@ -449,6 +480,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(!callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } server.registerObject(); @@ -457,6 +489,7 @@ void tst_QDBusConnection::registerObjectPeer() QDBusConnection con("foo"); QVERIFY(con.isConnected()); QVERIFY(callMethodPeer(con, path)); + QVERIFY_HOOKCALLED(); } QDBusConnection::disconnectFromPeer("foo"); @@ -478,10 +511,15 @@ void tst_QDBusConnection::registerObject2() // make sure nothing is using our paths: QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p2")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { // register one object at root: @@ -489,76 +527,99 @@ void tst_QDBusConnection::registerObject2() QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/")); QCOMPARE(obj.path, QString("/")); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); { // register one at an element: MyObject obj; QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); // re-register it somewhere else QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p2")); QCOMPARE(obj.path, QString("/p2")); + QVERIFY_HOOKCALLED(); } // make sure it's gone QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p2")); + QVERIFY_HOOKCALLED(); { // register at a deep path MyObject obj; QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethod(con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/q/r")); QCOMPARE(obj.path, QString("/p1/q/r")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethod(con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { MyObject obj; QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // try unregistering con.unregisterObject("/p1/q2"); QVERIFY(!callMethod(con, "/p1/q2")); + QVERIFY_HOOKCALLED(); // register it again QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethod(con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // now try removing things around it: con.unregisterObject("/p2"); QVERIFY(callMethod(con, "/p1/q2")); // unrelated object shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering just the parent shouldn't affect it + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q2/r"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/r"); QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + QVERIFY_HOOKCALLED(); // now remove it: con.unregisterObject("/p1", QDBusConnection::UnregisterTree); QVERIFY(!callMethod(con, "/p1/q2")); // we removed the full tree + QVERIFY_HOOKCALLED(); } } @@ -577,10 +638,15 @@ void tst_QDBusConnection::registerObjectPeer2() // make sure nothing is using our paths: QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p2")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { // register one object at root: @@ -588,76 +654,101 @@ void tst_QDBusConnection::registerObjectPeer2() QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/")); QCOMPARE(obj.path, QString("/")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); { // register one at an element: MyObject obj; QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); // re-register it somewhere else QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.path, QString("/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p2")); QCOMPARE(obj.path, QString("/p2")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p2")); + QVERIFY_HOOKCALLED(); { // register at a deep path MyObject obj; QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/q/r")); QCOMPARE(obj.path, QString("/p1/q/r")); + QVERIFY_HOOKCALLED(); } + // make sure it's gone QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + QVERIFY_HOOKCALLED(); { MyObject obj; QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // try unregistering con.unregisterObject("/p1/q2"); QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); + QVERIFY_HOOKCALLED(); // register it again QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); QCOMPARE(obj.path, QString("/p1/q2")); + QVERIFY_HOOKCALLED(); // now try removing things around it: con.unregisterObject("/p2"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unrelated object shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering just the parent shouldn't affect it + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q2/r"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/q"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + QVERIFY_HOOKCALLED(); con.unregisterObject("/p1/r"); QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + QVERIFY_HOOKCALLED(); // now remove it: con.unregisterObject("/p1", QDBusConnection::UnregisterTree); QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); // we removed the full tree + QVERIFY_HOOKCALLED(); } QDBusConnection::disconnectFromPeer("foo"); @@ -669,6 +760,7 @@ void tst_QDBusConnection::registerQObjectChildren() // make sure no one is there QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); { MyObject obj, *a, *b, *c, *cc; @@ -691,32 +783,47 @@ void tst_QDBusConnection::registerQObjectChildren() // make calls QVERIFY(callMethod(con, "/p1")); QCOMPARE(obj.callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/a")); QCOMPARE(a->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/b")); QCOMPARE(b->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/c")); QCOMPARE(c->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethod(con, "/p1/c/cc")); QCOMPARE(cc->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/d")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/abc")); + QVERIFY_HOOKCALLED(); // pull an object, see if it goes away: delete b; QVERIFY(!callMethod(con, "/p1/b")); + QVERIFY_HOOKCALLED(); delete c; QVERIFY(!callMethod(con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/a")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/b")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethod(con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::registerQObjectChildrenPeer() @@ -734,6 +841,7 @@ void tst_QDBusConnection::registerQObjectChildrenPeer() QDBusConnection srv_con = server.connection(); QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); { MyObject obj, *a, *b, *c, *cc; @@ -756,32 +864,47 @@ void tst_QDBusConnection::registerQObjectChildrenPeer() // make calls QVERIFY(callMethodPeer(srv_con, "/p1")); QCOMPARE(obj.callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/a")); QCOMPARE(a->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/b")); QCOMPARE(b->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/c")); QCOMPARE(c->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(callMethodPeer(srv_con, "/p1/c/cc")); QCOMPARE(cc->callCount, 1); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/d")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/abc")); + QVERIFY_HOOKCALLED(); // pull an object, see if it goes away: delete b; QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + QVERIFY_HOOKCALLED(); delete c; QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); } QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/a")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY_HOOKCALLED(); QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + QVERIFY_HOOKCALLED(); QDBusConnection::disconnectFromPeer("foo"); } @@ -827,20 +950,25 @@ void tst_QDBusConnection::callSelf() QVERIFY(connection.registerService(serviceName())); QDBusInterface interface(serviceName(), "/test"); QVERIFY(interface.isValid()); + QVERIFY_HOOKCALLED(); interface.call(QDBus::Block, "test0"); QCOMPARE(testObject.func, QString("test0")); + QVERIFY_HOOKCALLED(); interface.call(QDBus::Block, "test1", 42); QCOMPARE(testObject.func, QString("test1 42")); + QVERIFY_HOOKCALLED(); QDBusMessage reply = interface.call(QDBus::Block, "test2"); QCOMPARE(testObject.func, QString("test2")); QCOMPARE(reply.arguments().value(0).toInt(), 43); + QVERIFY_HOOKCALLED(); QDBusMessage msg = QDBusMessage::createMethodCall(serviceName(), "/test", QString(), "test3"); msg << 44; reply = connection.call(msg); QCOMPARE(reply.arguments().value(0).toInt(), 45); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::callSelfByAnotherName_data() @@ -908,12 +1036,14 @@ void tst_QDBusConnection::callSelfByAnotherName() QDBusMessage reply = con.call(msg, QDBus::Block, 1000); QVERIFY(reply.type() == QDBusMessage::ReplyMessage); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::multipleInterfacesInQObject() { QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(!callMethod(con, "/p1")); + QVERIFY_HOOKCALLED(); MyObject obj; con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots); @@ -924,6 +1054,7 @@ void tst_QDBusConnection::multipleInterfacesInQObject() QDBusMessage reply = con.call(msg, QDBus::Block); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); QVERIFY(reply.arguments().count() == 0); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::slotsWithLessParameters() @@ -981,6 +1112,7 @@ void tst_QDBusConnection::nestedCallWithCallback() QTestEventLoop::instance().enterLoop(15); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(signalsReceived, 1); + QCOMPARE_HOOKCOUNT(2); } void tst_QDBusConnection::serviceRegistrationRaceCondition() @@ -1145,6 +1277,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QCOMPARE(obj.callCount, 1); QCOMPARE(obj.lastMessage.service(), con2.baseService()); @@ -1162,6 +1295,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QCOMPARE(obj.callCount, 2); QCOMPARE(obj.lastMessage.service(), con2.baseService()); @@ -1179,6 +1313,7 @@ void tst_QDBusConnection::callVirtualObject() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY_HOOKCALLED(); QTest::qWait(100); QVERIFY(errorReply.isError()); QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject")); @@ -1207,6 +1342,7 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.lastMessage.interface(), QString()); QCOMPARE(obj.lastMessage.path(), path); QCOMPARE(obj.replyArguments, reply.arguments()); + QVERIFY_HOOKCALLED(); obj.replyArguments << QString("alien abduction"); QDBusMessage subPathMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "hello"); @@ -1216,6 +1352,7 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.lastMessage.interface(), QString()); QCOMPARE(obj.lastMessage.path(), childPath); QCOMPARE(obj.replyArguments, subPathReply.arguments()); + QVERIFY_HOOKCALLED(); } void tst_QDBusConnection::pendingCallWhenDisconnected() diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h index 720e484cc21743bfec527e7b61c5576f8c3d4703..b47daa118b626c22058258f18961ebe1008a7201 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2015 Intel Corporation. +** Copyright (C) 2016 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -79,11 +79,18 @@ class tst_QDBusConnection: public QObject Q_OBJECT int signalsReceived; +public: + static int hookCallCount; + tst_QDBusConnection(); + public slots: void oneSlot() { ++signalsReceived; } void exitLoop() { ++signalsReceived; QTestEventLoop::instance().exitLoop(); } void secondCallWithCallback(); + void init(); + void cleanup(); + private slots: void noConnection(); void connectToBus(); diff --git a/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro b/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro new file mode 100644 index 0000000000000000000000000000000000000000..020d30380d8edf6fb235e25b6dab2c4bc231e82c --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_spyhook/qdbusconnection_spyhook.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qdbusconnection_spyhook +QT = core dbus testlib +SOURCES += tst_qdbusconnection_spyhook.cpp +HEADERS += ../qdbusconnection/tst_qdbusconnection.h +DEFINES += SRCDIR=\\\"$$PWD/\\\" tst_QDBusConnection=tst_QDBusConnection_SpyHook +include(../dbus-testcase.pri) diff --git a/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp b/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa1c19920aa688c1d45a66f5e402ddd5a541531b --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_spyhook/tst_qdbusconnection_spyhook.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +#include <QtDBus/QDBusMessage> + +#define HAS_HOOKSETUPFUNCTION 1 +static void hookSetupFunction(); + +// Ugly hack, look away +#include "../qdbusconnection/tst_qdbusconnection.cpp" + +QT_BEGIN_NAMESPACE +extern Q_DBUS_EXPORT void qDBusAddSpyHook(void (*Hook)(const QDBusMessage&)); +QT_END_NAMESPACE + +static void hookFunction(const QDBusMessage &) +{ +// qDebug() << "hook called"; + ++tst_QDBusConnection::hookCallCount; +} + +static void hookSetupFunction() +{ + QT_PREPEND_NAMESPACE(qDBusAddSpyHook)(hookFunction); +} + +QTEST_MAIN(tst_QDBusConnection_SpyHook) diff --git a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp index 93d3eacb087be712bf76fed1169270f953e5a12e..91cae3272a3ed06ad9d55ce9170b5cfce2fd33d3 100644 --- a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp @@ -407,6 +407,7 @@ public: VirtualObject() :success(true) {} QString introspect(const QString &path) const { + Q_ASSERT(QThread::currentThread() == thread()); if (path == "/some/path/superNode") return "zitroneneis"; if (path == "/some/path/superNode/foo") @@ -417,6 +418,7 @@ public: } bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) { + Q_ASSERT(QThread::currentThread() == thread()); ++callCount; lastMessage = message; diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index 57fd5084beaf1c9bcf02cf347ffaaaf04c23a117..b628738fe3552da6ce1c094167f4af7ce881e651 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -41,6 +41,11 @@ #include <QtDBus/private/qdbusconnection_p.h> #include <QtDBus/private/qdbus_symbols_p.h> +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +# define DBUS_TYPE_UNIX_FD_AS_STRING "h" +#endif + static const char serviceName[] = "org.qtproject.autotests.qpong"; static const char objectPath[] = "/org/qtproject/qpong"; static const char *interfaceName = serviceName; @@ -1088,9 +1093,6 @@ static bool canSendUnixFd(DBusConnection *connection) can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); #endif -#ifndef DBUS_TYPE_UNIX_FD -# define DBUS_TYPE_UNIX_FD int('h') -#endif return can_send_type && can_send_type(connection, DBUS_TYPE_UNIX_FD); } diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST index 3e936aebf69a02e05f381abb37436645d83e9bca..fb8455e6d3978153a380e8992f70d828198cf50b 100644 --- a/tests/auto/network/socket/qudpsocket/BLACKLIST +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -6,3 +6,15 @@ osx osx [multicast:same bind, group ipv4 address] osx +[writeDatagramToNonExistingPeer] +windows +[asyncReadDatagram] +windows +[multicastLeaveAfterClose] +osx +[readyRead] +osx +[readyReadForEmptyDatagram] +osx +[asyncReadDatagram] +osx diff --git a/tests/auto/network/socket/qudpsocket/test/test.pro b/tests/auto/network/socket/qudpsocket/test/test.pro index 8ad16c652d0504057f1f5762e97169af3b033e22..e4812416dc7a3475059806ea85ee2e6dfddd867a 100644 --- a/tests/auto/network/socket/qudpsocket/test/test.pro +++ b/tests/auto/network/socket/qudpsocket/test/test.pro @@ -22,5 +22,3 @@ wince* { } TARGET = tst_qudpsocket - -CONFIG+=insignificant_test # QTBUG-25367, QTBUG-25368 diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 6446fec51097270f0bc76f97f0a6cd914617ed6a..09a90508d33bda77a83f89f023a161f569270395 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -156,8 +156,9 @@ void tst_Cmptest::compare_unregistered_enums() void tst_Cmptest::compare_registered_enums() { - QCOMPARE(Qt::ArrowCursor, Qt::ArrowCursor); - QCOMPARE(Qt::ArrowCursor, Qt::BusyCursor); + // use an enum that doesn't start at 0 + QCOMPARE(Qt::Monday, Qt::Monday); + QCOMPARE(Qt::Monday, Qt::Sunday); } static bool boolfunc() { return true; } diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 36929cec6bca60d2bd208f4959a714687653c514..8f02e2e1ad11500d494853c9fdaf853c2d5f0b24 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -16,8 +16,8 @@ <TestFunction name="compare_registered_enums"> <Incident type="fail" file="tst_cmptest.cpp" line="160"> <Description><![CDATA[Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor]]></Description> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 70c54704f94b10ff4d91e5cc92201d8928c6631b..920565850900f9bb1af40f8791518ac3e6dbaea9 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -4,8 +4,8 @@ PASS : tst_Cmptest::initTestCase() FAIL! : tst_Cmptest::compare_unregistered_enums() Compared values are not the same Loc: [tst_cmptest.cpp(154)] FAIL! : tst_Cmptest::compare_registered_enums() Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday Loc: [tst_cmptest.cpp(160)] PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index 9437e8e4b7c3ade760bb55e12113aa93ce981b64..55a97062276dea740b87900348a31f18148e5d40 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -18,8 +18,8 @@ <TestFunction name="compare_registered_enums"> <Incident type="fail" file="tst_cmptest.cpp" line="160"> <Description><![CDATA[Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor]]></Description> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index fa970d41726cfb50b8b5e770fbd080fc16f4b5e0..c26f723cfc0049ae0b899d32b7586161226dcb27 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -11,8 +11,8 @@ </testcase> <testcase result="fail" name="compare_registered_enums"> <failure message="Compared values are not the same - Actual (Qt::ArrowCursor): ArrowCursor - Expected (Qt::BusyCursor) : BusyCursor" result="fail"/> + Actual (Qt::Monday): Monday + Expected (Qt::Sunday): Sunday" result="fail"/> </testcase> <testcase result="pass" name="compare_boolfuncs"/> <testcase result="pass" name="compare_pointerfuncs"/> diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index 42e2bd09a5e7886902cc8694961908d75f5c8865..05f42cf685bdd9d24eea6f1206547440a9124a60 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -569,6 +569,22 @@ void tst_QFiledialog::completer() if (expectedFile.startsWith(input, caseSensitivity)) ++expected; } + // The temporary dir may create a node in QFileSystemModel + // which will bypass filters. If the path to the temporary + // dir contains an element which should be a subdirectory + // of x dir, but which is not listed, then take it into + // accont. + if (!tempDir.isNull()) { + QString xPath = x.absolutePath(); + if (!xPath.endsWith(QLatin1Char('/'))) + xPath.append(QLatin1Char('/')); + QString tmpPath = tempDir->path(); + if (tmpPath.startsWith(xPath)) { + QString bypassedDirName = tmpPath.mid(xPath.size()).section(QLatin1Char('/'), 0, 0); + if (!expectedFiles.contains(bypassedDirName)) + ++expected; + } + } } QTRY_COMPARE(cModel->rowCount(), expected); diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 19b1d0e7c8c0c0cad35884e5d934118068628ae5..b27943f071ceb3675441b0d8fa55c7107f52501f 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -126,6 +126,8 @@ private slots: void doNotUnwatchOnFailedRmdir(); void specialFiles(); + void fileInfo(); + protected: bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList()); @@ -1146,6 +1148,25 @@ void tst_QFileSystemModel::specialFiles() QTRY_VERIFY(!fileListUnderIndex(&model, rootIndex).contains(testFileName)); } +void tst_QFileSystemModel::fileInfo() +{ + QFileSystemModel model; + QModelIndex idx; + + QVERIFY(model.fileInfo(idx).filePath().isEmpty()); + + const QString dirPath = flatDirTestPath; + QDir dir(dirPath); + const QString subdir = QStringLiteral("subdir"); + QVERIFY(dir.mkdir(subdir)); + const QString subdirPath = dir.absoluteFilePath(subdir); + + idx = model.setRootPath(subdirPath); + QCOMPARE(model.fileInfo(idx), QFileInfo(subdirPath)); + idx = model.setRootPath(dirPath); + QCOMPARE(model.fileInfo(idx), QFileInfo(dirPath)); +} + QTEST_MAIN(tst_QFileSystemModel) #include "tst_qfilesystemmodel.moc" diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index e5abd6bc463fdb7068d956ed2981bcce4c4c9de8..2bb3f6a1369fbd39bccd969a6378d02d076e0e25 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -203,6 +203,7 @@ private slots: void taskQTBUG_8777_scrollToSpans(); void taskQTBUG_10169_sizeHintForRow(); void taskQTBUG_30653_doItemsLayout(); + void taskQTBUG_50171_selectRowAfterSwapColumns(); #ifndef QT_NO_WHEELEVENT void mouseWheel_data(); @@ -4476,5 +4477,40 @@ void tst_QTableView::taskQTBUG_30653_doItemsLayout() QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset); } +void tst_QTableView::taskQTBUG_50171_selectRowAfterSwapColumns() +{ + { + QtTestTableView tableView; + QtTestTableModel model(2, 3); + tableView.setModel(&model); + + tableView.horizontalHeader()->swapSections(1, 2); + tableView.horizontalHeader()->hideSection(0); + tableView.selectRow(1); + + QItemSelectionModel* tableSelectionModel = tableView.selectionModel(); + QCOMPARE(tableSelectionModel->isRowSelected(1, QModelIndex()), true); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 0)), false); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 1)), false); + QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 2)), false); + } + + { + QtTestTableView tableView; + QtTestTableModel model(3, 2); + tableView.setModel(&model); + + tableView.verticalHeader()->swapSections(1, 2); + tableView.verticalHeader()->hideSection(0); + tableView.selectColumn(1); + + QItemSelectionModel* sModel = tableView.selectionModel(); + QCOMPARE(sModel->isColumnSelected(1, QModelIndex()), true); + QCOMPARE(sModel->isSelected(tableView.model()->index(0, 0)), false); + QCOMPARE(sModel->isSelected(tableView.model()->index(1, 0)), false); + QCOMPARE(sModel->isSelected(tableView.model()->index(2, 0)), false); + } +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 4563da8d482c58af77d8f525e2e64dd0a360d284..8fc882112e42f88a6195b0431973b1eed38980dc 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -1,10 +1,8 @@ # OSX QTBUG-25300 QTBUG-45502 [normalGeometry] ubuntu-14.04 -osx [saveRestoreGeometry] ubuntu-14.04 -osx [restoreVersion1Geometry] ubuntu-14.04 osx @@ -20,20 +18,12 @@ ubuntu-14.04 ubuntu-14.04 [largerThanScreen_QTBUG30142] ubuntu-14.04 -[windowState] -osx [showMaximized] osx [setGeometry] osx -[stackUnder] -osx [raise] osx -[widgetAt] -osx -[sheetOpacity] -osx [resizeEvent] osx [setWindowGeometry] @@ -50,12 +40,6 @@ osx osx [render_systemClip] osx -[update] -osx -[doubleRepaint] -osx -[childAt_unifiedToolBar] -osx [showMinimizedKeepsFocus] osx-10.10 [moveWindowInShowEvent:1] diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index c2b01ea087b9cb5b43b824449b62f4c62c0a8156..10d32472be32bc2f9920e078b6fc982f0fea361e 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -269,7 +269,6 @@ private slots: void widgetAt(); #ifdef Q_OS_OSX - void sheetOpacity(); void setMask(); #endif void optimizedResizeMove(); @@ -435,7 +434,6 @@ private slots: void movedAndResizedAttributes(); void childAt(); #ifdef Q_OS_OSX - void childAt_unifiedToolBar(); void taskQTBUG_11373(); #endif void taskQTBUG_17333_ResizeInfiniteRecursion(); @@ -1877,6 +1875,10 @@ void tst_QWidget::activation() void tst_QWidget::windowState() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("xcb")) QSKIP("X11: Many window managers do not support window state properly, which causes this test to fail."); if (m_platform == QStringLiteral("wayland")) @@ -2088,6 +2090,10 @@ void tst_QWidget::showMaximized() void tst_QWidget::showFullScreen() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); QWidget plain; @@ -2447,6 +2453,10 @@ void tst_QWidget::reparent() // Qt/Embedded does it differently. void tst_QWidget::icon() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + QPixmap p(20,20); p.fill(Qt::red); testWidget->setWindowIcon(p); @@ -2498,6 +2508,10 @@ void tst_QWidget::hideWhenFocusWidgetIsChild() void tst_QWidget::normalGeometry() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); QWidget parent; @@ -2848,8 +2862,6 @@ void tst_QWidget::raise() } } -// Cocoa has no Z-Order for views, we hack it, but it results in paint events. -#ifndef QT_OS_MAC void tst_QWidget::lower() { QScopedPointer<QWidget> parent(new QWidget); @@ -2911,12 +2923,13 @@ void tst_QWidget::lower() list2 << child4 << child1 << child2 << child3; QCOMPARE(parent->children(), list2); } -#endif -// Cocoa has no Z-Order for views, we hack it, but it results in paint events. -#ifndef QT_OS_MAC void tst_QWidget::stackUnder() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: Cocoa has no Z-Order for views, we hack it, but it results in paint events."); +#endif + QScopedPointer<QWidget> parent(new QWidget); parent->setObjectName(QLatin1String("stackUnder")); parent->setWindowTitle(parent->objectName()); @@ -2997,7 +3010,6 @@ void tst_QWidget::stackUnder() child->reset(); } } -#endif void drawPolygon(QPaintDevice *dev, int w, int h) { @@ -3086,6 +3098,10 @@ void tst_QWidget::testContentsPropagation() void tst_QWidget::saveRestoreGeometry() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); const QPoint position = m_availableTopLeft + QPoint(100, 100); @@ -3311,6 +3327,10 @@ void tst_QWidget::restoreVersion1Geometry() void tst_QWidget::widgetAt() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); Q_CHECK_PAINTEVENTS @@ -3524,17 +3544,6 @@ void tst_QWidget::testDeletionInEventHandlers() } #ifdef Q_OS_OSX -void tst_QWidget::sheetOpacity() -{ - QWidget tmpWindow; - QWidget sheet(&tmpWindow, Qt::Sheet); - tmpWindow.show(); - sheet.show(); - QCOMPARE(int(sheet.windowOpacity() * 255), 242); // 95% - sheet.setParent(0, Qt::Dialog); - QCOMPARE(int(sheet.windowOpacity() * 255), 255); -} - class MaskedPainter : public QWidget { public: @@ -4176,6 +4185,10 @@ void tst_QWidget::showHideEventWhileMinimize() void tst_QWidget::update() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + QTest::qWait(10); // Wait for the initStuff to do it's stuff. Q_CHECK_PAINTEVENTS @@ -5165,10 +5178,13 @@ void tst_QWidget::showAndMoveChild() VERIFY_COLOR(parent, QRegion(parent.rect()) - child.geometry(), Qt::red); } -// Cocoa only has rect granularity. -#ifndef QT_OS_MAC + void tst_QWidget::subtractOpaqueSiblings() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: Cocoa only has rect granularity."); +#endif + QWidget w; w.setGeometry(50, 50, 300, 300); @@ -5201,7 +5217,6 @@ void tst_QWidget::subtractOpaqueSiblings() QRegion(medium->geometry().translated(large->pos())) - tall->geometry()); } -#endif void tst_QWidget::deleteStyle() { @@ -5243,6 +5258,10 @@ public slots: void tst_QWidget::multipleToplevelFocusCheck() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + if (m_platform == QStringLiteral("wayland")) QSKIP("Wayland: This fails. Figure out why."); TopLevelFocusCheck w1; @@ -7916,6 +7935,10 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974"); +#endif + #if defined(Q_OS_OSX) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); @@ -9432,10 +9455,6 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() void tst_QWidget::movedAndResizedAttributes() { -#if defined (Q_OS_OSX) - QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); - QVERIFY(false); -#else // Use Qt::Tool as fully decorated windows have a minimum width of 160 on QWidget w(0, Qt::Tool); w.show(); @@ -9481,7 +9500,6 @@ void tst_QWidget::movedAndResizedAttributes() w.resize(100, 100); QVERIFY(w.testAttribute(Qt::WA_Moved)); QVERIFY(w.testAttribute(Qt::WA_Resized)); -#endif } void tst_QWidget::childAt() @@ -9540,46 +9558,11 @@ void tst_QWidget::childAt() } #ifdef Q_OS_OSX -void tst_QWidget::childAt_unifiedToolBar() -{ - QLabel *label = new QLabel(QLatin1String("foo")); - QToolBar *toolBar = new QToolBar; - toolBar->addWidget(new QLabel("dummy")); - toolBar->addWidget(label); - - QMainWindow mainWindow; - mainWindow.addToolBar(toolBar); - mainWindow.show(); - - // Calculate the top-left corner of the tool bar and the label (in mainWindow's coordinates). - QPoint labelTopLeft = label->mapTo(&mainWindow, QPoint()); - QPoint toolBarTopLeft = toolBar->mapTo(&mainWindow, QPoint()); - - QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); - QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); - - // Enable unified tool bars. - mainWindow.setUnifiedTitleAndToolBarOnMac(true); - QTest::qWait(50); - - // The tool bar is now in the "non-client" area of QMainWindow, i.e. - // outside the mainWindow's rect(), and since mapTo et al. doesn't work - // in that case (see commit 35667fd45ada49269a5987c235fdedfc43e92bb8), - // we use mapToGlobal/mapFromGlobal to re-calculate the corners. - QPoint oldToolBarTopLeft = toolBarTopLeft; - toolBarTopLeft = mainWindow.mapFromGlobal(toolBar->mapToGlobal(QPoint())); - QVERIFY2(toolBarTopLeft != oldToolBarTopLeft, - msgComparisonFailed(toolBarTopLeft, "!=", oldToolBarTopLeft)); - QVERIFY2(toolBarTopLeft.y() < 0, - msgComparisonFailed(toolBarTopLeft.y(), "<", 0)); - labelTopLeft = mainWindow.mapFromGlobal(label->mapToGlobal(QPoint())); - - QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); - QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); -} void tst_QWidget::taskQTBUG_11373() { + QSKIP("QTBUG-52974"); + QScopedPointer<QMainWindow> myWindow(new QMainWindow); QWidget * center = new QWidget(); myWindow -> setCentralWidget(center); @@ -9595,6 +9578,7 @@ void tst_QWidget::taskQTBUG_11373() // The drawer should still not be visible, since we haven't shown it. QCOMPARE(drawer->isVisible(), false); } + #endif void tst_QWidget::taskQTBUG_17333_ResizeInfiniteRecursion() @@ -10442,6 +10426,9 @@ public: // when mousing over it. void tst_QWidget::taskQTBUG_27643_enterEvents() { +#ifdef Q_OS_OSX + QSKIP("QTBUG-52974: this test can crash!"); +#endif // Move the mouse cursor to a safe location so it won't interfere QCursor::setPos(m_safeCursorPos); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 57be110c15c30d09f3151f26b4a6f062ad431f23..f832ebfee0c145891c5f0be2f46401c31ed2a9e1 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -499,7 +499,7 @@ void tst_QMdiArea::subWindowActivated2() mdiArea.show(); mdiArea.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&mdiArea)); - QTRY_COMPARE(spy.count(), 1); + QTRY_VERIFY(!spy.isEmpty()); // Normally 1, but 2 events might be received on some X11 window managers QVERIFY(mdiArea.currentSubWindow()); QTRY_COMPARE(mdiArea.activeSubWindow(), activeSubWindow); spy.clear(); diff --git a/tests/baselineserver/src/baselineserver.pro b/tests/baselineserver/src/baselineserver.pro index 519cacea9cf5afe41d4106b39b708d4eb1281478..a77014c1e60838d613df28c77e342709451330f0 100644 --- a/tests/baselineserver/src/baselineserver.pro +++ b/tests/baselineserver/src/baselineserver.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-08-11T11:51:09 -# -#------------------------------------------------- - QT += core network # gui needed for QImage diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index bec098d462635d462aabaf469baee1ae9f9663ef..8e77a321dd76e2935e8eecd7e1b73a1b31ab3b4d 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -24,6 +24,7 @@ qnetworkaccessmanager/qget \ qnetworkconfigurationmanager \ qnetworkconfiguration \ qnetworkreply \ +qstorageinfo \ qscreen \ qssloptions \ qsslsocket \ diff --git a/tests/manual/qcursor/allcursors/allcursors.pro b/tests/manual/qcursor/allcursors/allcursors.pro index c85ef861c2f26b97eb2b8c828a3c48d590539db9..72bec669402cfbd8af0e84d992a240fbb4ea8dc3 100644 --- a/tests/manual/qcursor/allcursors/allcursors.pro +++ b/tests/manual/qcursor/allcursors/allcursors.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2009-08-05T17:13:23 -# -#------------------------------------------------- - TARGET = tst_allcursors TEMPLATE = app QT = core gui widgets diff --git a/tests/manual/qcursor/grab_override/grab_override.pro b/tests/manual/qcursor/grab_override/grab_override.pro index d163a726c3860628500ebca83898d8da8821c671..f105fa11e0bae3ce58dfe016dec3caa3b37fddaa 100644 --- a/tests/manual/qcursor/grab_override/grab_override.pro +++ b/tests/manual/qcursor/grab_override/grab_override.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2009-08-05T17:13:23 -# -#------------------------------------------------- - TARGET = t_cursors TEMPLATE = app QT = core gui widgets diff --git a/tests/manual/qstorageinfo/main.cpp b/tests/manual/qstorageinfo/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c106ff45b41a04bc9fc584a8372df1f11acbf96 --- /dev/null +++ b/tests/manual/qstorageinfo/main.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +#include <QtCore/QCoreApplication> +#include <QtCore/QStorageInfo> + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + QList<QStorageInfo> volumes; + QStringList args = a.arguments(); + args.takeFirst(); // skip application name + + foreach (const QString &path, args) { + QStorageInfo info(path); + if (!info.isValid()) { + // no error string... + fprintf(stderr, "Could not get info on %s\n", qPrintable(path)); + return 1; + } + volumes << info; + } + + if (volumes.isEmpty()) + volumes = QStorageInfo::mountedVolumes(); + + // Sample output: + // Filesystem (Type) Size Available BSize Label Mounted on + // /dev/sda2 (ext4) RO 388480 171218 1024 /boot + // /dev/mapper/system-root (btrfs) RW + // 214958080 39088272 4096 / + // /dev/disk1s2 (hfs) RW 488050672 419909696 4096 Macintosh HD2 /Volumes/Macintosh HD2 + + printf("Filesystem (Type) Size Available BSize Label Mounted on\n"); + foreach (const QStorageInfo &info, volumes) { + QByteArray fsAndType = info.device(); + if (info.fileSystemType() != fsAndType) + fsAndType += " (" + info.fileSystemType() + ')'; + + printf("%-19s R%c ", fsAndType.constData(), info.isReadOnly() ? 'O' : 'W'); + if (fsAndType.size() > 19) + printf("\n%23s", ""); + + printf("%10llu %10llu %5u ", info.bytesTotal() / 1024, info.bytesFree() / 1024, info.blockSize()); + printf("%-16s %s\n", qPrintable(info.name()), qPrintable(info.rootPath())); + } + + return 0; +} diff --git a/tests/manual/qstorageinfo/qstorageinfo.pro b/tests/manual/qstorageinfo/qstorageinfo.pro new file mode 100644 index 0000000000000000000000000000000000000000..25acd24c806b53e33c40af719e7b58edb7c6b31c --- /dev/null +++ b/tests/manual/qstorageinfo/qstorageinfo.pro @@ -0,0 +1,4 @@ +QT = core +CONFIG += console +CONFIG -= app_bundle +SOURCES += main.cpp diff --git a/tests/manual/qtbug-8933/qtbug-8933.pro b/tests/manual/qtbug-8933/qtbug-8933.pro index 0d8bfcc797a4d1c4a72ea02617d41b1b76ef20fb..d92aa3ab66803fc8659629e44d04435f38d2d32f 100644 --- a/tests/manual/qtbug-8933/qtbug-8933.pro +++ b/tests/manual/qtbug-8933/qtbug-8933.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-03-16T14:40:16 -# -#------------------------------------------------- - TARGET = qtbug-8933 TEMPLATE = app QT += widgets