From 27fce8c07d93eec39df2440e253f2c0f719b9e19 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 21 Apr 2016 15:45:13 +0300 Subject: Android: Fix style extract on Android N Task-number: QTBUG-52744 Change-Id: If53a76929f3bc903573917cfd968431532817ace Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 392372392c3c9096984a535a975dda163a62a28a) Reviewed-by: Christian Stromme --- src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index f5dac1fa60..22e2c7a85b 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -787,7 +787,14 @@ public class ExtractStyle { private JSONObject findPatchesMarings(Drawable d) throws JSONException, NoSuchFieldException, IllegalAccessException { - NinePatch np = (NinePatch) getAccessibleField(NinePatchDrawable.class, "mNinePatch").get(d); + NinePatch np; + Field f = tryGetAccessibleField(NinePatchDrawable.class, "mNinePatch"); + if (f != null) { + np = (NinePatch) f.get(d); + } else { + Object state = getAccessibleField(NinePatchDrawable.class, "mNinePatchState").get(d); + np = (NinePatch) getAccessibleField(state.getClass(), "mNinePatch").get(state); + } if (Build.VERSION.SDK_INT < 19) return getJsonChunkInfo(extractChunkInfo((byte[]) getAccessibleField(np.getClass(), "mChunk").get(np))); else -- cgit v1.2.3 From d4302ec6936b8b3799a266b640b5d116b3296b29 Mon Sep 17 00:00:00 2001 From: Luca Bellonda Date: Wed, 13 Jul 2016 21:44:16 +0200 Subject: QtCore: Fix QXmlStreamReader for invalid characters in XML 1.0 The XML parser uses fastScanLiteralContent() to read a block of text. The routine was not checking the range of valid characters as defined in the XML standard: https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Char A check has been added to stop reading the bad character. Note that the characters are legal in XML 1.1, but QXmlStreamReader is a well-formed XML 1.0 parser [ChangeLog][QtCore][QXmlStreamReader] Fixed a bug in the XML parser that prevented to load XML that contained invalid characters for XML 1.0. Change-Id: I10aaf84fbf95ccdaf9f6d683ea7c31925efff36d Reviewed-by: Thiago Macieira --- src/corelib/xml/qxmlstream.cpp | 4 ++ .../auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp | 59 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index a235145669..ef7d454dca 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -1175,6 +1175,10 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent() } // fall through default: + if (c < 0x20) { + putChar(c); + return n; + } textBuffer += QChar(c); ++n; } diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index b0fd1187f5..686b8f22fa 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -562,6 +562,8 @@ private slots: void checkCommentIndentation_data() const; void crashInXmlStreamReader() const; void write8bitCodec() const; + void invalidStringCharacters_data() const; + void invalidStringCharacters() const; void hasError() const; private: @@ -1616,6 +1618,63 @@ void tst_QXmlStream::write8bitCodec() const QVERIFY(decodedText.startsWith(expected)); } +void tst_QXmlStream::invalidStringCharacters() const +{ + // test scan in attributes + QFETCH(QString, testString); + QFETCH(bool, expectedResultNoError); + + QByteArray values = testString.toUtf8(); + QBuffer inBuffer; + inBuffer.setData(values); + QVERIFY(inBuffer.open(QIODevice::ReadOnly)); + QXmlStreamReader reader(&inBuffer); + do { + reader.readNext(); + } while (!reader.atEnd()); + QCOMPARE((reader.error() == QXmlStreamReader::NoError), expectedResultNoError); +} + +void tst_QXmlStream::invalidStringCharacters_data() const +{ + // test scan in attributes + QTest::addColumn("expectedResultNoError"); + QTest::addColumn("testString"); + QChar ctrl(0x1A); + QTest::newRow("utf8, attributes, legal") << true << QString(""); + QTest::newRow("utf8, attributes, only char, control") << false << QString(""); + QTest::newRow("utf8, attributes, 1st char, control") << false << QString(""); + QTest::newRow("utf8, attributes, middle char, control") << false << QString(""); + QTest::newRow("utf8, attributes, last char, control") << false << QString(""); + // + QTest::newRow("utf8, text, legal") << true << QString("abcx1A"); + QTest::newRow("utf8, text, only, control") << false << QString("")+ctrl+QString(""); + QTest::newRow("utf8, text, 1st char, control") << false << QString("abc")+ctrl+QString("def"); + QTest::newRow("utf8, text, middle char, control") << false << QString("abc")+ctrl+QString("efg"); + QTest::newRow("utf8, text, last char, control") << false << QString("abc")+ctrl+QString(""); + // + QTest::newRow("utf8, cdata text, legal") << true << QString(""); + QTest::newRow("utf8, cdata text, only, control") << false << QString(""); + QTest::newRow("utf8, cdata text, 1st char, control") << false << QString(""); + QTest::newRow("utf8, cdata text, middle char, control") << false << QString(""); + QTest::newRow("utf8, cdata text, last char, control") << false << QString(""); + // + QTest::newRow("utf8, mixed, control") << false << QString(""); + QTest::newRow("utf8, tag") << false << QString(""); + // + QTest::newRow("utf8, attributes, 1st char, legal escaping hex") << true << QString(""); + QTest::newRow("utf8, attributes, 1st char, control escaping hex") << false << QString(""); + QTest::newRow("utf8, attributes, middle char, legal escaping hex") << false << QString(""); + QTest::newRow("utf8, attributes, last char, control escaping hex") << false << QString(""); + QTest::newRow("utf8, attributes, 1st char, legal escaping dec") << true << QString(""); + QTest::newRow("utf8, attributes, 1st char, control escaping dec") << false << QString(""); + QTest::newRow("utf8, attributes, middle char, legal escaping dec") << false << QString(""); + QTest::newRow("utf8, attributes, last char, control escaping dec") << false << QString(""); + QTest::newRow("utf8, tag escaping") << false << QString(""); + // + QTest::newRow("utf8, mix of illegal control") << false << QString(""); + // +} #include "tst_qxmlstream.moc" // vim: et:ts=4:sw=4:sts=4 -- cgit v1.2.3 From 92ccb76550316072801bc26d7e393db78577544a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 14 Jun 2016 12:28:02 +0200 Subject: QUtcTimeZonePrivate::data - skip spurious invalid start state. Most fields were over-written after setting invalid. The two that weren't (not used by QUtcTimeZonePrivate) should be (if only for uniformity with other QTimeZonePrivate variants), so set them to sensible values. Change-Id: I824ca0108d5b6bc322f76a0d1683342f789523b1 Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp index be53a07591..01055bc2c0 100644 --- a/src/corelib/tools/qtimezoneprivate.cpp +++ b/src/corelib/tools/qtimezoneprivate.cpp @@ -650,10 +650,11 @@ QTimeZonePrivate *QUtcTimeZonePrivate::clone() QTimeZonePrivate::Data QUtcTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { - Data d = invalidData(); + Data d; d.abbreviation = m_abbreviation; d.atMSecsSinceEpoch = forMSecsSinceEpoch; - d.offsetFromUtc = m_offsetFromUtc; + d.standardTimeOffset = d.offsetFromUtc = m_offsetFromUtc; + d.daylightTimeOffset = 0; return d; } -- cgit v1.2.3 From 975d21a8c9359dd073f5d1b116f63691565550f6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 14 Jun 2016 12:33:28 +0200 Subject: QTzTimeZonePrivate: missing spaces for readability. Change-Id: If19669750fab89fbe0ac24d98b89fa1ea597fbb9 Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_tz.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index bfa967e67b..29544a5c37 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -894,7 +894,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch - &&!m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { + && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector posixTrans = calculatePosixTransitions(m_posixRule, year - 1, @@ -938,7 +938,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch - &&!m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { + && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector posixTrans = calculatePosixTransitions(m_posixRule, year - 1, @@ -964,7 +964,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch - &&!m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { + && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector posixTrans = calculatePosixTransitions(m_posixRule, year - 1, -- cgit v1.2.3 From dabaaf96b77066f7d3bb113210ac21097c7ad1e2 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 30 May 2016 18:43:10 +0300 Subject: Change compiler flags for Android Same as Google did here: https://android-review.googlesource.com/#/c/207721 Change-Id: I24b964aae6d79aa41b07a6de30da1d124609066d Reviewed-by: Thiago Macieira --- mkspecs/android-g++/qmake.conf | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index ef78c42de9..1ea6a1fa55 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -89,20 +89,16 @@ equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ # modifications to g++.conf QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-gcc +# -fstack-protector-strong offers good protection against stack smashing attacks. +# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it +QMAKE_CFLAGS = -fstack-protector-strong -DANDROID + equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ - QMAKE_CFLAGS = -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove + QMAKE_CFLAGS += -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove else: equals(ANDROID_TARGET_ARCH, armeabi): \ - QMAKE_CFLAGS = -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, x86): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -O2 -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, x86_64): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, mips): \ - QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -O2 -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, mips64): \ - QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Werror -Wa,--noexecstack + QMAKE_CFLAGS += -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove + +# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 QMAKE_CFLAGS_WARN_ON = -Wall -Wno-psabi -W QMAKE_CFLAGS_WARN_OFF = -Wno-psabi @@ -117,19 +113,19 @@ equals(ANDROID_TARGET_ARCH, x86) { } else: equals(ANDROID_TARGET_ARCH, mips) { QMAKE_CFLAGS_RELEASE = -O2 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer + QMAKE_CFLAGS_DEBUG = -g } else: equals(ANDROID_TARGET_ARCH, mips64) { QMAKE_CFLAGS_RELEASE = -O2 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer + QMAKE_CFLAGS_DEBUG = -g } else: equals(ANDROID_TARGET_ARCH, arm64-v8a) { QMAKE_CFLAGS_RELEASE = -O2 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer + QMAKE_CFLAGS_DEBUG = -g } else { # arm - QMAKE_CFLAGS_RELEASE = -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 - QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer + QMAKE_CFLAGS_RELEASE = -Os + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os + QMAKE_CFLAGS_DEBUG = -g -marm -O0 equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND } else { @@ -138,6 +134,9 @@ equals(ANDROID_TARGET_ARCH, x86) { } } +# Don't override our options with -O3 +QMAKE_CFLAGS_OPTIMIZE_FULL = + QMAKE_CFLAGS_SHLIB = -fPIC QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses QMAKE_CFLAGS_THREAD = -D_REENTRANT -- cgit v1.2.3 From 9467bdc9093d9b02e249c6cce508b9df3ff8b2f4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Jun 2016 15:16:55 -0700 Subject: Update QLibrary's debug output when loading failed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were printing 'loaded library "xxx"' even when ret == false, which was misleading. So instead print the error string. Change-Id: Ib57b52598e2f452985e9fffd1459ea860ed2dfcf Reviewed-by: Jędrzej Nowacki Reviewed-by: Oswald Buddenhagen --- src/corelib/plugin/qlibrary.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index f7e57461e3..2b6c983cb8 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -536,8 +536,13 @@ bool QLibraryPrivate::load() return false; bool ret = load_sys(); - if (qt_debug_component()) - qDebug() << "loaded library" << fileName; + if (qt_debug_component()) { + if (ret) { + qDebug() << "loaded library" << fileName; + } else { + qDebug() << qUtf8Printable(errorString); + } + } if (ret) { //when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted //this allows to unload the library at a later time -- cgit v1.2.3 From ea582cdcbf8c5b94f9baf5bffdbedc622d39ed9f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jun 2016 13:57:23 -0700 Subject: Work around Apple defining "check" The header says they'll stop doing that in the next release. It's been like that since at least the OS X 10.8 SDK... Change-Id: Ib57b52598e2f452985e9fffd14585d4838dc8b09 Reviewed-by: Richard J. Moore --- src/corelib/kernel/qeventdispatcher_unix_p.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index df080809b6..32c9de03fa 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -84,6 +84,11 @@ public: }; +#ifdef check +// defined in Apple's /usr/include/AssertMacros.h header +# undef check +#endif + class QEventDispatcherUNIXPrivate; #ifdef Q_OS_QNX -- cgit v1.2.3 From af6f7179e8faf890d7845a68560732f46275e105 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 17 Jun 2016 11:36:09 -0700 Subject: tests/manual: add highdpi subdir to the test list Change-Id: Ib57b52598e2f452985e9fffd1458f2bf00ddc84f Reviewed-by: Oswald Buddenhagen Reviewed-by: Shawn Rutledge --- tests/manual/manual.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 8e77a321dd..801297790e 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -4,6 +4,7 @@ SUBDIRS = bearerex \ filetest \ foreignwindows \ gestures \ +highdpi \ inputmethodhints \ keypadnavigation \ lance \ -- cgit v1.2.3 From 902a5e7aaa0ec156d19b5a7988eff1809a6a2046 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 17 Jun 2016 15:07:26 +0300 Subject: QDataStream: adjust containers' deserialization in transaction mode If an error occurs during the transaction, we should prevent the containers from being successfully read. So, check the status of the stream before reading the container, because the deserialization procedure temporarily resets it on entry. Task-number: QTBUG-54022 Change-Id: Ie955c2fa3e449374f0f8403f00e487efa2bfdaf3 Reviewed-by: Oswald Buddenhagen Reviewed-by: Edward Welbourne --- src/corelib/io/qdatastream.h | 7 +- .../corelib/io/qdatastream/tst_qdatastream.cpp | 144 +++++++++++++-------- 2 files changed, 97 insertions(+), 54 deletions(-) diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index 260dd519e3..e8634fddef 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -63,6 +63,9 @@ template class QMap; #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) class QDataStreamPrivate; +namespace QtPrivate { +class StreamStateSaver; +} class Q_CORE_EXPORT QDataStream { public: @@ -192,6 +195,7 @@ private: Status q_status; int readBlock(char *data, int len); + friend class QtPrivate::StreamStateSaver; }; namespace QtPrivate { @@ -201,7 +205,8 @@ class StreamStateSaver public: inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status()) { - stream->resetStatus(); + if (!stream->dev || !stream->dev->isTransactionStarted()) + stream->resetStatus(); } inline ~StreamStateSaver() { diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index b7e7344b16..447cf2845e 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -2750,27 +2750,43 @@ void tst_QDataStream::status_QBitArray() } #define MAP_TEST(byteArray, initialStatus, expectedStatus, expectedHash) \ - { \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> hash; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(hash.size(), expectedHash.size()); \ - QCOMPARE(hash, expectedHash); \ - } \ - { \ - QByteArray ba = byteArray; \ - StringMap expectedMap; \ - StringHash::const_iterator it = expectedHash.constBegin(); \ - for (; it != expectedHash.constEnd(); ++it) \ - expectedMap.insert(it.key(), it.value()); \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> map; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(map.size(), expectedMap.size()); \ - QCOMPARE(map, expectedMap); \ + for (bool inTransaction = false;; inTransaction = true) { \ + { \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> hash; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(hash.size(), expectedHash.size()); \ + QCOMPARE(hash, expectedHash); \ + } else { \ + QVERIFY(hash.isEmpty()); \ + } \ + } \ + { \ + QByteArray ba = byteArray; \ + StringMap expectedMap; \ + StringHash::const_iterator it = expectedHash.constBegin(); \ + for (; it != expectedHash.constEnd(); ++it) \ + expectedMap.insert(it.key(), it.value()); \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> map; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(map.size(), expectedMap.size()); \ + QCOMPARE(map, expectedMap); \ + } else { \ + QVERIFY(map.isEmpty()); \ + } \ + } \ + if (inTransaction) \ + break; \ } void tst_QDataStream::status_QHash_QMap() @@ -2815,38 +2831,60 @@ void tst_QDataStream::status_QHash_QMap() } #define LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \ - { \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> list; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(list.size(), expectedList.size()); \ - QCOMPARE(list, expectedList); \ - } \ - { \ - LinkedList expectedLinkedList; \ - for (int i = 0; i < expectedList.count(); ++i) \ - expectedLinkedList << expectedList.at(i); \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> linkedList; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(linkedList.size(), expectedLinkedList.size()); \ - QCOMPARE(linkedList, expectedLinkedList); \ - } \ - { \ - Vector expectedVector; \ - for (int i = 0; i < expectedList.count(); ++i) \ - expectedVector << expectedList.at(i); \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> vector; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(vector.size(), expectedVector.size()); \ - QCOMPARE(vector, expectedVector); \ + for (bool inTransaction = false;; inTransaction = true) { \ + { \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> list; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(list.size(), expectedList.size()); \ + QCOMPARE(list, expectedList); \ + } else { \ + QVERIFY(list.isEmpty()); \ + } \ + } \ + { \ + LinkedList expectedLinkedList; \ + for (int i = 0; i < expectedList.count(); ++i) \ + expectedLinkedList << expectedList.at(i); \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> linkedList; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(linkedList.size(), expectedLinkedList.size()); \ + QCOMPARE(linkedList, expectedLinkedList); \ + } else { \ + QVERIFY(linkedList.isEmpty()); \ + } \ + } \ + { \ + Vector expectedVector; \ + for (int i = 0; i < expectedList.count(); ++i) \ + expectedVector << expectedList.at(i); \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> vector; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(vector.size(), expectedVector.size()); \ + QCOMPARE(vector, expectedVector); \ + } else { \ + QVERIFY(vector.isEmpty()); \ + } \ + } \ + if (inTransaction) \ + break; \ } void tst_QDataStream::status_QLinkedList_QList_QVector() -- cgit v1.2.3 From af055964f57dfccc76663bbf8e96b90d0fee984c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 19 Jul 2016 12:48:10 +0200 Subject: moc: fix infinite loop over malformed input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should not call prev() if we had already reched the end. Task-number: QTBUG-54815 Change-Id: I56bc86880a0dbfdce57fc4a08e5950f2ff3a5958 Reviewed-by: Jędrzej Nowacki --- src/tools/moc/moc.cpp | 5 +++++ tests/auto/tools/moc/tst_moc.cpp | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 7dd94cdca7..5534cdd6b8 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Olivier Goffart ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -184,6 +185,8 @@ Type Moc::parseType() case Q_SLOT_TOKEN: type.name += lexem(); return type; + case NOTOKEN: + return type; default: prev(); break; @@ -218,6 +221,8 @@ Type Moc::parseType() type.name += lexem(); isVoid |= (lookup(0) == VOID); break; + case NOTOKEN: + return type; default: prev(); ; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 9d2b883112..7f73e8f23d 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1942,6 +1942,13 @@ void tst_Moc::warnings_data() << 1 << QString("IGNORE_ALL_STDOUT") << QString(":-1: Error: Unexpected character in macro argument list."); + + QTest::newRow("QTBUG-54815: Crash on invalid input") + << QByteArray("class M{(})F<{}d000000000000000#0") + << QStringList() + << 0 + << QString() + << QString("standard input:1: Note: No relevant classes found. No output generated."); } void tst_Moc::warnings() -- cgit v1.2.3 From cc119dee73c6cc46abf8d779a91f0ccad3ce1bd7 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 27 May 2016 15:59:16 +0300 Subject: Workaround clang explicit specializations function templates export bug Should be reverted when https://github.com/android-ndk/ndk/issues/34 is fixed Change-Id: Ic7fe394412afc25082a9689da59d36cba8b3dade Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjni.cpp | 300 ++++++++++++++++++++++---------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 108a01aab7..5a894907a4 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -470,7 +470,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) env->DeleteLocalRef(cls); } template <> -void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); @@ -480,7 +480,7 @@ void QJNIObjectPrivate::callMethodV(const char *methodName, const char *si } template <> -void QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -489,7 +489,7 @@ void QJNIObjectPrivate::callMethod(const char *methodName, const char *sig } template <> -jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -501,7 +501,7 @@ jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const } template <> -jboolean QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -511,7 +511,7 @@ jboolean QJNIObjectPrivate::callMethod(const char *methodName, const c } template <> -jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -523,7 +523,7 @@ jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char * } template <> -jbyte QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -533,7 +533,7 @@ jbyte QJNIObjectPrivate::callMethod(const char *methodName, const char *s } template <> -jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jchar res = 0; @@ -545,7 +545,7 @@ jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char * } template <> -jchar QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -555,7 +555,7 @@ jchar QJNIObjectPrivate::callMethod(const char *methodName, const char *s } template <> -jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jshort res = 0; @@ -567,7 +567,7 @@ jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char } template <> -jshort QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -577,7 +577,7 @@ jshort QJNIObjectPrivate::callMethod(const char *methodName, const char } template <> -jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jint res = 0; @@ -589,7 +589,7 @@ jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *si } template <> -jint QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -599,7 +599,7 @@ jint QJNIObjectPrivate::callMethod(const char *methodName, const char *sig } template <> -jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jlong res = 0; @@ -611,7 +611,7 @@ jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char * } template <> -jlong QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -621,7 +621,7 @@ jlong QJNIObjectPrivate::callMethod(const char *methodName, const char *s } template <> -jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -633,7 +633,7 @@ jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char } template <> -jfloat QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -643,7 +643,7 @@ jfloat QJNIObjectPrivate::callMethod(const char *methodName, const char } template <> -jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -655,7 +655,7 @@ jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const ch } template <> -jdouble QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -665,61 +665,61 @@ jdouble QJNIObjectPrivate::callMethod(const char *methodName, const cha } template <> -void QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethod(const char *methodName) const { callMethod(methodName, "()V"); } template <> -jboolean QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()Z"); } template <> -jbyte QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()B"); } template <> -jchar QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()C"); } template <> -jshort QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()S"); } template <> -jint QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()I"); } template <> -jlong QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()J"); } template <> -jfloat QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()F"); } template <> -jdouble QJNIObjectPrivate::callMethod(const char *methodName) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod(const char *methodName) const { return callMethod(methodName, "()D"); } template <> -void QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -735,7 +735,7 @@ void QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -void QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -747,7 +747,7 @@ void QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -void QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -760,7 +760,7 @@ void QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -void QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -772,7 +772,7 @@ void QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -791,7 +791,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jboolean QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -804,7 +804,7 @@ jboolean QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -820,7 +820,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jboolean QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -833,7 +833,7 @@ jboolean QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -852,7 +852,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jbyte QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -865,7 +865,7 @@ jbyte QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -881,7 +881,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jbyte QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -894,7 +894,7 @@ jbyte QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jchar QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -913,7 +913,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jchar QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -926,7 +926,7 @@ jchar QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -942,7 +942,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jchar QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -955,7 +955,7 @@ jchar QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jshort QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -974,7 +974,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jshort QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -987,7 +987,7 @@ jshort QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1003,7 +1003,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jshort QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -1016,7 +1016,7 @@ jshort QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jint QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -1035,7 +1035,7 @@ jint QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jint QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -1048,7 +1048,7 @@ jint QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1064,7 +1064,7 @@ jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jint QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -1077,7 +1077,7 @@ jint QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jlong QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -1096,7 +1096,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jlong QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -1109,7 +1109,7 @@ jlong QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1125,7 +1125,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jlong QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -1138,7 +1138,7 @@ jlong QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -1157,7 +1157,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jfloat QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -1170,7 +1170,7 @@ jfloat QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1186,7 +1186,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jfloat QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -1199,7 +1199,7 @@ jfloat QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, const char *methodName, const char *sig, va_list args) @@ -1218,7 +1218,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, } template <> -jdouble QJNIObjectPrivate::callStaticMethod(const char *className, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName, const char *sig, ...) @@ -1231,7 +1231,7 @@ jdouble QJNIObjectPrivate::callStaticMethod(const char *className, } template <> -jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1247,7 +1247,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, } template <> -jdouble QJNIObjectPrivate::callStaticMethod(jclass clazz, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...) @@ -1260,109 +1260,109 @@ jdouble QJNIObjectPrivate::callStaticMethod(jclass clazz, } template <> -void QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { callStaticMethod(className, methodName, "()V"); } template <> -void QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { callStaticMethod(clazz, methodName, "()V"); } template <> -jboolean QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()Z"); } template <> -jboolean QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()Z"); } template <> -jbyte QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()B"); } template <> -jbyte QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()B"); } template <> -jchar QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()C"); } template <> -jchar QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()C"); } template <> -jshort QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()S"); } template <> -jshort QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()S"); } template <> -jint QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()I"); } template <> -jint QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()I"); } template <> -jlong QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()J"); } template <> -jlong QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()J"); } template <> -jfloat QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()F"); } template <> -jfloat QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()F"); } template <> -jdouble QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod(const char *className, const char *methodName) { return callStaticMethod(className, methodName, "()D"); } template <> -jdouble QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod(jclass clazz, const char *methodName) { return callStaticMethod(clazz, methodName, "()D"); } @@ -1397,49 +1397,49 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName, } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()Ljava/lang/String;"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[Z"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[B"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[S"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[I"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[J"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[F"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName) const { return callObjectMethod(methodName, "()[D"); } @@ -1510,7 +1510,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz, } template <> -jboolean QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -1522,7 +1522,7 @@ jboolean QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jbyte QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -1534,7 +1534,7 @@ jbyte QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jchar QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jchar res = 0; @@ -1546,7 +1546,7 @@ jchar QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jshort QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jshort res = 0; @@ -1558,7 +1558,7 @@ jshort QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jint QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jint QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jint res = 0; @@ -1570,7 +1570,7 @@ jint QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jlong QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jlong res = 0; @@ -1582,7 +1582,7 @@ jlong QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jfloat QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -1594,7 +1594,7 @@ jfloat QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jdouble QJNIObjectPrivate::getField(const char *fieldName) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -1606,7 +1606,7 @@ jdouble QJNIObjectPrivate::getField(const char *fieldName) const } template <> -jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -1618,7 +1618,7 @@ jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *f } template <> -jboolean QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1633,7 +1633,7 @@ jboolean QJNIObjectPrivate::getStaticField(const char *className, cons } template <> -jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -1645,7 +1645,7 @@ jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa } template <> -jbyte QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1660,7 +1660,7 @@ jbyte QJNIObjectPrivate::getStaticField(const char *className, const char } template <> -jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jchar res = 0; @@ -1672,7 +1672,7 @@ jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa } template <> -jchar QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1687,7 +1687,7 @@ jchar QJNIObjectPrivate::getStaticField(const char *className, const char } template <> -jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jshort res = 0; @@ -1699,7 +1699,7 @@ jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *field } template <> -jshort QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1714,7 +1714,7 @@ jshort QJNIObjectPrivate::getStaticField(const char *className, const ch } template <> -jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jint res = 0; @@ -1726,7 +1726,7 @@ jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName } template <> -jint QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1741,7 +1741,7 @@ jint QJNIObjectPrivate::getStaticField(const char *className, const char * } template <> -jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jlong res = 0; @@ -1753,7 +1753,7 @@ jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa } template <> -jlong QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1768,7 +1768,7 @@ jlong QJNIObjectPrivate::getStaticField(const char *className, const char } template <> -jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -1780,7 +1780,7 @@ jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *field } template <> -jfloat QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1795,7 +1795,7 @@ jfloat QJNIObjectPrivate::getStaticField(const char *className, const ch } template <> -jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -1807,7 +1807,7 @@ jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fie } template <> -jdouble QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1879,7 +1879,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jboolean value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jboolean value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); @@ -1889,7 +1889,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jboolean value } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); @@ -1899,7 +1899,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jchar value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jchar value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); @@ -1909,7 +1909,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jchar value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jshort value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jshort value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); @@ -1919,7 +1919,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jshort value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jint value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jint value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); @@ -1929,7 +1929,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jint value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jlong value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jlong value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); @@ -1939,7 +1939,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jlong value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); @@ -1949,7 +1949,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); @@ -1959,7 +1959,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jbooleanArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jbooleanArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z"); @@ -1969,7 +1969,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jbooleanA } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B"); @@ -1979,7 +1979,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray v } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jcharArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jcharArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C"); @@ -1989,7 +1989,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jcharArray v } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jshortArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jshortArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S"); @@ -1999,7 +1999,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jshortArray } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jintArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jintArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I"); @@ -2009,7 +2009,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jintArray val } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jlongArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jlongArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J"); @@ -2019,7 +2019,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jlongArray v } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F"); @@ -2029,7 +2029,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D"); @@ -2039,7 +2039,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArr } template <> -void QJNIObjectPrivate::setField(const char *fieldName, jstring value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, jstring value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;"); @@ -2049,7 +2049,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jstring value) } template <> -void QJNIObjectPrivate::setField(const char *fieldName, +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, const char *sig, jobject value) { @@ -2061,7 +2061,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, } template <> -void QJNIObjectPrivate::setField(const char *fieldName, +Q_CORE_EXPORT void QJNIObjectPrivate::setField(const char *fieldName, const char *sig, jobjectArray value) { @@ -2073,7 +2073,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jboolean value) { @@ -2084,7 +2084,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jboolean value) { @@ -2101,7 +2101,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jbyte value) { @@ -2112,7 +2112,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jbyte value) { @@ -2129,7 +2129,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jchar value) { @@ -2140,7 +2140,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jchar value) { @@ -2157,7 +2157,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jshort value) { @@ -2168,7 +2168,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jshort value) { @@ -2185,7 +2185,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jint value) { @@ -2196,7 +2196,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jint value) { @@ -2213,7 +2213,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jlong value) { @@ -2224,7 +2224,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jlong value) { @@ -2241,7 +2241,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jfloat value) { @@ -2252,7 +2252,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jfloat value) { @@ -2269,7 +2269,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, jdouble value) { @@ -2280,7 +2280,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, jdouble value) { @@ -2297,7 +2297,7 @@ void QJNIObjectPrivate::setStaticField(const char *className, } template <> -void QJNIObjectPrivate::setStaticField(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(jclass clazz, const char *fieldName, const char *sig, jobject value) @@ -2309,7 +2309,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField(const char *className, const char *fieldName, const char *sig, jobject value) -- cgit v1.2.3 From b2029e9ca6c1645e85cbada1b09ba63fd1ee31ed Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Mon, 4 Jul 2016 13:57:09 +0900 Subject: Bearer/Connman: emit missing updateCompleted() emit missing updateCompleted() in some conditions after QNetworkConfigurationManager::updateConfigurations() is called. * There is no wifi devices. * The wifi device returns error when scan is called. Change-Id: I2668644249a0584bf43efea95348424aa64ab4a6 Reviewed-by: Lorn Potter --- src/plugins/bearer/connman/qconnmanengine.cpp | 10 +++++++--- src/plugins/bearer/connman/qconnmanengine.h | 2 +- src/plugins/bearer/connman/qconnmanservice_linux.cpp | 13 ++++++++++--- src/plugins/bearer/connman/qconnmanservice_linux_p.h | 6 +++--- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index b7cc5f949c..fdedaa46dc 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -85,7 +85,7 @@ void QConnmanEngine::initialize() this, SLOT(updateServices(ConnmanMapList,QList))); connect(connmanManager,SIGNAL(servicesReady(QStringList)),this,SLOT(servicesReady(QStringList))); - connect(connmanManager,SIGNAL(scanFinished()),this,SLOT(finishedScan())); + connect(connmanManager,SIGNAL(scanFinished(bool)),this,SLOT(finishedScan(bool))); foreach (const QString &servPath, connmanManager->getServices()) { addServiceConfiguration(servPath); @@ -197,11 +197,15 @@ void QConnmanEngine::requestUpdate() void QConnmanEngine::doRequestUpdate() { - connmanManager->requestScan("wifi"); + bool scanned = connmanManager->requestScan("wifi"); + if (!scanned) + Q_EMIT updateCompleted(); } -void QConnmanEngine::finishedScan() +void QConnmanEngine::finishedScan(bool error) { + if (error) + Q_EMIT updateCompleted(); } void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList &removed) diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index 8c79b22bf9..c499886261 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -94,7 +94,7 @@ private Q_SLOTS: void updateServices(const ConnmanMapList &changed, const QList &removed); void servicesReady(const QStringList &); - void finishedScan(); + void finishedScan(bool error); void changedModem(); void serviceStateChanged(const QString &state); void configurationChange(QConnmanServiceInterface * service); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 10d8285a4a..40bab4fda6 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -243,13 +243,16 @@ QStringList QConnmanManagerInterface::getServices() return servicesList; } -void QConnmanManagerInterface::requestScan(const QString &type) +bool QConnmanManagerInterface::requestScan(const QString &type) { + bool scanned = false; Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) { if (tech->type() == type) { tech->scan(); + scanned = true; } } + return scanned; } void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, const QVariantMap &) @@ -259,7 +262,7 @@ void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, cons QConnmanTechnologyInterface *tech; tech = new QConnmanTechnologyInterface(path.path(),this); technologiesMap.insert(path.path(),tech); - connect(tech,SIGNAL(scanFinished()),this,SIGNAL(scanFinished())); + connect(tech,SIGNAL(scanFinished(bool)),this,SIGNAL(scanFinished(bool))); } } @@ -495,7 +498,11 @@ void QConnmanTechnologyInterface::scan() void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call) { - Q_EMIT scanFinished(); + QDBusPendingReply props_reply = *call; + if (props_reply.isError()) { + qDebug() << props_reply.error().message(); + } + Q_EMIT scanFinished(props_reply.isError()); call->deleteLater(); } diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index 7292736e2e..b199a17af3 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -108,7 +108,7 @@ public: bool getOfflineMode(); QStringList getTechnologies(); QStringList getServices(); - void requestScan(const QString &type); + bool requestScan(const QString &type); QHash technologiesMap; @@ -119,7 +119,7 @@ Q_SIGNALS: void servicesChanged(const ConnmanMapList&, const QList &); void servicesReady(const QStringList &); - void scanFinished(); + void scanFinished(bool error); protected: void connectNotify(const QMetaMethod &signal); @@ -204,7 +204,7 @@ public: Q_SIGNALS: void propertyChanged(const QString &, const QDBusVariant &value); void propertyChangedContext(const QString &,const QString &,const QDBusVariant &); - void scanFinished(); + void scanFinished(bool error); protected: void connectNotify(const QMetaMethod &signal); QVariant getProperty(const QString &); -- cgit v1.2.3 From c14c149b51a1c7bf01e4e039f6e8cf1819e37ca6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 19 Jul 2016 10:18:39 +0200 Subject: Fix QTemporaryDir to handle Unicode characters on Windows For platforms not providing mkdtemp(), QTemporaryDir relied on an implementation of q_mkdtemp() operating on char *, converting back and forth using QFile::encodeName()/decodeName() when passing the name to QFileSystemEngine. This caused failures on Windows (which uses "System"/Latin1 encoding) for names containing characters outside the Latin1 space. Reimplement q_mkdtemp() to operate on QString, which avoids the conversions altogether and also enables the use of larger character spaces for the pattern. Add tests. Task-number: QTBUG-54810 Change-Id: Ie4323ad73b5beb8a1b8ab81425f73d03c626d58a Reviewed-by: Thiago Macieira --- src/corelib/io/qtemporarydir.cpp | 52 +++++++++++++--------- .../corelib/io/qtemporarydir/tst_qtemporarydir.cpp | 41 +++++++++++++++++ .../io/qtemporaryfile/tst_qtemporaryfile.cpp | 41 +++++++++++++++++ 3 files changed, 112 insertions(+), 22 deletions(-) diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 71436c6497..d869318e35 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -44,8 +44,12 @@ #include "qcoreapplication.h" #endif +#if !defined(Q_OS_QNX) && !defined(Q_OS_WIN) &&!defined(Q_OS_ANDROID) +# define USE_SYSTEM_MKDTEMP +#endif + #include // mkdtemp -#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) +#ifndef USE_SYSTEM_MKDTEMP #include #endif @@ -91,8 +95,7 @@ static QString defaultTemplateName() return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX"); } -#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) - +#ifndef USE_SYSTEM_MKDTEMP static int nextRand(int &v) { int r = v % 62; @@ -102,30 +105,28 @@ static int nextRand(int &v) return r; } -QPair q_mkdtemp(char *templateName) +QPair q_mkdtemp(QString templateName) { - static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + Q_ASSERT(templateName.endsWith(QLatin1String("XXXXXX"))); - const size_t length = strlen(templateName); + static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - char *XXXXXX = templateName + length - 6; + const int length = templateName.size(); - Q_ASSERT((length >= 6u) && strncmp(XXXXXX, "XXXXXX", 6) == 0); + QChar *XXXXXX = templateName.data() + length - 6; for (int i = 0; i < 256; ++i) { int v = qrand(); /* Fill in the random bits. */ - XXXXXX[0] = letters[nextRand(v)]; - XXXXXX[1] = letters[nextRand(v)]; - XXXXXX[2] = letters[nextRand(v)]; - XXXXXX[3] = letters[nextRand(v)]; - XXXXXX[4] = letters[nextRand(v)]; - XXXXXX[5] = letters[v % 62]; - - QString templateNameStr = QFile::decodeName(templateName); - - QFileSystemEntry fileSystemEntry(templateNameStr); + XXXXXX[0] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[1] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[2] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[3] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[4] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[5] = QLatin1Char(letters[v % 62]); + + QFileSystemEntry fileSystemEntry(templateName); if (QFileSystemEngine::createDirectory(fileSystemEntry, false)) { QSystemError error; QFileSystemEngine::setPermissions(fileSystemEntry, @@ -134,10 +135,10 @@ QPair q_mkdtemp(char *templateName) QFile::ExeOwner, error); if (error.error() != 0) { if (!QFileSystemEngine::removeDirectory(fileSystemEntry, false)) - qWarning() << "Unable to remove unused directory" << templateNameStr; + qWarning() << "Unable to remove unused directory" << templateName; continue; } - return qMakePair(QFile::decodeName(templateName), true); + return qMakePair(templateName, true); } # ifdef Q_OS_WIN const int exists = ERROR_ALREADY_EXISTS; @@ -152,7 +153,7 @@ QPair q_mkdtemp(char *templateName) return qMakePair(qt_error_string(), false); } -#else // defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) +#else // !USE_SYSTEM_MKDTEMP QPair q_mkdtemp(char *templateName) { @@ -160,14 +161,21 @@ QPair q_mkdtemp(char *templateName) return qMakePair(ok ? QFile::decodeName(templateName) : qt_error_string(), ok); } -#endif +#endif // USE_SYSTEM_MKDTEMP void QTemporaryDirPrivate::create(const QString &templateName) { +#ifndef USE_SYSTEM_MKDTEMP + QString buffer = templateName; + if (!buffer.endsWith(QLatin1String("XXXXXX"))) + buffer += QLatin1String("XXXXXX"); + const QPair result = q_mkdtemp(buffer); +#else // !USE_SYSTEM_MKDTEMP QByteArray buffer = QFile::encodeName(templateName); if (!buffer.endsWith("XXXXXX")) buffer += "XXXXXX"; QPair result = q_mkdtemp(buffer.data()); // modifies buffer +#endif // USE_SYSTEM_MKDTEMP pathOrError = result.first; success = result.second; } diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 6e03d8360e..67a39f21ca 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef Q_OS_WIN # include #endif @@ -113,6 +114,38 @@ void tst_QTemporaryDir::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } +static inline bool canHandleUnicodeFileNames() +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + return true; +#else + // Check for UTF-8 by converting the Euro symbol (see tst_utf8) + return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); +#endif +} + +static QString hanTestText() +{ + QString text; + text += QChar(0x65B0); + text += QChar(0x5E10); + text += QChar(0x6237); + return text; +} + +static QString umlautTestText() +{ + QString text; + text += QChar(0xc4); + text += QChar(0xe4); + text += QChar(0xd6); + text += QChar(0xf6); + text += QChar(0xdc); + text += QChar(0xfc); + text += QChar(0xdf); + return text; +} + void tst_QTemporaryDir::fileTemplate_data() { QTest::addColumn("constructorTemplate"); @@ -129,6 +162,14 @@ void tst_QTemporaryDir::fileTemplate_data() QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_"; QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_"; QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_"; + if (canHandleUnicodeFileNames()) { + // Test Umlauts (contained in Latin1) + QString prefix = "qt_" + umlautTestText(); + QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix; + // Test Chinese + prefix = "qt_" + hanTestText(); + QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix; + } } void tst_QTemporaryDir::fileTemplate() diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 7b06355990..7fdc8fd44c 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #if defined(Q_OS_WIN) # include @@ -145,6 +146,38 @@ void tst_QTemporaryFile::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } +static inline bool canHandleUnicodeFileNames() +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + return true; +#else + // Check for UTF-8 by converting the Euro symbol (see tst_utf8) + return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); +#endif +} + +static QString hanTestText() +{ + QString text; + text += QChar(0x65B0); + text += QChar(0x5E10); + text += QChar(0x6237); + return text; +} + +static QString umlautTestText() +{ + QString text; + text += QChar(0xc4); + text += QChar(0xe4); + text += QChar(0xd6); + text += QChar(0xf6); + text += QChar(0xdc); + text += QChar(0xfc); + text += QChar(0xdf); + return text; +} + void tst_QTemporaryFile::fileTemplate_data() { QTest::addColumn("constructorTemplate"); @@ -171,6 +204,14 @@ void tst_QTemporaryFile::fileTemplate_data() QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx"; QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx"; QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX"; + if (canHandleUnicodeFileNames()) { + // Test Umlauts (contained in Latin1) + QString prefix = "qt_" + umlautTestText(); + QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix << QString() << QString(); + // Test Chinese + prefix = "qt_" + hanTestText(); + QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix << QString() << QString(); + } } void tst_QTemporaryFile::fileTemplate() -- cgit v1.2.3 From b828c94eace2df976ba8ab534f9c50195cda8733 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 15 Jul 2016 08:27:23 +0200 Subject: Document that -nocrashhandler enables debugging of crashes It's not clear why an assertion triggered while running a test can't be debugged, while the same assertion triggered while running an application can. Even though this documentation might still not be the place people will look, hopefully having the terms "debugging crashes" here will make it more visible in search results. Task-number: QTBUG-54779 Change-Id: I151b04380df57126259d3d7797957a548eb6cd55 Reviewed-by: Thiago Macieira --- src/testlib/doc/src/qttestlib-manual.qdoc | 2 +- src/testlib/qtestcase.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 781eec0560..d8e2dc2516 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -251,7 +251,7 @@ \li \c -nocrashhandler \br Disables the crash handler on Unix platforms. On Windows, it re-enables the Windows Error Reporting dialog, which is - turned off by default. + turned off by default. This is useful for debugging crashes. \li \c -platform \e name \br This command line argument applies to all Qt applications, but might be diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index eae490e278..d674b0af7a 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1680,7 +1680,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n" " -maxwarnings n : Sets the maximum amount of messages to output.\n" " 0 means unlimited, default: 2000\n" - " -nocrashhandler : Disables the crash handler\n" + " -nocrashhandler : Disables the crash handler. Useful for debugging crashes.\n" "\n" " Benchmarking options:\n" #ifdef QTESTLIB_USE_VALGRIND -- cgit v1.2.3 From d2c98368d7885108112897230130adc2b459dc12 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 14 Jun 2016 13:50:57 +0200 Subject: Doc: Add a thumbnail for an example that has no UI Without this change, Qt Creator tags this example as "broken" and hides it from the Examples tab in the Welcome mode. Change-Id: If1982495ec68f5cebb931f5e9498258af21f5aa7 Reviewed-by: Venugopal Shivashankar --- doc/global/manifest-meta.qdocconf | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index 6b4e3410c9..f928a89f6a 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -254,6 +254,7 @@ manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \ "QtHelp/*" \ "QtMultimedia/AudioEngine Example" \ "QtQml/Extending QML*" \ + "QtQuick/C++ Extensions: Image Response Provider Example" \ "QtQuick/Qt Quick Examples - Accessibility" \ "QtSensors/Qt Sensors - SensorGesture QML Type example" \ "QtWinExtras/Icon Extractor" -- cgit v1.2.3 From aeb36d5292abd979b9c064877f3ed1b4da961c4e Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Thu, 9 Jun 2016 18:37:59 +0300 Subject: QAbstractSocket: ensure bind()+connect() works on delayed close While connecting, the socket goes through the HostLookupState. In this state, the socket engine is not yet created, unless the socket had previously been bound. When it has been bound, we should keep the socket engine even if the user initiates a delayed close by using the write()+close() sequence. Change-Id: Iefebcb33cd72cb49617acbac8e02af9d8209c869 Reviewed-by: Edward Welbourne --- src/network/socket/qabstractsocket.cpp | 13 +++---------- tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 098739adc3..88237dc416 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2651,9 +2651,8 @@ void QAbstractSocket::setPeerName(const QString &name) } /*! - Closes the I/O device for the socket, disconnects the socket's connection with the - host, closes the socket, and resets the name, address, port number and underlying - socket descriptor. + Closes the I/O device for the socket and calls disconnectFromHost() + to close the socket's connection. See QIODevice::close() for a description of the actions that occur when an I/O device is closed. @@ -2669,13 +2668,6 @@ void QAbstractSocket::close() QIODevice::close(); if (d->state != UnconnectedState) disconnectFromHost(); - - d->localPort = 0; - d->peerPort = 0; - d->localAddress.clear(); - d->peerAddress.clear(); - d->peerName.clear(); - d->cachedSocketDescriptor = -1; } /*! @@ -2778,6 +2770,7 @@ void QAbstractSocket::disconnectFromHost() d->peerPort = 0; d->localAddress.clear(); d->peerAddress.clear(); + d->peerName.clear(); d->setWriteChannelCount(0); #if defined(QABSTRACTSOCKET_DEBUG) diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 6bb502edcb..fb6b0c6e32 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -673,6 +673,12 @@ void tst_QTcpSocket::bindThenResolveHost() const quint16 port = 80; socket->connectToHost(hostName, port); + // Additionally, initiate a delayed close before the socket connects + // to ensure that we don't lose the socket engine in HostLookupState. + // After a connection has been established, socket should send all + // the pending data and close the socket engine automatically. + QVERIFY(socket->putChar(0)); + socket->close(); QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' ' + QtNetworkSettings::msgSocketError(*socket)).constData()); -- cgit v1.2.3 From e6034a4740756334317ab2445b518a645930f4f4 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 20 Jul 2016 14:56:01 +0300 Subject: Make sure JNI_OnLoad is not called more than once Since Android 5.0 Google introduce a nasty bug[1] which calls JNI_OnLoad more than once. Basically every time when a library is loaded JNI_OnLoad is called if found, but it calls *again* JNI_OnLoad of its .so dependencies! So, JNI_OnLoad of libQt5Core.so gets called may times, this is not a problem as long as it's called from Qt's java delegate class loader. The problem is that the application .so file *must* be called from default class loader to allow the user to find his custom Activity/Service stuff. [1] Workaround https://code.google.com/p/android/issues/detail?id=215069 Change-Id: Ia71209658ef56056b560018597608acf7cb0f9ea Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjnionload.cpp | 5 +++++ src/plugins/platforms/android/androidjnimain.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/corelib/kernel/qjnionload.cpp b/src/corelib/kernel/qjnionload.cpp index 0f7b4b69ef..3bfcf3e666 100644 --- a/src/corelib/kernel/qjnionload.cpp +++ b/src/corelib/kernel/qjnionload.cpp @@ -38,6 +38,11 @@ Q_CORE_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { Q_UNUSED(reserved) + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + typedef union { JNIEnv *nenv; void *venv; diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index ac37e7bd92..671dad98b2 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -822,6 +822,11 @@ QT_END_NAMESPACE Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) { + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + QT_USE_NAMESPACE typedef union { JNIEnv *nativeEnvironment; -- cgit v1.2.3 From 2b9b9a38e7273f640b6d1f3e174e8204cf7d81dd Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 19 Jul 2016 14:56:06 +0100 Subject: QOpenGLVertexArrayObject: clean up the destructor Calling QOpenGLContext::surface() on a non-current context will likely return NULL, so the code path that tried to reset the old context as current would actually fail. Change-Id: Ibbc8da877740a596aa7dd0af8ccffb9a1877290a Reviewed-by: Sean Harmer --- src/gui/opengl/qopenglvertexarrayobject.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 2a1b7f4bf4..33c38519cc 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -352,9 +352,11 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() Q_D(QOpenGLVertexArrayObject); QOpenGLContext *oldContext = 0; + QSurface *oldContextSurface = 0; QScopedPointer offscreenSurface; if (d->context && ctx && d->context != ctx) { oldContext = ctx; + oldContextSurface = ctx->surface(); // Cannot just make the current surface current again with another context. // The format may be incompatible and some platforms (iOS) may impose // restrictions on using a window with different contexts. Create an @@ -374,7 +376,7 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() destroy(); if (oldContext) { - if (!oldContext->makeCurrent(oldContext->surface())) + if (!oldContext->makeCurrent(oldContextSurface)) qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to restore current context"); } } -- cgit v1.2.3 From 68f22d84ab795d53b25635c641c47b1577f8fbc2 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 20 Jul 2016 10:12:59 +0300 Subject: Android: Add support for clang compiler [ChangeLog][Android] Added support for clang compiler Task-number: QTBUG-50724 Change-Id: I6147021b814fcb230d125c4450c554a7fea8f31e Reviewed-by: Eskil Abrahamsen Blomfeldt --- configure | 17 ++- mkspecs/android-clang/qmake.conf | 32 ++++++ mkspecs/android-clang/qplatformdefs.h | 176 ++++++++++++++++++++++++++++++ mkspecs/android-g++/qmake.conf | 197 +--------------------------------- mkspecs/common/android-base-head.conf | 78 ++++++++++++++ mkspecs/common/android-base-tail.conf | 105 ++++++++++++++++++ 6 files changed, 407 insertions(+), 198 deletions(-) create mode 100644 mkspecs/android-clang/qmake.conf create mode 100644 mkspecs/android-clang/qplatformdefs.h create mode 100644 mkspecs/common/android-base-head.conf create mode 100644 mkspecs/common/android-base-tail.conf diff --git a/configure b/configure index e0228a9bfb..a1f0a8fecb 100755 --- a/configure +++ b/configure @@ -3016,7 +3016,10 @@ case "$XPLATFORM" in *unsupported*) ;; *android-g++*) - XPLATFORM_ANDROID=yes + XPLATFORM_ANDROID=g++ + ;; + *android-clang*) + XPLATFORM_ANDROID=clang ;; esac @@ -3220,7 +3223,7 @@ if ( [ "$CFG_XCB" = "system" ] || [ "$CFG_XCB" = "qt" ] ) && [ "$CFG_XKBCOMMON" exit 101 fi -if [ "$XPLATFORM_ANDROID" = "yes" ]; then +if [ "$XPLATFORM_ANDROID" != "no" ]; then if [ "$CFG_DBUS" = "auto" ]; then CFG_DBUS="no" fi @@ -3444,7 +3447,7 @@ QMAKE_CONF_COMPILER=`getXQMakeConf QMAKE_CXX` TEST_COMPILER=$QMAKE_CONF_COMPILER -if [ "$XPLATFORM_ANDROID" = "yes" ] ; then +if [ "$XPLATFORM_ANDROID" != "no" ] ; then ANDROID_NDK_TOOLCHAIN_PREFIX= ANDROID_NDK_TOOLS_PREFIX= ANDROID_PLATFORM_ARCH= @@ -3484,7 +3487,11 @@ if [ "$XPLATFORM_ANDROID" = "yes" ] ; then exit 1 ;; esac - QMAKE_CONF_COMPILER=$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/$ANDROID_NDK_TOOLCHAIN_PREFIX-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST/bin/$ANDROID_NDK_TOOLS_PREFIX-g++ + if [ "$XPLATFORM_ANDROID" = "g++" ] ; then + QMAKE_CONF_COMPILER=$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/$ANDROID_NDK_TOOLCHAIN_PREFIX-$CFG_DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST/bin/$ANDROID_NDK_TOOLS_PREFIX-g++ + else + QMAKE_CONF_COMPILER=$CFG_DEFAULT_ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$CFG_DEFAULT_ANDROID_NDK_HOST/bin/clang++ + fi TEST_COMPILER="$QMAKE_CONF_COMPILER --sysroot=$CFG_DEFAULT_ANDROID_NDK_ROOT/platforms/$CFG_DEFAULT_ANDROID_PLATFORM/$ANDROID_PLATFORM_ARCH/" if [ "$CFG_ANDROID_STYLE_ASSETS" = "yes" ]; then QMAKE_CONFIG="$QMAKE_CONFIG android-style-assets" @@ -4586,7 +4593,7 @@ elif [ "$CFG_ARCH" != "mips" ]; then fi [ "$XPLATFORM_MINGW" = "yes" ] && QMakeVar add styles "windowsxp windowsvista" -[ "$XPLATFORM_ANDROID" = "yes" ] && QMakeVar add styles "android" +[ "$XPLATFORM_ANDROID" != "no" ] && QMakeVar add styles "android" # check IPC support if ! compileTest unix/ipc_sysv "ipc_sysv" ; then diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf new file mode 100644 index 0000000000..6d53bb921d --- /dev/null +++ b/mkspecs/android-clang/qmake.conf @@ -0,0 +1,32 @@ +# qmake configuration for building with android-g++ +MAKEFILE_GENERATOR = UNIX +QMAKE_PLATFORM = android +QMAKE_COMPILER = gcc clang llvm + +CONFIG += android_install unversioned_soname unversioned_libname android_deployment_settings + +include(../common/linux.conf) +include(../common/clang.conf) +include(../common/android-base-head.conf) + +NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST +QMAKE_CC = $$NDK_LLVM_PATH/bin/clang +QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++ +QMAKE_GCC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++ + +equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + QMAKE_CFLAGS = -target armv7-none-linux-androideabi +else: equals(ANDROID_TARGET_ARCH, armeabi): \ + QMAKE_CFLAGS = -target armv5te-none-linux-androideabi +else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ + QMAKE_CFLAGS = -target aarch64-none-linux-android +else: equals(ANDROID_TARGET_ARCH, x86): \ + QMAKE_CFLAGS = -target i686-none-linux-android +else: equals(ANDROID_TARGET_ARCH, x86_64): \ + QMAKE_CFLAGS = -target x86_64-none-linux-android +else: equals(ANDROID_TARGET_ARCH, mips): \ + QMAKE_CFLAGS += -target mipsel-none-linux-android +else: equals(ANDROID_TARGET_ARCH, mips64): \ + QMAKE_CFLAGS = -target mips64el-none-linux-android + +include(../common/android-base-tail.conf) diff --git a/mkspecs/android-clang/qplatformdefs.h b/mkspecs/android-clang/qplatformdefs.h new file mode 100644 index 0000000000..9d3820fa27 --- /dev/null +++ b/mkspecs/android-clang/qplatformdefs.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +#define QT_QPA_DEFAULT_PLATFORM_NAME "android" + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +// 1) need to reset default environment if _BSD_SOURCE is defined +// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 +// 3) it seems older glibc need this to include the X/Open stuff + +#include + +// We are hot - unistd.h should have turned on the specific APIs we requested + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_IPV6IFNAME +#include +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_STATBUF struct stat64 +#define QT_STATBUF4TSTAT struct stat64 +#define QT_STAT ::stat64 +#define QT_FSTAT ::fstat64 +#define QT_LSTAT ::lstat64 +#define QT_OPEN ::open64 +#define QT_TRUNCATE ::truncate64 +#define QT_FTRUNCATE ::ftruncate64 +#define QT_LSEEK ::lseek64 +#else +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::lstat +#define QT_OPEN ::open +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_FOPEN ::fopen64 +#define QT_FSEEK ::fseeko64 +#define QT_FTELL ::ftello64 +#define QT_FGETPOS ::fgetpos64 +#define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 +#define QT_FPOS_T fpos64_t +#define QT_OFF_T off64_t +#else +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseek +#define QT_FTELL ::ftell +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap +#define QT_FPOS_T fpos_t +#define QT_OFF_T long +#endif + +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_CLOSE ::close +#define QT_READ ::read +#define QT_WRITE ::write +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR ::mkdir +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE O_LARGEFILE +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +// Directory iteration +#define QT_DIR DIR + +#define QT_OPENDIR ::opendir +#define QT_CLOSEDIR ::closedir + +#if defined(QT_LARGEFILE_SUPPORT) \ + && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \ + && !defined(QT_NO_READDIR64) +#define QT_DIRENT struct dirent64 +#define QT_READDIR ::readdir64 +#define QT_READDIR_R ::readdir64_r +#else +#define QT_DIRENT struct dirent +#define QT_READDIR ::readdir +#define QT_READDIR_R ::readdir_r +#endif + +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind + + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE SIG_IGN + +#define QT_SOCKLEN_T socklen_t + +#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf +#endif + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 1ea6a1fa55..93bd5fa1c2 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -7,201 +7,12 @@ CONFIG += android_install unversioned_soname unversioned_libname include(../common/linux.conf) include(../common/gcc-base-unix.conf) +include(../common/android-base-head.conf) -load(device_config) - -NDK_ROOT = $$(ANDROID_NDK_ROOT) -!exists($$NDK_ROOT) { - NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT -} - -NDK_HOST = $$(ANDROID_NDK_HOST) -isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST - -ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) -isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM - -ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH) -isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH - -NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) -isEmpty(NDK_TOOLCHAIN_PREFIX) { - equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 - else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 - else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android - else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android - else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi -} - -NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX) -isEmpty(NDK_TOOLS_PREFIX) { - equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android - else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android - else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android - else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android - else: NDK_TOOLS_PREFIX = arm-linux-androideabi -} - -NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) -isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION - -equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86 -else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64 -else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips -else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64 -else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64 -else: ANDROID_ARCHITECTURE = arm - -!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION - -NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION -NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST - - -ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT) -isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT - -ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION) -isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) { - SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*) - for (REVISION, SDK_BUILD_TOOLS_REVISIONS) { - BASENAME = $$basename(REVISION) - greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME - } -} - -CONFIG += $$ANDROID_PLATFORM -ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ -ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr - -# used to compile platform plugins for android-4 and android-5 -QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include -QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib - -ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH -ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include - -equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ - QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64 - -# modifications to g++.conf QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-gcc - -# -fstack-protector-strong offers good protection against stack smashing attacks. -# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it -QMAKE_CFLAGS = -fstack-protector-strong -DANDROID - -equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ - QMAKE_CFLAGS += -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove -else: equals(ANDROID_TARGET_ARCH, armeabi): \ - QMAKE_CFLAGS += -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove - -# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 - -QMAKE_CFLAGS_WARN_ON = -Wall -Wno-psabi -W -QMAKE_CFLAGS_WARN_OFF = -Wno-psabi -equals(ANDROID_TARGET_ARCH, x86) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, x86_64) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, mips) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, mips64) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, arm64-v8a) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else { # arm - QMAKE_CFLAGS_RELEASE = -Os - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os - QMAKE_CFLAGS_DEBUG = -g -marm -O0 - equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { - DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND - } else { - QMAKE_CFLAGS_RELEASE += -mthumb - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb - } -} - -# Don't override our options with -O3 -QMAKE_CFLAGS_OPTIMIZE_FULL = - -QMAKE_CFLAGS_SHLIB = -fPIC -QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CFLAGS_THREAD = -D_REENTRANT -QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden - QMAKE_CXX = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=c++11 -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD -QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_LINK - -# modifications to linux.conf -QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs -QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy -QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P - -QMAKE_STRIP = -#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip - -QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib - -equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ - LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -mthumb-interwork -print-libgcc-file-name") -else: \ - LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -print-libgcc-file-name") - -LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL) - -QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH -QMAKE_INCDIR_X11 = -QMAKE_LIBDIR_X11 = -QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX -QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR -QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared -QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined -QMAKE_LFLAGS_RPATH = -Wl,-rpath= -QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link= - -QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc -QMAKE_LIBS_X11 = -QMAKE_LIBS_THREAD = -QMAKE_LIBS_EGL = -lEGL -QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 - -!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") +QMAKE_GCC = $$QMAKE_CXX -load(qt_config) +QMAKE_CFLAGS = -QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR -QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR +include(../common/android-base-tail.conf) diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf new file mode 100644 index 0000000000..7b2e988808 --- /dev/null +++ b/mkspecs/common/android-base-head.conf @@ -0,0 +1,78 @@ +load(device_config) + +NDK_ROOT = $$(ANDROID_NDK_ROOT) +!exists($$NDK_ROOT) { + NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT +} + +NDK_HOST = $$(ANDROID_NDK_HOST) +isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST + +ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) +isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM + +ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH) +isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH + +NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) +isEmpty(NDK_TOOLCHAIN_PREFIX) { + equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 + else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 + else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android + else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android + else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi +} + +NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX) +isEmpty(NDK_TOOLS_PREFIX) { + equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android + else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android + else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android + else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android + else: NDK_TOOLS_PREFIX = arm-linux-androideabi +} + +NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) +isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION + +equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86 +else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64 +else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips +else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64 +else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64 +else: ANDROID_ARCHITECTURE = arm + +!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION + +NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION +NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST + + +ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT) +isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT + +ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION) +isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) { + SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*) + for (REVISION, SDK_BUILD_TOOLS_REVISIONS) { + BASENAME = $$basename(REVISION) + greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME + } +} + +CONFIG += $$ANDROID_PLATFORM +ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ +ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr + +# used to compile platform plugins for android-4 and android-5 +QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include +QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib + +ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH +ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include + +equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ + QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64 + diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf new file mode 100644 index 0000000000..0dcaf64cff --- /dev/null +++ b/mkspecs/common/android-base-tail.conf @@ -0,0 +1,105 @@ +# -fstack-protector-strong offers good protection against stack smashing attacks. +# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it +QMAKE_CFLAGS += -fstack-protector-strong -DANDROID + +equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove +else: equals(ANDROID_TARGET_ARCH, armeabi): \ + QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove +# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 + +QMAKE_CFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +QMAKE_CFLAGS_WARN_ON = -Wall -W +QMAKE_CFLAGS_WARN_OFF = +equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) { + QMAKE_CFLAGS_RELEASE = -Os + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os + QMAKE_CFLAGS_DEBUG = -g -marm -O0 + equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { + DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND + } else { + QMAKE_CFLAGS_RELEASE += -mthumb + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb + } + + # Don't override our options with -O3 + QMAKE_CFLAGS_OPTIMIZE_FULL = +} else { + QMAKE_CFLAGS_RELEASE = -O2 + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 + QMAKE_CFLAGS_DEBUG = -g +} + +QMAKE_CFLAGS_SHLIB = -fPIC +QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden +QMAKE_CFLAGS_NEON = -mfpu=neon + +QMAKE_CXXFLAGS_CXX11 = -std=c++11 +QMAKE_CXXFLAGS_CXX14 = -std=c++14 +QMAKE_CXXFLAGS_CXX1Z = -std=c++1z +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 +QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++14 +QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z + +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD +QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden + +# modifications to linux.conf +QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs +QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy +QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P + +QMAKE_STRIP = +#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip + +QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib + +equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -mthumb-interwork -print-libgcc-file-name") +else: \ + LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -print-libgcc-file-name") + +LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL) + +QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = +QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR + +QMAKE_LINK = $$QMAKE_GCC +QMAKE_LINK_SHLIB = $$QMAKE_GCC +QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR +QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared +QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared +QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined +QMAKE_LFLAGS_RPATH = -Wl,-rpath= +QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link= + +QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc +QMAKE_LIBS_X11 = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_EGL = -lEGL +QMAKE_LIBS_OPENGL = +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 + + +!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") + +load(qt_config) + +QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR +QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR -- cgit v1.2.3 From 1ef8c640f8d2ef57f6779dd2749058a082394bcc Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 20 Jul 2016 11:43:34 +0300 Subject: Workaround clang function export bug Should be reverted when https://github.com/android-ndk/ndk/issues/142 is fixed. Change-Id: Ie68807062247bee4969bc9aa00b0221c8147fed7 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/opengl/qopengltexturehelper_p.h | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h index d659fcedfb..fa055cd28a 100644 --- a/src/gui/opengl/qopengltexturehelper_p.h +++ b/src/gui/opengl/qopengltexturehelper_p.h @@ -69,6 +69,14 @@ QT_BEGIN_NAMESPACE #define GL_TEXTURE_COMPARE_FUNC 0x884D #endif +// use GL_APICALL only on Android + __clang__ +#if !defined(Q_OS_ANDROID) || !defined(__clang__) +# undef GL_APICALL +# define GL_APICALL +#elif !defined(GL_APICALL) +# define GL_APICALL +#endif + class QOpenGLContext; class QOpenGLTextureHelper @@ -821,26 +829,26 @@ private: void (QOPENGLF_APIENTRYP TextureImage2DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); // OpenGL 1.0 - void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetBooleanv)(GLenum pname, GLboolean *params); - void (QOPENGLF_APIENTRYP PixelStorei)(GLenum pname, GLint param); + GL_APICALL void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params); + GL_APICALL void (QOPENGLF_APIENTRYP GetBooleanv)(GLenum pname, GLboolean *params); + GL_APICALL void (QOPENGLF_APIENTRYP PixelStorei)(GLenum pname, GLint param); void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetTexParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params); + GL_APICALL void (QOPENGLF_APIENTRYP GetTexParameteriv)(GLenum target, GLenum pname, GLint *params); + GL_APICALL void (QOPENGLF_APIENTRYP GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params); void (QOPENGLF_APIENTRYP GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); void (QOPENGLF_APIENTRYP TexImage2D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void (QOPENGLF_APIENTRYP TexImage1D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexParameteriv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP TexParameteri)(GLenum target, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP TexParameterf)(GLenum target, GLenum pname, GLfloat param); + GL_APICALL void (QOPENGLF_APIENTRYP TexParameteriv)(GLenum target, GLenum pname, const GLint *params); + GL_APICALL void (QOPENGLF_APIENTRYP TexParameteri)(GLenum target, GLenum pname, GLint param); + GL_APICALL void (QOPENGLF_APIENTRYP TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params); + GL_APICALL void (QOPENGLF_APIENTRYP TexParameterf)(GLenum target, GLenum pname, GLfloat param); // OpenGL 1.1 - void (QOPENGLF_APIENTRYP GenTextures)(GLsizei n, GLuint *textures); - void (QOPENGLF_APIENTRYP DeleteTextures)(GLsizei n, const GLuint *textures); - void (QOPENGLF_APIENTRYP BindTexture)(GLenum target, GLuint texture); - void (QOPENGLF_APIENTRYP TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + GL_APICALL void (QOPENGLF_APIENTRYP GenTextures)(GLsizei n, GLuint *textures); + GL_APICALL void (QOPENGLF_APIENTRYP DeleteTextures)(GLsizei n, const GLuint *textures); + GL_APICALL void (QOPENGLF_APIENTRYP BindTexture)(GLenum target, GLuint texture); + GL_APICALL void (QOPENGLF_APIENTRYP TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void (QOPENGLF_APIENTRYP TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); // OpenGL 1.2 @@ -850,15 +858,15 @@ private: // OpenGL 1.3 void (QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img); void (QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); + GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexImage1D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); + GL_APICALL void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); // OpenGL 3.0 - void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); + GL_APICALL void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); // OpenGL 3.2 void (QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -- cgit v1.2.3 From 8e4c8be0b9821ee2f3dbdda3ebbe16126d334959 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Jul 2016 16:41:41 -0700 Subject: Don't compile configure.exe with clang-cl.exe if cl.exe is available Sometimes clang-cl.exe is on PATH and would get picked up by the build. That is often by mistake, but it will inreasingly happen as clang-cl becomes more popular. Unfortunately, configure.bat is too early to detect which MSVC version it's set to compile against, so the -fms-compatibility-version option will often be wrong. One such case is when trying to build for MSVC 2013. Microsoft headers for VS2013 are unsuitable for our use in Qt with clang-cl. Instead, use cl.exe. It's a much better-known quantity and is always on PATH if trying to build with clang-cl, as the latter needs the former to fall back to if necessary. This does not affect the build of Qt libraries and tools. Task-number: QTBUG-51534 Change-Id: I149e0540c00745fe8119fffd146287662436c4b9 Reviewed-by: Oswald Buddenhagen --- configure.bat | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.bat b/configure.bat index 1cbd733531..5c01890116 100644 --- a/configure.bat +++ b/configure.bat @@ -81,18 +81,18 @@ if not "%icl.exe%" == "" ( rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 -) else if not "%clang-cl.exe%" == "" ( - echo CXX = clang-cl>>Makefile - echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 ) else if not "%cl.exe%" == "" ( echo CXX = cl>>Makefile echo EXTRA_CXXFLAGS =>>Makefile rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 +) else if not "%clang-cl.exe%" == "" ( + echo CXX = clang-cl>>Makefile + echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 ) else if not "%g++.exe%" == "" ( echo CXX = g++>>Makefile echo EXTRA_CXXFLAGS =>>Makefile -- cgit v1.2.3 From 0696566b1e19c8178e00c0d14f185935e17d9e8b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 Jul 2016 16:49:33 +0200 Subject: Windows: Fix truncation in QFSFileEnginePrivate::nativeWrite() The number of bytes to write was converted to a 32bit unsigned value, causing losses. Change the type to qint64 and adapt the code determining the block size. Task-number: QTBUG-54870 Change-Id: I294da5bfe97c7e60f67228399e1244a1aba4c89c Reviewed-by: Maurice Kalinowski --- src/corelib/io/qfsfileengine_win.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 689251a6c7..391fbcc519 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -423,15 +423,13 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) if (fileHandle == INVALID_HANDLE_VALUE) return -1; - qint64 bytesToWrite = DWORD(len); // <- lossy + qint64 bytesToWrite = len; // Writing on Windows fails with ERROR_NO_SYSTEM_RESOURCES when // the chunks are too large, so we limit the block size to 32MB. - static const DWORD maxBlockSize = 32 * 1024 * 1024; - + const DWORD blockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024))); qint64 totalWritten = 0; do { - DWORD blockSize = qMin(bytesToWrite, maxBlockSize); DWORD bytesWritten; if (!WriteFile(fileHandle, data + totalWritten, blockSize, &bytesWritten, NULL)) { if (totalWritten == 0) { -- cgit v1.2.3 From 08a908c549e455a9443ca1594fe6ad9e938ea1fa Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 29 Jun 2016 16:34:55 -0700 Subject: QMacStyle: Fix use of deprecated symbol Change-Id: I5a6bfc937267817b2c815be0216ea91fe6860ba3 Reviewed-by: Timur Pocheptsov Reviewed-by: Jake Petroules --- src/widgets/styles/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 3352c5d589..52f6ca2131 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1907,7 +1907,7 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const } case QCocoaPushButton: { NSButton *bc = (NSButton *)bv; - bc.buttonType = NSMomentaryPushButton; + bc.buttonType = NSMomentaryLightButton; bc.bezelStyle = NSRoundedBezelStyle; break; } -- cgit v1.2.3 From f8ef7e1d2619e6d394c57561bb275767f0517b24 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 14 Jul 2016 18:10:50 +0200 Subject: terminate when command called by system() got SIGINT or SIGQUIT these are the two signals unhelpfully suppressed by system(2). Change-Id: I5e5df9f6d136601f0f36a8d645f90a1cab9995ad Reviewed-by: Lars Knoll --- qmake/library/qmakebuiltins.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index c1d23295e7..9fc6603075 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -62,6 +62,8 @@ #include #include #include +#include +#include #include #include #else @@ -1504,9 +1506,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( runProcess(&proc, args.at(0).toQString(m_tmp2)); return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0); #else - return returnBool(system((QLatin1String("cd ") - + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) - + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0); + int ec = system((QLatin1String("cd ") + + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) + + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()); +# ifdef Q_OS_UNIX + if (ec != -1 && WIFSIGNALED(ec) && (WTERMSIG(ec) == SIGQUIT || WTERMSIG(ec) == SIGINT)) + raise(WTERMSIG(ec)); +# endif + return returnBool(ec == 0); #endif #else return ReturnTrue; -- cgit v1.2.3 From 77a71c32c9d19b87f79b208929e71282e8d8b5d9 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 7 Jul 2016 16:00:17 -0700 Subject: configure and mkspecs: Don't try to find xcrun with xcrun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Xcode 8 (beta 2) that tool is no longer available through xcrun. We resort to xcodebuild instead. Change-Id: If9d7b535c1cbac2caae0112b2003283aeff34fb9 Reviewed-by: Jake Petroules Reviewed-by: Oswald Buddenhagen Reviewed-by: Morten Johan Sørvig --- configure | 2 +- mkspecs/features/mac/default_pre.prf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index a1f0a8fecb..f4c7813fd0 100755 --- a/configure +++ b/configure @@ -543,7 +543,7 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then exit 2 fi - if ! /usr/bin/xcrun -find xcrun >/dev/null 2>&1; then + if ! /usr/bin/xcrun -find xcodebuild >/dev/null 2>&1; then echo >&2 echo " Xcode not set up properly. You may need to confirm the license" >&2 echo " agreement by running /usr/bin/xcodebuild without arguments." >&2 diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index 0cc8cd6dfd..5df99d1acd 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -12,7 +12,7 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) { error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.") # Make sure Xcode is set up properly - isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \ + isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null"))): \ error("Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.") } -- cgit v1.2.3 From b5153d5bfab63da811b7a4615238d9e50198b412 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Jul 2016 16:34:22 -0700 Subject: Windows: Disable unsupported C++11 features with Clang-cl and ICC Whenever someone installs Clang or the Intel compiler on Windows, it's very likely that the compiler will be much newer than the MS headers that came with the installed Visual Studio version. So let's make sure we disable the C++11 features that the MS headers don't support properly. For example, MS's header supplied with VS 2013 doesn't mark the max() function as constexpr, resulting compiler errors in uses of that function in Qt code declared with Q_DECL_CONSTEXPR: qdeadlinetimer.h(62,13) : note: non-constexpr function 'max' cannot be used in a constant expression : s(std::numeric_limits::max()), ns(0), type(type_) {} ^ Change-Id: I149e0540c00745fe8119fffd146286ffe480d216 Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/global/qcompilerdetection.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 33e42a944d..e152786d3f 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1031,6 +1031,33 @@ // critical definitions. (Reported as Intel Issue ID 6000117277) # define __USE_CONSTEXPR 1 # define __USE_NOEXCEPT 1 +# elif defined(Q_CC_MSVC) && (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) +// Clang and the Intel compiler support more C++ features than the Microsoft compiler +// so make sure we don't enable them if the MS headers aren't properly adapted. +# ifndef _HAS_CONSTEXPR +# undef Q_COMPILER_CONSTEXPR +# endif +# ifndef _HAS_DECLTYPE +# undef Q_COMPILER_DECLTYPE +# endif +# ifndef _HAS_INITIALIZER_LISTS +# undef Q_COMPILER_INITIALIZER_LISTS +# endif +# ifndef _HAS_NULLPTR_T +# undef Q_COMPILER_NULLPTR +# endif +# ifndef _HAS_RVALUE_REFERENCES +# undef Q_COMPILER_RVALUE_REFS +# endif +# ifndef _HAS_SCOPED_ENUM +# undef Q_COMPILER_CLASS_ENUM +# endif +# ifndef _HAS_TEMPLATE_ALIAS +# undef Q_COMPILER_TEMPLATE_ALIAS +# endif +# ifndef _HAS_VARIADIC_TEMPLATES +# undef Q_COMPILER_VARIADIC_TEMPLATES +# endif # elif defined(_LIBCPP_VERSION) // libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler // doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example. -- cgit v1.2.3 From dd59118b87d779e5cbfcd0b4ee2a3d5332433da9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 7 Jul 2016 11:18:41 +0200 Subject: move c++11 test into qcompilerdetection.h and make it stricter it positively makes no sense to have a configure test which will be never reached due to the configure/qmake bootstrap failing with a slew of totally unhelpful error messages. pre-standardization partial c++11 implementations are now rejected, except for VS2013, which is still sufficient despite not announcing full compatibility. Change-Id: I58af10e03960af06b80cedac105cf8433f7a1745 Reviewed-by: Thiago Macieira --- config.tests/common/c++11/c++11.cpp | 49 --------------------------------- config.tests/common/c++11/c++11.pro | 3 -- configure | 6 +--- src/corelib/global/qcompilerdetection.h | 6 ++++ tools/configure/configureapp.cpp | 7 +---- 5 files changed, 8 insertions(+), 63 deletions(-) delete mode 100644 config.tests/common/c++11/c++11.cpp delete mode 100644 config.tests/common/c++11/c++11.pro diff --git a/config.tests/common/c++11/c++11.cpp b/config.tests/common/c++11/c++11.cpp deleted file mode 100644 index 88b67b5bff..0000000000 --- a/config.tests/common/c++11/c++11.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the configuration of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__INTEL_CXX11_MODE__) -// Compiler claims to support C++11, trust it -#else -# error "__cplusplus must be >= 201103L, or one of __GXX_EXPERIMENTAL_CXX0X__ or __INTEL_CXX11_MODE__ must be defined" -#endif - -#include -#include - -int main(int, char **) { return std::move(0); } diff --git a/config.tests/common/c++11/c++11.pro b/config.tests/common/c++11/c++11.pro deleted file mode 100644 index 3620f99c71..0000000000 --- a/config.tests/common/c++11/c++11.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = c++11.cpp -CONFIG += c++11 console -CONFIG -= qt diff --git a/configure b/configure index f2822503c4..0ba0c31e4a 100755 --- a/configure +++ b/configure @@ -4430,11 +4430,7 @@ fi # Detect C++11 & up support stdcxx_error=false -if ! compileTest common/c++11 "C++11"; then - echo "ERROR: Qt requires a C++11 compiler and yours does not seem to be that." - echo "Please upgrade." - exit 1 -elif [ "$CFG_STDCXX" = "c++11" ]; then +if [ "$CFG_STDCXX" = "c++11" ]; then : # CFG_STDCXX is correct elif ! compileTest common/c++14 "C++14"; then if [ "$CFG_STDCXX" != "auto" ]; then diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index e152786d3f..285931e794 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -557,6 +557,12 @@ * Q_COMPILER_RESTRICTED_VLA variable-length arrays, prior to __cpp_runtime_arrays */ +#ifdef __cplusplus +# if __cplusplus < 201103L && !(defined(Q_CC_MSVC) && Q_CC_MSVC >= 1800) +# error Qt requires a C++11 compiler and yours does not seem to be that. +# endif +#endif + #ifdef Q_CC_INTEL # define Q_COMPILER_RESTRICTED_VLA # define Q_COMPILER_VARIADIC_MACROS // C++11 feature supported as an extension in other modes, too diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index a89e66c377..0fa205bd98 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2310,12 +2310,7 @@ void Configure::autoDetection() detectArch(); if (dictionary["C++STD"] == "auto" && !dictionary["QMAKESPEC"].contains("msvc")) { - if (!tryCompileProject("common/c++11")) { - dictionary["DONE"] = "error"; - cout << "ERROR: Qt requires a C++11 compiler and yours does not seem to be that." << endl - << "Please upgrade." << endl; - return; - } else if (!tryCompileProject("common/c++14")) { + if (!tryCompileProject("common/c++14")) { dictionary["C++STD"] = "c++11"; } else if (!tryCompileProject("common/c++1z")) { dictionary["C++STD"] = "c++14"; -- cgit v1.2.3 From 49926bb9ef983d4c19aed635a00b388252c065e4 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 20 Jul 2016 10:29:51 +0200 Subject: Fix performance regression when changing fonts Change e109b8a0f3c89c595f0da689e7ee847130e2ee47 introduced a performance regression when rapidly switching fonts as long as the number of different fonts is over a relatively small number, since the cost of fonts can be high compared to the limits set on the cache. Since the original patch was intended to avoid exceeding the open file limit when using Freetype on Windows, we add an additional check on the number of engines in the cache as well for the added, synchronous cache flush. The limit is set to 256 to make it unlikely that it is exceeded during a single paint event, but it can also be configured when building Qt if a higher limit is needed. [ChangeLog][QtGui][Text] Fixed performance regression when rapidly switching between a large set of fonts. Task-number: QTBUG-54180 Change-Id: I92b9fbe14fca4f11c9c6dfdcdbec6d19a61b86a7 Reviewed-by: Konstantin Ritt --- src/gui/text/qfont.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index fe68149346..ea34614cb5 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -70,7 +70,9 @@ QT_BEGIN_NAMESPACE - +#ifndef QFONTCACHE_DECREASE_TRIGGER_LIMIT +# define QFONTCACHE_DECREASE_TRIGGER_LIMIT 256 +#endif bool QFontDef::exactMatch(const QFontDef &other) const { @@ -2797,7 +2799,7 @@ void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineDa engineData->ref.ref(); // Decrease now rather than waiting - if (total_cost > min_cost * 2) + if (total_cost > min_cost * 2 && engineDataCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT) decreaseCache(); engineDataCache.insert(def, engineData); @@ -2846,7 +2848,7 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu #endif engine->ref.ref(); // Decrease now rather than waiting - if (total_cost > min_cost * 2) + if (total_cost > min_cost * 2 && engineCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT) decreaseCache(); Engine data(engine); -- cgit v1.2.3 From 091e61b3525c700ce4198086bbd0d95a59fcb31f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 5 Jul 2016 13:09:17 -0700 Subject: Fix namespaced build using harfbuzz-ng harfbuzz-ng doesn't link to Qt libraries, but uses the Qt headers for some types. With CONFIG -= qt, we don't get QT_NAMESPACE set, which leads to linker errors later. Instead of setting QT_NAMESPACE, ask qversiontagging.h not to tag the headers. Change-Id: Ie585843cfb684bc3b6e3fffd145e7e438ae7c6bd Reviewed-by: Oswald Buddenhagen --- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index 163842e8fc..4325fd153b 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -23,7 +23,10 @@ win32: DEFINES += HB_NO_WIN1256 android: DEFINES += _POSIX_C_SOURCE=200112L INCLUDEPATH += $$PWD/include + +# Harfbuzz-NG inside Qt uses the Qt atomics (inline code only) INCLUDEPATH += $$QT.core.includes +DEFINES += QT_NO_VERSION_TAGGING SOURCES += \ $$PWD/src/hb-blob.cc \ -- cgit v1.2.3 From 5123dba5640c8a8c25ec61194a703add17510401 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 Jul 2016 15:16:58 +0200 Subject: QImage::setAlphaChannel(): Check result of image conversion alphaChannel.convertToFormat() may fail due to OOM. Check the obtained image. Task-number: QTBUG-54873 Change-Id: I778b7de7de611105fe23c1c24cbd69bd8f7c72d9 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index d9f9c1a7ad..60d402289d 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4233,6 +4233,8 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) } else { const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32); + if (sourceImage.isNull()) + return; const uchar *src_data = sourceImage.d->data; uchar *dest_data = d->data; for (int y=0; y Date: Fri, 22 Jul 2016 18:08:49 -0700 Subject: Work around ICC bug about shadowing declarations that aren't shadowing Known ICC bug, still present in version 17 beta. qdatetime.h(126): error #3280: declaration hides member "QDate::jd" (declared at line 136) Obviously a parameter to static function or to a function in a nested class can't shadow an NSDM. Intel issue IDs: 0000698329 / DPD200245740 Change-Id: I149e0540c00745fe8119fffd1463c679a3a9c8c3 Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetime.h | 4 ++-- src/corelib/tools/qsharedpointer_impl.h | 12 ++++++------ src/gui/kernel/qevent.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index c44f7f8fee..389fc927c3 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -115,8 +115,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d) static bool isValid(int y, int m, int d); static bool isLeapYear(int year); - static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd) - { return jd >= minJd() && jd <= maxJd() ? QDate(jd) : QDate() ; } + static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd_) + { return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; } Q_DECL_CONSTEXPR inline qint64 toJulianDay() const { return jd; } private: diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 70b100d018..c408f54b04 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -486,14 +486,14 @@ private: void deref() Q_DECL_NOTHROW { deref(d); } - static void deref(Data *d) Q_DECL_NOTHROW + static void deref(Data *dd) Q_DECL_NOTHROW { - if (!d) return; - if (!d->strongref.deref()) { - d->destroy(); + if (!dd) return; + if (!dd->strongref.deref()) { + dd->destroy(); } - if (!d->weakref.deref()) - delete d; + if (!dd->weakref.deref()) + delete dd; } template diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b407663338..b5d2c4d159 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -524,7 +524,7 @@ public: }; class Attribute { public: - Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {} + Attribute(AttributeType typ, int s, int l, QVariant val) : type(typ), start(s), length(l), value(qMove(val)) {} AttributeType type; int start; -- cgit v1.2.3 From 65cdffeaeadfc52fe0d1f2a73f82b698327a3b27 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Jun 2016 12:50:01 +0200 Subject: QPlatformWindow::initialGeometry(): Do not touch child window positions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Child window positions should not be mapped back and forth by High DPI scaling as this can cause them to change screens or be moved to invalid locations. Introduce a separate branch for child windows applying only size constraints. Task-number: QTBUG-54420 Change-Id: I4f86666952a49ed6fa03234a04031bc406281c45 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformwindow.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 9f2c6af51f..9bfda7f334 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -572,6 +572,20 @@ void QPlatformWindow::invalidateSurface() { } +static QSize fixInitialSize(QSize size, const QWindow *w, + int defaultWidth, int defaultHeight) +{ + if (size.width() == 0) { + const int minWidth = w->minimumWidth(); + size.setWidth(minWidth > 0 ? minWidth : defaultWidth); + } + if (size.height() == 0) { + const int minHeight = w->minimumHeight(); + size.setHeight(minHeight > 0 ? minHeight : defaultHeight); + } + return size; +} + /*! Helper function to get initial geometry on windowing systems which do not do smart positioning and also do not provide a means of centering a @@ -584,19 +598,18 @@ void QPlatformWindow::invalidateSurface() QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, int defaultWidth, int defaultHeight) { + if (!w->isTopLevel()) { + const qreal factor = QHighDpiScaling::factor(w); + const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), + w, defaultWidth, defaultHeight); + return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor)); + } const QScreen *screen = effectiveScreen(w); if (!screen) return initialGeometry; QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); - if (rect.width() == 0) { - const int minWidth = w->minimumWidth(); - rect.setWidth(minWidth > 0 ? minWidth : defaultWidth); - } - if (rect.height() == 0) { - const int minHeight = w->minimumHeight(); - rect.setHeight(minHeight > 0 ? minHeight : defaultHeight); - } - if (w->isTopLevel() && qt_window_private(const_cast(w))->positionAutomatic + rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); + if (qt_window_private(const_cast(w))->positionAutomatic && w->type() != Qt::Popup) { const QRect availableGeometry = screen->availableGeometry(); // Center unless the geometry ( + unknown window frame) is too large for the screen). -- cgit v1.2.3 From ad0d2f463a0905c4705660d96e8a514539c51d36 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 25 Jul 2016 12:37:20 +0200 Subject: Cocoa integration - fix a crash in QMacPasteboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMacPasteboard's dtor skips LazyRequest promises and this leaves pasteboard manager in broken state, since we release the pasteboard itself of the next step in destructor. As a result, not only Qt's app doing D & D (and thus via QCocoaDrag creating a stack-allocated QMacPasteboard) can die suddenly when somebody inspects a pasteboard, this 'somebody' ... can also die amazingly. So now we DO resolve promises using PasteboardResolvePromises (but we also preserve the original intent of not providing or providing empty data for lazy requests). Task-number: QTBUG-54663 Task-number: QTBUG-54832 Change-Id: I3ce90bd0a012dd3cbb30c93b2b17dce9473acb28 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qmacclipboard.h | 1 + src/plugins/platforms/cocoa/qmacclipboard.mm | 19 ++++++------------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h index 0d1f195f48..6989a44a0e 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.h +++ b/src/plugins/platforms/cocoa/qmacclipboard.h @@ -69,6 +69,7 @@ private: uchar mime_type; mutable QPointer mime; mutable bool mac_mime_source; + bool resolvingBeforeDestruction; static OSStatus promiseKeeper(PasteboardRef, PasteboardItemID, CFStringRef, void *); void clear_helper(); public: diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index f4fd32ffd1..d0e2c39895 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -81,6 +81,7 @@ QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt) mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL); paste = p; CFRetain(paste); + resolvingBeforeDestruction = false; } QMacPasteboard::QMacPasteboard(uchar mt) @@ -94,6 +95,7 @@ QMacPasteboard::QMacPasteboard(uchar mt) } else { qDebug("PasteBoard: Error creating pasteboard: [%d]", (int)err); } + resolvingBeforeDestruction = false; } QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt) @@ -107,23 +109,14 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt) } else { qDebug("PasteBoard: Error creating pasteboard: %s [%d]", QCFString::toQString(name).toLatin1().constData(), (int)err); } + resolvingBeforeDestruction = false; } QMacPasteboard::~QMacPasteboard() { // commit all promises for paste after exit close - for (int i = 0; i < promises.count(); ++i) { - const Promise &promise = promises.at(i); - // At this point app teardown has started and control is somewhere in the Q[Core]Application - // destructor. Skip "lazy" promises where the application has not provided data; - // the application will generally not be in a state to provide it. - if (promise.dataRequestType == LazyRequest) - continue; - QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime)); - NSInteger pbItemId = promise.itemId; - promiseKeeper(paste, reinterpret_cast(pbItemId), flavor, this); - } - + resolvingBeforeDestruction = true; + PasteboardResolvePromises(paste); if (paste) CFRelease(paste); } @@ -175,7 +168,7 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id, // to request the data from the application. QVariant promiseData; if (promise.dataRequestType == LazyRequest) { - if (!promise.mimeData.isNull()) + if (!qpaste->resolvingBeforeDestruction && !promise.mimeData.isNull()) promiseData = promise.mimeData->variantData(promise.mime); } else { promiseData = promise.variantData; -- cgit v1.2.3 From 1fcea117560fb528f6a4824b1eca930b322953f9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 Jul 2016 18:45:36 -0700 Subject: Fix enabling of precompiled headers on macOS On macOS, the test script is passed the full path to the compiler, like /usr/local/bin/icpc. That doesn't match "icpc". Change-Id: I149e0540c00745fe8119fffd1463c87b8f6a89b2 Reviewed-by: Oswald Buddenhagen --- config.tests/unix/precomp.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tests/unix/precomp.test b/config.tests/unix/precomp.test index 9ffea20ff9..0b8377b21a 100755 --- a/config.tests/unix/precomp.test +++ b/config.tests/unix/precomp.test @@ -5,7 +5,7 @@ COMPILER=$1 VERBOSE=$2 case "$COMPILER" in -icpc) +*icpc) cat >header.h < Date: Mon, 25 Jul 2016 08:57:47 +0200 Subject: QWindowsTheme::themeHint(): Handle special value of SPI_GETWHEELSCROLLLINES When the mouse wheel step is set to "Scroll one screen", querying SPI_GETWHEELSCROLLLINES returns the special value unsigned(-1). Return the default instead of converting it to int in that case since Qt does not implement it. Task-number: QTBUG-52384 Change-Id: I793e5c09103fe0c7c4a378aba97e9f63ae1c2f35 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowstheme.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index ce0c69f9ed..40be4fa31f 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -401,8 +401,13 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false)); case ContextMenuOnMouseRelease: return QVariant(true); - case WheelScrollLines: - return QVariant(int(dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3))); + case WheelScrollLines: { + int result = 3; + const DWORD scrollLines = dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, DWORD(result)); + if (scrollLines != DWORD(-1)) // Special value meaning "scroll one screen", unimplemented in Qt. + result = int(scrollLines); + return QVariant(result); + } default: break; } -- cgit v1.2.3 From 79af4e1e31f4fadcd5b0546455894b098f1acc07 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 25 Jul 2016 16:51:51 +0300 Subject: Android: introduce setContext setContext is needed by modules that don't need an Activity object to run (e.g. QtMultimeida, QtSensors, etc.) Task-number: QTBUG-54506 Change-Id: Ief9daff52ddefdb27092040c89dfce9e466eac5c Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../org/qtproject/qt5/android/QtActivityDelegate.java | 18 +++++++++++++----- .../org/qtproject/qt5/android/QtServiceDelegate.java | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 0cfce2c6af..656dbdda45 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -489,11 +489,19 @@ public class QtActivityDelegate continue; try { - @SuppressWarnings("rawtypes") - Class initClass = classLoader.loadClass(className); - Object staticInitDataObject = initClass.newInstance(); // create an instance - Method m = initClass.getMethod("setActivity", Activity.class, Object.class); - m.invoke(staticInitDataObject, m_activity, this); + Class initClass = classLoader.loadClass(className); + Object staticInitDataObject = initClass.newInstance(); // create an instance + try { + Method m = initClass.getMethod("setActivity", Activity.class, Object.class); + m.invoke(staticInitDataObject, m_activity, this); + } catch (Exception e) { + } + + try { + Method m = initClass.getMethod("setContext", Context.class); + m.invoke(staticInitDataObject, (Context)m_activity); + } catch (Exception e) { + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java index 634658eefb..5ac406c710 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java @@ -120,12 +120,20 @@ public class QtServiceDelegate for (String className: loaderParams.getStringArray(STATIC_INIT_CLASSES_KEY)) { if (className.length() == 0) continue; - try { - Class initClass = classLoader.loadClass(className); - Object staticInitDataObject = initClass.newInstance(); // create an instance - Method m = initClass.getMethod("setService", Service.class, Object.class); - m.invoke(staticInitDataObject, m_service, this); + Class initClass = classLoader.loadClass(className); + Object staticInitDataObject = initClass.newInstance(); // create an instance + try { + Method m = initClass.getMethod("setService", Service.class, Object.class); + m.invoke(staticInitDataObject, m_service, this); + } catch (Exception e) { + } + + try { + Method m = initClass.getMethod("setContext", Context.class); + m.invoke(staticInitDataObject, (Context)m_service); + } catch (Exception e) { + } } catch (Exception e) { e.printStackTrace(); } -- cgit v1.2.3 From 7095db363331e6434d64405ba1a8573de2e01230 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 25 Jul 2016 12:51:30 +0100 Subject: Update .gitignore Change-Id: Ib091f294c8557a44a2c39594fcf6f2d39de1d7e2 Reviewed-by: Oswald Buddenhagen --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 1beec5c3ec..a48134a899 100644 --- a/.gitignore +++ b/.gitignore @@ -147,6 +147,8 @@ tools/activeqt/testcon/testcon.tlb translations/*.qm translations/*_untranslated.ts qrc_*.cpp +*.version +*.version.in # Test generated files QObject.log -- cgit v1.2.3 From d57bfa21ce7cf656c5ac55ab3b729ecaeb874bd3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 Jul 2016 09:10:58 +0200 Subject: QDialog::adjustPosition(): Check screen number The screen number has been observed to be -1 in setups with multiple virtual desktops. Amends change eb50193136c7c73be864e3232d01e98ddc24e539. Task-number: QTBUG-52735 Change-Id: If01acf74fdd701a9211df732c0defdfd522ba72d Reviewed-by: hjk --- src/widgets/dialogs/qdialog.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 45d2279ed5..889b5ef9f5 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -863,8 +863,10 @@ void QDialog::adjustPosition(QWidget* w) // QTBUG-52735: Manually set the correct target screen since scaling in a // subsequent call to QWindow::resize() may otherwise use the wrong factor // if the screen changed notification is still in an event queue. - if (QWindow *window = windowHandle()) - window->setScreen(QGuiApplication::screens().at(scrn)); + if (scrn >= 0) { + if (QWindow *window = windowHandle()) + window->setScreen(QGuiApplication::screens().at(scrn)); + } move(p); } -- cgit v1.2.3 From d9831a03ca3bd8a9a86ae37f1e18d48c9cc3fb9f Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 26 Jul 2016 09:47:32 +0200 Subject: Fix grammar error in QFlags documentation Change-Id: I1c5d2be402f7e194eaa2e6f646aa5edad1bfd9d9 Reviewed-by: Marc Mutz --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index a21dbffad5..d5f2f9bcd8 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4262,7 +4262,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) \relates QObject \since 5.5 - This macro registers a single \l{QFlags}{flags types} with the + This macro registers a single \l{QFlags}{flags type} with the meta-object system. It is typically used in a class definition to declare that values of a given enum can be used as flags and combined using the bitwise OR operator. -- cgit v1.2.3 From 2ceccc6f7fd3e7496df26d16119e9b7693932658 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 30 Jun 2016 12:07:18 +0200 Subject: Add manual test embeddedintoforeignwindow Add a test for embedding Qt windows into foreign windows. Complements the existing "foreignwindows" test (which embeds foreign windows into Qt). The test has a simple UI based on QRasterWindow allowing for checking events and geometries. Task-number: QTBUG-41186 Change-Id: Ie62a3e250ca666e2fa5c2e3ef37ef0654829397c Reviewed-by: Laszlo Agocs --- .../embeddedintoforeignwindow.pro | 7 + .../embeddedintoforeignwindow/itemwindow.cpp | 72 ++++++ .../manual/embeddedintoforeignwindow/itemwindow.h | 126 +++++++++ tests/manual/embeddedintoforeignwindow/main.cpp | 287 +++++++++++++++++++++ tests/manual/manual.pro | 3 +- 5 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro create mode 100644 tests/manual/embeddedintoforeignwindow/itemwindow.cpp create mode 100644 tests/manual/embeddedintoforeignwindow/itemwindow.h create mode 100644 tests/manual/embeddedintoforeignwindow/main.cpp diff --git a/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro new file mode 100644 index 0000000000..93da4b8c91 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +QT += gui-private +CONFIG += console c++11 +CONFIG -= app_bundle +SOURCES += main.cpp itemwindow.cpp +HEADERS += itemwindow.h +include(../diaglib/diaglib.pri) diff --git a/tests/manual/embeddedintoforeignwindow/itemwindow.cpp b/tests/manual/embeddedintoforeignwindow/itemwindow.cpp new file mode 100644 index 0000000000..32a2e6557c --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/itemwindow.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "itemwindow.h" + +#include +#include + +void TextItem::paint(QPainter &painter) +{ + painter.fillRect(m_rect, m_col); + painter.drawRect(m_rect); + QTextOption textOption; + textOption.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + painter.drawText(m_rect, m_text, textOption); +} + +void ButtonItem::mouseEvent(QMouseEvent *mouseEvent) +{ + if (mouseEvent->type() == QEvent::MouseButtonPress && rect().contains(mouseEvent->pos())) { + mouseEvent->accept(); + emit clicked(); + } +} + +void ButtonItem::keyEvent(QKeyEvent *keyEvent) +{ + if (m_shortcut && keyEvent->type() == QEvent::KeyPress + && (keyEvent->key() + int(keyEvent->modifiers())) == m_shortcut) { + keyEvent->accept(); + emit clicked(); + } +} + +void ItemWindow::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + QRect rect(QPoint(0, 0), size()); + painter.fillRect(rect, m_background); + foreach (Item *i, m_items) + i->paint(painter); +} diff --git a/tests/manual/embeddedintoforeignwindow/itemwindow.h b/tests/manual/embeddedintoforeignwindow/itemwindow.h new file mode 100644 index 0000000000..8ea9adaa16 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/itemwindow.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ITEMWINDOW_H +#define ITEMWINDOW_H + +#include +#include + +QT_USE_NAMESPACE + +// ItemWindow: Primitive UI item classes for use with a ItemWindow based +// on QRasterWindow without widgets allowing a simple UI without widgets. + +// Basic item to be used in a ItemWindow +class Item : public QObject { + Q_OBJECT +public: + explicit Item(QObject *parent = nullptr) : QObject(parent) {} + + virtual void paint(QPainter &painter) = 0; + virtual void mouseEvent(QMouseEvent *) {} + virtual void keyEvent(QKeyEvent *) {} +}; + +// Positionable text item +class TextItem : public Item { + Q_OBJECT +public: + explicit TextItem(const QString &text, const QRect &rect, const QColor &col, + QObject *parent = nullptr) + : Item(parent), m_text(text), m_rect(rect), m_col(col) {} + + void paint(QPainter &painter) override; + + QRect rect() const { return m_rect; } + +private: + const QString m_text; + const QRect m_rect; + const QColor m_col; +}; + +// "button" item +class ButtonItem : public TextItem { + Q_OBJECT +public: + explicit ButtonItem(const QString &text, const QRect &rect, const QColor &col, + QObject *parent = nullptr) + : TextItem(text, rect, col, parent), m_shortcut(0) {} + + void mouseEvent(QMouseEvent *mouseEvent) override; + void keyEvent(QKeyEvent *keyEvent) override; + + int shortcut() const { return m_shortcut; } + void setShortcut(int shortcut) { m_shortcut = shortcut; } + +signals: + void clicked(); + +private: + int m_shortcut; +}; + +#define PROPAGATE_EVENT(windowHandler, eventClass, itemHandler) \ +void windowHandler(eventClass *e) override \ +{ \ + foreach (Item *i, m_items) \ + i->itemHandler(e); \ +} + +class ItemWindow : public QRasterWindow { + Q_OBJECT +public: + explicit ItemWindow(QWindow *parent = nullptr) : QRasterWindow(parent), m_background(Qt::white) {} + + void addItem(Item *item) { m_items.append(item); } + + QColor background() const { return m_background; } + void setBackground(const QColor &background) { m_background = background; } + +protected: + void paintEvent(QPaintEvent *) override; + PROPAGATE_EVENT(mousePressEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseReleaseEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseDoubleClickEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseMoveEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(keyPressEvent, QKeyEvent, keyEvent) + PROPAGATE_EVENT(keyReleaseEvent, QKeyEvent, keyEvent) + +private: + QList m_items; + QColor m_background; +}; + +#endif // ITEMWINDOW_H diff --git a/tests/manual/embeddedintoforeignwindow/main.cpp b/tests/manual/embeddedintoforeignwindow/main.cpp new file mode 100644 index 0000000000..d7b33683a7 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/main.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "itemwindow.h" + +#include + +#include +#include +#include +#include + +#ifdef Q_OS_WIN +# include +# include +# include +#endif + +#include // diaglib +#include + +#include + +QT_USE_NAMESPACE + +static const char usage[] = + "\nEmbeds a QWindow into a native foreign window passed on the command line.\n" + "When no window ID is passed, a test window is created (Windows only)."; + +static QString windowTitle() +{ + return QLatin1String(QT_VERSION_STR) + QLatin1Char(' ') + QGuiApplication::platformName(); +} + +#ifdef Q_OS_WIN +// Helper to create a native test window (Windows) +static QString registerWindowClass(const QString &name) +{ + QString result; + void *proc = DefWindowProc; + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + if (!QMetaObject::invokeMethod(ni, "registerWindowClass", Qt::DirectConnection, + Q_RETURN_ARG(QString, result), + Q_ARG(QString, name), + Q_ARG(void *, proc))) { + qWarning("registerWindowClass failed"); + } + return result; +} + +static HWND createNativeWindow(const QString &name) +{ + const HWND hwnd = + CreateWindowEx(0, reinterpret_cast(name.utf16()), + L"NativeWindow", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + 0, 0, GetModuleHandle(NULL), NULL); + + if (!hwnd) { + qErrnoWarning("Cannot create window \"%s\"", qPrintable(name)); + return 0; + } + + const QString text = windowTitle() + QLatin1String(" 0x") + QString::number(quint64(hwnd), 16); + SetWindowText(hwnd, reinterpret_cast(text.utf16())); + return hwnd; +} +#endif // Q_OS_WIN + +// Helper functions for simple management of native windows. +static WId createNativeTestWindow() +{ + WId result = 0; +#ifdef Q_OS_WIN + const QString className = registerWindowClass(QLatin1String("TestClass") + windowTitle()); + const HWND nativeWin = createNativeWindow(className); + result = WId(nativeWin); +#else // Q_OS_WIN + Q_UNIMPLEMENTED(); +#endif + return result; +} + +static void showNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + ShowWindow(HWND(wid), SW_SHOW); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +static void setFocusToNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + SetFocus(HWND(wid)); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +static void destroyNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + DestroyWindow(HWND(wid)); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +// Main test window to be embedded into foreign window with some buttons. +class EmbeddedTestWindow : public ItemWindow { + Q_OBJECT +public: + explicit EmbeddedTestWindow(QWindow *parent = nullptr) : ItemWindow(parent) + { + const int spacing = 10; + const QSize buttonSize(100, 30); + const int width = 3 * buttonSize.width() + 4 * spacing; + + QPoint pos(spacing, spacing); + addItem(new TextItem(::windowTitle(), QRect(pos, QSize(width - 2 * spacing, buttonSize.height())), + Qt::white)); + + pos.ry() += 2 * spacing + buttonSize.height(); + + ButtonItem *mgi = new ButtonItem("Map to global", QRect(pos, buttonSize), + QColor(Qt::yellow).lighter(), this); + connect(mgi, &ButtonItem::clicked, this, &EmbeddedTestWindow::testMapToGlobal); + addItem(mgi); + + pos.rx() += buttonSize.width() + spacing; + ButtonItem *di = new ButtonItem("Dump Wins", QRect(pos, buttonSize), + QColor(Qt::cyan).lighter(), this); + connect(di, &ButtonItem::clicked, this, [] () { QtDiag::dumpAllWindows(); }); + addItem(di); + + pos.rx() += buttonSize.width() + spacing; + ButtonItem *qi = new ButtonItem("Quit", QRect(pos, buttonSize), + QColor(Qt::red).lighter(), this); + qi->setShortcut(Qt::CTRL + Qt::Key_Q); + connect(qi, &ButtonItem::clicked, qApp, &QCoreApplication::quit); + addItem(qi); + + setBackground(Qt::lightGray); + resize(width, pos.y() + buttonSize.height() + spacing); + } + +public slots: + void testMapToGlobal(); +}; + +void EmbeddedTestWindow::testMapToGlobal() +{ + const QPoint globalPos = mapToGlobal(QPoint(0,0)); + qDebug() << "mapToGlobal(QPoint(0,0)" << globalPos + << "cursor at:" << QCursor::pos(); +} + +struct EventFilterOption +{ + const char *name; + const char *description; + QtDiag::EventFilter::EventCategories categories; +}; + +EventFilterOption eventFilterOptions[] = { +{"mouse-events", "Dump mouse events.", QtDiag::EventFilter::MouseEvents}, +{"keyboard-events", "Dump keyboard events.", QtDiag::EventFilter::KeyEvents}, +{"state-events", "Dump state/focus change events.", QtDiag::EventFilter::StateChangeEvents | QtDiag::EventFilter::FocusEvents} +}; + +static inline bool isOptionSet(int argc, char *argv[], const char *option) +{ + return (argv + argc) != + std::find_if(argv + 1, argv + argc, + [option] (const char *arg) { return !qstrcmp(arg, option); }); +} + +int main(int argc, char *argv[]) +{ + // Check for no scaling before QApplication is instantiated. + if (isOptionSet(argc, argv, "-s")) + QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QGuiApplication::setApplicationDisplayName("Foreign Window Embedding Tester"); + + QGuiApplication app(argc, argv); + + // Process command line + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setApplicationDescription(QLatin1String(usage)); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption noScalingDummy(QStringLiteral("s"), + QStringLiteral("Disable High DPI scaling.")); + parser.addOption(noScalingDummy); + const int eventFilterOptionCount = int(sizeof(eventFilterOptions) / sizeof(eventFilterOptions[0])); + for (int i = 0; i < eventFilterOptionCount; ++i) { + parser.addOption(QCommandLineOption(QLatin1String(eventFilterOptions[i].name), + QLatin1String(eventFilterOptions[i].description))); + } + parser.addPositionalArgument(QStringLiteral("[windows]"), QStringLiteral("Window ID.")); + + parser.process(QCoreApplication::arguments()); + + QtDiag::EventFilter::EventCategories eventCategories = 0; + for (int i = 0; i < eventFilterOptionCount; ++i) { + if (parser.isSet(QLatin1String(eventFilterOptions[i].name))) + eventCategories |= eventFilterOptions[i].categories; + } + if (eventCategories) + app.installEventFilter(new QtDiag::EventFilter(eventCategories, &app)); + + // Obtain foreign window to test with. + WId testForeignWinId = 0; + bool createdTestWindow = false; + if (parser.positionalArguments().isEmpty()) { + testForeignWinId = createNativeTestWindow(); + if (!testForeignWinId) + parser.showHelp(-1); + showNativeWindow(testForeignWinId); + createdTestWindow = true; + } else { + bool ok; + const QString &winIdArgument = parser.positionalArguments().constFirst(); + testForeignWinId = winIdArgument.toULongLong(&ok, 0); + if (!ok) { + std::cerr << "Invalid window id: \"" << qPrintable(winIdArgument) << "\"\n"; + return -1; + } + } + if (!testForeignWinId) + parser.showHelp(1); + + QWindow *foreignWindow = QWindow::fromWinId(testForeignWinId); + if (!foreignWindow) + return -2; + foreignWindow->setObjectName("ForeignWindow"); + EmbeddedTestWindow *embeddedTestWindow = new EmbeddedTestWindow(foreignWindow); + embeddedTestWindow->setObjectName("EmbeddedTestWindow"); + embeddedTestWindow->show(); + setFocusToNativeWindow(embeddedTestWindow->winId()); // Windows: Set keyboard focus. + + const int exitCode = app.exec(); + delete embeddedTestWindow; + delete foreignWindow; + if (createdTestWindow) + destroyNativeWindow(testForeignWinId); + return exitCode; +} + +#include "main.moc" diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 8e77a321dd..34fd6662ec 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -2,6 +2,7 @@ TEMPLATE=subdirs SUBDIRS = bearerex \ filetest \ +embeddedintoforeignwindow \ foreignwindows \ gestures \ inputmethodhints \ @@ -66,4 +67,4 @@ win32 { lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \ qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency \ -foreignwindows +embeddedintoforeignwindow foreignwindows -- cgit v1.2.3 From 107ac187bcc3c552217181a3b247ed5f31a9cb49 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 19 Jul 2016 13:48:33 +0100 Subject: QOpenGLDebugLogger: do not crash if deleted with the wrong GL context current Task-number: QTBUG-54799 Change-Id: Ifee3183e7944fbe266fe644628d33d0667be99a8 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengldebug.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index 8b2ffb1a20..99d1e691c9 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -1500,6 +1500,12 @@ void QOpenGLDebugLogger::stopLogging() if (!d->isLogging) return; + QOpenGLContext *currentContext = QOpenGLContext::currentContext(); + if (!currentContext || currentContext != d->context) { + qWarning("QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current"); + return; + } + d->isLogging = false; d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter); -- cgit v1.2.3 From 65bad0d0f4e2ac14e7f439659c500c1d2c6817bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sat, 16 Jul 2016 13:16:49 +0100 Subject: Update documentation regarding QPixmap HICON conversions The QPixmap methods are gone in Qt5. QtWinExtras should be used instead. Task-Id: QTBUG-54838 Change-Id: Ia52ab9786f57d92caf4c44142a3131dbf973a193 Reviewed-by: Friedemann Kleint --- src/gui/image/qpixmap.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 0c8ab527b2..78031bca97 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1412,10 +1412,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) QPixmap using the fromImage(). If this is too expensive an operation, you can use QBitmap::fromImage() instead. - The QPixmap class also supports conversion to and from HICON: - the toWinHICON() function creates a HICON equivalent to the - QPixmap, and returns the HICON handle. The fromWinHICON() - function returns a QPixmap that is equivalent to the given icon. + To convert a QPixmap to and from HICON you can use the QtWinExtras + functions QtWin::toHICON() and QtWin::fromHICON() respectively. \section1 Pixmap Transformations -- cgit v1.2.3 From b694fe987cc423f5189102d25db1f7215a56b7f9 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 19 Jul 2016 14:57:12 +0100 Subject: QOpenGLDebugLogger: strengthen the code path in case of GL context destruction Trying to move closer to GL semantics: it is allowed to destroy a GL context at any time and that must free all of its resources. Change-Id: I3daa81d721cf26baf86a1a6435b77e3c28feb1a2 Reviewed-by: Sean Harmer --- src/gui/opengl/qopengldebug.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index 99d1e691c9..19ceaaf815 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include "qopengldebug.h" @@ -1281,8 +1282,41 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source */ void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed() { + Q_ASSERT(context); + + // Re-make our context current somehow, otherwise stopLogging will fail. + + // Save the current context and its surface in case we need to set them back + QOpenGLContext *currentContext = QOpenGLContext::currentContext(); + QSurface *currentSurface = 0; + + QScopedPointer offscreenSurface; + + if (context != currentContext) { + // Make our old context current on a temporary surface + if (currentContext) + currentSurface = currentContext->surface(); + + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(context->format()); + offscreenSurface->create(); + if (!context->makeCurrent(offscreenSurface.data())) + qWarning("QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup"); + } + Q_Q(QOpenGLDebugLogger); q->stopLogging(); + + if (offscreenSurface) { + // We did change the current context: set it back + if (currentContext) + currentContext->makeCurrent(currentSurface); + else + context->doneCurrent(); + } + + QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); + context = 0; initialized = false; } -- cgit v1.2.3 From 97318a3d5fc3a2e9b97c7dd5a49ad0e09acbeaaa Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 26 Jul 2016 13:48:28 +0200 Subject: embedded: Make signal handlers optional [ChangeLog][Platform Specific Changes] It is now possible to opt out from installing signal handlers when running with eglfs and linuxfb by setting the QT_QPA_NO_SIGNAL_HANDLER environment variable to a non-zero value. Task-number: QTBUG-54733 Change-Id: Ib07d4bbf714c752631c49b76ad0a16677c1ba5bd Reviewed-by: Andy Nichols --- src/platformsupport/fbconvenience/qfbvthandler.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp index 5e062b3f0a..bfe6b28115 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler.cpp +++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp @@ -110,14 +110,16 @@ QFbVtHandler::QFbVtHandler(QObject *parent) m_signalNotifier = new QSocketNotifier(m_sigFd[1], QSocketNotifier::Read, this); connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal); - struct sigaction sa; - sa.sa_flags = 0; - sa.sa_handler = signalHandler; - sigemptyset(&sa.sa_mask); - sigaction(SIGINT, &sa, 0); // Ctrl+C - sigaction(SIGTSTP, &sa, 0); // Ctrl+Z - sigaction(SIGCONT, &sa, 0); - sigaction(SIGTERM, &sa, 0); // default signal used by kill + if (!qEnvironmentVariableIntValue("QT_QPA_NO_SIGNAL_HANDLER")) { + struct sigaction sa; + sa.sa_flags = 0; + sa.sa_handler = signalHandler; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, 0); // Ctrl+C + sigaction(SIGTSTP, &sa, 0); // Ctrl+Z + sigaction(SIGCONT, &sa, 0); + sigaction(SIGTERM, &sa, 0); // default signal used by kill + } #endif } -- cgit v1.2.3 From a2157df28b8aaa0c6fc02a35a2b24fa82cb77230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 26 Jul 2016 13:16:53 +0200 Subject: HighDPI: Disable scrolling for non-integer deltas Disable the scrolling optimization in QBackingStore and fall back to repainting for non-integer deltas. The existing rendered pixels are not re-usable in this case. The test is made on the delta, and not on the scale factor. This means that user code can cooperate and generate (logical delta, scale factor) combinations that result in integer pixel deltas (which _can_ be scrolled). Change-Id: I36eb5d9e00449428bc9095edd8732782b996db16 Task-number: QTBUG-52452 Reviewed-by: Friedemann Kleint --- src/gui/painting/qbackingstore.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index c39675b0b6..aca246e9bf 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -230,11 +230,16 @@ QSize QBackingStore::size() const */ bool QBackingStore::scroll(const QRegion &area, int dx, int dy) { - Q_UNUSED(area); - Q_UNUSED(dx); - Q_UNUSED(dy); - - return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window)); + // Disable scrolling for non-integer scroll deltas. For this case + // the the existing rendered pixels can't be re-used, and we return + // false to signal that a repaint is needed. + const qreal nativeDx = QHighDpi::toNativePixels(qreal(dx), d_ptr->window); + const qreal nativeDy = QHighDpi::toNativePixels(qreal(dy), d_ptr->window); + if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy) + return false; + + return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), + nativeDx, nativeDy); } /*! -- cgit v1.2.3 From 5b64b64717caca231d399a138e747bdded9c116c Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 22 Jul 2016 10:43:01 +0200 Subject: Fontengine: Avoid invalid alpha maps when antialiasing is off When font antialising is disabled, the created alpha maps will be Mono format. Make sure that the created QImage is valid by ensuring that it has a color table of the right size. Issue was earlier handled by a4e2f2e687ca7aec88ecf82f72d42ac61e17a5b9, but that will be partially reverted because of compatibility break. Task-number: QTBUG-50745 Change-Id: I7c521288469ae94805a3326644771270d97ab979 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine_ft.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 361702681f..4de41dfa99 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1738,7 +1738,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng Q_UNREACHABLE(); }; - return QImage(static_cast(glyph->data), glyph->width, glyph->height, bytesPerLine, format); + QImage img(static_cast(glyph->data), glyph->width, glyph->height, bytesPerLine, format); + if (format == QImage::Format_Mono) + img.setColor(1, QColor(Qt::white).rgba()); // Expands color table to 2 items; item 0 set to transparent. + return img; } QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition, -- cgit v1.2.3 From 69b43e74d78e050cf5e40197acafa4bc9f90c0bd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 27 Jul 2016 09:28:13 +0200 Subject: Harfbuzz: Fix warnings of MSVC 64 bit qtbase\src\3rdparty\harfbuzz\src\harfbuzz-shaper.cpp(97): error C2220: warning treated as error - no 'object' file generated qtbase\src\3rdparty\harfbuzz\src\harfbuzz-shaper.cpp(97): warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) qtbase\src\3rdparty\harfbuzz\src\harfbuzz-shaper.cpp(284): warning C4800: 'HB_Bool': forcing value to bool 'true' or 'false' (performance warning) qtbase\src\3rdparty\harfbuzz\src\harfbuzz-arabic.c(924): warning C4244: 'initializing': conversion from '__int64' to 'int', possible loss of data qtbase\src\3rdparty\harfbuzz\src\harfbuzz-arabic.c(984): warning C4244: '=': conversion from '__int64' to 'int', possible loss of data qtbase\src\3rdparty\harfbuzz\src\harfbuzz-arabic.c(995): warning C4244: '=': conversion from '__int64' to 'int', possible loss of data Required to build QtCore after change a372cf5a80ec1a774f8f624b30b3c8209b800ec8. Change-Id: Ieb65c19e518984dde91bc8acab35203f8c271da3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/harfbuzz/src/harfbuzz-arabic.c | 6 +++--- src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c index b43ac9c353..966537ffa0 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c @@ -921,7 +921,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 for (i = 0; i < len; i++) { hb_uint8 r = *ch >> 8; - int gpos = data - shapeBuffer; + const int gpos = int(data - shapeBuffer); if (r != 0x06) { if (r == 0x20) { @@ -981,7 +981,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 /* qDebug("glyph %d (char %d) is mark!", gpos, i); */ } else { attributes[gpos].mark = FALSE; - clusterStart = data - shapeBuffer; + clusterStart = int(data - shapeBuffer); } attributes[gpos].clusterStart = !attributes[gpos].mark; attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch); @@ -992,7 +992,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 ch++; logClusters[i] = clusterStart; } - *shapedLength = data - shapeBuffer; + *shapedLength = int(data - shapeBuffer); HB_FREE_STACKARRAY(props); } diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index f7a4195308..30dde281e8 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -94,7 +94,7 @@ static inline void positionCluster(HB_ShaperItem *item, int gfrom, int glast) offsetBase = ((size * 10) - markTotalHeight) / 2; // Use offset that just fits } - bool rightToLeft = item->item.bidiLevel % 2; + const bool rightToLeft = (item->item.bidiLevel % 2) != 0; int i; unsigned char lastCmb = 0; @@ -281,7 +281,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) // first char in a run is never (treated as) a mark int cStart = 0; - const bool symbolFont = item->face->isSymbolFont; + const bool symbolFont = item->face->isSymbolFont != 0; attributes[0].mark = false; attributes[0].clusterStart = true; attributes[0].dontPrint = (!symbolFont && uc[0] == 0x00ad) || HB_IsControlChar(uc[0]); -- cgit v1.2.3 From 7bf002c3b3f8009138fca217c7fa0c234aed21bd Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 22 Jul 2016 11:13:41 +0200 Subject: Backwards compatibility fix: No default colormap for Mono QImages This is a partial revert of a4e2f2e687ca7aec88ecf82f72d42ac61e17a5b9. That fix tried to avoid the risk of a crash in pixel() by ensuring Mono QImages created with external data also got a default color table. However, that broke usable behavior in existing code that was painting in Mono QImages using color0/color1. This commit reverts to the old behavior, and instead expands on the checking in pixel() so that lacking color table is handled gracefully for all indexed formats. Task-number: QTBUG-54827 Change-Id: I9164198bed9d20c4b12cdba40a31c141bef3128d Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/image/qimage.cpp | 42 ++++++++++++++---------------- tests/auto/gui/image/qimage/tst_qimage.cpp | 38 +++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 60d402289d..ee77a32b86 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -828,17 +828,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm d->cleanupFunction = cleanupFunction; d->cleanupInfo = cleanupInfo; - switch (format) { - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - d->colortable.resize(2); - d->colortable[0] = QColor(Qt::black).rgba(); - d->colortable[1] = QColor(Qt::white).rgba(); - break; - default: - break; - } - return d; } @@ -2237,21 +2226,30 @@ QRgb QImage::pixel(int x, int y) const } const uchar *s = d->data + y * d->bytes_per_line; - switch(d->format) { + + int index = -1; + switch (d->format) { case Format_Mono: - return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1); + index = (*(s + (x >> 3)) >> (~x & 7)) & 1; + break; case Format_MonoLSB: - return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1); + index = (*(s + (x >> 3)) >> (x & 7)) & 1; + break; case Format_Indexed8: - { - int index = (int)s[x]; - if (index < d->colortable.size()) { - return d->colortable.at(index); - } else { - qWarning("QImage::pixel: color table index %d out of range.", index); - return 0; - } + index = s[x]; + break; + default: + break; + } + if (index >= 0) { // Indexed format + if (index >= d->colortable.size()) { + qWarning("QImage::pixel: color table index %d out of range.", index); + return 0; } + return d->colortable.at(index); + } + + switch (d->format) { case Format_RGB32: return 0xff000000 | reinterpret_cast(s)[x]; case Format_ARGB32: // Keep old behaviour. diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 435178a885..6f088bea24 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -99,6 +99,8 @@ private slots: void setPixel_data(); void setPixel(); + void defaultColorTable_data(); + void defaultColorTable(); void setColorCount(); void setColor(); @@ -1450,6 +1452,38 @@ void tst_QImage::convertToFormatPreserveText() QCOMPARE(imgResult2.textKeys(), listResult); } +void tst_QImage::defaultColorTable_data() +{ + QTest::addColumn("format"); + QTest::addColumn("createdDataCount"); + QTest::addColumn("externalDataCount"); + + // For historical reasons, internally created mono images get a default colormap. + // Externally created and Indexed8 images do not. + QTest::newRow("Mono") << QImage::Format_Mono << 2 << 0; + QTest::newRow("MonoLSB") << QImage::Format_MonoLSB << 2 << 0; + QTest::newRow("Indexed8") << QImage::Format_Indexed8 << 0 << 0; + QTest::newRow("ARGB32_PM") << QImage::Format_A2BGR30_Premultiplied << 0 << 0; +} + +void tst_QImage::defaultColorTable() +{ + QFETCH(QImage::Format, format); + QFETCH(int, createdDataCount); + QFETCH(int, externalDataCount); + + QImage img1(1, 1, format); + QCOMPARE(img1.colorCount(), createdDataCount); + QCOMPARE(img1.colorTable().size(), createdDataCount); + + quint32 buf; + QImage img2(reinterpret_cast(&buf), 1, 1, format); + QCOMPARE(img2.colorCount(), externalDataCount); + + QImage nullImg(0, 0, format); + QCOMPARE(nullImg.colorCount(), 0); +} + void tst_QImage::setColorCount() { QImage img(0, 0, QImage::Format_Indexed8); @@ -3127,8 +3161,8 @@ void tst_QImage::pixel() QImage monolsb(&a, 1, 1, QImage::Format_MonoLSB); QImage indexed(&a, 1, 1, QImage::Format_Indexed8); - QCOMPARE(QColor(mono.pixel(0, 0)), QColor(Qt::black)); - QCOMPARE(QColor(monolsb.pixel(0, 0)), QColor(Qt::black)); + mono.pixel(0, 0); // Don't crash + monolsb.pixel(0, 0); // Don't crash indexed.pixel(0, 0); // Don't crash } } -- cgit v1.2.3 From 0e40781c1637f575acc842044b67da412c8e2026 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 21 Jul 2016 21:51:12 +0300 Subject: QAbstractItemViewPrivate: de-inline hasEditor() This is in preparation of fixing a design problem with indexEditorHash. Change-Id: I6045ad3f15cd3087a894b96e9e068e42af7a1dea Reviewed-by: hjk --- src/widgets/itemviews/qabstractitemview.cpp | 5 +++++ src/widgets/itemviews/qabstractitemview_p.h | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 057718cdba..f31f2f5256 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -4275,6 +4275,11 @@ const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex & return it.value(); } +bool QAbstractItemViewPrivate::hasEditor(const QModelIndex &index) const +{ + return indexEditorHash.find(index) != indexEditorHash.constEnd(); +} + QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const { // do not try to search to avoid slow implicit cast from QModelIndex to QPersistentModelIndex diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index bb88b25652..8b0b08fd94 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -264,9 +264,7 @@ public: } const QEditorInfo &editorForIndex(const QModelIndex &index) const; - inline bool hasEditor(const QModelIndex &index) const { - return indexEditorHash.find(index) != indexEditorHash.constEnd(); - } + bool hasEditor(const QModelIndex &index) const; QModelIndex indexForEditor(QWidget *editor) const; void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic); -- cgit v1.2.3 From 29c6e39086831f6811e94364273c1f4bff119bef Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 Jul 2016 10:53:41 +0200 Subject: Windows style: Scale native metrics per monitor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The native sizes returned by the metrics and theme functions refer to the primary monitor. They need adaption when showing on a secondary monitor with differing logical DPI. Introduce a helper function QWindowsStylePrivate::nativeMetricScaleFactor() to calculate the total factor. Task-number: QTBUG-49374 Change-Id: I34c843ff34108424e1ef0aafcf9f563d17ebbc89 Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qwindowsstyle.cpp | 47 ++++++++++++++++++++++++++++++- src/widgets/styles/qwindowsstyle_p_p.h | 2 ++ src/widgets/styles/qwindowsvistastyle.cpp | 22 +++++++-------- src/widgets/styles/qwindowsxpstyle.cpp | 15 +++++----- 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 536ef2d49a..a0830a1f92 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -59,8 +59,12 @@ #include "qlistview.h" #include #include +#include +#include #include +#include #include +#include #include #include @@ -395,6 +399,47 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) return QWindowsStylePrivate::InvalidMetric; } +static QWindow *windowOf(const QWidget *w) +{ + QWindow *result = Q_NULLPTR; + if (w) { + result = w->windowHandle(); + if (!result) { + if (const QWidget *np = w->nativeParentWidget()) + result = np->windowHandle(); + } + } + return result; +} + +static QScreen *screenOf(const QWidget *w) +{ + if (const QWindow *window = windowOf(w)) + return window->screen(); + return QGuiApplication::primaryScreen(); +} + +// Calculate the overall scale factor to obtain Qt Device Independent +// Pixels from a native Windows size. Divide by devicePixelRatio +// and account for secondary screens with differing logical DPI. +qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget) +{ + if (!QHighDpiScaling::isActive()) + return 1; + qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget); + if (QGuiApplicationPrivate::screen_list.size() > 1) { + const QScreen *primaryScreen = QGuiApplication::primaryScreen(); + const QScreen *screen = screenOf(widget); + if (screen != primaryScreen) { + const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first; + const qreal logicalDpi = screen->handle()->logicalDpi().first; + if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi)) + result *= logicalDpi / primaryLogicalDpi; + } + } + return result; +} + /*! \reimp */ @@ -402,7 +447,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW { int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget); if (ret != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(ret) / QWindowsStylePrivate::devicePixelRatio(widget)); + return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); ret = QWindowsStylePrivate::fixedPixelMetric(pm); if (ret != QWindowsStylePrivate::InvalidMetric) diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h index 7971b84923..dc5a15db70 100644 --- a/src/widgets/styles/qwindowsstyle_p_p.h +++ b/src/widgets/styles/qwindowsstyle_p_p.h @@ -66,6 +66,7 @@ public: static int fixedPixelMetric(QStyle::PixelMetric pm); static qreal devicePixelRatio(const QWidget *widget = 0) { return widget ? widget->devicePixelRatioF() : QWindowsStylePrivate::appDevicePixelRatio(); } + static qreal nativeMetricScaleFactor(const QWidget *widget = Q_NULLPTR); bool hasSeenAlt(const QWidget *widget) const; bool altDown() const { return alt_down; } @@ -98,3 +99,4 @@ QT_END_NAMESPACE #endif // QT_NO_STYLE_WINDOWS #endif //QWINDOWSSTYLE_P_P_H +; diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 2ce54fe207..fe9684a25f 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -426,7 +426,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt XPThemeData themeSize = theme; themeSize.partId = TVP_HOTGLYPH; themeSize.stateId = GLPS_OPENED; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); decoration_size = qRound(qMax(size.width(), size.height())); } int mid_h = option->rect.x() + option->rect.width() / 2; @@ -988,7 +988,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, TP_DROPDOWNBUTTON); if (theme.isValid()) { - const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); if (!size.isEmpty()) { mbiw = qRound(size.width()); mbih = qRound(size.height()); @@ -1184,8 +1184,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right())); } QRect rect = option->rect; @@ -1210,7 +1210,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { int yoff = y-2 + h / 2; - const int separatorSize = 6 / QWindowsXPStylePrivate::devicePixelRatio(widget); + const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); QPoint p1 = QPoint(x + checkcol, yoff); QPoint p2 = QPoint(x + w + separatorSize, yoff); stateId = MBI_HOT; @@ -1243,8 +1243,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()), qRound(size.height() + margins.bottom() + margins.top())); checkRect.moveCenter(vCheckRect.center()); @@ -1856,8 +1856,8 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height()); sz.rwidth() += qRound(size.width() + margins.left() + margins.right()); } @@ -1967,7 +1967,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption int arrowWidth = 13; int arrowHeight = 5; if (theme.isValid()) { - const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); if (!size.isEmpty()) { arrowWidth = qRound(size.width()); arrowHeight = qRound(size.height()); @@ -2450,7 +2450,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, QWindowsXPStylePrivate::ButtonTheme, BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QIcon linkGlyph; QPixmap pm(size); pm.fill(Qt::transparent); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index a850787af0..f2ee8e0b47 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -481,7 +481,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *widget) { if (!tabbody) { XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY); - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); tabbody = new QPixmap(size.width(), QApplication::desktop()->screenGeometry().height()); QPainter painter(tabbody); @@ -3449,7 +3449,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option, widget); if (res != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(res) / QWindowsStylePrivate::devicePixelRatio(widget)); + return qRound(qreal(res) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); res = 0; switch (pm) { @@ -3595,9 +3595,10 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl const int height = tb->rect.height(); const int width = tb->rect.width(); const int buttonMargin = int(QStyleHelper::dpiScaled(4)); - int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget)) + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); + int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor) - buttonMargin; - int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget)) + int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor) - buttonMargin; const int delta = buttonWidth + 2; int controlTop = option->rect.bottom() - buttonHeight - 2; @@ -3967,7 +3968,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt if (widget && widget->isWindow()) { XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size); } } @@ -4001,7 +4002,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, WP_MAXBUTTON, MAXBS_NORMAL); if (theme.isValid()) { - const QSize size = (themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QPixmap pm(size); pm.fill(Qt::transparent); QPainter p(&pm); @@ -4035,7 +4036,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QPixmap pm(size); pm.fill(Qt::transparent); QPainter p(&pm); -- cgit v1.2.3 From d12a284bbbf1192502e7dcd49031781ce9b54d01 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 3 Jun 2016 12:29:47 +0200 Subject: Windows QPA: Pass ExcludeUserInputEvents to QWSI::flushWindowSystemEvents() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User Input events flushed out by those calls have been observed to cause crashes. Task-number: QTBUG-39842 Change-Id: I950b80f2863def5b28e9fe46ef2b73aa6db2592f Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/windows/qwindowswindow.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index e4888d6b87..b38d7c29ae 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1480,7 +1480,7 @@ void QWindowsWindow::handleGeometryChange() QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); } if (testFlag(SynchronousGeometryChangeEvent)) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry; } @@ -1580,7 +1580,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, // Our tests depend on it. fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true); if (!QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); EndPaint(hwnd, &ps); return true; @@ -1644,7 +1644,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) switch (state) { case Qt::WindowMinimized: handleHidden(); - QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // Tell QQuickWindow to stop rendering now. break; case Qt::WindowMaximized: case Qt::WindowFullScreen: @@ -1667,7 +1667,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) } } if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } break; default: @@ -1773,7 +1773,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) if (!wasSync) clearFlag(SynchronousGeometryChangeEvent); QWindowSystemInterface::handleGeometryChange(window(), r); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } else if (newState != Qt::WindowMinimized) { // Restore saved state. unsigned newStyle = m_savedStyle ? m_savedStyle : style(); -- cgit v1.2.3 From ebb651aa7395bd28474580a10f7d389c72f39e14 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Mon, 13 Jun 2016 17:56:49 +0200 Subject: Handle device pixel ratio in QTreeWidget animations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we are rendering into a new paint device we need to copy the device pixel ratio from the widget. Task-number: QTBUG-50207 Change-Id: Ica99ae84fe04311edfef817ab719863d627faf64 (cherry picked from commit 49491dd678071661db2e34133c051cb176a83e0b) Reviewed-by: Morten Johan Sørvig --- src/widgets/itemviews/qtreeview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 01ebae0848..3a2005b95c 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3244,7 +3244,8 @@ void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) const { Q_Q(const QTreeView); - QPixmap pixmap(rect.size()); + QPixmap pixmap(rect.size() * q->devicePixelRatio()); + pixmap.setDevicePixelRatio(q->devicePixelRatio()); if (rect.size().isEmpty()) return pixmap; pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels. -- cgit v1.2.3 From f2ef587906062706e576e376e4c6481ab192f50d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 30 Jun 2016 12:50:10 +0200 Subject: QWindow::fromWinId(): Return 0 when foreign window cannot be wrapped Change window creation code in QWindow to not assert should platform window creation fail for foreign windows. Prototypically add check to the Windows QPA plugin. [ChangeLog][Windows][Important Behavioral Changes] QWindow::fromWinId() may return 0 when passing invalid window handles. Task-number: QTBUG-41186 Change-Id: I936112607ec6e0838d36ac2a72aa88b869df5c23 Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- src/gui/kernel/qwindow.cpp | 9 +++++++-- src/plugins/platforms/windows/qwindowsintegration.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index fa26fd77a3..f061a2bf50 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -402,7 +402,7 @@ void QWindowPrivate::create(bool recursive) q->parent()->create(); platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); - Q_ASSERT(platformWindow); + Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow); if (!platformWindow) { qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags(); @@ -2432,7 +2432,8 @@ QWindow *QWindowPrivate::topLevelWindow() const This can be used, on platforms which support it, to embed a QWindow inside a native window, or to embed a native window inside a QWindow. - If foreign windows are not supported, this function returns 0. + If foreign windows are not supported or embedding the native window + failed in the platform plugin, this function returns 0. \note The resulting QWindow should not be used to manipulate the underlying native window (besides re-parenting), or to observe state changes of the @@ -2453,6 +2454,10 @@ QWindow *QWindow::fromWinId(WId id) window->setFlags(Qt::ForeignWindow); window->setProperty("_q_foreignWinId", QVariant::fromValue(id)); window->create(); + if (!window->handle()) { + delete window; + return nullptr; + } return window; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 6142aac92e..debe6dd131 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -311,7 +311,12 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons } if (window->type() == Qt::ForeignWindow) { - QWindowsForeignWindow *result = new QWindowsForeignWindow(window, reinterpret_cast(window->winId())); + const HWND hwnd = reinterpret_cast(window->winId()); + if (!IsWindow(hwnd)) { + qWarning("Windows QPA: Invalid foreign window ID %p."); + return nullptr; + } + QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); const QRect obtainedGeometry = result->geometry(); QScreen *screen = Q_NULLPTR; if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) -- cgit v1.2.3 From fdd15b7f99a54d37090a3bedb44815603edc53a5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 28 Jul 2016 13:50:04 +0200 Subject: Bump version Change-Id: I147acca09694b89b16ff19da36626f6559f8a9ae --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 44af7abb45..8fbdbb6e6e 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.7.0 +MODULE_VERSION = 5.7.1 -- cgit v1.2.3 From c9354429dd90aff3f1174d0b56515cb4a8aef9c2 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 19 Feb 2016 20:02:30 +0100 Subject: QSocketNotifier: improve warning to show thread names and pointers. Much like the QObject::setParent() warning, which helps a bit when debugging. Change-Id: I2abf277a12aa1ce04bd8b5759f46f8bfdcb25383 Reviewed-by: Robin Burchell Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qeventdispatcher_unix.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 9afbb84abf..802962d77d 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -421,7 +421,12 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) QSocketNotifier::Type type = notifier->type(); #ifndef QT_NO_DEBUG if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); + qWarning("QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n" + "(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))", + sockfd, + notifier->thread() ? notifier->thread()->metaObject()->className() : "QThread", notifier->thread(), + thread() ? thread()->metaObject()->className() : "QThread", thread(), + QThread::currentThread() ? QThread::currentThread()->metaObject()->className() : "QThread", QThread::currentThread()); return; } #endif -- cgit v1.2.3 From f5af4428c3ede16c742df7890bc5f5ebf8ed2535 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 26 Jul 2016 10:07:57 +0200 Subject: QVector: fix crash on reserve(0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It crashed when d was equal to Data::unsharableEmpty(). Task-number: QTBUG-51758 Change-Id: If9f2a7d11892507135f4dc0aeef909f59b7478fc Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qvector.h | 6 +++++- tests/auto/corelib/tools/qvector/tst_qvector.cpp | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 3154220634..eefab5905c 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -391,7 +391,11 @@ void QVector::reserve(int asize) { if (asize > int(d->alloc)) reallocData(d->size, asize); - if (isDetached()) + if (isDetached() +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) + && d != Data::unsharableEmpty() +#endif + ) d->capacityReserved = 1; Q_ASSERT(capacity() >= asize); } diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index edcf4c72b6..7c90f05ea4 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -276,6 +276,7 @@ private slots: void testOperators() const; void reserve(); + void reserveZero(); void reallocAfterCopy_data(); void reallocAfterCopy(); void initializeListInt(); @@ -2369,13 +2370,34 @@ void tst_QVector::reserve() { QVector a; a.resize(2); + QCOMPARE(fooCtor, 2); QVector b(a); b.reserve(1); QCOMPARE(b.size(), a.size()); + QCOMPARE(fooDtor, 0); } QCOMPARE(fooCtor, fooDtor); } +// This is a regression test for QTBUG-51758 +void tst_QVector::reserveZero() +{ + QVector vec; + vec.detach(); + vec.reserve(0); // should not crash + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.squeeze(); + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.reserve(-1); + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.append(42); + QCOMPARE(vec.size(), 1); + QVERIFY(vec.capacity() >= 1); +} + // This is a regression test for QTBUG-11763, where memory would be reallocated // soon after copying a QVector. void tst_QVector::reallocAfterCopy_data() -- cgit v1.2.3 From 444ba31a0a68421ee9ff7de788f6026599202455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Fri, 10 Jun 2016 00:11:35 +0200 Subject: xcb: Don't activate bypassed windows on mouse press Windows with "Qt::BypassWindowManagerHint" flag can't be activated by mouse. They can be activated only from code calling "activateWindow()" or "requestActivate()" methods. The patch applies also for "Qt::ToolTip" and "Qt::Popup" windows which have implicit "Qt::BypassWindowManagerHint" flag. The patch fixes some major issues: - don't activate tooltips on mouse press - this causes that Qt "thinks" that original windows loses its focus causing e.g. that text cursor stops blinking, - don't activate X11 tray icon - this causes that the active window looses its focus by clicking tray icon. The patch restores the Qt4 behavior. Task-number: QTBUG-53993 Change-Id: I80b226f2f5ea0ebbfe8922c90d9da9f4132e8cce Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0c2f0d7c4d..b5cde141f1 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2201,8 +2201,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); - if (!(w->flags() & Qt::WindowDoesNotAcceptFocus)) + if (!(w->flags() & (Qt::WindowDoesNotAcceptFocus | Qt::BypassWindowManagerHint)) + && w->type() != Qt::ToolTip + && w->type() != Qt::Popup) { w->requestActivate(); + } } updateNetWmUserTime(timestamp); -- cgit v1.2.3 From 695d85363e537b51b5d0ae6ab08a9a1e7d9e8354 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 6 Apr 2015 13:47:16 +0300 Subject: Item delegates: show localized detailed tooltips and "What's this?" texts Extract the common part from QItemDelegate and QStyledItemDelegate which uses QLocale to convert a value for Qt::DisplayRole to a string. Use this code to get the text for tooltips and "What's this?". [ChangeLog][QtWidgets][QAbstractItemDelegate] Show localized detailed tooltips and "What's this?" texts. Task-number: QTBUG-16469 Change-Id: I8618763d45b8cfddafc2f263d658ba256be60a15 Reviewed-by: Giuseppe D'Angelo --- src/widgets/itemviews/qabstractitemdelegate.cpp | 55 ++++++++++++++++--- src/widgets/itemviews/qabstractitemdelegate_p.h | 3 +- src/widgets/itemviews/qitemdelegate.cpp | 42 +++------------ src/widgets/itemviews/qstyleditemdelegate.cpp | 36 +------------ .../itemviews/qitemdelegate/qitemdelegate.pro | 2 +- .../itemviews/qitemdelegate/tst_qitemdelegate.cpp | 62 ++++++++++++++++++++++ 6 files changed, 121 insertions(+), 79 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index c2dd1ec8fd..00f2b87f93 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -370,6 +370,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index) { + Q_D(QAbstractItemDelegate); Q_UNUSED(option); if (!event || !view) @@ -378,9 +379,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, #ifndef QT_NO_TOOLTIP case QEvent::ToolTip: { QHelpEvent *he = static_cast(event); - QVariant tooltip = index.data(Qt::ToolTipRole); - if (tooltip.canConvert()) { - QToolTip::showText(he->globalPos(), tooltip.toString(), view); + const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp + const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision); + if (!tooltip.isEmpty()) { + QToolTip::showText(he->globalPos(), tooltip, view); return true; } break;} @@ -392,9 +394,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, break; } case QEvent::WhatsThis: { QHelpEvent *he = static_cast(event); - QVariant whatsthis = index.data(Qt::WhatsThisRole); - if (whatsthis.canConvert()) { - QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view); + const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp + const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision); + if (!whatsthis.isEmpty()) { + QWhatsThis::showText(he->globalPos(), whatsthis, view); return true; } break ; } @@ -537,6 +540,46 @@ bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor) return true; } +QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision) const +{ + const QLocale::FormatType formatType = (role == Qt::DisplayRole) ? QLocale::ShortFormat : QLocale::LongFormat; + QString text; + switch (value.userType()) { + case QMetaType::Float: + text = locale.toString(value.toFloat()); + break; + case QVariant::Double: + text = locale.toString(value.toDouble(), 'g', precision); + break; + case QVariant::Int: + case QVariant::LongLong: + text = locale.toString(value.toLongLong()); + break; + case QVariant::UInt: + case QVariant::ULongLong: + text = locale.toString(value.toULongLong()); + break; + case QVariant::Date: + text = locale.toString(value.toDate(), formatType); + break; + case QVariant::Time: + text = locale.toString(value.toTime(), formatType); + break; + case QVariant::DateTime: { + const QDateTime dateTime = value.toDateTime(); + text = locale.toString(dateTime.date(), formatType) + + QLatin1Char(' ') + + locale.toString(dateTime.time(), formatType); + break; } + default: + text = value.toString(); + if (role == Qt::DisplayRole) + text.replace(QLatin1Char('\n'), QChar::LineSeparator); + break; + } + return text; +} + void QAbstractItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor) { Q_Q(QAbstractItemDelegate); diff --git a/src/widgets/itemviews/qabstractitemdelegate_p.h b/src/widgets/itemviews/qabstractitemdelegate_p.h index 05f1bd138c..1796290ba9 100644 --- a/src/widgets/itemviews/qabstractitemdelegate_p.h +++ b/src/widgets/itemviews/qabstractitemdelegate_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -class QAbstractItemDelegatePrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QAbstractItemDelegatePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QAbstractItemDelegate) public: @@ -60,6 +60,7 @@ public: bool editorEventFilter(QObject *object, QEvent *event); bool tryFixup(QWidget *editor); + QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision = 6) const; void _q_commitDataAndCloseEditor(QWidget *editor); }; diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index cd952737dd..2b6e1210ca 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -61,6 +61,7 @@ #include +// keep in sync with QAbstractItemDelegate::helpEvent() #ifndef DBL_DIG # define DBL_DIG 10 #endif @@ -96,7 +97,7 @@ public: return text; } - static QString valueToText(const QVariant &value, const QStyleOptionViewItem &option); + QString valueToText(const QVariant &value, const QStyleOptionViewItem &option) const; QItemEditorFactory *f; bool clipPainting; @@ -326,40 +327,9 @@ void QItemDelegate::setClipping(bool clip) d->clipPainting = clip; } -QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) +QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) const { - QString text; - switch (value.userType()) { - case QMetaType::Float: - text = option.locale.toString(value.toFloat(), 'g'); - break; - case QVariant::Double: - text = option.locale.toString(value.toDouble(), 'g', DBL_DIG); - break; - case QVariant::Int: - case QVariant::LongLong: - text = option.locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - text = option.locale.toString(value.toULongLong()); - break; - case QVariant::Date: - text = option.locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - text = option.locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - text = option.locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - text += QLatin1Char(' '); - text += option.locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: - text = replaceNewLine(value.toString()); - break; - } - return text; + return textForRole(Qt::DisplayRole, value, option.locale, DBL_DIG); } /*! @@ -428,7 +398,7 @@ void QItemDelegate::paint(QPainter *painter, QRect displayRect; value = index.data(Qt::DisplayRole); if (value.isValid() && !value.isNull()) { - text = QItemDelegatePrivate::valueToText(value, opt); + text = d->valueToText(value, opt); displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text); } @@ -1055,7 +1025,7 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option, return QRect(QPoint(0, 0), option.decorationSize); case QVariant::String: default: { - QString text = QItemDelegatePrivate::valueToText(value, option); + const QString text = d->valueToText(value, option); value = index.data(Qt::FontRole); QFont fnt = qvariant_cast(value).resolve(option.font); return textRectangle(0, d->textLayoutBounds(option), fnt, text); } diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp index f02f98cb31..483cfbdc36 100644 --- a/src/widgets/itemviews/qstyleditemdelegate.cpp +++ b/src/widgets/itemviews/qstyleditemdelegate.cpp @@ -255,41 +255,7 @@ QStyledItemDelegate::~QStyledItemDelegate() */ QString QStyledItemDelegate::displayText(const QVariant &value, const QLocale& locale) const { - QString text; - switch (value.userType()) { - case QMetaType::Float: - case QVariant::Double: - text = locale.toString(value.toReal()); - break; - case QVariant::Int: - case QVariant::LongLong: - text = locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - text = locale.toString(value.toULongLong()); - break; - case QVariant::Date: - text = locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - text = locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - text = locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - text += QLatin1Char(' '); - text += locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: - // convert new lines into line separators - text = value.toString(); - for (int i = 0; i < text.count(); ++i) { - if (text.at(i) == QLatin1Char('\n')) - text[i] = QChar::LineSeparator; - } - break; - } - return text; + return d_func()->textForRole(Qt::DisplayRole, value, locale); } /*! diff --git a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro index f7fb41e60c..02a71f8101 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro +++ b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qitemdelegate -QT += widgets testlib +QT += widgets widgets-private testlib SOURCES += tst_qitemdelegate.cpp win32:!wince:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 25f27cb0c7..45bac13c92 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -56,6 +56,8 @@ #include #include +#include + Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) #if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) @@ -229,6 +231,8 @@ private slots: void task257859_finalizeEdit(); void QTBUG4435_keepSelectionOnCheck(); + + void QTBUG16469_textForRole(); }; @@ -1558,6 +1562,64 @@ void tst_QItemDelegate::testLineEditValidation() QCOMPARE(item->data(Qt::DisplayRole).toString(), QStringLiteral("abc,def")); } +void tst_QItemDelegate::QTBUG16469_textForRole() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("This test requires a developer build"); +#else + struct TestDelegate : public QItemDelegate + { + QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale) + { + QAbstractItemDelegatePrivate *d = reinterpret_cast(qGetPtrHelper(d_ptr)); + return d->textForRole(role, value, locale); + } + } delegate; + QLocale locale; + + const float f = 123.456f; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, f, locale), locale.toString(f)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, f, locale), locale.toString(f)); + const double d = 123.456; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, d, locale), locale.toString(d, 'g', 6)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, d, locale), locale.toString(d, 'g', 6)); + const int i = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, i, locale), locale.toString(i)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, i, locale), locale.toString(i)); + const qlonglong ll = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ll, locale), locale.toString(ll)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ll, locale), locale.toString(ll)); + const uint ui = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ui, locale), locale.toString(ui)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ui, locale), locale.toString(ui)); + const qulonglong ull = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ull, locale), locale.toString(ull)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ull, locale), locale.toString(ull)); + + const QDateTime dateTime = QDateTime::currentDateTime(); + const QDate date = dateTime.date(); + const QTime time = dateTime.time(); + const QString shortDate = locale.toString(date, QLocale::ShortFormat); + const QString longDate = locale.toString(date, QLocale::LongFormat); + const QString shortTime = locale.toString(time, QLocale::ShortFormat); + const QString longTime = locale.toString(time, QLocale::LongFormat); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, date, locale), shortDate); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, date, locale), longDate); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, time, locale), shortTime); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, time, locale), longTime); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, dateTime, locale), shortDate + QLatin1Char(' ') + shortTime); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, dateTime, locale), longDate + QLatin1Char(' ') + longTime); + + const QString text("text"); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, text, locale), text); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, text, locale), text); + const QString multipleLines("multiple\nlines"); + QString multipleLines2 = multipleLines; + multipleLines2.replace(QLatin1Char('\n'), QChar::LineSeparator); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, multipleLines, locale), multipleLines2); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, multipleLines, locale), multipleLines); +#endif +} // ### _not_ covered: -- cgit v1.2.3 From 4790ccfa7a7dcdaf5b1c3c3f71bd333a6d754fba Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 27 Jul 2016 22:57:51 +0200 Subject: Fix gcc -Wsuggest-override warning on Q_OBJECT Same reasoning as commit 3092bd5 (which was for Clang), but for gcc >= 5.1. Change-Id: I123b17670c1a64876b01fd39fb11648fa4e8b1fd Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobjectdefs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 8d32795af2..0a4492dcda 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -173,6 +173,8 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") +#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510 +# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override") #else # define Q_OBJECT_NO_OVERRIDE_WARNING #endif -- cgit v1.2.3 From 10d4969966082578205912c8000524eb20307e6e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 19 Jul 2016 21:29:21 +0300 Subject: examples: use QSignalBlocker Examples should show idiomatic Qt, and QSignalBlocker is idiomatic since it's inception in Qt 5.3. Just updating the examples was forgotten. This commit makes good for that. Fix coding-style issues as a drive-by. Change-Id: If138e87ea2ab7a444599734113f7cc6df11fb42d Reviewed-by: Friedemann Kleint --- .../widgets/mainwindows/mainwindow/colorswatch.cpp | 31 +++++++++++---------- .../widgets/widgets/charactermap/mainwindow.cpp | 32 ++++++++++++---------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index d746bbe8d3..efc94f7d97 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -409,20 +410,22 @@ void ColorSwatch::updateContextMenu() allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea); } - leftAction->blockSignals(true); - rightAction->blockSignals(true); - topAction->blockSignals(true); - bottomAction->blockSignals(true); - - leftAction->setChecked(area == Qt::LeftDockWidgetArea); - rightAction->setChecked(area == Qt::RightDockWidgetArea); - topAction->setChecked(area == Qt::TopDockWidgetArea); - bottomAction->setChecked(area == Qt::BottomDockWidgetArea); - - leftAction->blockSignals(false); - rightAction->blockSignals(false); - topAction->blockSignals(false); - bottomAction->blockSignals(false); + { + const QSignalBlocker blocker(leftAction); + leftAction->setChecked(area == Qt::LeftDockWidgetArea); + } + { + const QSignalBlocker blocker(rightAction); + rightAction->setChecked(area == Qt::RightDockWidgetArea); + } + { + const QSignalBlocker blocker(topAction); + topAction->setChecked(area == Qt::TopDockWidgetArea); + } + { + const QSignalBlocker blocker(bottomAction); + bottomAction->setChecked(area == Qt::BottomDockWidgetArea); + } if (areaActions->isEnabled()) { leftAction->setEnabled(areas & Qt::LeftDockWidgetArea); diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index 02be26c5ce..14784e7d65 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -157,25 +157,27 @@ void MainWindow::findSizes(const QFont &font) { QFontDatabase fontDatabase; QString currentSize = sizeCombo->currentText(); - sizeCombo->blockSignals(true); - sizeCombo->clear(); - - int size; - if(fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) { - foreach(size, QFontDatabase::standardSizes()) { - sizeCombo->addItem(QVariant(size).toString()); - sizeCombo->setEditable(true); - } - } else { - foreach(size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) { - sizeCombo->addItem(QVariant(size).toString()); - sizeCombo->setEditable(false); + { + const QSignalBlocker blocker(sizeCombo); + // sizeCombo signals are now blocked until end of scope + sizeCombo->clear(); + + int size; + if (fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) { + foreach (size, QFontDatabase::standardSizes()) { + sizeCombo->addItem(QVariant(size).toString()); + sizeCombo->setEditable(true); + } + + } else { + foreach (size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) { + sizeCombo->addItem(QVariant(size).toString()); + sizeCombo->setEditable(false); + } } } - sizeCombo->blockSignals(false); - int sizeIndex = sizeCombo->findText(currentSize); if(sizeIndex == -1) -- cgit v1.2.3 From f24cc53cc27d8ed4be4c1d0d2df059dd6a6909a9 Mon Sep 17 00:00:00 2001 From: Denis Kormalev Date: Fri, 22 Jul 2016 19:00:35 +0300 Subject: Fix for race condition in signal activation There was a race condition between QObject::disconnect() and QMetaObject::activate() which can occur if there are multiple BlockingQueued connections to one signal from different threads and they connect/disconnect their connections often. What can happen in this case is: T1 is in activate() method and T2 is in disconnect() method T1 T2 locks sender mutex selects next connection unlocks sender mutex locks sender mutex sets isSlotObject to false creates QMetaCallEvent derefs connection posts event Two things can happen here: 1. Connection can still be valid, but it will have isSlotObject==false and callFunction will be used instead of slotObj 2. Connection can already be invalid To fix it mutex unlock should be moved after QMetaCallEvent creation. Also there is another case, when we don't disconnect but delete the receiver object. In this case it can already be invalid during postEvent, so we need to move mutex unlock after postEvent. Change-Id: I8103798324140ee11de5b4e10906562ba878ff8b Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/corelib/kernel/qobject.cpp | 2 +- tests/auto/other/qobjectrace/tst_qobjectrace.cpp | 175 +++++++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index d5f2f9bcd8..467b4c6780 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3683,7 +3683,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i continue; #ifndef QT_NO_THREAD } else if (c->connectionType == Qt::BlockingQueuedConnection) { - locker.unlock(); if (receiverInSameThread) { qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: " "Sender is %s(%p), receiver is %s(%p)", @@ -3695,6 +3694,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore) : new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore); QCoreApplication::postEvent(receiver, ev); + locker.unlock(); semaphore.acquire(); locker.relock(); continue; diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index 036f6f6fdd..36481465d5 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -51,6 +51,7 @@ class tst_QObjectRace: public QObject private slots: void moveToThreadRace(); void destroyRace(); + void disconnectRace(); }; class RaceObject : public QObject @@ -298,6 +299,180 @@ void tst_QObjectRace::destroyRace() delete threads[i]; } +static QAtomicInteger countedStructObjectsCount; +struct CountedFunctor +{ + CountedFunctor() : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); } + CountedFunctor(const CountedFunctor &) : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); } + CountedFunctor &operator=(const CountedFunctor &) { return *this; } + ~CountedFunctor() { destroyed = true; countedStructObjectsCount.fetchAndAddRelaxed(-1);} + void operator()() const {QCOMPARE(destroyed, false);} + +private: + bool destroyed; +}; + +class DisconnectRaceSenderObject : public QObject +{ + Q_OBJECT +signals: + void theSignal(); +}; + +class DisconnectRaceThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; + bool emitSignal; +public: + DisconnectRaceThread(DisconnectRaceSenderObject *s, bool emitIt) + : QThread(), sender(s), emitSignal(emitIt) + { + } + + void run() + { + while (!isInterruptionRequested()) { + QMetaObject::Connection conn = connect(sender, &DisconnectRaceSenderObject::theSignal, + sender, CountedFunctor(), Qt::BlockingQueuedConnection); + if (emitSignal) + emit sender->theSignal(); + disconnect(conn); + yieldCurrentThread(); + } + } +}; + +class DeleteReceiverRaceSenderThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; +public: + DeleteReceiverRaceSenderThread(DisconnectRaceSenderObject *s) + : QThread(), sender(s) + { + } + + void run() + { + while (!isInterruptionRequested()) { + emit sender->theSignal(); + yieldCurrentThread(); + } + } +}; + +class DeleteReceiverRaceReceiver : public QObject +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; + QObject *receiver; + QTimer *timer; +public: + DeleteReceiverRaceReceiver(DisconnectRaceSenderObject *s) + : QObject(), sender(s), receiver(0) + { + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &DeleteReceiverRaceReceiver::onTimeout); + timer->start(1); + } + + void onTimeout() + { + if (receiver) + delete receiver; + receiver = new QObject; + connect(sender, &DisconnectRaceSenderObject::theSignal, receiver, CountedFunctor(), Qt::BlockingQueuedConnection); + } +}; + +class DeleteReceiverRaceReceiverThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; +public: + DeleteReceiverRaceReceiverThread(DisconnectRaceSenderObject *s) + : QThread(), sender(s) + { + } + + void run() + { + QScopedPointer receiver(new DeleteReceiverRaceReceiver(sender)); + exec(); + } +}; + +void tst_QObjectRace::disconnectRace() +{ + enum { ThreadCount = 20, TimeLimit = 3000 }; + + QCOMPARE(countedStructObjectsCount.load(), 0u); + + { + QScopedPointer sender(new DisconnectRaceSenderObject()); + QScopedPointer senderThread(new QThread()); + senderThread->start(); + sender->moveToThread(senderThread.data()); + + DisconnectRaceThread *threads[ThreadCount]; + for (int i = 0; i < ThreadCount; ++i) { + threads[i] = new DisconnectRaceThread(sender.data(), !(i % 10)); + threads[i]->start(); + } + + QTime timeLimiter; + timeLimiter.start(); + + while (timeLimiter.elapsed() < TimeLimit) + QTest::qWait(10); + + for (int i = 0; i < ThreadCount; ++i) { + threads[i]->requestInterruption(); + QVERIFY(threads[i]->wait(300)); + delete threads[i]; + } + + senderThread->quit(); + QVERIFY(senderThread->wait(300)); + } + + QCOMPARE(countedStructObjectsCount.load(), 0u); + + { + QScopedPointer sender(new DisconnectRaceSenderObject()); + QScopedPointer senderThread(new DeleteReceiverRaceSenderThread(sender.data())); + senderThread->start(); + sender->moveToThread(senderThread.data()); + + DeleteReceiverRaceReceiverThread *threads[ThreadCount]; + for (int i = 0; i < ThreadCount; ++i) { + threads[i] = new DeleteReceiverRaceReceiverThread(sender.data()); + threads[i]->start(); + } + + QTime timeLimiter; + timeLimiter.start(); + + while (timeLimiter.elapsed() < TimeLimit) + QTest::qWait(10); + + senderThread->requestInterruption(); + QVERIFY(senderThread->wait(300)); + + for (int i = 0; i < ThreadCount; ++i) { + threads[i]->quit(); + QVERIFY(threads[i]->wait(300)); + delete threads[i]; + } + } + + QCOMPARE(countedStructObjectsCount.load(), 0u); +} QTEST_MAIN(tst_QObjectRace) #include "tst_qobjectrace.moc" -- cgit v1.2.3 From 2ff1557937c398a7fb5cc7ba120e7ca3b5eacd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 24 Jun 2016 14:25:04 +0200 Subject: =?UTF-8?q?Cocoa:=20Don=E2=80=99t=20beep=20on=20return=20keypress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Limit event propagation to AA_PluginApplication Applications. Change-Id: Id56ceea8d2aacae3f2be17f5894791de4eca528e Task-number: QTBUG-54211 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index d4f2cf32fc..e88ae76c75 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1662,12 +1662,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; - // Track keyDown acceptance state for later acceptance of the keyUp. - if (accepted) + // When Qt is used to implement a plugin for a native application we + // want to propagate unhandled events to other native views. However, + // Qt does not always set the accepted state correctly (in particular + // for return key events), so do this for plugin applications only + // to prevent incorrect forwarding in the general case. + const bool shouldPropagate = QCoreApplication::testAttribute(Qt::AA_PluginApplication) && !accepted; + + // Track keyDown acceptance/forward state for later acceptance of the keyUp. + if (!shouldPropagate) m_acceptedKeyDowns.insert([nsevent keyCode]); - // Propagate the keyDown to the next responder if Qt did not accept it. - if (!accepted) + if (shouldPropagate) [super keyDown:nsevent]; } -- cgit v1.2.3 From 0eb77c3011ee4d6bbc46dd2d40c9324e9bfcbecf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 1 Aug 2016 10:04:38 +0200 Subject: mimetypebrowser example: Add Generic Icon Name Show QMimeType::genericIconName() to description pane. Change-Id: I698d07084b6396469686057ea53e2f497fdbe287 Reviewed-by: David Faure --- examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp index 99d73717e2..46e603621a 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp +++ b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp @@ -172,7 +172,8 @@ QString MimetypeModel::formatMimeTypeInfo(const QMimeType &t) str << "" << "Comment:" << t.comment() << "" - << "Icon name:" << t.iconName() << ""; + << "Icon name:" << t.iconName() << "" + << "Generic icon name" << t.genericIconName() << ""; const QString &filter = t.filterString(); if (!filter.isEmpty()) -- cgit v1.2.3