diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-18 20:45:53 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-18 20:50:35 +0100 |
commit | 4fe2fbcf827ae6bec976b0b8dcaa5d14bd05dc33 (patch) | |
tree | d1ba753b45b09b417a9447ebdfe2fa6fc47dba69 | |
parent | c1da6347e8d3ba73de20ab8fb3e50ec3359b75ac (diff) | |
parent | 4889269ff0fb37130b332863e82dd7c19564116c (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
This also reverts commit 018e670a26ff5a61b949100ae080f5e654e7bee8.
The change was introduced in 5.6. After the refactoring, 14960f52,
in 5.7 branch and a merge, it is not needed any more.
Conflicts:
.qmake.conf
src/corelib/io/qstandardpaths_mac.mm
src/corelib/tools/qsharedpointer_impl.h
tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
Change-Id: If4fdff0ebf2b9b5df9f9db93ea0022d5ee3da2a4
130 files changed, 1166 insertions, 361 deletions
diff --git a/config.tests/unix/journald/journald.pro b/config.tests/unix/journald/journald.pro index 2bb50ceb71..ea765642e6 100644 --- a/config.tests/unix/journald/journald.pro +++ b/config.tests/unix/journald/journald.pro @@ -1,6 +1,10 @@ SOURCES = journald.c CONFIG += link_pkgconfig -PKGCONFIG_PRIVATE += libsystemd-journal + +packagesExist(libsystemd): \ + PKGCONFIG_PRIVATE += libsystemd +else: \ + PKGCONFIG_PRIVATE += libsystemd-journal CONFIG -= qt @@ -2872,7 +2872,7 @@ if [ -z "$PLATFORM" ]; then PLATFORM=ultrix-g++ ;; FreeBSD:*) - PLATFORM=freebsd-g++ + PLATFORM=freebsd-clang PLATFORM_NOTES=" - Also available for FreeBSD: freebsd-icc " diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index e543ea65e6..bb28af975f 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -194,7 +194,7 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support android: CONFIG += qt_android_deps no_linker_version_script !header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { - verscript = $$OUT_PWD/$${TARGET}.version + verscript = $${TARGET}.version QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript internal_module { @@ -219,16 +219,20 @@ android: CONFIG += qt_android_deps no_linker_version_script } # Add a post-processing step to replace the @FILE:filename@ - verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in > $@ - verscriptprocess.target = $$verscript + verscript_in = $${verscript}.in + verscriptprocess.name = linker version script ${QMAKE_FILE_BASE} + verscriptprocess.input = verscript_in + verscriptprocess.CONFIG += no_link target_predeps for(header, SYNCQT.PRIVATE_HEADER_FILES): \ verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header - verscriptprocess.depends += $${verscript}.in - QMAKE_EXTRA_TARGETS += verscriptprocess - PRE_TARGETDEPS += $$verscript - verscript = $${verscript}.in + verscriptprocess.output = $$verscript + verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@ + silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands + QMAKE_EXTRA_COMPILERS += verscriptprocess + + verscript = $$verscript_in } - write_file($$verscript, verscript_content)|error("Aborting.") + write_file($$OUT_PWD/$$verscript, verscript_content)|error("Aborting.") unset(current) unset(previous) unset(verscript) diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/freebsd-clang/qmake.conf index 9d9815a7b3..7f18bbb721 100644 --- a/mkspecs/unsupported/freebsd-clang/qmake.conf +++ b/mkspecs/freebsd-clang/qmake.conf @@ -30,7 +30,7 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../../common/gcc-base-unix.conf) -include(../../common/clang.conf) +include(../common/gcc-base-unix.conf) +include(../common/clang.conf) load(qt_config) diff --git a/mkspecs/freebsd-g++/qplatformdefs.h b/mkspecs/freebsd-clang/qplatformdefs.h index d92eadd7e8..d92eadd7e8 100644 --- a/mkspecs/freebsd-g++/qplatformdefs.h +++ b/mkspecs/freebsd-clang/qplatformdefs.h diff --git a/mkspecs/freebsd-g++/qmake.conf b/mkspecs/unsupported/freebsd-g++/qmake.conf index 282b6bdfa7..527a94870c 100644 --- a/mkspecs/freebsd-g++/qmake.conf +++ b/mkspecs/unsupported/freebsd-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = freebsd bsd -include(../common/unix.conf) +include(../../common/unix.conf) QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE @@ -29,6 +29,6 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../common/gcc-base-unix.conf) -include(../common/g++-unix.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) load(qt_config) diff --git a/mkspecs/unsupported/freebsd-clang/qplatformdefs.h b/mkspecs/unsupported/freebsd-g++/qplatformdefs.h index 41f1da615c..a3086b973a 100644 --- a/mkspecs/unsupported/freebsd-clang/qplatformdefs.h +++ b/mkspecs/unsupported/freebsd-g++/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../../freebsd-g++/qplatformdefs.h" +#include "../../freebsd-clang/qplatformdefs.h" diff --git a/mkspecs/freebsd-g++46/qmake.conf b/mkspecs/unsupported/freebsd-g++46/qmake.conf index b930fca78b..11041dee3d 100644 --- a/mkspecs/freebsd-g++46/qmake.conf +++ b/mkspecs/unsupported/freebsd-g++46/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = freebsd bsd -include(../common/unix.conf) +include(../../common/unix.conf) QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE @@ -29,8 +29,8 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../common/gcc-base-unix.conf) -include(../common/g++-unix.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) # Redefined here because g++-base.conf sets QMAKE_CC and QMAKE_CXX # to gcc and g++, respectively. diff --git a/mkspecs/freebsd-g++46/qplatformdefs.h b/mkspecs/unsupported/freebsd-g++46/qplatformdefs.h index e2f2d7c85b..a3086b973a 100644 --- a/mkspecs/freebsd-g++46/qplatformdefs.h +++ b/mkspecs/unsupported/freebsd-g++46/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../freebsd-g++/qplatformdefs.h" +#include "../../freebsd-clang/qplatformdefs.h" diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index a8c8f65d37..78ea489ebc 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -25,6 +25,10 @@ ANDROID_PERMISSIONS = \ android.permission.INTERNET \ android.permission.WRITE_EXTERNAL_STORAGE +# QtCore can't be compiled with -Wl,-no-undefined because it uses the "environ" +# variable and on FreeBSD, this variable is in the final executable itself +freebsd: QMAKE_LFLAGS_NOUNDEF = + load(qt_module) load(qfeatures) diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index aa4945f90e..dd846955f6 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -53,7 +53,10 @@ slog2 { journald { CONFIG += link_pkgconfig - PKGCONFIG_PRIVATE += libsystemd-journal + packagesExist(libsystemd): \ + PKGCONFIG_PRIVATE += libsystemd + else: \ + PKGCONFIG_PRIVATE += libsystemd-journal DEFINES += QT_USE_JOURNALD } diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h index f9062a98fb..ef3da7c658 100644 --- a/src/corelib/global/qversiontagging.h +++ b/src/corelib/global/qversiontagging.h @@ -65,11 +65,7 @@ QT_BEGIN_NAMESPACE #elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID) # if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL)) # if defined(Q_PROCESSOR_X86_64) // x86-64 or x32 -# if defined(__code_model_large__) -# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" -# else -# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n" -# endif +# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # else // x86 # define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # endif diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 48b915eef8..c7144d2c6b 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -49,13 +49,8 @@ QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipe, QObject * parent) quitNow(false), hasWritten(false) { -#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600) DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(), &writePipe, 0, FALSE, DUPLICATE_SAME_ACCESS); -#else - Q_UNUSED(pipe); - writePipe = GetCurrentProcess(); -#endif } QWindowsPipeWriter::~QWindowsPipeWriter() @@ -66,9 +61,7 @@ QWindowsPipeWriter::~QWindowsPipeWriter() lock.unlock(); if (!wait(30000)) terminate(); -#if !defined(Q_OS_WINCE) || (_WIN32_WCE >= 0x600) CloseHandle(writePipe); -#endif } bool QWindowsPipeWriter::waitForWrite(int msecs) @@ -159,7 +152,6 @@ void QWindowsPipeWriter::run() msleep(100); continue; } -#ifndef Q_OS_WINCE if (writeError != ERROR_IO_PENDING) { qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed."); return; @@ -168,9 +160,6 @@ void QWindowsPipeWriter::run() qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed."); return; } -#else - return; -#endif } totalWritten += written; #if defined QPIPEWRITER_DEBUG diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp index 3f599e464f..d7745ae1b6 100644 --- a/src/corelib/io/qwinoverlappedionotifier.cpp +++ b/src/corelib/io/qwinoverlappedionotifier.cpp @@ -81,6 +81,22 @@ QT_BEGIN_NAMESPACE or WriteFile() is ignored and can be used for other purposes. \warning This class is only available on Windows. + + Due to peculiarities of the Windows I/O completion port API, users of + QWinOverlappedIoNotifier must pay attention to the following restrictions: + \list + \li File handles with a QWinOverlappedIoNotifer are assigned to an I/O + completion port until the handle is closed. It is impossible to + disassociate the file handle from the I/O completion port. + \li There can be only one QWinOverlappedIoNotifer per file handle. Creating + another QWinOverlappedIoNotifier for that file, even with a duplicated + handle, will fail. + \li Certain Windows API functions are unavailable for file handles that are + assigned to an I/O completion port. This includes the functions + \c{ReadFileEx} and \c{WriteFileEx}. + \endlist + See also the remarks in the MSDN documentation for the + \c{CreateIoCompletionPort} function. */ struct IOResult diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 5f6484728a..4c628ff1fe 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -795,7 +795,11 @@ public: if (reserve) { if (reserve < 128) reserve = 128; - size = qMax(size + reserve, size *2); + size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize)); + if (size > Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return 0; + } } char *raw = (char *)malloc(size); Q_CHECK_PTR(raw); diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 3eecc458aa..d4cc4b81df 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -262,8 +262,45 @@ QJsonArray QJsonArray::fromStringList(const QStringList &list) QJsonArray QJsonArray::fromVariantList(const QVariantList &list) { QJsonArray array; - for (QVariantList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) - array.append(QJsonValue::fromVariant(*it)); + if (list.isEmpty()) + return array; + + array.detach2(1024); + + QVector<QJsonPrivate::Value> values; + values.resize(list.size()); + QJsonPrivate::Value *valueData = values.data(); + uint currentOffset = sizeof(QJsonPrivate::Base); + + for (int i = 0; i < list.size(); ++i) { + QJsonValue val = QJsonValue::fromVariant(list.at(i)); + + bool latinOrIntValue; + int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue); + + if (!array.detach2(valueSize)) + return QJsonArray(); + + QJsonPrivate::Value *v = valueData + i; + v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t); + v->latinOrIntValue = latinOrIntValue; + v->latinKey = false; + v->value = QJsonPrivate::Value::valueToStore(val, currentOffset); + if (valueSize) + QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue); + + currentOffset += valueSize; + array.a->size = currentOffset; + } + + // write table + array.a->tableOffset = currentOffset; + if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size())) + return QJsonArray(); + memcpy(array.a->table(), values.constData(), values.size()*sizeof(uint)); + array.a->length = values.size(); + array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size(); + return array; } @@ -388,7 +425,7 @@ void QJsonArray::removeAt(int i) if (!a || i < 0 || i >= (int)a->length) return; - detach(); + detach2(); a->removeItems(i, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u) @@ -448,7 +485,8 @@ void QJsonArray::insert(int i, const QJsonValue &value) bool compressed; int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - detach(valueSize + sizeof(QJsonPrivate::Value)); + if (!detach2(valueSize + sizeof(QJsonPrivate::Value))) + return; if (!a->length) a->tableOffset = sizeof(QJsonPrivate::Array); @@ -498,7 +536,8 @@ void QJsonArray::replace(int i, const QJsonValue &value) bool compressed; int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed); - detach(valueSize); + if (!detach2(valueSize)) + return; if (!a->length) a->tableOffset = sizeof(QJsonPrivate::Array); @@ -1129,21 +1168,38 @@ bool QJsonArray::operator!=(const QJsonArray &other) const */ void QJsonArray::detach(uint reserve) { + Q_UNUSED(reserve) + Q_ASSERT(!reserve); + detach2(0); +} + +/*! + \internal + */ +bool QJsonArray::detach2(uint reserve) +{ if (!d) { + if (reserve >= QJsonPrivate::Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return false; + } d = new QJsonPrivate::Data(reserve, QJsonValue::Array); a = static_cast<QJsonPrivate::Array *>(d->header->root()); d->ref.ref(); - return; + return true; } if (reserve == 0 && d->ref.load() == 1) - return; + return true; QJsonPrivate::Data *x = d->clone(a, reserve); + if (!x) + return false; x->ref.ref(); if (!d->ref.deref()) delete d; d = x; a = static_cast<QJsonPrivate::Array *>(d->header->root()); + return true; } /*! @@ -1154,7 +1210,7 @@ void QJsonArray::compact() if (!d || !d->compactionCounter) return; - detach(); + detach2(); d->compact(); a = static_cast<QJsonPrivate::Array *>(d->header->root()); } diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h index 899b675600..3b6fa37cfa 100644 --- a/src/corelib/json/qjsonarray.h +++ b/src/corelib/json/qjsonarray.h @@ -191,10 +191,10 @@ public: friend class const_iterator; // stl style - inline iterator begin() { detach(); return iterator(this, 0); } + inline iterator begin() { detach2(); return iterator(this, 0); } inline const_iterator begin() const { return const_iterator(this, 0); } inline const_iterator constBegin() const { return const_iterator(this, 0); } - inline iterator end() { detach(); return iterator(this, size()); } + inline iterator end() { detach2(); return iterator(this, size()); } inline const_iterator end() const { return const_iterator(this, size()); } inline const_iterator constEnd() const { return const_iterator(this, size()); } iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; } @@ -235,7 +235,9 @@ private: QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array); void initialize(); void compact(); + // ### Qt 6: remove me and merge with detach2 void detach(uint reserve = 0); + bool detach2(uint reserve = 0); QJsonPrivate::Data *d; QJsonPrivate::Array *a; diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index a6746d5afe..1fde69ecf6 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -488,7 +488,7 @@ void QJsonDocument::setObject(const QJsonObject &object) if (d->compactionCounter) o.compact(); else - o.detach(); + o.detach2(); d = o.d; d->ref.ref(); return; @@ -515,7 +515,7 @@ void QJsonDocument::setArray(const QJsonArray &array) if (d->compactionCounter) a.compact(); else - a.detach(); + a.detach2(); d = a.d; d->ref.ref(); return; diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index a3ce13a99f..4ee20ef168 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -203,11 +203,54 @@ QJsonObject &QJsonObject::operator =(const QJsonObject &other) */ QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) { - // ### this is implemented the trivial way, not the most efficient way - QJsonObject object; - for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) - object.insert(it.key(), QJsonValue::fromVariant(it.value())); + if (map.isEmpty()) + return object; + + object.detach2(1024); + + QVector<QJsonPrivate::offset> offsets; + QJsonPrivate::offset currentOffset; + currentOffset = sizeof(QJsonPrivate::Base); + + // the map is already sorted, so we can simply append one entry after the other and + // write the offset table at the end + for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { + QString key = it.key(); + QJsonValue val = QJsonValue::fromVariant(it.value()); + + bool latinOrIntValue; + int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue); + + bool latinKey = QJsonPrivate::useCompressed(key); + int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey); + int requiredSize = valueOffset + valueSize; + + if (!object.detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry + return QJsonObject(); + + QJsonPrivate::Entry *e = reinterpret_cast<QJsonPrivate::Entry *>(reinterpret_cast<char *>(object.o) + currentOffset); + e->value.type = val.t; + e->value.latinKey = latinKey; + e->value.latinOrIntValue = latinOrIntValue; + e->value.value = QJsonPrivate::Value::valueToStore(val, (char *)e - (char *)object.o + valueOffset); + QJsonPrivate::copyString((char *)(e + 1), key, latinKey); + if (valueSize) + QJsonPrivate::Value::copyData(val, (char *)e + valueOffset, latinOrIntValue); + + offsets << currentOffset; + currentOffset += requiredSize; + object.o->size = currentOffset; + } + + // write table + object.o->tableOffset = currentOffset; + if (!object.detach2(sizeof(QJsonPrivate::offset)*offsets.size())) + return QJsonObject(); + memcpy(object.o->table(), offsets.constData(), offsets.size()*sizeof(uint)); + object.o->length = offsets.size(); + object.o->size = currentOffset + sizeof(QJsonPrivate::offset)*offsets.size(); + return object; } @@ -276,16 +319,14 @@ QVariantHash QJsonObject::toVariantHash() const */ QStringList QJsonObject::keys() const { - if (!d) - return QStringList(); - QStringList keys; - keys.reserve(o->length); - for (uint i = 0; i < o->length; ++i) { - QJsonPrivate::Entry *e = o->entryAt(i); - keys.append(e->key()); + if (o) { + keys.reserve(o->length); + for (uint i = 0; i < o->length; ++i) { + QJsonPrivate::Entry *e = o->entryAt(i); + keys.append(e->key()); + } } - return keys; } @@ -397,7 +438,8 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey); int requiredSize = valueOffset + valueSize; - detach(requiredSize + sizeof(QJsonPrivate::offset)); // offset for the new index entry + if (!detach2(requiredSize + sizeof(QJsonPrivate::offset))) // offset for the new index entry + return iterator(); if (!o->length) o->tableOffset = sizeof(QJsonPrivate::Object); @@ -441,7 +483,7 @@ void QJsonObject::remove(const QString &key) if (!keyExists) return; - detach(); + detach2(); o->removeItems(index, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) @@ -468,7 +510,7 @@ QJsonValue QJsonObject::take(const QString &key) return QJsonValue(QJsonValue::Undefined); QJsonValue v(d, o, o->entryAt(index)->value); - detach(); + detach2(); o->removeItems(index, 1); ++d->compactionCounter; if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) @@ -562,7 +604,7 @@ QJsonObject::iterator QJsonObject::find(const QString &key) int index = o ? o->indexOf(key, &keyExists) : 0; if (!keyExists) return end(); - detach(); + detach2(); return iterator(this, index); } @@ -1069,21 +1111,35 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const */ void QJsonObject::detach(uint reserve) { + Q_UNUSED(reserve) + Q_ASSERT(!reserve); + detach2(reserve); +} + +bool QJsonObject::detach2(uint reserve) +{ if (!d) { + if (reserve >= QJsonPrivate::Value::MaxSize) { + qWarning("QJson: Document too large to store in data structure"); + return false; + } d = new QJsonPrivate::Data(reserve, QJsonValue::Object); o = static_cast<QJsonPrivate::Object *>(d->header->root()); d->ref.ref(); - return; + return true; } if (reserve == 0 && d->ref.load() == 1) - return; + return true; QJsonPrivate::Data *x = d->clone(o, reserve); + if (!x) + return false; x->ref.ref(); if (!d->ref.deref()) delete d; d = x; o = static_cast<QJsonPrivate::Object *>(d->header->root()); + return true; } /*! @@ -1094,7 +1150,7 @@ void QJsonObject::compact() if (!d || !d->compactionCounter) return; - detach(); + detach2(); d->compact(); o = static_cast<QJsonPrivate::Object *>(d->header->root()); } diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index 5617eee04f..6cffbce83a 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -188,10 +188,10 @@ public: friend class const_iterator; // STL style - inline iterator begin() { detach(); return iterator(this, 0); } + inline iterator begin() { detach2(); return iterator(this, 0); } inline const_iterator begin() const { return const_iterator(this, 0); } inline const_iterator constBegin() const { return const_iterator(this, 0); } - inline iterator end() { detach(); return iterator(this, size()); } + inline iterator end() { detach2(); return iterator(this, size()); } inline const_iterator end() const { return const_iterator(this, size()); } inline const_iterator constEnd() const { return const_iterator(this, size()); } iterator erase(iterator it); @@ -221,7 +221,9 @@ private: QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object); void initialize(); + // ### Qt 6: remove me and merge with detach2 void detach(uint reserve = 0); + bool detach2(uint reserve = 0); void compact(); QString keyAt(int i) const; diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 4d5b0f156c..a923d83bcf 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -113,6 +113,7 @@ QAppleOperatingSystemVersion qt_apple_os_version() // Use temporary variables so we can return 0.0.0 (unknown version) // in case of an error partway through determining the OS version qint32 major = 0, minor = 0, patch = 0; +#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_10, __IPHONE_8_0) #if defined(Q_OS_IOS) @autoreleasepool { NSArray *parts = [UIDevice.currentDevice.systemVersion componentsSeparatedByString:@"."]; @@ -136,6 +137,7 @@ QAppleOperatingSystemVersion qt_apple_os_version() if (pGestalt('sys3', &patch) != 0) return v; #endif +#endif v.major = major; v.minor = minor; v.patch = patch; diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 73cefdafd7..4d7aa83c43 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -942,9 +942,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); - int sockfd = notifier->socket(); - int type = notifier->type(); #ifndef QT_NO_DEBUG + int sockfd = notifier->socket(); if (sockfd < 0) { qWarning("QSocketNotifier: Internal error"); return; @@ -953,8 +952,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) return; } #endif + doUnregisterSocketNotifier(notifier); +} +void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier) +{ Q_D(QEventDispatcherWin32); + int type = notifier->type(); + int sockfd = notifier->socket(); + Q_ASSERT(sockfd >= 0); + QSFDict::iterator it = d->active_fd.find(sockfd); if (it != d->active_fd.end()) { QSockFd &sd = it.value(); @@ -1210,11 +1217,11 @@ void QEventDispatcherWin32::closingDown() // clean up any socketnotifiers while (!d->sn_read.isEmpty()) - unregisterSocketNotifier((*(d->sn_read.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj); while (!d->sn_write.isEmpty()) - unregisterSocketNotifier((*(d->sn_write.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj); while (!d->sn_except.isEmpty()) - unregisterSocketNotifier((*(d->sn_except.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj); Q_ASSERT(d->active_fd.isEmpty()); // clean up any timers diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 848dbaf475..d745f16975 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -109,6 +109,7 @@ public: protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); virtual void sendPostedEvents(); + void doUnregisterSocketNotifier(QSocketNotifier *notifier); private: friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 2a4d6da477..90edeca0a8 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -1181,7 +1181,7 @@ void QMapDataBase::freeData(QMapDataBase *d) /*! \fn QPair<iterator, iterator> QMap::equal_range(const Key &key) - Returns a pair of iterators delimiting the range of values that + Returns a pair of iterators delimiting the range of values \c{[first, second)}, that are stored under \a key. */ diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index 366ce1477f..13b0032605 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -42,7 +42,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index a946191cde..6a5c8f4fe5 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -63,7 +63,7 @@ QT_END_NAMESPACE #include <QtCore/qatomic.h> #include <QtCore/qobject.h> // for qobject_cast #include <QtCore/qdebug.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 37f5939f53..32c33f19f2 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -49,6 +49,10 @@ #include <QtDBus/qdbusextratypes.h> #include <QtDBus/qdbusconnection.h> +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 017691aaf7..3f2e80cdac 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -60,6 +60,10 @@ #include <algorithm> +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h index 8c18459f2a..b65bfc1e9b 100644 --- a/src/dbus/qdbusextratypes.h +++ b/src/dbus/qdbusextratypes.h @@ -45,7 +45,7 @@ #include <QtCore/qvariant.h> #include <QtCore/qstring.h> #include <QtDBus/qdbusmacros.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index b6fb9ae7cf..25678a56a9 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -69,6 +69,9 @@ #include "qdbusthreaddebug_p.h" #include <algorithm> +#ifdef interface +#undef interface +#endif #ifndef QT_NO_DBUS diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 3c8cc57572..b8290861af 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -300,7 +300,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int if (depth != 32) { ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; - if (ncols > 256) // sanity check - don't run out of mem if color table is broken + if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken return false; image.setColorCount(ncols); } diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 436567d432..476b456563 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -205,7 +205,7 @@ void QGIFFormat::disposePrevious(QImage *image) fillRect(image, l, t, r-l+1, b-t+1, color(bgcol)); } else { // Impossible: We don't know of a bgcol - use pixel 0 - QRgb *bits = (QRgb*)image->bits(); + const QRgb *bits = reinterpret_cast<const QRgb *>(image->constBits()); fillRect(image, l, t, r-l+1, b-t+1, bits[0]); } // ### Changed: QRect(l, t, r-l+1, b-t+1) @@ -214,7 +214,7 @@ void QGIFFormat::disposePrevious(QImage *image) if (frame >= 0) { for (int ln=t; ln<=b; ln++) { memcpy(image->scanLine(ln)+l, - backingstore.scanLine(ln-t), + backingstore.constScanLine(ln-t), (r-l+1)*sizeof(QRgb)); } // ### Changed: QRect(l, t, r-l+1, b-t+1) diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 8e65f69d6e..8106289ad1 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -195,6 +195,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format) return QImage::Format_ARGB32_Premultiplied; } +inline QImage::Format qt_maybeAlphaVersionWithSameDepth(QImage::Format format) +{ + const QImage::Format toFormat = qt_alphaVersion(format); + return qt_depthForFormat(format) == qt_depthForFormat(toFormat) ? toFormat : format; +} + inline QImage::Format qt_alphaVersionForPainting(QImage::Format format) { QImage::Format toFormat = qt_alphaVersion(format); diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index a409840612..0906b65d96 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -189,7 +189,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image, correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags); uchar *mem = thisImg->bits(); - const uchar *bits = correctFormatPic.bits(); + const uchar *bits = correctFormatPic.constBits(); int bytesCopied = 0; while (bytesCopied < correctFormatPic.byteCount()) { memcpy(mem,bits,correctFormatPic.bytesPerLine()); diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 73700a9f52..7f20586156 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -204,7 +204,7 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap) QScopedArrayPointer<uchar> bits(new uchar[bpl * h]); bm.invertPixels(); for (int y = 0; y < h; ++y) - memcpy(bits.data() + y * bpl, bm.scanLine(y), bpl); + memcpy(bits.data() + y * bpl, bm.constScanLine(y), bpl); HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data()); return hbm; } diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 1e34db1450..42d3684aea 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -335,7 +335,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy if (image.format() == QImage::Format_Indexed8) { QVector<QRgb> color = image.colorTable(); for (uint y=0; y<h; y++) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); uchar *p = buf; uchar *end = buf+bpl; if (gray) { @@ -356,7 +356,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy } } else { for (uint y=0; y<h; y++) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); uchar *p = buf; uchar *end = buf + bpl; if (gray) { @@ -386,7 +386,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy uint bpl = w * 3; uchar *buf = new uchar[bpl]; for (uint y=0; y<h; y++) { - QRgb *b = (QRgb*)image.scanLine(y); + const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y)); uchar *p = buf; uchar *end = buf+bpl; while (p < end) { diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index d277f8ccfd..eda816f0f2 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -216,7 +216,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const char *p = buf; int bpl = (w+7)/8; for (int y = 0; y < h; ++y) { - uchar *b = image.scanLine(y); + const uchar *b = image.constScanLine(y); for (i = 0; i < bpl; ++i) { *p++ = '0'; *p++ = 'x'; *p++ = hexrep[*b >> 4]; diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index 235a9c5410..5ae8e893cb 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -1104,7 +1104,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const // build color table for(y=0; y<h; y++) { - QRgb * yp = (QRgb *)image.scanLine(y); + const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y)); for(x=0; x<w; x++) { QRgb color = *(yp + x); if (!colorMap.contains(color)) @@ -1150,7 +1150,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const // write pixels, limit to 4 characters per pixel line.truncate(cpp*w); for(y=0; y<h; y++) { - QRgb * yp = (QRgb *) image.scanLine(y); + const QRgb *yp = reinterpret_cast<const QRgb *>(image.constScanLine(y)); int cc = 0; for(x=0; x<w; x++) { int color = (int)(*(yp + x)); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index ce9d1cbe45..0d34016dff 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3576,6 +3576,7 @@ static inline void formatTouchEvent(QDebug d, const QTouchEvent &t) { d << "QTouchEvent("; QtDebugUtils::formatQEnum(d, t.type()); + d << " device: " << t.device()->name(); d << " states: "; QtDebugUtils::formatQFlags(d, t.touchPointStates()); d << ", " << t.touchPoints().size() << " points: " << t.touchPoints() << ')'; diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 50fb4d73ea..60e8dcf562 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -53,6 +53,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qmargins.h> +#include <QtCore/qmath.h> #include <QtCore/qrect.h> #include <QtCore/qvector.h> #include <QtCore/qloggingcategory.h> @@ -389,6 +390,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow * return pointRegion; } +// When mapping expose events to Qt rects: round top/left towards the origin and +// bottom/right away from the origin, making sure that we cover the whole window. +inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelRegion; + + const qreal scaleFactor = QHighDpiScaling::factor(window); + QRegion pointRegion; + foreach (const QRect &rect, pixelRegion.rects()) { + const QPointF topLeftP = QPointF(rect.topLeft()) / scaleFactor; + const QPointF bottomRightP = QPointF(rect.bottomRight()) / scaleFactor; + pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())), + QPoint(qCeil(bottomRightP.x()), qCeil(bottomRightP.y()))); + } + return pointRegion; +} + inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) @@ -506,6 +525,8 @@ namespace QHighDpi { template <typename T> inline T fromNativeLocalRegion(const T &value, ...) { return value; } template <typename T> inline + T fromNativeLocalExposedRegion(const T &value, ...) { return value; } + template <typename T> inline T toNativeLocalRegion(const T &value, ...) { return value; } template <typename T> inline diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index b3c7fe957d..56eb6f0e12 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -60,7 +60,7 @@ #include <QtGui/qopengl.h> #include <QtGui/qopenglversionfunctions.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index abbd1fe999..769d30888b 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -490,8 +490,10 @@ QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) co { QPlatformScreen *currentScreen = screen(); QPlatformScreen *fallback = currentScreen; - //QRect::center can return a value outside the rectangle if it's empty - const QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); + // QRect::center can return a value outside the rectangle if it's empty. + // Apply mapToGlobal() in case it is a foreign/embedded window. + const QPoint center = + mapToGlobal(newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center()); if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { const auto screens = currentScreen->virtualSiblings(); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 0c7e0e5816..44fa88e7cf 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -375,7 +375,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) { Q_Q(QWindow); if (parentWindow) { - qWarning() << this << '(' << newScreen << "): Attempt to set a screen on a child window."; + qWarning() << q << '(' << newScreen << "): Attempt to set a screen on a child window."; return; } if (newScreen != topLevelScreen) { diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 2489974bb3..c76721f89b 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -588,7 +588,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); + QWindowSystemInterfacePrivate::ExposeEvent *e = + new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -874,7 +875,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) { #ifndef QT_NO_SHORTCUT diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 35b1ec3bcf..a798db662c 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -85,7 +85,7 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() if (!glGetStringi) return; - GLint numExtensions; + GLint numExtensions = 0; funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); for (int i = 0; i < numExtensions; ++i) { diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index cf6af549cb..20b21b8103 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -53,7 +53,7 @@ #ifndef QT_NO_OPENGL -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 17304b16aa..801397751b 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -112,7 +112,8 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off } #endif - d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset); + d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, win), + QHighDpi::toNativeLocalPosition(offset, win)); } /*! diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index dcfa3f0647..1143123717 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3426,13 +3426,13 @@ static SourceFetchProc64 sourceFetch64[NBlendTypes][QImage::NImageFormats] = { static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos) { int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32(); + return data->colorTable32[qt_gradient_clamp(data, ipos)]; } static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos) { int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - return data->colorTable[qt_gradient_clamp(data, ipos)]; + return data->colorTable64[qt_gradient_clamp(data, ipos)]; } static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index cd53b688e9..af52ed0b43 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -274,7 +274,8 @@ struct QGradientData #define GRADIENT_STOPTABLE_SIZE 1024 #define GRADIENT_STOPTABLE_SIZE_SHIFT 10 - QRgba64* colorTable; //[GRADIENT_STOPTABLE_SIZE]; + const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE]; + const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE]; uint alphaColor : 1; }; @@ -382,13 +383,13 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) { int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - return data->colorTable[qt_gradient_clamp(data, ipos)].toArgb32(); + return data->colorTable32[qt_gradient_clamp(data, ipos)]; } static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos) { int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - return data->colorTable[qt_gradient_clamp(data, ipos)]; + return data->colorTable64[qt_gradient_clamp(data, ipos)]; } static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) @@ -556,7 +557,7 @@ public: delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \ b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \ for (int i = 0; i < 4; ++i) \ - *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]].toArgb32(); \ + *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable32[index_vec.i[i]]; \ } #define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \ diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e63d29a39d..0df9d6873e 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3616,7 +3616,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) { Q_ASSERT(image.depth() == 1); - QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB); + const QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB); QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied); QRgb fg = qPremultiply(color.rgba()); @@ -3625,7 +3625,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) int height = sourceImage.height(); int width = sourceImage.width(); for (int y=0; y<height; ++y) { - uchar *source = sourceImage.scanLine(y); + const uchar *source = sourceImage.constScanLine(y); QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y)); if (!source || !target) QT_THROW(std::bad_alloc()); // we must have run out of memory @@ -4144,7 +4144,8 @@ class QGradientCache { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : stops(qMove(s)), opacity(op), interpolationMode(mode) {} - QRgba64 buffer[GRADIENT_STOPTABLE_SIZE]; + QRgba64 buffer64[GRADIENT_STOPTABLE_SIZE]; + QRgb buffer32[GRADIENT_STOPTABLE_SIZE]; QGradientStops stops; int opacity; QGradient::InterpolationMode interpolationMode; @@ -4153,7 +4154,9 @@ class QGradientCache typedef QMultiHash<quint64, CacheInfo> QGradientColorTableHash; public: - inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) { + typedef QPair<const QRgb *, const QRgba64 *> ColorBufferPair; + + inline ColorBufferPair getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; const QGradientStops stops = gradient.stops(); @@ -4169,7 +4172,8 @@ public: do { const CacheInfo &cache_info = it.value(); if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) - return cache_info.buffer; + return qMakePair(reinterpret_cast<const QRgb *>(cache_info.buffer32), + reinterpret_cast<const QRgba64 *>(cache_info.buffer64)); ++it; } while (it != cache.constEnd() && it.key() == hash_val); // an exact match for these stops and opacity was not found, create new cache @@ -4183,14 +4187,18 @@ protected: inline void generateGradientColorTable(const QGradient& g, QRgba64 *colorTable, int size, int opacity) const; - QRgba64 *addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { + ColorBufferPair addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK cache.erase(cache.begin() + (qrand() % maxCacheSize())); } CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - generateGradientColorTable(gradient, cache_entry.buffer, paletteSize(), opacity); - return cache.insert(hash_val, cache_entry).value().buffer; + generateGradientColorTable(gradient, cache_entry.buffer64, paletteSize(), opacity); + for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i) + cache_entry.buffer32[i] = cache_entry.buffer64[i].toArgb32(); + CacheInfo &cache_value = cache.insert(hash_val, cache_entry).value(); + return qMakePair(reinterpret_cast<const QRgb *>(cache_value.buffer32), + reinterpret_cast<const QRgba64 *>(cache_value.buffer64)); } QGradientColorTableHash cache; @@ -4424,7 +4432,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = LinearGradient; const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QLinearGradientData &linearData = gradient.linear; @@ -4441,7 +4453,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = RadialGradient; const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = g->spread(); QRadialGradientData &radialData = gradient.radial; @@ -4462,7 +4478,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode type = ConicalGradient; const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - gradient.colorTable = const_cast<QRgba64*>(qt_gradient_cache()->getBuffer(*g, alpha)); + + QGradientCache::ColorBufferPair colorBuffers = qt_gradient_cache()->getBuffer(*g, alpha); + gradient.colorTable64 = colorBuffers.second; + gradient.colorTable32 = colorBuffers.first; + gradient.spread = QGradient::RepeatSpread; QConicalGradientData &conicalData = gradient.conical; diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 9a3bde3fa3..6cec4a0a8d 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -269,12 +269,14 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, QOpenGLTextureBlitter *blitter, const QPoint &offset) { + const QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + return; + QRect rectInWindow = textures->geometry(idx); // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust rectInWindow.translate(-offset); - QRect clipRect = textures->clipRect(idx); - if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); @@ -520,7 +522,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu if (needsConversion) image = image.convertToFormat(QImage::Format_RGBA8888); + // The image provided by the backingstore may have a stride larger than width * 4, for + // instance on platforms that manually implement client-side decorations. + static const int bytesPerPixel = 4; + const int strideInPixels = image.bytesPerLine() / bytesPerPixel; + const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3; + QOpenGLFunctions *funcs = ctx->functions(); + + if (hasUnpackRowLength) { + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels); + } else if (strideInPixels != image.width()) { + // No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically + // hit with QtWayland which is rarely used in combination with a ES2.0-only GL + // implementation. Therefore, accept the performance hit and do a copy. + image = image.copy(); + } + if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); @@ -542,11 +560,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; - if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); + if (hasUnpackRowLength) { funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, - image.constScanLine(rect.y()) + rect.x() * 4); - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + image.constScanLine(rect.y()) + rect.x() * bytesPerPixel); } else { // if the rect is wide enough it's cheaper to just // extend it instead of doing an image copy @@ -568,6 +584,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu } } + if (hasUnpackRowLength) + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + return d_ptr->textureId; } #endif // QT_NO_OPENGL diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index d104f9ff5a..35c4abb3ac 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -3751,7 +3751,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap) { - QImage image = bitmap.toImage(); + const QImage image = bitmap.toImage(); QRegionPrivate *region = new QRegionPrivate; @@ -3769,7 +3769,7 @@ QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap) int x, y; for (y = 0; y < image.height(); ++y) { - uchar *line = image.scanLine(y); + const uchar *line = image.constScanLine(y); int w = image.width(); uchar all = zero; int prev1 = -1; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index fe5564148e..d2c3eceeef 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -345,7 +345,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP uchar *dest = d + (c.y + y) *dbpl + c.x/8; if (y < mh) { - uchar *src = mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w/8; ++x) { if (x < (mw+7)/8) dest[x] = src[x]; @@ -367,7 +367,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP for (int y = 0; y < c.h; ++y) { uchar *dest = d + (c.y + y) *dbpl + c.x; if (y < mh) { - uchar *src = (uchar *) mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w; ++x) { if (x < mw) dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0; @@ -378,7 +378,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP for (int y = 0; y < c.h; ++y) { uchar *dest = d + (c.y + y) *dbpl + c.x; if (y < mh) { - uchar *src = (uchar *) mask.scanLine(y); + const uchar *src = mask.constScanLine(y); for (int x = 0; x < c.w; ++x) { if (x < mw) dest[x] = src[x]; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 8924a7c4ae..7c0492bb1a 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -829,7 +829,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp } } } - const uchar *bitmap_data = bitmap.bits(); + const uchar *bitmap_data = bitmap.constBits(); QFixedPoint offset = glyphs.offsets[i]; advanceX += offset.x; advanceY += offset.y; @@ -886,12 +886,12 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, con QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t) { - QImage alphaMask = alphaMapForGlyph(glyph, t); + const QImage alphaMask = alphaMapForGlyph(glyph, t); QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32); for (int y=0; y<alphaMask.height(); ++y) { uint *dst = (uint *) rgbMask.scanLine(y); - uchar *src = (uchar *) alphaMask.scanLine(y); + const uchar *src = alphaMask.constScanLine(y); for (int x=0; x<alphaMask.width(); ++x) { int val = src[x]; dst[x] = qRgb(val, val, val); @@ -979,7 +979,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) for (int y=0; y<im.height(); ++y) { uchar *dst = (uchar *) alphaMap.scanLine(y); - uint *src = (uint *) im.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y)); for (int x=0; x<im.width(); ++x) dst[x] = qAlpha(src[x]); } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 81657a2702..3b330a0fd3 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1261,7 +1261,7 @@ QFixed QFontEngineFT::xHeight() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->sxHeight) { lockFace(); - QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1273,7 +1273,7 @@ QFixed QFontEngineFT::averageCharWidth() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->xAvgCharWidth) { lockFace(); - QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1301,7 +1301,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c kerning_pairs_loaded = true; lockFace(); if (freetype->face->size->metrics.x_ppem != 0) { - QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem); + QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem); unlockFace(); const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor); } else { diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 3bc8288b73..2189923b25 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -795,7 +795,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is @@ -1579,7 +1579,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist These flags are defined in the \l{Qt::TextFlag} enum. diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 85484b8b03..f824d1b369 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1078,8 +1078,8 @@ QTextCursor::QTextCursor(const QTextBlock &block) /*! \internal */ -QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos) - : d(new QTextCursorPrivate(&p)) +QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos) + : d(new QTextCursorPrivate(p)) { d->adjusted_anchor = d->anchor = d->position = pos; diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index b8fa3145eb..9610e61b39 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -67,6 +67,8 @@ class Q_GUI_EXPORT QTextCursor public: QTextCursor(); explicit QTextCursor(QTextDocument *document); + QTextCursor(QTextDocumentPrivate *p, int pos); + explicit QTextCursor(QTextCursorPrivate *d); explicit QTextCursor(QTextFrame *frame); explicit QTextCursor(const QTextBlock &block); QTextCursor(const QTextCursor &cursor); @@ -225,9 +227,6 @@ public: QTextDocument *document() const; private: - QTextCursor(QTextDocumentPrivate &p, int pos); - explicit QTextCursor(QTextCursorPrivate *d); - QSharedDataPointer<QTextCursorPrivate> d; friend class QTextCursorPrivate; friend class QTextDocumentPrivate; diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 5b593b8a9b..84f912a3fa 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -107,7 +107,7 @@ public: void aboutToRemoveCell(int from, int to); static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos) - { return QTextCursor(*d, pos); } + { return QTextCursor(d, pos); } QTextDocumentPrivate *priv; qreal x; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 5cb9e1bb74..348fa83756 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1710,7 +1710,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount() beginEditBlock(); const int blocksToRemove = blocks.numNodes() - maximumBlockCount; - QTextCursor cursor(*this, 0); + QTextCursor cursor(this, 0); cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove); unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 1cb42e822b..9cc9cc9206 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1064,12 +1064,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const QVector<quint32> indexes = oldGlyphRun.glyphIndexes(); QVector<QPointF> positions = oldGlyphRun.positions(); + QRectF boundingRect = oldGlyphRun.boundingRect(); indexes += glyphRun.glyphIndexes(); positions += glyphRun.positions(); + boundingRect = boundingRect.united(glyphRun.boundingRect()); oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); + oldGlyphRun.setBoundingRect(boundingRect); } else { glyphRunHash[key] = glyphRun; } diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index f3d504a6b6..20f7ab2622 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -300,19 +300,6 @@ static inline QAbstractSocket::SocketType qt_socket_getType(qintptr socketDescri return QAbstractSocket::UnknownSocketType; } -/*! \internal - -*/ -static inline int qt_socket_getMaxMsgSize(qintptr socketDescriptor) -{ - int value = 0; - QT_SOCKLEN_T valueSize = sizeof(value); - if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *) &value, &valueSize) != 0) { - WS_ERROR_DEBUG(WSAGetLastError()); - } - return value; -} - // MS Transport Provider IOCTL to control // reporting PORT_UNREACHABLE messages // on UDP sockets via recv/WSARecv/etc. diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index a2dcce905d..6ee66d1ec1 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -43,7 +43,7 @@ #include <QtCore/QtGlobal> #include <QtCore/QString> #include <QtCore/QMetaType> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/QHash> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index dc60adda39..0674c05d71 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -145,7 +145,7 @@ public: unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len); #ifdef Q_OS_WIN void fetchCaRootForCert(const QSslCertificate &cert); - void _q_caRootLoaded(QSslCertificate,QSslCertificate); + void _q_caRootLoaded(QSslCertificate,QSslCertificate) Q_DECL_OVERRIDE; #endif Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions); diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 7bd7ba4834..610619a4e4 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE It is up to the platform plugin to manage the lifetime of the compositor (instance(), destroy()), set the correct destination - context and window as early as possible (setTargetWindow()), + context and window as early as possible (setTarget()), register the composited windows as they are shown, activated, raised and lowered (addWindow(), moveToTop(), etc.), and to schedule repaints (update()). @@ -183,11 +183,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) { - const QRect rectInWindow = textures->geometry(idx); - QRect clipRect = textures->clipRect(idx); + const QRect clipRect = textures->clipRect(idx); if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + return; + const QRect rectInWindow = textures->geometry(idx); const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 80d20eac93..7c29be7804 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -40,6 +40,7 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QWindow> #include <QtGui/QPainter> +#include <QtGui/QOffscreenSurface> #include <qpa/qplatformbackingstore.h> #include <private/qwindow_p.h> @@ -88,13 +89,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore() { if (m_bsTexture) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); + // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is + // made current before destroying backingstores. That is however not the case for + // windows with regular widgets only. + QScopedPointer<QOffscreenSurface> tempSurface; + if (!ctx) { + ctx = QOpenGLCompositor::instance()->context(); + tempSurface.reset(new QOffscreenSurface); + tempSurface->setFormat(ctx->format()); + tempSurface->create(); + ctx->makeCurrent(tempSurface.data()); + } + if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup()) glDeleteTextures(1, &m_bsTexture); else qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context"); + + if (tempSurface) + ctx->doneCurrent(); } - delete m_textures; + delete m_textures; // this does not actually own any GL resources } QPaintDevice *QOpenGLCompositorBackingStore::paintDevice() @@ -164,16 +180,15 @@ void QOpenGLCompositorBackingStore::updateTexture() void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - // Called for ordinary raster windows. This is rare since RasterGLSurface - // support is claimed which leads to having all QWidget windows marked as - // RasterGLSurface instead of just Raster. These go through - // compositeAndFlush() instead of this function. + // Called for ordinary raster windows. Q_UNUSED(region); Q_UNUSED(offset); QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; @@ -190,7 +205,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QPlatformTextureList *textures, QOpenGLContext *context, bool translucentBackground) { - // QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top. + // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top. Q_UNUSED(region); Q_UNUSED(offset); @@ -199,6 +214,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow + + // The compositor's context and the context to which QOpenGLWidget/QQuickWidget + // textures belong are not the same. They share resources, though. + Q_ASSERT(context->shareGroup() == dstCtx->shareGroup()); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; @@ -260,6 +281,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta if (m_bsTexture) { glDeleteTextures(1, &m_bsTexture); m_bsTexture = 0; + m_bsTextureContext = Q_NULLPTR; } } diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp index 8adf15cec4..e2c4bf9dc4 100644 --- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp +++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp @@ -136,10 +136,6 @@ void QTuioHandler::processPackets() if (size != datagram.size()) datagram.resize(size); - QOscBundle bundle(datagram); - if (!bundle.isValid()) - continue; - // "A typical TUIO bundle will contain an initial ALIVE message, // followed by an arbitrary number of SET messages that can fit into the // actual bundle capacity and a concluding FSEQ message. A minimal TUIO @@ -147,7 +143,19 @@ void QTuioHandler::processPackets() // messages. The FSEQ frame ID is incremented for each delivered bundle, // while redundant bundles can be marked using the frame sequence ID // -1." - QList<QOscMessage> messages = bundle.messages(); + QList<QOscMessage> messages; + + QOscBundle bundle(datagram); + if (bundle.isValid()) { + messages = bundle.messages(); + } else { + QOscMessage msg(datagram); + if (!msg.isValid()) { + qCWarning(lcTuioSet) << "Got invalid datagram."; + continue; + } + messages.push_back(msg); + } foreach (const QOscMessage &message, messages) { if (message.addressPattern() != "/tuio/2Dcur") { @@ -320,6 +328,14 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message) Q_UNUSED(message); // TODO: do we need to do anything with the frame id? QWindow *win = QGuiApplication::focusWindow(); + // With TUIO the first application takes exclusive ownership of the "device" + // we cannot attach more than one application to the same port anyway. + // Forcing delivery makes it easy to use simulators in the same machine + // and forget about headaches about unfocused TUIO windows. + static bool forceDelivery = qEnvironmentVariableIsSet("QT_TUIOTOUCH_DELIVER_WITHOUT_FOCUS"); + if (!win && QGuiApplication::topLevelWindows().length() > 0 && forceDelivery) + win = QGuiApplication::topLevelWindows().at(0); + if (!win) return; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 7028b4d9ec..bc4cb227a8 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -59,7 +59,7 @@ QCocoaAccessibility::~QCocoaAccessibility() void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - if (!isActive() || !event->accessibleInterface()) + if (!isActive() || !event->accessibleInterface() || !event->accessibleInterface()->isValid()) return; QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()]; if (!element) { diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 11c68efd40..0f8081715b 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -126,7 +126,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (!element) { QAccessibleInterface *iface = QAccessible::accessibleInterface(anId); Q_ASSERT(iface); - if (!iface) + if (!iface || !iface->isValid()) return nil; element = [[self alloc] initWithId:anId]; cache->insertElement(anId, element); @@ -178,7 +178,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of static NSArray *defaultAttributes = nil; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return defaultAttributes; if (defaultAttributes == nil) { @@ -232,7 +232,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)parentElement { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; if (QWindow *window = iface->window()) { @@ -265,7 +265,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -344,9 +344,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { - int line = -1; - int position = text->cursorPosition(); - convertLineOffset(text, &line, &position); + int line = 0; // true for all single line edits + if (iface->state().multiLine) { + int position = text->cursorPosition(); + convertLineOffset(text, &line, &position); + } return [NSNumber numberWithInt: line]; } return nil; @@ -362,7 +364,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityParameterizedAttributeNames { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -387,7 +389,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -454,7 +456,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return NO; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { @@ -473,7 +475,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if (QAccessibleActionInterface *action = iface->actionInterface()) @@ -502,7 +504,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityActionNames { NSMutableArray * nsActions = [NSMutableArray new]; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nsActions; const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); @@ -517,7 +519,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSString *)accessibilityActionDescription:(NSString *)action { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; // FIXME is that the right return type?? QString qtAction = QCocoaAccessible::translateAction(action, iface); QString description; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 966ae0982a..4eb35f5495 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -134,7 +134,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); if ([mSavePanel respondsToSelector:@selector(setLevel:)]) [mSavePanel setLevel:NSModalPanelWindowLevel]; - [mSavePanel setDelegate:self]; + mReturnCode = -1; mHelper = helper; mNameFilterDropDownList = new QStringList(mOptions->nameFilters()); @@ -155,7 +155,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); [self createTextField]; [self createAccessory]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; - + // -setAccessoryView: can result in -panel:directoryDidChange: + // resetting our mCurrentDir, set the delegate + // here to make sure it gets the correct value. + [mSavePanel setDelegate:self]; if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept)) [mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]]; diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 3d3381323c..88b4692c80 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -200,11 +200,8 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display(); - QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QPlatformOpenGLContext *share = context->shareHandle(); QVariant nativeHandle = context->nativeHandle(); QEglFSContext *ctx; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c37096160e..2c386e2aea 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -142,6 +142,14 @@ void QEglFSWindow::create() if (Q_UNLIKELY(!context->create())) qFatal("EGLFS: Failed to create compositing context"); compositor->setTarget(context, window()); + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + if (!qt_gl_global_share_context()) { + qt_gl_set_global_share_context(context); + // What we set up here is in effect equivalent to the application setting + // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + } } } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index b2cd5b124b..b265054e12 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -162,7 +162,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha) m_alphaNeedsFill = true; else // upgrade but here we know app painting does not rely on alpha hence no need to fill - format = qt_alphaVersionForPainting(format); + format = qt_maybeAlphaVersionWithSameDepth(format); QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 5c2610a3fe..a13fe5c40e 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -148,8 +148,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, QScopedArrayPointer<uchar> xMask(new uchar[height * n]); int x = 0; for (int i = 0; i < height; ++i) { - const uchar *bits = bbits.scanLine(i); - const uchar *mask = mbits.scanLine(i); + const uchar *bits = bbits.constScanLine(i); + const uchar *mask = mbits.constScanLine(i); for (int j = 0; j < n; ++j) { uchar b = bits[j]; uchar m = mask[j]; @@ -179,8 +179,8 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits, x += sysN; } else { int fillWidth = n > sysN ? sysN : n; - const uchar *bits = bbits.scanLine(i); - const uchar *mask = mbits.scanLine(i); + const uchar *bits = bbits.constScanLine(i); + const uchar *mask = mbits.constScanLine(i); for (int j = 0; j < fillWidth; ++j) { uchar b = bits[j]; uchar m = mask[j]; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index da28b5b19b..704f99c4ef 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -996,7 +996,7 @@ EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format) QVector<EGLConfig> configs(matching); QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), configs.data(), configs.size(), &matching); if (!cfg && matching > 0) - cfg = configs.first(); + cfg = configs.constFirst(); EGLint red = 0; EGLint green = 0; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 2d5eb4b4b9..dde85f2e6a 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -877,14 +877,13 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. - const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; + const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH); + const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE); + const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight; + const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; - const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); + const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_OUTPUT @@ -964,18 +963,21 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, return true; } -static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM registerAlias) +static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD type, LPARAM lParam) { + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const uchar charSet = f->elfLogFont.lfCharSet; + const bool registerAlias = bool(lParam); - const FONTSIGNATURE signature = textmetric->ntmFontSig; - - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type, registerAlias); + // NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according + // to the documentation is identical to a TEXTMETRIC except for the last four + // members, which we don't use anyway + const FONTSIGNATURE *signature = Q_NULLPTR; + if (type & TRUETYPE_FONTTYPE) + signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig; + addFontToDatabase(familyName, charSet, textmetric, signature, type, registerAlias); // keep on enumerating return 1; @@ -994,7 +996,7 @@ void QWindowsFontDatabase::populateFamily(const QString &familyName, bool regist familyName.toWCharArray(lf.lfFaceName); lf.lfFaceName[familyName.size()] = 0; lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, (LPARAM)registerAlias, 0); + EnumFontFamiliesEx(dummy, &lf, storeFont, LPARAM(registerAlias), 0); ReleaseDC(0, dummy); } @@ -1015,9 +1017,11 @@ struct PopulateFamiliesContext }; } // namespace -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD, LPARAM lparam) { // the "@family" fonts are just the same as "family". Ignore them. + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const wchar_t *faceNameW = f->elfLogFont.lfFaceName; if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { const QString faceName = QString::fromWCharArray(faceNameW); @@ -1027,7 +1031,7 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE context->seenSystemDefaultFont = true; // Register current font's english name as alias - const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE; if (ttf && localizedName(faceName)) { const QString englishName = getEnglishName(faceName); if (!englishName.isEmpty()) { @@ -1051,7 +1055,7 @@ void QWindowsFontDatabase::populateFontDatabase() lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font. if (!context.seenSystemDefaultFont) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 8b61379c42..fb75e75dcd 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -396,14 +396,13 @@ static bool addFontToDatabase(const QString &faceName, static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. - const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; + const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH); + const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE); + const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight; + const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; - const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); + const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_STREAM @@ -520,19 +519,21 @@ static QByteArray getFntTable(HFONT hfont, uint tag) } #endif -static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM) +static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD type, LPARAM) { - + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); const QString fullName = QString::fromWCharArray(f->elfFullName); const uchar charSet = f->elfLogFont.lfCharSet; - const FONTSIGNATURE signature = textmetric->ntmFontSig; - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(faceName, fullName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false); + // NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according + // to the documentation is identical to a TEXTMETRIC except for the last four + // members, which we don't use anyway + const FONTSIGNATURE *signature = Q_NULLPTR; + if (type & TRUETYPE_FONTTYPE) + signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig; + addFontToDatabase(faceName, fullName, charSet, textmetric, signature, type, false); // keep on enumerating return 1; @@ -559,7 +560,7 @@ void QWindowsFontDatabaseFT::populateFamily(const QString &familyName) familyName.toWCharArray(lf.lfFaceName); lf.lfFaceName[familyName.size()] = 0; lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0); + EnumFontFamiliesEx(dummy, &lf, storeFont, 0, 0); ReleaseDC(0, dummy); } @@ -579,17 +580,20 @@ struct PopulateFamiliesContext // Delayed population of font families -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD, LPARAM lparam) { + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); // the "@family" fonts are just the same as "family". Ignore them. const wchar_t *faceNameW = f->elfLogFont.lfFaceName; if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { // Register only font families for which a font file exists for delayed population + const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE; const QString faceName = QString::fromWCharArray(faceNameW); const FontKey *key = findFontKey(faceName); if (!key) { key = findFontKey(QString::fromWCharArray(f->elfFullName)); - if (!key && (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE) && localizedName(faceName)) + if (!key && ttf && localizedName(faceName)) key = findFontKey(getEnglishName(faceName)); } if (key) { @@ -599,7 +603,6 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE context->seenSystemDefaultFont = true; // Register current font's english name as alias - const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); if (ttf && localizedName(faceName)) { const QString englishName = getEnglishName(faceName); if (!englishName.isEmpty()) { @@ -623,7 +626,7 @@ void QWindowsFontDatabaseFT::populateFontDatabase() lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font if (!context.seenSystemDefaultFont) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 1b88f8bbe4..160560dbda 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1181,11 +1181,11 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo for (int y=0; y<mask->height(); ++y) { uchar *dest = alphaMap.scanLine(y); if (mask->image().format() == QImage::Format_RGB16) { - const qint16 *src = (qint16 *) ((const QImage &) mask->image()).scanLine(y); + const qint16 *src = reinterpret_cast<const qint16 *>(mask->image().constScanLine(y)); for (int x=0; x<mask->width(); ++x) dest[x] = 255 - qGray(src[x]); } else { - const uint *src = (uint *) ((const QImage &) mask->image()).scanLine(y); + const uint *src = reinterpret_cast<const uint *>(mask->image().constScanLine(y)); for (int x=0; x<mask->width(); ++x) { if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16) dest[x] = 255 - qGray(src[x]); @@ -1230,7 +1230,7 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32); for (int y=0; y<mask->height(); ++y) { uint *dest = (uint *) rgbMask.scanLine(y); - const uint *src = (uint *) source.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y)); for (int x=0; x<mask->width(); ++x) { dest[x] = 0xffffffff - (0x00ffffff & src[x]); } diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 02b56fc40a..2831962ef4 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -499,7 +499,7 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed sub QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8); for (int y=0; y<im.height(); ++y) { - uint *src = (uint*) im.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y)); uchar *dst = alphaMap.scanLine(y); for (int x=0; x<im.width(); ++x) { *dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.); @@ -765,12 +765,17 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph transform.m21 = matrix.m21(); transform.m22 = matrix.m22(); + DWRITE_RENDERING_MODE renderMode = + fontDef.hintingPreference == QFont::PreferNoHinting + ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC + : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL; + IDWriteGlyphRunAnalysis *glyphAnalysis = NULL; HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis( &glyphRun, 1.0f, &transform, - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + renderMode, DWRITE_MEASURING_MODE_NATURAL, 0.0, 0.0, &glyphAnalysis diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 61c867cf07..79f627d458 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -181,8 +181,8 @@ static bool qt_write_dibv5(QDataStream &s, QImage image) memset(buf, 0, bpl_bmp); for (int y=image.height()-1; y>=0; y--) { // write the image bits - QRgb *p = (QRgb *)image.scanLine(y); - QRgb *end = p + image.width(); + const QRgb *p = reinterpret_cast<const QRgb *>(image.constScanLine(y)); + const QRgb *end = p + image.width(); b = buf; while (p < end) { int alpha = qAlpha(*p); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 22a2922235..150f26c641 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -189,7 +189,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) return QPoint(0, 0); const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager(); const QWindowsScreen *screen = screenManager.screens().size() == 1 - ? screenManager.screens().first() : screenManager.screenAtDp(point); + ? screenManager.screens().constFirst() : screenManager.screenAtDp(point); if (screen) return screen->availableGeometry().topLeft() - screen->geometry().topLeft(); #else diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index 4517200a2d..fc7ab15f73 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -47,6 +47,9 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore") +Q_LOGGING_CATEGORY(lcQpaBackingStoreVerbose, "qt.qpa.backingstore.verbose") + class QWinRTBackingStorePrivate { public: @@ -62,6 +65,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) : QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate) { Q_D(QWinRTBackingStore); + qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window; d->initialized = false; d->screen = static_cast<QWinRTScreen*>(window->screen()->handle()); @@ -73,6 +77,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) bool QWinRTBackingStore::initialize() { Q_D(QWinRTBackingStore); + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << d->initialized; if (d->initialized) return true; @@ -94,6 +99,7 @@ bool QWinRTBackingStore::initialize() QWinRTBackingStore::~QWinRTBackingStore() { + qCDebug(lcQpaBackingStore) << __FUNCTION__ << this; } QPaintDevice *QWinRTBackingStore::paintDevice() @@ -107,6 +113,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo Q_D(QWinRTBackingStore); Q_UNUSED(offset) + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << window << region; + if (d->size.isEmpty()) return; @@ -140,6 +148,8 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents Q_D(QWinRTBackingStore); Q_UNUSED(staticContents) + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << size; + if (!initialize()) return; @@ -169,11 +179,14 @@ QImage QWinRTBackingStore::toImage() const void QWinRTBackingStore::beginPaint(const QRegion ®ion) { + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << region; + resize(window()->size(), region); } void QWinRTBackingStore::endPaint() { + qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index 20b27a3865..b5d9dfed4f 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -39,9 +39,13 @@ #include <qpa/qplatformbackingstore.h> #include <QtCore/QScopedPointer> +#include <QtCore/QLoggingCategory> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore) +Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStoreVerbose) + class QWinRTScreen; class QWinRTBackingStorePrivate; diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp new file mode 100644 index 0000000000..4e71490902 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinrtclipboard.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/qfunctions_winrt.h> +#include <QtCore/private/qeventdispatcher_winrt_p.h> + +#include <Windows.ApplicationModel.datatransfer.h> + +#include <functional> + +using namespace ABI::Windows::ApplicationModel::DataTransfer; +using namespace ABI::Windows::Foundation; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +typedef IEventHandler<IInspectable *> ContentChangedHandler; + +#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr) + +QT_BEGIN_NAMESPACE + +QWinRTClipboard::QWinRTClipboard() +{ +#ifndef Q_OS_WINPHONE + QEventDispatcherWinRT::runOnXamlThread([this]() { + HRESULT hr; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(), + &m_nativeClipBoard); + Q_ASSERT_SUCCEEDED(hr); + + EventRegistrationToken tok; + hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok); + Q_ASSERT_SUCCEEDED(hr); + + return hr; + }); +#endif // !Q_OS_WINPHONE +} + +QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode) +{ + if (!supportsMode(mode)) + return nullptr; + +#ifndef Q_OS_WINPHONE + ComPtr<IDataPackageView> view; + HRESULT hr; + hr = m_nativeClipBoard->GetContent(&view); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard content."); + + ComPtr<IAsyncOperation<HSTRING>> op; + HString result; + // This throws a security exception (WinRT originate error / 0x40080201. + // Unfortunately there seems to be no way to avoid this, neither + // running on the XAML thread, nor some other way. Stack Overflow + // confirms this problem since Windows (Phone) 8.0. + hr = view->GetTextAsync(&op); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard text."); + + hr = QWinRTFunctions::await(op, result.GetAddressOf()); + RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content"); + + quint32 size; + const wchar_t *textStr = result.GetRawBuffer(&size); + QString text = QString::fromWCharArray(textStr, size); + text.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); + m_mimeData.setText(text); + + return &m_mimeData; +#else // Q_OS_WINPHONE + return QPlatformClipboard::mimeData(mode); +#endif // Q_OS_WINPHONE +} + +// Inspired by QWindowsMimeText::convertFromMime +inline QString convertToWindowsLineEnding(const QString &text) +{ + const QChar *u = text.unicode(); + QString res; + const int s = text.length(); + int maxsize = s + s / 40 + 3; + res.resize(maxsize); + int ri = 0; + bool cr = false; + for (int i = 0; i < s; ++i) { + if (*u == QLatin1Char('\r')) + cr = true; + else { + if (*u == QLatin1Char('\n') && !cr) + res[ri++] = QLatin1Char('\r'); + cr = false; + } + res[ri++] = *u; + if (ri+3 >= maxsize) { + maxsize += maxsize / 4; + res.resize(maxsize); + } + ++u; + } + res.truncate(ri); + return res; +} + +void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + if (!supportsMode(mode)) + return; + +#ifndef Q_OS_WINPHONE + const QString text = data->text(); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() { + HRESULT hr; + ComPtr<IDataPackage> package; + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(), + &package); + + const QString nativeString = convertToWindowsLineEnding(text); + HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length()); + + hr = package->SetText(textRef.Get()); + RETURN_HR_IF_FAILED("Could not set text to clipboard data package."); + + hr = m_nativeClipBoard->SetContent(package.Get()); + RETURN_HR_IF_FAILED("Could not set clipboard content."); + return S_OK; + }); + RETURN_VOID_IF_FAILED("Could not set clipboard text."); + emitChanged(mode); +#else // Q_OS_WINPHONE + QPlatformClipboard::setMimeData(data, mode); +#endif // Q_OS_WINPHONE +} + +bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const +{ +#ifndef Q_OS_WINPHONE + return mode == QClipboard::Clipboard; +#else + return QPlatformClipboard::supportsMode(mode); +#endif +} + +HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *) +{ + emitChanged(QClipboard::Clipboard); + return S_OK; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.h b/src/plugins/platforms/winrt/qwinrtclipboard.h new file mode 100644 index 0000000000..1fb10bdfc0 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtclipboard.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINRTPLATFORMCLIPBOARD_H +#define QWINRTPLATFORMCLIPBOARD_H + +#include <qpa/qplatformclipboard.h> +#include <QMimeData> + +#include <wrl.h> + +#ifndef Q_OS_WINPHONE +namespace ABI { + namespace Windows { + namespace ApplicationModel { + namespace DataTransfer { + struct IClipboardStatics; + } + } + } +} +#endif // !Q_OS_WINPHONE + +QT_BEGIN_NAMESPACE + +class QWinRTClipboard: public QPlatformClipboard +{ +public: + QWinRTClipboard(); + + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + + HRESULT onContentChanged(IInspectable *, IInspectable *); +private: +#ifndef Q_OS_WINPHONE + Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard; +#endif + QMimeData m_mimeData; +}; + +QT_END_NAMESPACE + +#endif // QWINRTPLATFORMCLIPBOARD_H diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 8ca669141e..34f439b70f 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -49,6 +49,7 @@ #include <QOffscreenSurface> #include <QOpenGLContext> #include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qeglpbuffer_p.h> QT_BEGIN_NAMESPACE @@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) Q_D(QWinRTEGLContext); Q_ASSERT(windowSurface->surface()->supportsOpenGL()); - if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen) - return false; + EGLSurface surface; + if (windowSurface->surface()->surfaceClass() == QSurface::Window) { + QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); + if (window->eglSurface() == EGL_NO_SURFACE) + window->createEglSurface(g->eglDisplay, d->eglConfig); - QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); - if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(g->eglDisplay, d->eglConfig); + surface = window->eglSurface(); + } else { // Offscreen + surface = static_cast<QEGLPbuffer *>(windowSurface)->pbuffer(); + } - EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; @@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName) return eglGetProcAddress(procName.constData()); } +EGLDisplay QWinRTEGLContext::display() +{ + return g->eglDisplay; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index 31a2124b03..49b289cd79 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -38,6 +38,7 @@ #define QWINDOWSEGLCONTEXT_H #include <qpa/qplatformopenglcontext.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -57,6 +58,7 @@ public: QSurfaceFormat format() const Q_DECL_OVERRIDE; QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; + static EGLDisplay display(); private: QScopedPointer<QWinRTEGLContextPrivate> d_ptr; Q_DECLARE_PRIVATE(QWinRTEGLContext) diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 793256a83f..22fb8cb63e 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -47,6 +47,20 @@ using namespace Microsoft::WRL; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") + +QDebug operator<<(QDebug d, const QFontDef &def) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "Family=" << def.family << " Stylename=" << def.styleName + << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize + << " styleHint=" << def.styleHint << " weight=" << def.weight + << " stretch=" << def.stretch << " hintingPreference=" + << def.hintingPreference; + return d; +} + // Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range) { @@ -114,6 +128,7 @@ static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_U QString QWinRTFontDatabase::fontDir() const { + qCDebug(lcQpaFonts) << __FUNCTION__; QString fontDirectory = QBasicFontDatabase::fontDir(); if (!QFile::exists(fontDirectory)) { // Fall back to app directory + fonts, and just app directory after that @@ -130,6 +145,8 @@ QString QWinRTFontDatabase::fontDir() const QWinRTFontDatabase::~QWinRTFontDatabase() { + qCDebug(lcQpaFonts) << __FUNCTION__; + foreach (IDWriteFontFile *fontFile, m_fonts.keys()) fontFile->Release(); @@ -149,6 +166,8 @@ bool QWinRTFontDatabase::fontsAlwaysScalable() const void QWinRTFontDatabase::populateFontDatabase() { + qCDebug(lcQpaFonts) << __FUNCTION__; + ComPtr<IDWriteFactory1> factory; HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory); if (FAILED(hr)) { @@ -204,6 +223,8 @@ void QWinRTFontDatabase::populateFontDatabase() void QWinRTFontDatabase::populateFamily(const QString &familyName) { + qCDebug(lcQpaFonts) << __FUNCTION__ << familyName; + IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName); if (!fontFamily) { qWarning("The font family %s was not found.", qPrintable(familyName)); @@ -367,6 +388,8 @@ void QWinRTFontDatabase::populateFamily(const QString &familyName) QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) { + qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle; + if (!handle) // Happens if a font family population failed return 0; @@ -436,6 +459,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont: Q_UNUSED(styleHint) Q_UNUSED(script) + qCDebug(lcQpaFonts) << __FUNCTION__ << family; + QStringList result; if (family == QLatin1String("Helvetica")) result.append(QStringLiteral("Arial")); @@ -445,6 +470,8 @@ QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont: void QWinRTFontDatabase::releaseHandle(void *handle) { + qCDebug(lcQpaFonts) << __FUNCTION__ << handle; + if (!handle) return; diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index 41619f5bd8..e8495e202f 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -38,12 +38,15 @@ #define QWINRTFONTDATABASE_H #include <QtPlatformSupport/private/qbasicfontdatabase_p.h> +#include <QtCore/QLoggingCategory> struct IDWriteFontFile; struct IDWriteFontFamily; QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + struct FontDescription { quint32 index; diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index a0474b6710..72fc378760 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -54,6 +54,8 @@ typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneV QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods") + inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor) { Rect rect; @@ -78,6 +80,8 @@ inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor) QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen) : m_screen(screen) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen; + IInputPaneStatics *statics; if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), &statics))) { @@ -114,6 +118,7 @@ bool QWinRTInputContext::isInputPanelVisible() const HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; m_isInputPanelVisible = true; emitInputPanelVisibleChanged(); return handleVisibilityChange(pane); @@ -121,6 +126,7 @@ HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEven HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; m_isInputPanelVisible = false; emitInputPanelVisibleChanged(); return handleVisibilityChange(pane); @@ -128,6 +134,7 @@ HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEvent HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) { + qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; const QRectF keyboardRect = getInputPaneRect(pane, m_screen->scaleFactor()); if (m_keyboardRect != keyboardRect) { m_keyboardRect = keyboardRect; @@ -165,31 +172,35 @@ static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) void QWinRTInputContext::showInputPanel() { + qCDebug(lcQpaInputMethods) << __FUNCTION__; + QEventDispatcherWinRT::runOnXamlThread([&]() { ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) - return hr; + return S_OK; boolean success; hr = inputPane->TryShow(&success); if (FAILED(hr) || !success) qErrnoWarning(hr, "Failed to show input panel."); - return hr; + return S_OK; }); } void QWinRTInputContext::hideInputPanel() { + qCDebug(lcQpaInputMethods) << __FUNCTION__; + QEventDispatcherWinRT::runOnXamlThread([&]() { ComPtr<IInputPane2> inputPane; HRESULT hr = getInputPane(&inputPane); if (FAILED(hr)) - return hr; + return S_OK; boolean success; hr = inputPane->TryHide(&success); if (FAILED(hr) || !success) qErrnoWarning(hr, "Failed to hide input panel."); - return hr; + return S_OK; }); } diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 6f88ff46e6..d5a1a40efc 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -39,6 +39,7 @@ #include <qpa/qplatforminputcontext.h> #include <QtCore/QRectF> +#include <QtCore/QLoggingCategory> #include <wrl.h> @@ -58,6 +59,8 @@ namespace ABI { QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods) + class QWinRTScreen; class QWinRTInputContext : public QPlatformInputContext { diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 2281bf56cc..30c0e81e21 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -44,13 +44,19 @@ #include "qwinrteglcontext.h" #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" +#include "qwinrtclipboard.h" -#include <QtGui/QSurface> +#include <QtGui/QOffscreenSurface> #include <QtGui/QOpenGLContext> -#include <qfunctions_winrt.h> +#include <QtGui/QSurface> +#include <QtPlatformSupport/private/qeglpbuffer_p.h> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformwindow.h> #include <qpa/qplatformoffscreensurface.h> +#include <qfunctions_winrt.h> + #include <functional> #include <wrl.h> #include <windows.ui.xaml.h> @@ -106,6 +112,7 @@ class QWinRTIntegrationPrivate public: QPlatformFontDatabase *fontDatabase; QPlatformServices *platformServices; + QPlatformClipboard *clipboard; QWinRTScreen *mainScreen; QScopedPointer<QWinRTInputContext> inputContext; @@ -190,6 +197,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) screenAdded(d->mainScreen); d->platformServices = new QWinRTServices; + d->clipboard = new QWinRTClipboard; } QWinRTIntegration::~QWinRTIntegration() @@ -295,6 +303,12 @@ QPlatformServices *QWinRTIntegration::services() const return d->platformServices; } +QPlatformClipboard *QWinRTIntegration::clipboard() const +{ + Q_D(const QWinRTIntegration); + return d->clipboard; +} + Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const { Q_D(const QWinRTIntegration); @@ -385,11 +399,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *) QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - // This is only used for shutdown of applications. - // In case we do not return an empty surface the scenegraph will try - // to create a new native window during application exit causing crashes - // or assertions. - return new QPlatformOffscreenSurface(surface); + QEGLPbuffer *pbuffer = nullptr; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() { + pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface); + return S_OK; + }); + if (hr == UI_E_WINDOW_CLOSED) { + // This is only used for shutdown of applications. + // In case we do not return an empty surface the scenegraph will try + // to create a new native window during application exit causing crashes + // or assertions. + return new QPlatformOffscreenSurface(surface); + } + + return pbuffer; } diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 9bf5d27973..1ed286ab2e 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -93,6 +93,7 @@ public: QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; QStringList themeNames() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index 7d09551f5b..7ef13fd0aa 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -56,6 +56,8 @@ using namespace ABI::Windows::UI::ViewManagement; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaTheme, "qt.qpa.theme") + static IUISettings *uiSettings() { static ComPtr<IUISettings> settings; @@ -285,12 +287,14 @@ QWinRTTheme::QWinRTTheme() : d_ptr(new QWinRTThemePrivate) { Q_D(QWinRTTheme); + qCDebug(lcQpaTheme) << __FUNCTION__; nativeColorSettings(d->palette); } bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const { + qCDebug(lcQpaTheme) << __FUNCTION__ << type; static bool useNativeDialogs = qEnvironmentVariableIsSet("QT_USE_WINRT_NATIVE_DIALOGS") ? qEnvironmentVariableIntValue("QT_USE_WINRT_NATIVE_DIALOGS") : true; @@ -301,6 +305,7 @@ bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) const { + qCDebug(lcQpaTheme) << __FUNCTION__ << type; switch (type) { case FileDialog: return new QWinRTFileDialogHelper; @@ -314,6 +319,7 @@ QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) { + qCDebug(lcQpaTheme) << __FUNCTION__ << hint; HRESULT hr; switch (hint) { case QPlatformIntegration::CursorFlashTime: { @@ -363,6 +369,7 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) const QPalette *QWinRTTheme::palette(Palette type) const { Q_D(const QWinRTTheme); + qCDebug(lcQpaTheme) << __FUNCTION__ << type; if (type == SystemPalette) return &d->palette; return QPlatformTheme::palette(type); diff --git a/src/plugins/platforms/winrt/qwinrttheme.h b/src/plugins/platforms/winrt/qwinrttheme.h index 2e159cbd55..e1a0e14964 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.h +++ b/src/plugins/platforms/winrt/qwinrttheme.h @@ -39,9 +39,12 @@ #include <qpa/qplatformtheme.h> #include <qpa/qplatformintegration.h> +#include <QtCore/QLoggingCategory> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaTheme) + class QWinRTThemePrivate; class QWinRTTheme : public QPlatformTheme { diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 8a53047d1e..c6ed0dea0c 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -69,6 +69,8 @@ using namespace ABI::Windows::UI::Xaml::Controls; QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows"); + static void setUIElementVisibility(IUIElement *uiElement, bool visibility) { Q_ASSERT(uiElement); @@ -101,6 +103,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window) , d_ptr(new QWinRTWindowPrivate) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; d->surface = EGL_NO_SURFACE; d->display = EGL_NO_DISPLAY; @@ -133,6 +136,15 @@ QWinRTWindow::QWinRTWindow(QWindow *window) hr = d->swapChainPanel.As(&d->uiElement); Q_ASSERT_SUCCEEDED(hr); + ComPtr<Xaml::IFrameworkElement> frameworkElement; + hr = d->swapChainPanel.As(&frameworkElement); + Q_ASSERT_SUCCEEDED(hr); + const QSizeF size = QSizeF(d->screen->geometry().size()) / d->screen->scaleFactor(); + hr = frameworkElement->put_Width(size.width()); + Q_ASSERT_SUCCEEDED(hr); + hr = frameworkElement->put_Height(size.height()); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<IDependencyObject> canvas = d->screen->canvas(); ComPtr<IPanel> panel; hr = canvas.As(&panel); @@ -152,6 +164,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window) QWinRTWindow::~QWinRTWindow() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; HRESULT hr; hr = QEventDispatcherWinRT::runOnXamlThread([d]() { @@ -178,6 +191,8 @@ QWinRTWindow::~QWinRTWindow() if (!d->surface) return; + qCDebug(lcQpaWindows) << __FUNCTION__ << ": Destroying surface"; + EGLBoolean value = eglDestroySurface(d->display, d->surface); d->surface = EGL_NO_SURFACE; if (Q_UNLIKELY(value == EGL_FALSE)) @@ -205,12 +220,15 @@ bool QWinRTWindow::isExposed() const void QWinRTWindow::setGeometry(const QRect &rect) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << rect; const Qt::WindowFlags windowFlags = window()->flags(); const Qt::WindowFlags windowType = windowFlags & Qt::WindowType_Mask; if (window()->isTopLevel() && (windowType == Qt::Window || windowType == Qt::Dialog)) { - QPlatformWindow::setGeometry(windowFlags & Qt::MaximizeUsingFullscreenGeometryHint - ? d->screen->geometry() : d->screen->availableGeometry()); + const QRect screenRect = windowFlags & Qt::MaximizeUsingFullscreenGeometryHint + ? d->screen->geometry() : d->screen->availableGeometry(); + qCDebug(lcQpaWindows) << __FUNCTION__ << "top-level, overwrite" << screenRect; + QPlatformWindow::setGeometry(screenRect); QWindowSystemInterface::handleGeometryChange(window(), geometry()); } else { QPlatformWindow::setGeometry(rect); @@ -234,6 +252,8 @@ void QWinRTWindow::setGeometry(const QRect &rect) Q_ASSERT_SUCCEEDED(hr); hr = frameworkElement->put_Height(size.height()); Q_ASSERT_SUCCEEDED(hr); + qCDebug(lcQpaWindows) << __FUNCTION__ << "(setGeometry Xaml)" << this + << topLeft << size; return S_OK; }); Q_ASSERT_SUCCEEDED(hr); @@ -242,6 +262,8 @@ void QWinRTWindow::setGeometry(const QRect &rect) void QWinRTWindow::setVisible(bool visible) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << visible; + if (!window()->isTopLevel()) return; if (visible) { @@ -263,6 +285,7 @@ void QWinRTWindow::setWindowTitle(const QString &title) void QWinRTWindow::raise() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; if (!window()->isTopLevel()) return; d->screen->raise(window()); @@ -271,6 +294,7 @@ void QWinRTWindow::raise() void QWinRTWindow::lower() { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this; if (!window()->isTopLevel()) return; d->screen->lower(window()); @@ -290,6 +314,8 @@ qreal QWinRTWindow::devicePixelRatio() const void QWinRTWindow::setWindowState(Qt::WindowState state) { Q_D(QWinRTWindow); + qCDebug(lcQpaWindows) << __FUNCTION__ << this << state; + if (d->state == state) return; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index 9ac7adbf4d..36f5b9de84 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -37,12 +37,15 @@ #ifndef QWINRTWINDOW_H #define QWINRTWINDOW_H +#include <QtCore/QLoggingCategory> #include <qpa/qplatformwindow.h> #include <qpa/qwindowsysteminterface.h> #include <EGL/egl.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows) + class QWinRTWindowPrivate; class QWinRTWindow : public QPlatformWindow { diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index be6aad02d1..991ec1789b 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -16,6 +16,7 @@ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include SOURCES = \ main.cpp \ qwinrtbackingstore.cpp \ + qwinrtclipboard.cpp \ qwinrtcursor.cpp \ qwinrteglcontext.cpp \ qwinrteventdispatcher.cpp \ @@ -33,6 +34,7 @@ SOURCES = \ HEADERS = \ qwinrtbackingstore.h \ + qwinrtclipboard.h \ qwinrtcursor.h \ qwinrteglcontext.h \ qwinrteventdispatcher.h \ diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index e3686ec010..d5a82a7509 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -185,7 +185,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; if (!m_hasAlpha) - format = qt_alphaVersionForPainting(format); + format = qt_maybeAlphaVersionWithSameDepth(format); m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index ea44585f33..d53331fb10 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -488,31 +488,23 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); break; case WhereStatement: - if (preparedStatement) { - for (int i = 0; i < rec.count(); ++i) { - s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); - if (rec.isNull(i)) - s.append(QLatin1String(" IS NULL")); - else - s.append(QLatin1String(" = ?")); - s.append(QLatin1String(" AND ")); - } - } else { - for (i = 0; i < rec.count(); ++i) { - s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); - QString val = formatValue(rec.field(i)); - if (val == QLatin1String("NULL")) - s.append(QLatin1String(" IS NULL")); - else - s.append(QLatin1String(" = ")).append(val); - s.append(QLatin1String(" AND ")); - } - } - if (!s.isEmpty()) { - s.prepend(QLatin1String("WHERE ")); - s.chop(5); // remove tailing AND + { + const QString tableNamePrefix = tableName.isEmpty() + ? QString() + : prepareIdentifier(tableName, QSqlDriver::TableName, this) + QLatin1Char('.'); + for (int i = 0; i < rec.count(); ++i) { + s.append(QLatin1String(i? " AND " : "WHERE ")); + s.append(tableNamePrefix); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); + if (rec.isNull(i)) + s.append(QLatin1String(" IS NULL")); + else if (preparedStatement) + s.append(QLatin1String(" = ?")); + else + s.append(QLatin1String(" = ")).append(formatValue(rec.field(i))); } break; + } case UpdateStatement: s.append(QLatin1String("UPDATE ")).append(tableName).append( QLatin1String(" SET ")); diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index 1119b04293..e750fdb5a9 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); namespace QTest { @@ -99,7 +99,7 @@ namespace QTest if (action == Shortcut) { int timestamp = 0; - qt_handleShortcutEvent(window, timestamp, code, modifier, text, repeat); + qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat); return; } @@ -180,7 +180,7 @@ namespace QTest QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat); QSpontaneKeyEvent::setSpontaneous(&a); - if (press && qt_handleShortcutEvent(widget, a.timestamp(), code, modifier, text, repeat)) + if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat)) return; if (!qApp->notify(widget, &a)) QTest::qWarn("Keyboard event not accepted by receiving widget"); diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 53a5dcba9c..8e4d94d2f0 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1440,7 +1440,7 @@ QModelIndexList QListView::selectedIndexes() const return QModelIndexList(); QModelIndexList viewSelected = d->selectionModel->selectedIndexes(); - for (int i = 0; i < viewSelected.count(); ++i) { + for (int i = 0; i < viewSelected.count();) { const QModelIndex &index = viewSelected.at(i); if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column) ++i; diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 38b23ec439..03f62582ff 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1065,6 +1065,31 @@ static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) return false; } +bool QWidgetBackingStore::syncAllowed() +{ +#ifndef QT_NO_OPENGL + QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); + if (textureListWatcher && !textureListWatcher->isLocked()) { + textureListWatcher->deleteLater(); + textureListWatcher = 0; + } else if (!tlwExtra->widgetTextures.isEmpty()) { + bool skipSync = false; + foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { + if (tl->isLocked()) { + if (!textureListWatcher) + textureListWatcher = new QPlatformTextureListWatcher(this); + if (!textureListWatcher->isLocked()) + textureListWatcher->watch(tl); + skipSync = true; + } + } + if (skipSync) // cannot compose due to widget textures being in use + return false; + } +#endif + return true; +} + /*! Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store. @@ -1095,7 +1120,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg else markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); - doSync(); + if (syncAllowed()) + doSync(); } /*! @@ -1121,27 +1147,8 @@ void QWidgetBackingStore::sync() return; } -#ifndef QT_NO_OPENGL - if (textureListWatcher && !textureListWatcher->isLocked()) { - textureListWatcher->deleteLater(); - textureListWatcher = 0; - } else if (!tlwExtra->widgetTextures.isEmpty()) { - bool skipSync = false; - foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { - if (tl->isLocked()) { - if (!textureListWatcher) - textureListWatcher = new QPlatformTextureListWatcher(this); - if (!textureListWatcher->isLocked()) - textureListWatcher->watch(tl); - skipSync = true; - } - } - if (skipSync) // cannot compose due to widget textures being in use - return; - } -#endif - - doSync(); + if (syncAllowed()) + doSync(); } void QWidgetBackingStore::doSync() diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index d2d4d97841..6e3ba57ced 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -170,6 +170,8 @@ private: void updateLists(QWidget *widget); + bool syncAllowed(); + inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) { if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 6b6ca2e9cc..0bc05cc3b5 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -718,7 +718,6 @@ void QWidgetWindow::handleCloseEvent(QCloseEvent *event) { bool is_closing = m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); event->setAccepted(is_closing); - QWindow::event(event); // Call QWindow QCloseEvent handler. } #ifndef QT_NO_WHEELEVENT diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 73e28e8230..73e6f69041 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -204,7 +204,7 @@ void QStyleOption::init(const QWidget *widget) if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget)) state &= ~QStyle::State_Enabled; #endif -#if defined(Q_OS_MACX) +#if defined(Q_OS_OSX) && !defined(QT_NO_STYLE_MAC) switch (QMacStyle::widgetSizePolicy(widget)) { case QMacStyle::SizeSmall: state |= QStyle::State_Small; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 46507e3e3c..1cf7591302 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2444,6 +2444,7 @@ struct IndexSetter { { cb->setCurrentIndex(index); emit cb->activated(index); + emit cb->activated(cb->itemText(index)); } }; } diff --git a/tests/auto/corelib/io/qstandardpaths/BLACKLIST b/tests/auto/corelib/io/qstandardpaths/BLACKLIST new file mode 100644 index 0000000000..8496a620b3 --- /dev/null +++ b/tests/auto/corelib/io/qstandardpaths/BLACKLIST @@ -0,0 +1,2 @@ +[testRuntimeDirectory] +rhel-7.1 diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 540284f0b1..b1b94a3c5f 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1844,6 +1844,8 @@ void tst_QObject::moveToThread() thread.wait(); } + // WinRT does not allow connection to localhost +#ifndef Q_OS_WINRT { // make sure socket notifiers are moved with the object MoveToThreadThread thread; @@ -1879,6 +1881,7 @@ void tst_QObject::moveToThread() QMetaObject::invokeMethod(socket, "deleteLater", Qt::QueuedConnection); thread.wait(); } +#endif } diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp index d70ed4f47f..1598382959 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp @@ -126,6 +126,10 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_WINRT + // WinRT does not allow a connection to the localhost + QSKIP("Local connection not allowed", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -191,6 +195,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif // !Q_OS_WINRT } class MixingWithTimersHelper : public QObject @@ -229,6 +234,9 @@ void MixingWithTimersHelper::socketFired() void tst_QSocketNotifier::mixingWithTimers() { +#ifdef Q_OS_WINRT + QSKIP("WinRT does not allow connection to localhost", SkipAll); +#else QTimer timer; timer.setInterval(0); timer.start(); @@ -253,6 +261,7 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.timerActivated, true); QTRY_COMPARE(helper.socketActivated, true); +#endif // !Q_OS_WINRT } #ifdef Q_OS_UNIX diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro index b7a5a85e09..63189e5562 100644 --- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro +++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro @@ -5,5 +5,5 @@ SOURCES = tst_qtranslator.cpp RESOURCES += qtranslator.qrc android:!android-no-sdk: RESOURCES += android_testdata.qrc -else: TESTDATA += hellotr_la.qm msgfmt_from_po.qm +else: TESTDATA += dependencies_la.qm hellotr_la.qm msgfmt_from_po.qm diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index c366b38d57..59ea484355 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -53,6 +53,7 @@ private slots: private: int languageChangeEventCounter; + QSharedPointer<QTemporaryDir> dataDir; }; tst_QTranslator::tst_QTranslator() @@ -85,8 +86,16 @@ void tst_QTranslator::initTestCase() // chdir into the directory containing our testdata, // to make the code simpler (load testdata via relative paths) +#ifdef Q_OS_WINRT + // ### TODO: Use this for all platforms in 5.7 + dataDir = QEXTRACTTESTDATA(QStringLiteral("/")); + QVERIFY2(!dataDir.isNull(), qPrintable("Could not extract test data")); + QVERIFY2(QDir::setCurrent(dataDir->path()), qPrintable("Could not chdir to " + dataDir->path())); +#else // !Q_OS_WINRT QString testdata_dir = QFileInfo(QFINDTESTDATA("hellotr_la.qm")).absolutePath(); QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); +#endif // !Q_OS_WINRT + } bool tst_QTranslator::eventFilter(QObject *, QEvent *event) diff --git a/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp b/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp Binary files differnew file mode 100644 index 0000000000..aeb063fce5 --- /dev/null +++ b/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 7d353dfb91..bd02dc6255 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -1477,6 +1477,7 @@ void tst_QImageReader::readCorruptImage_data() QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif"); QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png"); QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp"); + QTest::newRow("corrupt bmp (clut)") << QString("corrupt_clut.bmp") << true << QString("") << QByteArray("bmp"); QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true << QString("QImage: XPM color specification is missing: bla9an.n#x") << QByteArray("xpm"); diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index 774c22a8e9..bdd27b4ea6 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -1,3 +1,5 @@ +[testInputEvents] +rhel-7.1 [positioning:default] ubuntu-14.04 [modalWindowPosition] diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 4b3d709812..7c60c8c9f8 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -65,6 +65,7 @@ private slots: void setRawDataAndGetAsVector(); void boundingRect(); void mixedScripts(); + void multiLineBoundingRect(); private: int m_testFontId; @@ -730,6 +731,34 @@ void tst_QGlyphRun::mixedScripts() QCOMPARE(glyphRuns.size(), 2); } +void tst_QGlyphRun::multiLineBoundingRect() +{ + QTextLayout layout; + layout.setText("Foo Bar"); + layout.beginLayout(); + + QTextLine line = layout.createLine(); + line.setNumColumns(4); + line.setPosition(QPointF(0, 0)); + + line = layout.createLine(); + line.setPosition(QPointF(0, 10)); + + layout.endLayout(); + + QCOMPARE(layout.lineCount(), 2); + + QList<QGlyphRun> firstLineGlyphRuns = layout.lineAt(0).glyphRuns(); + QList<QGlyphRun> allGlyphRuns = layout.glyphRuns(); + QCOMPARE(firstLineGlyphRuns.size(), 1); + QCOMPARE(allGlyphRuns.size(), 1); + + QGlyphRun firstLineGlyphRun = firstLineGlyphRuns.first(); + QGlyphRun allGlyphRun = allGlyphRuns.first(); + + QVERIFY(firstLineGlyphRun.boundingRect().height() < allGlyphRun.boundingRect().height()); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QGlyphRun) diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST index fa7c829b30..547a9a2a73 100644 --- a/tests/auto/opengl/qgl/BLACKLIST +++ b/tests/auto/opengl/qgl/BLACKLIST @@ -1,3 +1,5 @@ +[] +rhel-7.1 [glWidgetRendering] windows [glFBORendering] diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST index 4e8745ca78..28e4856056 100644 --- a/tests/auto/other/gestures/BLACKLIST +++ b/tests/auto/other/gestures/BLACKLIST @@ -1,2 +1,4 @@ +[] +rhel-7.1 [customGesture] opensuse-13.1 diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index b4f403fc0c..799b93c33b 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -104,7 +104,7 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)")); QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)")); - QVERIFY_SQL( q, exec("create table " + reltest2 + " (tid int not null primary key, title varchar(20))")); + QVERIFY_SQL( q, exec("create table " + reltest2 + " (id int not null primary key, title varchar(20))")); QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(1, 'herr')")); QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(2, 'mister')")); @@ -196,7 +196,7 @@ void tst_QSqlRelationalTableModel::data() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.columnCount(), 4); @@ -241,7 +241,7 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(reltest1); model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); @@ -271,7 +271,7 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -284,7 +284,7 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(reltest1); model.setEditStrategy(QSqlTableModel::OnFieldChange); model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(1,1), QString("trond2"))); @@ -302,7 +302,7 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond2")); QCOMPARE(model.data(model.index(2, 2)).toInt(), 2); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("mister")); } @@ -312,12 +312,12 @@ void tst_QSqlRelationalTableModel::setData() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); //sybase doesn't allow tables with the same alias used twice as col names //so don't set up an identical relation when using the tds driver if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); @@ -346,9 +346,9 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); @@ -406,7 +406,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -420,7 +420,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() // Redo same test in the LeftJoin mode model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); model.setJoinMode(QSqlRelationalTableModel::LeftJoin); @@ -443,7 +443,7 @@ void tst_QSqlRelationalTableModel::insertRecord() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -493,7 +493,7 @@ void tst_QSqlRelationalTableModel::setRecord() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -554,11 +554,11 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setSort(0, Qt::AscendingOrder); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); @@ -662,7 +662,7 @@ void tst_QSqlRelationalTableModel::removeColumn() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY_SQL(model, removeColumn(3)); @@ -688,7 +688,7 @@ void tst_QSqlRelationalTableModel::removeColumn() QSqlRelationalTableModel lmodel(0, db); lmodel.setTable(reltest1); - lmodel.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + lmodel.setRelation(2, QSqlRelation(reltest2, "id", "title")); lmodel.setJoinMode(QSqlRelationalTableModel::LeftJoin); QVERIFY_SQL(lmodel, select()); @@ -719,7 +719,7 @@ void tst_QSqlRelationalTableModel::filter() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setFilter("title = 'herr'"); QVERIFY_SQL(model, select()); @@ -746,9 +746,9 @@ void tst_QSqlRelationalTableModel::sort() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -874,7 +874,7 @@ void tst_QSqlRelationalTableModel::revert() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setRelation(3, QSqlRelation(reltest4, "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -912,10 +912,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); if (dbType != QSqlDriver::Sybase) - model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(3, QSqlRelation(reltest2, "id", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -1013,7 +1013,7 @@ void tst_QSqlRelationalTableModel::invalidData() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); //try set a non-existent relational key @@ -1043,7 +1043,7 @@ void tst_QSqlRelationalTableModel::relationModel() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(!model.relationModel(0)); @@ -1137,7 +1137,7 @@ void tst_QSqlRelationalTableModel::casing() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("CASETEST1", db).toUpper()); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); @@ -1160,11 +1160,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() //try with relation table name quoted if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2.toUpper(),QSqlDriver::TableName), - "tid", + "id", "title")); } else { model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2,QSqlDriver::TableName), - "tid", + "id", "title")); } @@ -1185,11 +1185,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() model.setJoinMode(QSqlRelationalTableModel::InnerJoin); if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName).toUpper(), "title")); } else { model.setRelation(2, QSqlRelation(reltest2, - db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName), "title")); } QVERIFY_SQL(model, select()); @@ -1210,11 +1210,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); } else { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); } @@ -1235,11 +1235,11 @@ void tst_QSqlRelationalTableModel::escapedRelations() model.setJoinMode(QSqlRelationalTableModel::InnerJoin); if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); } else { model.setRelation(2, QSqlRelation(reltest2, - "tid", + "id", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); } QVERIFY_SQL(model, select()); @@ -1273,7 +1273,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); } model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); @@ -1303,7 +1303,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -1320,7 +1320,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); } model.setSort(0, Qt::AscendingOrder); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); model.setJoinMode(QSqlRelationalTableModel::LeftJoin); QVERIFY_SQL(model, select()); @@ -1352,7 +1352,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); @@ -1480,7 +1480,7 @@ void tst_QSqlRelationalTableModel::selectAfterUpdate() QSqlRelationalTableModel model(0, db); model.setTable(reltest1); - model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); + model.setRelation(2, QSqlRelation(reltest2, "id", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.relationModel(2)->rowCount(), 2); { diff --git a/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST index 6d3c17f35f..ae0f7bb868 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST +++ b/tests/auto/widgets/dialogs/qfontdialog/BLACKLIST @@ -1,5 +1,6 @@ [task256466_wrongStyle] opensuse-13.1 +rhel-7.1 [setFont] ubuntu-14.04 redhatenterpriselinuxworkstation-6.6 diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST index 7f55c2dae0..14c41711ac 100644 --- a/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST +++ b/tests/auto/widgets/gestures/qgesturerecognizer/BLACKLIST @@ -1,2 +1,8 @@ [panGesture:Two finger] xcb +[swipeGesture:SmallDirectionChange] +rhel-7.1 +[swipeGesture:Line] +rhel-7.1 +[pinchGesture:Standard] +rhel-7.1 diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST index 717c791280..373343fa22 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/BLACKLIST @@ -1,2 +1,5 @@ [hoverEnterLeaveEvent] ubuntu-14.04 +rhel-7.1 +[QTBUG_6986_sendMouseEventToAlienWidget] +rhel-7.1 diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST index 5db5c97917..c8d93585b2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/BLACKLIST @@ -1,2 +1,3 @@ [initialShow2] ubuntu-14.04 +rhel-7.1 diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 5058dd2a81..651172e79f 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -149,6 +149,7 @@ private slots: void taskQTBUG_39902_mutualScrollBars(); void horizontalScrollingByVerticalWheelEvents(); void taskQTBUG_7232_AllowUserToControlSingleStep(); + void taskQTBUG_51086_skippingIndexesInSelectedIndexes(); }; // Testing get/set functions @@ -2492,5 +2493,32 @@ void tst_QListView::taskQTBUG_7232_AllowUserToControlSingleStep() QCOMPARE(hStep1, lv.horizontalScrollBar()->singleStep()); } +void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes() +{ + // simple way to get access to selectedIndexes() + class QListViewWithPublicSelectedIndexes : public QListView + { + public: + using QListView::selectedIndexes; + }; + + QStandardItemModel data(10, 1); + QItemSelectionModel selections(&data); + QListViewWithPublicSelectedIndexes list; + list.setModel(&data); + list.setSelectionModel(&selections); + + list.setRowHidden(7, true); + list.setRowHidden(8, true); + + for (int i = 0, count = data.rowCount(); i < count; ++i) + selections.select(data.index(i, 0), QItemSelectionModel::Select); + + const QModelIndexList indexes = list.selectedIndexes(); + + QVERIFY(!indexes.contains(data.index(7, 0))); + QVERIFY(!indexes.contains(data.index(8, 0))); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 78ccbe302a..8d18d40e05 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -10,6 +10,7 @@ ubuntu-14.04 osx [updateWhileMinimized] ubuntu-14.04 +rhel-7.1 osx [focusProxyAndInputMethods] linux @@ -31,6 +32,7 @@ osx osx [widgetAt] osx +rhel-7.1 [sheetOpacity] osx [resizeEvent] @@ -63,8 +65,10 @@ osx osx [taskQTBUG_4055_sendSyntheticEnterLeave] osx +rhel-7.1 [syntheticEnterLeave] osx +rhel-7.1 [maskedUpdate] osx [hideWhenFocusWidgetIsChild] diff --git a/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST b/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST new file mode 100644 index 0000000000..a10cf663d0 --- /dev/null +++ b/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST @@ -0,0 +1,2 @@ +[setSystemMenu] +rhel-7.1 diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST index de49d5ff45..dbc3e26837 100644 --- a/tests/auto/widgets/widgets/qmenu/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST @@ -1,2 +1,5 @@ [task258920_mouseBorder] osx +rhel-7.1 +[pushButtonPopulateOnAboutToShow] +rhel-7.1 diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp index 44ed45c2a2..d2c11fdfd1 100644 --- a/tests/manual/qopenglwidget/openglwidget/main.cpp +++ b/tests/manual/qopenglwidget/openglwidget/main.cpp @@ -176,6 +176,13 @@ int main(int argc, char *argv[]) glw3->setObjectName("GL widget in scroll area (possibly native)"); glw3->setFormat(format); glw3->setFixedSize(600, 600); + OpenGLWidget *glw3child = new OpenGLWidget(0); + const float glw3ClearColor[] = { 0.5f, 0.2f, 0.8f }; + glw3child->setClearColor(glw3ClearColor); + glw3child->setObjectName("Child widget of GL Widget in scroll area"); + glw3child->setFormat(format); + glw3child->setParent(glw3); + glw3child->setGeometry(500, 500, 100, 100); // lower right corner of parent QScrollArea *sa = new QScrollArea; sa->setWidget(glw3); sa->setMinimumSize(100, 100); diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp index 5819a14e9e..031558a787 100644 --- a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp +++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp @@ -73,6 +73,8 @@ public: int m_interval; QVector3D m_rotAxis; + + float clearColor[3]; }; @@ -80,6 +82,7 @@ OpenGLWidget::OpenGLWidget(int interval, const QVector3D &rotAxis, QWidget *pare : QOpenGLWidget(parent) { d.reset(new OpenGLWidgetPrivate(this)); + d->clearColor[0] = d->clearColor[1] = d->clearColor[2] = 0.0f; d->m_interval = interval; d->m_rotAxis = rotAxis; if (interval > 0) { @@ -146,7 +149,7 @@ void OpenGLWidgetPrivate::render() const qreal retinaScale = q->devicePixelRatio(); glViewport(0, 0, width() * retinaScale, height() * retinaScale); - glClearColor(0.0, 0.0, 0.0, 1.0); + glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT); m_program->bind(); @@ -189,3 +192,10 @@ void OpenGLWidgetPrivate::render() if (m_interval <= 0) q->update(); } + +void OpenGLWidget::setClearColor(const float *c) +{ + d->clearColor[0] = c[0]; + d->clearColor[1] = c[1]; + d->clearColor[2] = c[2]; +} diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.h b/tests/manual/qopenglwidget/openglwidget/openglwidget.h index affef103f8..32fb4e2660 100644 --- a/tests/manual/qopenglwidget/openglwidget/openglwidget.h +++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.h @@ -44,6 +44,8 @@ public: void resizeGL(int w, int h); void paintGL(); + void setClearColor(const float *c); + private: QScopedPointer<OpenGLWidgetPrivate> d; }; |