From 490b24b06408e90e9684d8331fd3fe8b0c51b0b5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Nov 2017 08:40:24 -0700 Subject: QTemporaryFile: hide the O_TMPFILE feature behind a check for linkat() Some Linux libc (I'm looking at you, Bionic) use the system call but don't expose it to userspace. We could use syscall() to make the system call, but instead I decided to penalize users of those libc by not having the feature. It's probably a good thing, since there were likely to be more problems with Android anyway and I don't have an environment to debug. Task-number: QTBUG-64154 Change-Id: I57a1bd6e0c194530b732fffd14f3007a1062d935 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/configure.json | 15 +++++++++++++++ src/corelib/global/minimum-linux_p.h | 2 +- src/corelib/global/qconfig-bootstrapped.h | 5 +++++ src/corelib/io/qtemporaryfile_p.h | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 8067ca70f1..bf44f2649d 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -349,6 +349,15 @@ "qmake": "linux: LIBS += -lpthread -lrt" } }, + "linkat": { + "label": "linkat()", + "type": "compile", + "test": { + "head": "#define _ATFILE_SOURCE 1", + "include": [ "fcntl.h", "unistd.h" ], + "main": "linkat(AT_FDCWD, \"foo\", AT_FDCWD, \"bar\", AT_SYMLINK_FOLLOW);" + } + }, "ppoll": { "label": "ppoll()", "type": "compile", @@ -540,6 +549,12 @@ "condition": "libs.journald", "output": [ "privateFeature" ] }, + "linkat": { + "label": "linkat()", + "autoDetect": "config.linux", + "condition": "tests.linkat", + "output": [ "privateFeature" ] + }, "std-atomic64": { "label": "64 bit atomic operations", "condition": "libs.libatomic", diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h index 324744b856..bad2488b4d 100644 --- a/src/corelib/global/minimum-linux_p.h +++ b/src/corelib/global/minimum-linux_p.h @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE * - inotify_init1 before 2.6.12-rc12 * - futex(2) before 2.6.12-rc12 * - FUTEX_WAKE_OP 2.6.14 FUTEX_OP - * - linkat(2) 2.6.17 O_TMPFILE + * - linkat(2) 2.6.17 O_TMPFILE && QT_CONFIG(linkat) * - FUTEX_PRIVATE_FLAG 2.6.22 * - O_CLOEXEC 2.6.23 * - eventfd 2.6.23 diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index 2164d7f21f..dabb715607 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -87,6 +87,11 @@ #define QT_FEATURE_futimens -1 #define QT_FEATURE_futimes -1 #define QT_FEATURE_library -1 +#ifdef __linux__ +# define QT_FEATURE_linkat 1 +#else +# define QT_FEATURE_linkat -1 +#endif #define QT_NO_QOBJECT #define QT_FEATURE_process -1 #define QT_FEATURE_renameat2 -1 diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index 46a0d7aba3..f74e5680b9 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -58,7 +58,7 @@ #include "private/qfile_p.h" #include "qtemporaryfile.h" -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) && QT_CONFIG(linkat) # include # ifdef O_TMPFILE // some early libc support had the wrong values for O_TMPFILE -- cgit v1.2.3 From 48afcf97b45a2f2729e5ff29a7d9d9ec71958a13 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 8 Nov 2017 13:45:26 +0100 Subject: Fix shader graph metatypes for static builds Cannot rely on Q_COREAPP_STARTUP_FUNCTION inside Qt since static builds have to be fully supported. Due to not registering those types, the shader builder silently generated incompilable shader code in static builds. This is critical especially on platforms where static builds are the only choice (INTEGRITY). Task-number: QTBUG-64365 Change-Id: I8820ded239ac160ab00c7fc34918fd3f273f0afb Reviewed-by: Lars Knoll --- src/gui/util/qshadergraphloader.cpp | 3 +++ src/gui/util/qshaderlanguage.cpp | 14 ++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/gui/util/qshadergraphloader.cpp b/src/gui/util/qshadergraphloader.cpp index c7560d9105..8d92c73a5a 100644 --- a/src/gui/util/qshadergraphloader.cpp +++ b/src/gui/util/qshadergraphloader.cpp @@ -48,10 +48,13 @@ QT_BEGIN_NAMESPACE +void qt_register_ShaderLanguage_enums(); + QShaderGraphLoader::QShaderGraphLoader() Q_DECL_NOTHROW : m_status(Null), m_device(nullptr) { + qt_register_ShaderLanguage_enums(); } QShaderGraphLoader::Status QShaderGraphLoader::status() const Q_DECL_NOTHROW diff --git a/src/gui/util/qshaderlanguage.cpp b/src/gui/util/qshaderlanguage.cpp index 4a0da5bfb5..f9192f5ff3 100644 --- a/src/gui/util/qshaderlanguage.cpp +++ b/src/gui/util/qshaderlanguage.cpp @@ -43,14 +43,12 @@ QT_BEGIN_NAMESPACE -namespace { - void registerEnums() - { - qRegisterMetaType(); - qRegisterMetaType(); - } +// Note: to be invoked explicitly. Relying for example on +// Q_COREAPP_STARTUP_FUNCTION would not be acceptable in static builds. +void qt_register_ShaderLanguage_enums() +{ + qRegisterMetaType(); + qRegisterMetaType(); } -Q_COREAPP_STARTUP_FUNCTION(registerEnums) - QT_END_NAMESPACE -- cgit v1.2.3 From 131c9a24626b0bb2c09d509d3ba7a1155501f0e1 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 10 Nov 2017 17:14:23 +0100 Subject: Fix BC breakage by adding an overload for the QSqlField constructor Change-Id: I253bb8cd97b982fa5ed5dd546c38deb1f7995986 Reviewed-by: Lars Knoll --- src/sql/kernel/qsqlfield.cpp | 13 +++++++++++++ src/sql/kernel/qsqlfield.h | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp index 59b992e803..a258d44df7 100644 --- a/src/sql/kernel/qsqlfield.cpp +++ b/src/sql/kernel/qsqlfield.cpp @@ -155,6 +155,19 @@ public: */ /*! + Constructs an empty field called \a fieldName of variant type \a type. + + \sa setRequiredStatus(), setLength(), setPrecision(), setDefaultValue(), + setGenerated(), setReadOnly() +*/ +QSqlField::QSqlField(const QString &fieldName, QVariant::Type type) +{ + d = new QSqlFieldPrivate(fieldName, type, QString()); + val = QVariant(type); +} + +/*! + \overload Constructs an empty field called \a fieldName of variant type \a type in \a table. diff --git a/src/sql/kernel/qsqlfield.h b/src/sql/kernel/qsqlfield.h index 30474735f4..8650ba8715 100644 --- a/src/sql/kernel/qsqlfield.h +++ b/src/sql/kernel/qsqlfield.h @@ -55,8 +55,9 @@ public: enum RequiredStatus { Unknown = -1, Optional = 0, Required = 1 }; explicit QSqlField(const QString& fieldName = QString(), - QVariant::Type type = QVariant::Invalid, - const QString &tableName = QString()); + QVariant::Type type = QVariant::Invalid); + QSqlField(const QString &fieldName, QVariant::Type type, + const QString &tableName); QSqlField(const QSqlField& other); QSqlField& operator=(const QSqlField& other); -- cgit v1.2.3 From 1456a7b78aad6ad3edf91dec7be76a7cb885cd24 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 8 Nov 2017 13:57:26 +0100 Subject: Doc: Remove the default list of highlighted examples Each module now maintain the list of examples to highlight separately. Change-Id: Ib9bca8d945bb3e81d4176cbbebcb89b1309dc0d4 Reviewed-by: Nico Vertriest --- doc/global/manifest-meta.qdocconf | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index 3b67049182..3db67a3131 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -30,26 +30,6 @@ manifestmeta.filters = highlighted android thumbnail ios -manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \ - "QtQuick/Qt Quick Demo - Photo Surface" \ - "QtQuick/Qt Quick Demo - Tweet Search" \ - "QtQuick/Qt Quick Demo - Calqlatr" \ - "QtQuick/Qt Quick Demo - StocQt" \ - "QtQuick/Qt Quick Demo - Clocks" \ - "QtQuick/Qt Quick Examples - Shader Effects" \ - "QtQuickExtras/Qt Quick Extras - Dashboard" \ - "QtQuickExtras/Qt Quick Extras - Flat" \ - "QtQuickExtras/Qt Quick Extras - Gallery" \ - "QtQuickDialogs/Qt Quick System Dialog Examples" \ - "QtWinExtras/Quick Player" \ - "QtMultimedia/QML Video Shader Effects Example" \ - "QtCanvas3D/Interactive Mobile Phone Example" \ - "QtLocation/Map Viewer (QML)" \ - "QtBluetooth/Bluetooth Low Energy Heart Rate Game" \ - "QtCharts/Chart Themes Example" \ - "QtDataVisualization/Bars Example" \ - "QtDataVisualization/Surface Example" - manifestmeta.highlighted.attributes = isHighlighted:true manifestmeta.android.names = "QtQuick/Qt Quick Demo - Calqlatr" \ -- cgit v1.2.3 From 285596ee199ae1767fc48a0d0c2d12b178c0234d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 9 Nov 2017 21:13:43 +0100 Subject: Special-case parsing of Zulu time-zone in date-times When parsing a date-time's zone, a stray Z denotes UTC (a.k.a. Zulu time), despite not being a valid name for the zone. Clients parsing such date strings had to treat the Z as a literal, rather than a zone-ID, but then they got back a LocalTime instead of the UTC the string actually described. So teach QTimeZoneParser to handle this special case and adapt an existing test (that used a time ending in Z, but had to treat it as a local time) to check this works. [ChangeLog][QtCore][QDateTime] When parsing a time-zone, "Z" is now recognized as an alias for UTC. Change-Id: Ib6aa2d8ea2dc6b2da526b39aec74dbc007f90fd8 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetimeparser.cpp | 7 ++++++- tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index dd277f7753..4b3777407c 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1155,7 +1155,8 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, // Synchronize with what findTimeZone() found: QStringRef zoneName = input->midRef(pos, sect.used); Q_ASSERT(!zoneName.isEmpty()); // sect.used > 0 - const QByteArray latinZone(zoneName.toLatin1()); + const QByteArray latinZone(zoneName == QLatin1String("Z") + ? QByteArray("UTC") : zoneName.toLatin1()); timeZone = QTimeZone(latinZone); tspec = timeZone.isValid() ? (QTimeZone::isTimeZoneIdAvailable(latinZone) @@ -1595,6 +1596,10 @@ QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when, while (index > 0) { str.truncate(index); + if (str == QLatin1String("Z")) { + offset = 0; // "Zulu" time - a.k.a. UTC + break; + } QTimeZone zone(str.toLatin1()); if (zone.isValid()) { offset = zone.offsetFromUtc(when); diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index c0ed88e154..7a047c67de 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2396,8 +2396,8 @@ void tst_QDateTime::fromStringStringFormat_data() QTest::newRow("data14") << QString("32.01.2004") << QString("dd.MM.yyyy") << invalidDateTime(); QTest::newRow("data15") << QString("Thu January 2004") << QString("ddd MMMM yyyy") << QDateTime(QDate(2004, 1, 1), QTime()); QTest::newRow("data16") << QString("2005-06-28T07:57:30.001Z") - << QString("yyyy-MM-ddThh:mm:ss.zZ") - << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1)); + << QString("yyyy-MM-ddThh:mm:ss.zt") + << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1), Qt::UTC); } void tst_QDateTime::fromStringStringFormat() -- cgit v1.2.3 From a066ad32b6ef87b8882642495dcabaa3ac1a0819 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 12 Nov 2017 15:56:20 -0800 Subject: QDateTime: Move the deprecation marker to Qt 5.10 Commit b6a61211280aa6ddd56f107a9795c9824b7702b0 went into dev at around the time of the 5.10 branching. We apparently got the side of it wrong. Change-Id: Ic632b4163d784b83951cfffd14f67bec63fbc795 Reviewed-by: Edward Welbourne --- src/corelib/tools/qdatetime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index adab47fc1f..3b741553d5 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -81,7 +81,7 @@ public: int daysInYear() const; int weekNumber(int *yearNum = Q_NULLPTR) const; -#if QT_DEPRECATED_SINCE(5, 11) && !defined QT_NO_TEXTDATE +#if QT_DEPRECATED_SINCE(5, 10) && !defined QT_NO_TEXTDATE QT_DEPRECATED_X("Use QLocale::monthName or QLocale::standaloneMonthName") static QString shortMonthName(int month, MonthNameType type = DateFormat); QT_DEPRECATED_X("Use QLocale::dayName or QLocale::standaloneDayName") -- cgit v1.2.3 From 12aa50175268064b3da36473ec0196cbdb1bdf7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Sep 2017 15:09:22 +0200 Subject: macOS: Fix OpenGL context sharing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See code comments for problem and fix description. Task-number: QTBUG-63180 Change-Id: I6c6381f2c77c246bd975f66f9baa0165e32de777 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 5ed81a7f1b..be5029b7e0 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -152,9 +152,32 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo QMacAutoReleasePool pool; // For the SG Canvas render thread + m_shareContext = share ? static_cast(share)->nsOpenGLContext() : nil; + + if (m_shareContext) { + // Allow sharing between 3.2 Core and 4.1 Core profile versions in + // cases where NSOpenGLContext creates a 4.1 context where a 3.2 + // context was requested. Due to the semantics of QSurfaceFormat + // this 4.1 version can find its way onto the format for the new + // context, even though it was at no point requested by the user. + GLint shareContextRequestedProfile; + [m_shareContext.pixelFormat getValues:&shareContextRequestedProfile + forAttribute:NSOpenGLPFAOpenGLProfile forVirtualScreen:0]; + auto shareContextActualProfile = share->format().version(); + + if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core && + shareContextActualProfile >= qMakePair(4, 1)) { + + // There is a mismatch, downgrade requested format to make the + // NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext will + // fail to create a new context if there is a mismatch). + if (m_format.version() >= qMakePair(4, 1)) + m_format.setVersion(3, 2); + } + } + // create native context for the requested pixel format and share NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat(m_format); - m_shareContext = share ? static_cast(share)->nsOpenGLContext() : nil; m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext]; // retry without sharing on context creation failure. -- cgit v1.2.3 From b72b5cd76004e54dc00c0f1133f4d59192ef154a Mon Sep 17 00:00:00 2001 From: Victor-Andrei Variu Date: Mon, 14 Aug 2017 15:47:26 +0300 Subject: Adjust screen scale factor for certain screen configurations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pixel density reported by the screen is sometimes not precise enough, so recalculate it: divide px (physical pixels) by dp (device-independent pixels) for both width and height, and then use the average if it is different from the one initially reported by the screen Task-number: QTBUG-62191 Change-Id: Ia2f485c7ce8849db6e7c1d2ac08f5e008aea2ff8 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 085652879c..078f185d08 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -376,8 +376,22 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) { qreal factor = qreal(1.0); if (screen) { - if (m_usePixelDensity) - factor *= screen->pixelDensity(); + if (m_usePixelDensity) { + qreal pixelDensity = screen->pixelDensity(); + + // Pixel density reported by the screen is sometimes not precise enough, + // so recalculate it: divide px (physical pixels) by dp (device-independent pixels) + // for both width and height, and then use the average if it is different from + // the one initially reported by the screen + QRect screenGeometry = screen->geometry(); + qreal wFactor = qreal(screenGeometry.width()) / qRound(screenGeometry.width() / pixelDensity); + qreal hFactor = qreal(screenGeometry.height()) / qRound(screenGeometry.height() / pixelDensity); + qreal averageDensity = (wFactor + hFactor) / 2; + if (!qFuzzyCompare(pixelDensity, averageDensity)) + pixelDensity = averageDensity; + + factor *= pixelDensity; + } if (m_screenFactorSet) { QVariant screenFactor = screen->screen()->property(scaleFactorProperty); if (screenFactor.isValid()) -- cgit v1.2.3 From 3c7a6a7a581f9ea6f05a22a912d660c5402a1fa8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 21 Oct 2017 11:24:54 -0700 Subject: QRandomGenerator: Enforce the use of 32-bit integers in the engine std::mt19937 is defined as operating on uint_fast32_t, which is usually just a 32-bit integer. That's not the case on 64-bit Linux, where it is actually 64-bit wide, meaning sizeof(std::mt19937) jumps from 2504 to 5000 bytes, with exactly 50% of it filled with zeroes. The seed() function also needs a large zero-extending loop. Change-Id: Icaa86fc7b54d4b368c0efffd14efa911e2a40b44 Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index bde64646a4..005de0941f 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -177,7 +177,8 @@ private: friend class QRandomGenerator64; struct SystemGenerator; struct SystemAndGlobalGenerators; - typedef std::mt19937 RandomEngine; + using RandomEngine = std::mersenne_twister_engine; union Storage { uint dummy; -- cgit v1.2.3 From 4ee85ff7c5db7aa228a30a9dc2a52d5d37089241 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 19 Nov 2017 11:26:33 -0800 Subject: QFileSystemEngine/Linux: fix when qt_lstatx() succeeds When qt_lstatx() succeeds and the target is not a link, we'd erroneously mark the file as non-existent during the pass to check qt_statx(). All flags besides the file's modes were cleared. This is unit-tested, but only happens on Linux kernels 4.12 or later. It didn't happen to me because I already had this fix applied as part of a later change relating to QSystemResult. Task-number: QTBUG-64514 Change-Id: I938b024e38bf4aac9154fffd14f893506a1ef55b Reviewed-by: Lars Knoll --- src/corelib/io/qfilesystemengine_unix.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index d77cdc123c..4051dc43a1 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -918,7 +918,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM data.entryFlags &= ~what; const QByteArray nativeFilePath = entry.nativeFilePath(); - bool entryExists = true; // innocent until proven otherwise + int entryErrno = 0; // innocent until proven otherwise // first, we may try lstat(2). Possible outcomes: // - success and is a symlink: filesystem entry exists, but we need stat(2) @@ -968,7 +968,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } } else { // it doesn't exist - entryExists = false; + entryErrno = errno; data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; } @@ -976,8 +976,8 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } // second, we try a regular stat(2) - if (statResult != 0 && (what & QFileSystemMetaData::PosixStatFlags)) { - if (entryExists && statResult == -1) { + if (statResult == -1 && (what & QFileSystemMetaData::PosixStatFlags)) { + if (entryErrno == 0 && statResult == -1) { data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; statResult = qt_statx(nativeFilePath, &statxBuffer); if (statResult == -ENOSYS) { @@ -991,7 +991,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } if (statResult != 0) { - entryExists = false; + entryErrno = errno; data.birthTime_ = 0; data.metadataChangeTime_ = 0; data.modificationTime_ = 0; @@ -1010,13 +1010,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (what & (QFileSystemMetaData::UserPermissions | QFileSystemMetaData::ExistsAttribute)) { // calculate user permissions auto checkAccess = [&](QFileSystemMetaData::MetaDataFlag flag, int mode) { - if (!entryExists || (what & flag) == 0) + if (entryErrno != 0 || (what & flag) == 0) return; if (QT_ACCESS(nativeFilePath, mode) == 0) { // access ok (and file exists) data.entryFlags |= flag | QFileSystemMetaData::ExistsAttribute; } else if (errno != EACCES && errno != EROFS) { - entryExists = false; + entryErrno = errno; } }; @@ -1025,9 +1025,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM checkAccess(QFileSystemMetaData::UserExecutePermission, X_OK); // if we still haven't found out if the file exists, try F_OK - if (entryExists && (data.entryFlags & QFileSystemMetaData::ExistsAttribute) == 0) { - entryExists = QT_ACCESS(nativeFilePath, F_OK) == 0; - if (entryExists) + if (entryErrno == 0 && (data.entryFlags & QFileSystemMetaData::ExistsAttribute) == 0) { + if (QT_ACCESS(nativeFilePath, F_OK) == -1) + entryErrno = errno; + else data.entryFlags |= QFileSystemMetaData::ExistsAttribute; } @@ -1037,13 +1038,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM #if defined(Q_OS_DARWIN) if (what & QFileSystemMetaData::AliasType) { - if (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsAliasFileKey)) + if (entryErrno == 0 && hasResourcePropertyFlag(data, entry, kCFURLIsAliasFileKey)) data.entryFlags |= QFileSystemMetaData::AliasType; data.knownFlagsMask |= QFileSystemMetaData::AliasType; } if (what & QFileSystemMetaData::BundleType) { - if (entryExists && isPackage(data, entry)) + if (entryErrno == 0 && isPackage(data, entry)) data.entryFlags |= QFileSystemMetaData::BundleType; data.knownFlagsMask |= QFileSystemMetaData::BundleType; @@ -1055,19 +1056,19 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM QString fileName = entry.fileName(); if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) #if defined(Q_OS_DARWIN) - || (entryExists && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey)) + || (entryErrno == 0 && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey)) #endif ) data.entryFlags |= QFileSystemMetaData::HiddenAttribute; data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } - if (!entryExists) { + if (entryErrno != 0) { what &= ~QFileSystemMetaData::LinkType; // don't clear link: could be broken symlink data.clearFlags(what); return false; } - return data.hasFlags(what); + return true; } // static -- cgit v1.2.3 From 0dc025bf9f0ba3760ae8a02356900f5f63e75047 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 16 Nov 2017 16:59:00 +0100 Subject: Fix macOS shadow prefix builds using pre-synced source packages For source packages that don't have a .git subdirectory, syncqt is executed before configure, with outdir set to srcdir, and this caused path misalignments for injected headers in qt_module.prf when generating makefile rules. The fix is to change syncqt to always output injected header paths relative to the source dir. Task-number: QTBUG-64539 Change-Id: Ia2296e44494093dbf124729062f430ad6fca7262 Reviewed-by: Oswald Buddenhagen --- bin/syncqt.pl | 5 +++-- mkspecs/features/qt_module.prf | 14 ++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index e741f22f65..02e55d847e 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -1037,7 +1037,8 @@ foreach my $lib (@modules_to_sync) { my $clean_header; my $requires; - my $iheader = $subdir . "/" . $header; + my $iheader_src = $subdir . "/" . $header; + my $iheader = $iheader_src; $iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow); if ($check_includes) { # We need both $public_header and $private_header because QPA headers count as neither @@ -1079,7 +1080,7 @@ foreach my $lib (@modules_to_sync) { } $header_copies++ if (!$shadow && syncHeader($lib, $oheader, $iheader, $copy_headers, $ts)); - my $pri_install_iheader = fixPaths($iheader, $dir); + my $pri_install_iheader = fixPaths($iheader_src, $dir); my $injection = ""; if ($public_header) { foreach my $class (@classes) { diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index a5c40a7899..c0a8dcc251 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -135,18 +135,12 @@ lib_bundle { !build_all| \ if(if(!debug_and_release|CONFIG(release, debug|release))) { FRAMEWORK_HEADERS.version = Versions - FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES - # Non-existing paths (yet, they will be generated) are used verbatim. - for (injected_header, SYNCQT.INJECTED_HEADER_FILES): \ - FRAMEWORK_HEADERS.files += \ - $$relative_path($$absolute_path($$injected_header, $$_PRO_FILE_PWD_), $$OUT_PWD) - + FRAMEWORK_HEADERS.files = \ + $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES $$SYNCQT.INJECTED_HEADER_FILES FRAMEWORK_HEADERS.path = Headers FRAMEWORK_PRIVATE_HEADERS.version = Versions - FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES - for (injected_header, SYNCQT.INJECTED_PRIVATE_HEADER_FILES): \ - FRAMEWORK_PRIVATE_HEADERS.files += \ - $$relative_path($$absolute_path($$injected_header, $$_PRO_FILE_PWD_), $$OUT_PWD) + FRAMEWORK_PRIVATE_HEADERS.files = \ + $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.INJECTED_PRIVATE_HEADER_FILES FRAMEWORK_PRIVATE_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/private FRAMEWORK_QPA_HEADERS.version = Versions FRAMEWORK_QPA_HEADERS.files = $$SYNCQT.QPA_HEADER_FILES -- cgit v1.2.3 From 0817e2a81ec1b0fc1e5cd7ed9473177c75dc6f1e Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 7 Nov 2017 12:11:45 +0100 Subject: Doc: Update the list of highlighted examples Update the list of highlighted examples for modules in qtbase, based on which examples have been updated to use C++11 features, the new signal/slot connection syntax, and documentation improvements. Not all the modules have highlighted examples yet as some of the work is still ongoing. Task-number: QTBUG-60641 Change-Id: If28d59c10ca1a30e5db408970f20159434ac94f8 Reviewed-by: Nico Vertriest Reviewed-by: Leena Miettinen Reviewed-by: Venugopal Shivashankar --- src/concurrent/doc/qtconcurrent.qdocconf | 2 ++ src/corelib/doc/qtcore.qdocconf | 3 +++ src/dbus/doc/qtdbus.qdocconf | 2 +- src/gui/doc/qtgui.qdocconf | 2 ++ src/network/doc/qtnetwork.qdocconf | 2 ++ src/widgets/doc/qtwidgets.qdocconf | 4 +++- 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf index d8ee963ef5..356d602a7c 100644 --- a/src/concurrent/doc/qtconcurrent.qdocconf +++ b/src/concurrent/doc/qtconcurrent.qdocconf @@ -36,6 +36,8 @@ exampledirs += ../../../examples/qtconcurrent \ ../ \ snippets +manifestmeta.highlighted.names = "QtConcurrent/QtConcurrent Progress Dialog Example" + excludedirs += ../../../examples/widgets/doc imagedirs += images diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 3d64708def..5a42e21845 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -45,5 +45,8 @@ excludedirs += snippets excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \ ../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc +manifestmeta.highlighted.names = "QtCore/JSON Save Game Example" \ + "QtCore/Local Fortune*" + navigation.landingpage = "Qt Core" navigation.cppclassespage = "Qt Core C++ Classes" diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index ff46cc5961..69eaa0eec3 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -59,4 +59,4 @@ navigation.cppclassespage = "Qt D-Bus C++ Classes" manifestmeta.thumbnail.names = "QtDBus/D-Bus List Names Example" \ "QtDBus/D-Bus Ping Pong Example" \ - "QtDBus/D-Bus Complex Ping Pong Example" \ + "QtDBus/D-Bus Complex Ping Pong Example" diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index 3b3ebafc2d..e1afa426ed 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -56,5 +56,7 @@ imagedirs += images \ ../../../examples/gui/doc/images \ ../../../doc/src/images \ +manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example" + navigation.landingpage = "Qt GUI" navigation.cppclassespage = "Qt GUI C++ Classes" diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 2a8e577dda..4f667eed9d 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -40,5 +40,7 @@ exampledirs += ../../../examples/network \ imagedirs += images \ ../../../examples/network/doc/images +manifestmeta.highlighted.names = "QtNetwork/HTTP Example" + navigation.landingpage = "Qt Network" navigation.cppclassespage = "Qt Network C++ Classes" diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index a49eb439af..88957b0f94 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -48,4 +48,6 @@ imagedirs += images \ navigation.landingpage = "Qt Widgets" navigation.cppclassespage = "Qt Widgets C++ Classes" manifestmeta.highlighted.names = "QtWidgets/Calendar Widget Example" \ - "QtWidgets/Simple Tree Model Example" + "QtWidgets/Editable Tree Model Example" \ + "QtWidgets/Address Book Example" \ + "QtWidgets/Application Example" -- cgit v1.2.3 From 42005951defded6cd1a9a60582b29f58c78fea9e Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 8 Nov 2017 13:06:46 +0200 Subject: Add changes file for Qt 5.10.0 Change-Id: I66bfe7a8897c7b2b4986a12dec37229e0ad82755 Reviewed-by: Edward Welbourne Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- dist/changes-5.10.0 | 564 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 564 insertions(+) create mode 100644 dist/changes-5.10.0 diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0 new file mode 100644 index 0000000000..b76f51543b --- /dev/null +++ b/dist/changes-5.10.0 @@ -0,0 +1,564 @@ +Qt 5.10 introduces many new features and improvements as well as bugfixes +over the 5.9.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - [QTBUG-60857] The names of the roles returned by + QSqlQueryModel::roleNames now only include a name for the + Qt::DisplayRole. Previously all the roles names of QSqlQueryModel were + returned. + - QFileInfo on empty strings now behaves like the default-constructed + QFileInfo. Notably, path() will now be the empty string too, instead of + ".", which means absoluteFilePath() is no longer the current working + directory. + + - QTemporaryFile: + * rename() no longer attempts to do block copying, as that usually + indicates a mistake in the user's code. Instead, either create the + temporary file in the same directory as the new name to be, or use + QSaveFile. + * On Linux, QTemporaryFile will attempt to create unnamed temporary + files. If that succeeds, open() will return true but exists() will be + false. If you call fileName() or any function that calls it, + QTemporaryFile will give the file a name, so most applications will + not see a difference. + + - Windows: + * [QTBUG-62662] On Windows, a drag & drop operation of local file URIs, + like QListView items backed by a QFileSystemModel, will result in the + attachment or opening of the files by the target application, instead + of the creation of hyperlinks. + +**************************************************************************** +* General Notes * +**************************************************************************** + +Deprecation Notice +------------------ + + - Starting with Qt 5.10, IPv6 support is mandatory for all platforms. + Systems without proper IPv6 support, such as the getaddrinfo() function + or the proper socket address structures, will not be able to build + QtNetwork anymore. + + - QSignalMapper is now marked as deprecated. + +Potentially Source-Incompatible Changes +--------------------------------------- + + - QByteArray: + * qbytearray.h no longer includes qstring.h. In particular, this means + that in order to use QStringBuilder with QByteArray, you need to + include both qbytearray.h and qstring.h now (or and + , resp.). + + - QStaticText: + * The QStaticText(const QString &) constructor is now explicit. + +Third-Party Code +---------------- + + - PCRE2 has been updated to version 10.30. + - Replaced bundled libjpeg by libjpeg-turbo 1.5.2 + - Improve documentation about Freetype 2 licenses. + - Sqlite was updated to version 3.20.1 + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - Added qHash(QStringView). + - [QTBUG-37253] Added QMetaObject::invokeMethod() overloads for function + pointers. + - [QTBUG-41006] Added qEnvironmentVariable, which returns the value of an + environment variable in a QString, while qgetenv continues to be used to + return it in a QByteArray. For Unix, since most environment variables + seem to contain path names, qEnvironmentVariable will do the same as + QFile::decodeName, which means NFC/NFD conversion on Apple OSes. + - [QTBUG-62915] qAddPostRoutine() and qRemovePostRoutine() are now + thread-safe. + + - Containers: + * Added an STL-like iterator to go through QHash/QMap returning both the + key and the value of the element pointed to. That lets QHash/QMap + interoperate better with stl's algorithms like std::set_union. + + - JSON: + * QJsonArray, QJsonDocument, QJsonObject and QJsonValue now have move + operations and a swap() member function. + + - Logging: + * If you set QT_FATAL_WARNINGS to a number n > 1, Qt will stop the + application on that n-th warning, instead of on the first. For the + sake of compatibility with previous versions, if the variable is set + to any non-empty and non-numeric value, Qt will understand it as "stop + on first warning". + + - QByteArray: + * Added shrink_to_fit() for compatibility with the Standard Library. This + function does the same as squeeze(). + + - QChar: + * Added constructors from char16_t and, on Windows, wchar_t. + + - QCoreApplication: + * [QTBUG-57095] Calling QCoreApplication::translate() is now + thread-safe. + + - QCryptographicHash: + * [QTBUG-59770] In order to preserve compatibility with earlier versions + of Qt, QCryptographicHash is now able to calculate Keccak message + digests. Please see the release notes for Qt 5.9.2 for more details. + + - QDate/QTime/QDateTime: + * Added toString() overloads taking the format as a QStringView. + * [QTBUG-22833] Added support for parsing of time-zones. + + - QDebug: + * Added streaming of QStringViews. + + - QFile: + * [QTBUG-984] Added fileTime() and setFileTime(). + + - QFileInfo: + * [QTBUG-984] Added fileTime(). + * Deprecated created() because it could return one of three different + file times depending on the OS and filesystem type, without the + ability to determine which one is which. It is replaced by + metadataChangeTime() and birthTime(). + * Added QFileInfo::metadataChangeTime(), which returns the time the + file's metadata was last changed, if it is known, and falling back to + the same value as lastModified() otherwise. On Unix systems, this + corresponds to the file's ctime. + * Added QFileInfo::birthTime(), which returns the file's birth time if + it is known, an invalid QDateTime otherwise. This function is + supported on Windows and on some Unix systems. + + - QIODevice: + * Added skip() method to improve performance in read operations. + + - QLatin1String: + * Added isEmpty(), isNull(). + * Added iterators, {c,}{r,}{begin,end}(). + * Added chopped(), chop(), truncate(). + * Added startsWith(), endsWith(). + * Added a constructor taking two pointers, complementing the constructor + that takes a pointer and a length. + * Added trimmed() function. + + - QLocale: + * Added toString(QDate/QTime/QDateTime) overloads taking the format + string as a QStringView. + * Added QLocale::formattedDataSize() for formatting quantities of bytes + as kB, MB, GB etc. + + - QLockFile: + * Fixed a bug that would cause QLockFile to mis-identify valid lock + files as stale if the application name was set with + QCoreApplication::setApplicationName(). + + - QMimeType: + * Add Q_GADGET, so that QML applications can make use of QMimeType's + properties and methods. + + - QObject: + * [QTBUG-60339] Added connect() support for move-only function objects. + + - QProcess: + * [QTBUG-2058][QTBUG-2284][QTBUG-37656][QTBUG-52405][QTBUG-57687] Added + non-static QProcess::startDetached to support more features for + detached processes. + * [QTBUG-2284] Added the ability to set a custom process environment for + detached processes. + * [QTBUG-52405] Added the ability to specify native arguments for + detached processes on Windows. + * [QTBUG-2058][QTBUG-37656] Added support for standard channel + redirection using setStandard{Input|Output|Error}File to + QProcess::startDetached. + + - QSaveFile: + * [QTBUG-47379] Saving to Alternate Data Streams on NTFS on Windows is + now possible, but requires setDirectWriteFallback(true). + + - QSemaphore: + * Added a new RAII class, QSemaphoreReleaser, to reliably perform + release() calls. + + - QSettings: + * [QTBUG-47379] Added setAtomicSyncRequired(), which allows one to use + QSettings with config files in unwriteable directories or in Alternate + Data Streams on NTFS on Windows. This used to work before Qt 5.4, but + remains a non-default behavior due to the potential of data + corruption. + + - QSortFilterProxyModel: + * QSortFilterProxyModel now does not emit an unnecessary layoutChanged() + following a model reset. + + - QStandardPaths: + * On Windows, QStandardPaths now also looks into + "/data/" for non-generic paths. + + - QString: + * Added arg(QStringView), arg(QLatin1String) overloads. + * Added shrink_to_fit(), for compatibility with the Standard + Library. This function does the same as squeeze(). + + - QString/QStringRef: + * Added startsWith(), endsWith() overloads taking QStringView. + + - QString/QStringRef/QByteArray: + * Added chopped(n), a const version of chop(n). + + - QString/QStringRef/QByteArray/QLatin1String: + * Added front() and back() for STL compatibility. + + - QStringBuilder: + * Added support for (non-const) char*. + + - QStringList: + * Added contains(QLatin1String) overload. + + - QStringRef: + * trimmed() now returns an empty string-ref for an empty input. Before, + it would return a null one. + + - QStringView: + * New class, superseding const QString and QStringRef as function + parameters, accepting a wide variety of UTF-16 string data sources, + e.g. u"string", std::u16string{,_view}, and, on Windows, L"string", + std::wstring{,_view} without converting to QString first. + + - QTemporaryDir: + * The class now supports the "XXXXXX" replacement token anywhere in the + template, not just at the end. This behavior is similar to what + QTemporaryFile supports. + + - QTextCodec: + * Added fromUnicode() and canEncode() overloads taking QStringView. + + - QTextEncoder: + * Added fromUnicode() overload taking QStringView. + + - QThread: + * Added the QThread::create() function. + * An exception escaping from QThread::run() will now result in immediate + and abnormal program termination. The same applies if an exception + leaves a slot connected directly to the QThread::started() or + QThread::finished() signals. + + - QUuid: + * Added fromString(QStringView/QLatin1String). + + - QVariant: + * QVariants containing pointers will now return true on isNull() if the + contained pointer is null. + + - QVarLengthArray: + * Added shrink_to_fit(), for compatibility with the Standard Library. + + - QVector: + * Added shrink_to_fit(), for compatibility with the Standard Library. + + - QVersionNumber: + * Added QStringView and QLatin1String overloads of fromString(). + + - QtGlobal: + * Q_ASSERT() and Q_ASSERT_X() now always expand to expressions of type + void that are usable in constexpr contexts. This makes them usable in + both C++11 and C++14 constexpr functions and in comma expressions. + +QtGui +----- + + - [QTBUG-55981] Added support for rendering to QWindow via the Vulkan + graphics API. + - [QTBUG-55981] Added QVulkanWindow, a convenience subclass of QWindow. + - Added support for the OpenGL ES 3.2 API in QOpenGLExtraFunctions + - [QTBUG-50987] Added support for requesting OpenGL windows with + sRGB-capable default framebuffers. While this is implicit on some + platforms, QSurfaceFormat now has the necessary flags to request such + windows in a cross-platform manner. + - High DPI variants of 9-patch images can now be loaded using the + following syntax: "foo@2x.9.png" + - It's now possible to retrieve the screen at a given point via + QGuiApplication::screenAt(). + + - Important Behvior Changes: + * [QTBUG-56848][QTCREATORBUG-17683] Changed CSS line-height property + with multiplier to follow CSS spec + + - Tablet support: + * [QTBUG-44964] If the application attribute AA_CompressTabletEvents is + set in addition to AA_CompressHighFrequencyEvents, even the + QTabletEvents will be compressed (only on the X11 platform so far). + AA_CompressHighFrequencyEvents does not enable compression of tablet + events by itself, because paint applications typically need to process + all possible tablet events in order to draw the smoothest curves. + + - QPA: + * [QTBUG-57608] QWindowSystemInterfacePrivate::handleGeometryChange no + longer takes the old geometry as an argument. + + - QImage: + * QImages can now use more than 2GByte of pixel data. + + - QCursor: + * Added equality operators. + + - QImageWriter: + * Add QImageWriter::InvalidImageError to communicate invalid attempts to + write a bad QImage (for instance, a null QImage). + + - QMovie: + * Added lastError and lastErrorString accessors, as a convenience over + connecting to the error() signal. + + - QWindow: + * setMask() no longer requires the window to be created to have an + effect; it can be set at any time. + + - Text: + * [QTBUG-56728] Added QFont::PreferNoShaping style strategy to support + improvements to performance at the expense of some cosmetic font + features. + + - Windows: + * [QTBUG-55967] Native menus have been implemented. + * A native system tray icon is now available for SystemTrayIcon. + +QtNetwork +--------- + + - [QTBUG-56102] QSslSocket can now use a temporary keychain on macOS. + - Fixed a proxy-authentication issue, after a wrong password has been used, + when supplying the right password. + + - HTTP/2: + * [QTBUG-61397] In case of clear text HTTP/2 we now initiate a required + protocol upgrade procedure instead of 'H2Direct' connection. + + - QHostInfo: + * Added swap() and move operator. + + - QLocalServer: + * [QTBUG-55043] Added a function to retrieve the socket descriptor. + + - QNetworkAccessManager: + * [QTBUG-63075] Added support for HTTP status 308. + + - QNetworkInterface: + * [QTBUG-51922] Changed allAddresses() to not include addresses found in + inactive interfaces, matching the user expectations of this function. + If those addresses are needed for some purpose, the application can + call allInterfaces() and obtain the addresses in each interface. + + - QNetworkProxy: + * [QTBUG-45495] Setting of network proxies is now supported on UWP. + * [QTBUG-45495] UWP now supports proxies using SOCKS5. + * The functions related to QNetworkConfiguration are deprecated. They've + performed no action since Qt 5.0, so code using them can safely stop + doing so. + + - QSslSocket: + * [QTBUG-52905] Added OpenSSL 1.1 backend. + +QtSql +----- + + - QSqlError: + * Added swap(). + + - SQLite: + * Named placeholder can now be used. If compiling Qt by hand and using + system libraries, this feature requires at least SQLite 3.3.11. + * [QTBUG-18084] Added QSQLITE_ENABLE_REGEXP connect option for the SQLite + backend. If set, a Qt based regexp() implementation is provided + allowing use of REGEXP in SQL statements. + +QtTest +------ + + - [QTBUG-53381] Added keySequence() function. + + - QCOMPARE: + * Can now be used for mixed-type comparisons. + * Now outputs contents of QPair and std::pair on failure. + * Now supports printing QStringViews in case of test failures. + +QtWidgets +--------- + + - The windowsxp style is no longer available as a separate style, because + it did not (and cannot) actually provide an XP-style appearance on + currently supported Qt platforms. + - Added AA_DisableWindowContextHelpButton attribute. Setting this + attribute globally prevents the automatic "What's this" button on + dialogs on Windows (WindowsContextHelpButtonHint). + - [QTBUG-56860] Fixed widget losing focus after showing menu second time. + - [QTBUG-47185][QTBUG-61280] QOpenGLWidget is now able to render and + return its content via grabFramebuffer(), QWidget::grab() or + QWidget::render() even when the widget has not been made visible. + - [QTBUG-10907] When tabbing to a widget with focus proxy, focus will now + be given to the proxy rather than just being ignored. + + - ItemViews: + * Made it easier to drop above and below items. + + - QAbstractItemView/QTreeWidget/QTableWidget/QListWidget: + * [QTBUG-61139] Added isPersistentEditorOpen(). + + - QDockWidget: + * When QMainWindow::GrouppedDragging and QMainWindow::AllowNestedDocks + are both enabled, floating dock widgets now have the ability to be + dropped together side by side. + * [QTBUG-63526] Fixed an issue in QDockWidgets where the widget would + not resize despite showing a resize cursor. + + - QFusionStyle: + * The default palette used by the platform-agnostic Fusion style has + been desaturated. Previously the window background color, and other + colors derived from it, were brown shades. Now these colors are + neutral gray that fit better on any desktop. + + - QInputDialog: + * [QTBUG-17547] Added setDoubleStep to enable changing of the step + amount for getDouble(). + + - QLineEdit: + * Added selectionEnd(), selectionLength(), complementing + selectionStart(). + + - QOpenGLWidget: + * [QTBUG-50987] Added support for specifying custom internal texture + formats in QOpenGLWidget in order to make it possible to have the + widget backed by an sRGB-capable framebuffer. + + - QSplashScreen: + * All constructors now implicitly set Qt::FramelessWindowHint, not just + the (pixmap, flags) one. + + - QWidget: + * [QTBUG-10907] QWidget::setTabOrder() will now preserve the local tab + order inside a widget if it has a focus proxy set to an inner child. + + - Styles: + * Added SH_Widget_Animation_Duration style hint which supersedes + SH_Widget_Animate, which is now deprecated. + + - Text: + * Introduced tabStopDistance property in QTextOption, QTextEdit and + QPlainTextEdit as replacement for the inconsistently named tabStop and + tabStopWidth properties. QTextOption::tabStop, QTextEdit::tabStopWidth + and QPlainTextEdit::tabStopWidth are now deprecated. + +**************************************************************************** +* Platform-specific Changes * +**************************************************************************** + + - [QTBUG-60268] Input context is now supported with the offscreen platform. + +Android +------- + + - QtLoader: Enabled loading shared libraries from /system/lib or a custom + path specified with the android.app.system_libs_prefix metadata variable in + AndroidManifest.xml. This supports deploying Qt apps as Android system + apps. + - [QTBUG-58060] Android dialogs now have more appropriate button layouts, + with affirmative actions on the right. + - [QTBUG-59175] QWidget::createWindowContainer() is now supported on + Android for embedding OpenGL-based QWindows into widget UIs. + +iOS +--- + + - [QTBUG-59403] Support added for using the input panel as a trackpad + using two-finger swipe. + - The minimum deployment target for applications is now iOS 10.0. + +Linux +----- + + - XInput device property changes are now detected at runtime (no + application restart required). + - [QTBUG-60513][QTBUG-29278][QTBUG-43768][QTBUG-18380] The _NET_WORKAREA + atom is used for calculating QScreen::availableGeometry() only on systems + with one monitor. In all other cases QScreen::availableGeometry() is + equal to QScreen::geometry(). To restore the legacy behavior with + untrustworthy values in QScreen::availableGeometry() set + QT_RELY_ON_NET_WORKAREA_ATOM=1 in the environment. + - The QT_XCB_NO_XI2_MOUSE environment variable is deprecated and will be + removed in Qt 6. If your application relies on behavior set by + QT_XCB_NO_XI2_MOUSE, it should be updated accordingly. + + - Pointer event delivery on X11 is now done starting from XInput version + 2.0 (when available) instead of 2.2. XInput support can be disabled by + setting QT_XCB_NO_XI2=1 in the environment; note that doing so will also + disable tablet and touch support. + + - Qt uses the statx(2) system call for obtaining file information on + kernels 4.12 and later. Some older container systems install system call + protection rules that do not include this system call. If you experience + problems running Qt applications inside containers (such as the report of + a file not existing when it does), ensure the statx(2) is allowed in the + container configuration. + + - Linux/XCB: + * Added screen product information from EDID. + + - eglfs/KMS: + * Screen modes, including current and preferred ones, are now listed. + * Added screen product information from EDID. + +Windows +------- + + - Accessibility: + * MinGW builds now support IAccessible2. + + - Fonts: + * [QTBUG-62176] Some key fonts, such as Calibri, were being detected as + bitmap fonts and not rendered correctly in Qt Quick. This has now been + fixed. + +**************************************************************************** +* Tools * +**************************************************************************** + +moc +--- + + - moc now supports NOTIFY signals of parent classes in Q_PROPERTY + +qmake +----- + + - If you use CONFIG+=qmltestcase with no SOURCES, 'make check' will now + run qmltestrunner for you. + +uic +--- + + - Old images embedded in ui files, imported from Qt 3, are now ignored. + uic will now behave consistently with Qt Designer - both will ignore + them. -- cgit v1.2.3 From 4be50ecafd3cc63469504aaae8ac28ff0736989d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 7 Nov 2017 14:08:54 -0800 Subject: QTemporaryFile: fix issues with removing a file twice The assertion in isUnnamedFile() we had was incorrect after the file was removed, since we cleared the name and possibly reset back to the template. Since ~QTemporaryFile() calls remove(), this was easy to trigger if you attempted to remove the temp file and leave QTemporaryFile like that. Take this opportunity to add to the docs of setAutoRemove() explaining the possibility of unnamed files. #7 0x00007f69bcc2b50e in qt_assert ( assertion=assertion@entry=0x7f69bcf194a0 "unnamedFile == d_func()->fileEntry.isEmpty()", file=file@entry=0x7f69bcf19458 "io/qtemporaryfile.cpp", line=line@entry=514) at global/qglobal.cpp:3123 #8 0x00007f69bcd672cf in QTemporaryFileEngine::isUnnamedFile (this=this@entry=0x55cd60644df0) at io/qtemporaryfile.cpp:514 #9 0x00007f69bcd683f7 in QTemporaryFileEngine::remove (this=0x55cd60644df0) at io/qtemporaryfile.cpp:396 #10 0x00007f69bcd48654 in QFile::remove (this=this@entry=0x7fffb393f7e0) at io/qfile.cpp:513 #11 0x00007f69bcd6653b in QTemporaryFile::~QTemporaryFile (this=0x7fffb393f7e0, __in_chrg=) at io/qtemporaryfile.cpp:719 Change-Id: I57a1bd6e0c194530b732fffd14f4ed28ca8185b2 Reviewed-by: Andreas Hartmetz Reviewed-by: Thiago Macieira --- src/corelib/io/qfile.cpp | 3 ++- src/corelib/io/qfsfileengine_p.h | 3 +++ src/corelib/io/qtemporaryfile.cpp | 22 +++++++++++++++++++--- src/corelib/io/qtemporaryfile_p.h | 2 +- .../io/qtemporaryfile/tst_qtemporaryfile.cpp | 20 ++++++++++++++++++-- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index bac995ff25..e4888e9523 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -503,7 +503,8 @@ bool QFile::remove() { Q_D(QFile); - if (d->fileName.isEmpty()) { + if (d->fileName.isEmpty() && + !static_cast(d->engine())->isUnnamedFile()) { qWarning("QFile::remove: Empty or null file name"); return false; } diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 1f34dfc2be..faef84cbe2 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -112,6 +112,9 @@ public: qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE; bool cloneTo(QAbstractFileEngine *target) override; + virtual bool isUnnamedFile() const + { return false; } + bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) Q_DECL_OVERRIDE; bool supportsExtension(Extension extension) const Q_DECL_OVERRIDE; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b8d3e859cf..35699d52df 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -393,7 +393,9 @@ bool QTemporaryFileEngine::remove() // we must explicitly call QFSFileEngine::close() before we remove it. d->unmapAll(); QFSFileEngine::close(); - if (isUnnamedFile() || QFSFileEngine::remove()) { + if (isUnnamedFile()) + return true; + if (!filePathIsTemplate && QFSFileEngine::remove()) { d->fileEntry.clear(); // If a QTemporaryFile is constructed using a template file path, the path // is generated in QTemporaryFileEngine::open() and then filePathIsTemplate @@ -511,7 +513,10 @@ bool QTemporaryFileEngine::materializeUnnamedFile(const QString &newName, QTempo bool QTemporaryFileEngine::isUnnamedFile() const { #ifdef LINUX_UNNAMED_TMPFILE - Q_ASSERT(unnamedFile == d_func()->fileEntry.isEmpty()); + if (unnamedFile) { + Q_ASSERT(d_func()->fileEntry.isEmpty()); + Q_ASSERT(filePathIsTemplate); + } return unnamedFile; #else return false; @@ -749,10 +754,21 @@ bool QTemporaryFile::autoRemove() const } /*! - Sets the QTemporaryFile into auto-remove mode if \a b is true. + Sets the QTemporaryFile into auto-remove mode if \a b is \c true. Auto-remove is on by default. + If you set this property to \c false, ensure the application provides a way + to remove the file once it is no longer needed, including passing the + responsibility on to another process. Always use the fileName() function to + obtain the name and never try to guess the name that QTemporaryFile has + generated. + + On some systems, if fileName() is not called before closing the file, the + temporary file may be removed regardless of the state of this property. + This behavior should not be relied upon, so application code should either + call fileName() or leave the auto removal functionality enabled. + \sa autoRemove(), remove() */ void QTemporaryFile::setAutoRemove(bool b) diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index f74e5680b9..c3a2c01790 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -140,7 +140,7 @@ public: enum MaterializationMode { Overwrite, DontOverwrite, NameIsTemplate }; bool materializeUnnamedFile(const QString &newName, MaterializationMode mode); - bool isUnnamedFile() const; + bool isUnnamedFile() const override final; const QString &templateName; quint32 fileMode; diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index f3ce902bbd..2d87c2193b 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -70,6 +70,7 @@ private slots: void io(); void openCloseOpenClose(); void removeAndReOpen(); + void removeUnnamed(); void size(); void resize(); void openOnRootDrives(); @@ -442,11 +443,13 @@ void tst_QTemporaryFile::removeAndReOpen() { QTemporaryFile file; file.open(); - fileName = file.fileName(); + fileName = file.fileName(); // materializes any unnamed file QVERIFY(QFile::exists(fileName)); - file.remove(); + QVERIFY(file.remove()); + QVERIFY(file.fileName().isEmpty()); QVERIFY(!QFile::exists(fileName)); + QVERIFY(!file.remove()); QVERIFY(file.open()); QCOMPARE(QFileInfo(file.fileName()).path(), QFileInfo(fileName).path()); @@ -456,6 +459,19 @@ void tst_QTemporaryFile::removeAndReOpen() QVERIFY(!QFile::exists(fileName)); } +void tst_QTemporaryFile::removeUnnamed() +{ + QTemporaryFile file; + file.open(); + + // we did not call fileName(), so the file name may not have a name + QVERIFY(file.remove()); + QVERIFY(file.fileName().isEmpty()); + + // if it was unnamed, this will succeed again, so we can't check the result + file.remove(); +} + void tst_QTemporaryFile::size() { QTemporaryFile file; -- cgit v1.2.3 From 36984dc8cec09703290692ce7e899e88754173c4 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Tue, 21 Nov 2017 11:37:31 -0800 Subject: Move a QRegExp out of a deeply nested loop This helps alleviate a performance issues where by building iOS based projects takes a significantly longer amount of time than it should. Task-number: QTBUG-59136 Change-Id: I77ae12f507725ceb11106b484d73bb7d46e0845c Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index a1f3352aa3..82573347b6 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2164,9 +2164,9 @@ MakefileGenerator::writeExtraVariables(QTextStream &t) ProStringList outlist; const ProValueMap &vars = project->variables(); const ProStringList &exports = project->values("QMAKE_EXTRA_VARIABLES"); - for (ProValueMap::ConstIterator it = vars.begin(); it != vars.end(); ++it) { - for (ProStringList::ConstIterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) { - QRegExp rx((*exp_it).toQString(), Qt::CaseInsensitive, QRegExp::Wildcard); + for (ProStringList::ConstIterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) { + QRegExp rx((*exp_it).toQString(), Qt::CaseInsensitive, QRegExp::Wildcard); + for (ProValueMap::ConstIterator it = vars.begin(); it != vars.end(); ++it) { if (rx.exactMatch(it.key().toQString())) outlist << ("EXPORT_" + it.key() + " = " + it.value().join(' ')); } -- cgit v1.2.3 From 915a81d7122fbcb6b28a5368c4d0364f60159bd6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 22 Nov 2017 20:29:45 +0100 Subject: amend changelog, mostly with buildsystem-related stuff Change-Id: I8da9054415457e61c219933622d866b6cd72d30b Reviewed-by: Lars Knoll --- dist/changes-5.10.0 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0 index b76f51543b..6c46c900b2 100644 --- a/dist/changes-5.10.0 +++ b/dist/changes-5.10.0 @@ -541,6 +541,12 @@ Windows bitmap fonts and not rendered correctly in Qt Quick. This has now been fixed. +X11 +--- + + - Native painting (instead of software rasterization) has been experimentally + re-introduced. Enabled by the configure option -xcb-native-painting. + **************************************************************************** * Tools * **************************************************************************** @@ -553,12 +559,19 @@ moc qmake ----- + - [QTBUG-1581] Introduced the variable OBJECTIVE_HEADERS. + - [QTBUG-11117][nmake] Added support for precompiled header also for + plain C files. + - Added versionAtLeast() and versionAtMost() test functions. - If you use CONFIG+=qmltestcase with no SOURCES, 'make check' will now run qmltestrunner for you. + - [Darwin] Added support for Info.plist in non-bundle apps and libs. uic --- + - [QTBUG-51602] Added the no-stringliteral option, to be used for building + shared objects which are meant to be unloadable. - Old images embedded in ui files, imported from Qt 3, are now ignored. uic will now behave consistently with Qt Designer - both will ignore them. -- cgit v1.2.3 From 2aaf5753197c87a0b3730850a1ab851ffb854d9e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Sep 2017 08:01:00 -0300 Subject: Fix the build if st_atimensec is defined It's a trick used by some C libraries to keep compatibility with BSD extensions while supporting POSIX.1-2008 API. st_atimensec is defined as st_atim.tv_nsec, so the code would expand to invalid C++ In substitution of 'template typename std::enable_if<((&T::st_atim.tv_nsec), true), long long int>::type{anonymous}::GetFileTimes::atime(const T&, int) [with T = stat]': error: invalid use of non-static data member 'stat::st_atim' Change-Id: I38341f8155354cc4a776fffd14e20f4fc0f6d5bb Reviewed-by: BogDan Vatra Reviewed-by: Lars Knoll --- src/corelib/io/qfilesystemengine_unix.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 4051dc43a1..b1f2fca32b 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -202,6 +202,8 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimespec, &T::st_mtimespec, modification->tv_usec = p->st_mtimespec.tv_nsec / 1000; } +# ifndef st_atimensec +// if "st_atimensec" is defined, this would expand to invalid C++ template static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) { @@ -211,6 +213,7 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, modification->tv_sec = p->st_mtime; modification->tv_usec = p->st_mtimensec / 1000; } +# endif #endif qint64 timespecToMSecs(const timespec &spec) @@ -268,6 +271,7 @@ mtime(const T &statBuffer, int) { return timespecToMSecs(statBuffer.st_mtimespec); } #endif +#ifndef st_mtimensec // Xtimensec template Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimensec, true), qint64>::type @@ -288,8 +292,9 @@ template Q_DECL_UNUSED static typename std::enable_if<(&T::st_mtimensec, true), qint64>::type mtime(const T &statBuffer, int) { return statBuffer.st_mtime * Q_INT64_C(1000) + statBuffer.st_mtimensec / 1000000; } -} -} +#endif +} // namespace GetFileTimes +} // unnamed namespace #ifdef STATX_BASIC_STATS static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer) -- cgit v1.2.3 From 7db0436ed2fee71cee086d77a2572886c31e072a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Nov 2017 08:48:11 -0800 Subject: Changelog edit: move the X11 entries from "Linux" to "X11" Change-Id: I5892efbfc2924eabbafafffd14f9c4f69a5c6416 Reviewed-by: Gatis Paeglis Reviewed-by: Allan Sandfeld Jensen --- dist/changes-5.10.0 | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0 index 6c46c900b2..002b58d3b4 100644 --- a/dist/changes-5.10.0 +++ b/dist/changes-5.10.0 @@ -499,23 +499,6 @@ iOS Linux ----- - - XInput device property changes are now detected at runtime (no - application restart required). - - [QTBUG-60513][QTBUG-29278][QTBUG-43768][QTBUG-18380] The _NET_WORKAREA - atom is used for calculating QScreen::availableGeometry() only on systems - with one monitor. In all other cases QScreen::availableGeometry() is - equal to QScreen::geometry(). To restore the legacy behavior with - untrustworthy values in QScreen::availableGeometry() set - QT_RELY_ON_NET_WORKAREA_ATOM=1 in the environment. - - The QT_XCB_NO_XI2_MOUSE environment variable is deprecated and will be - removed in Qt 6. If your application relies on behavior set by - QT_XCB_NO_XI2_MOUSE, it should be updated accordingly. - - - Pointer event delivery on X11 is now done starting from XInput version - 2.0 (when available) instead of 2.2. XInput support can be disabled by - setting QT_XCB_NO_XI2=1 in the environment; note that doing so will also - disable tablet and touch support. - - Qt uses the statx(2) system call for obtaining file information on kernels 4.12 and later. Some older container systems install system call protection rules that do not include this system call. If you experience @@ -546,6 +529,22 @@ X11 - Native painting (instead of software rasterization) has been experimentally re-introduced. Enabled by the configure option -xcb-native-painting. + - XInput device property changes are now detected at runtime (no + application restart required). + - [QTBUG-60513][QTBUG-29278][QTBUG-43768][QTBUG-18380] The _NET_WORKAREA + atom is used for calculating QScreen::availableGeometry() only on systems + with one monitor. In all other cases QScreen::availableGeometry() is + equal to QScreen::geometry(). To restore the legacy behavior with + untrustworthy values in QScreen::availableGeometry() set + QT_RELY_ON_NET_WORKAREA_ATOM=1 in the environment. + - The QT_XCB_NO_XI2_MOUSE environment variable is deprecated and will be + removed in Qt 6. If your application relies on behavior set by + QT_XCB_NO_XI2_MOUSE, it should be updated accordingly. + + - Pointer event delivery on X11 is now done starting from XInput version + 2.0 (when available) instead of 2.2. XInput support can be disabled by + setting QT_XCB_NO_XI2=1 in the environment; note that doing so will also + disable tablet and touch support. **************************************************************************** * Tools * -- cgit v1.2.3 From 07fcfb793d52b94f0f108cbfc025050b2353f9a1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 24 Nov 2017 11:41:32 +0100 Subject: Fix regression in painted emoji offset Factor out translation from the matrix applied on bitmap glyphs, as that gets applied as position when painted. Task-number: QTBUG-64313 Change-Id: Iab8d995c00ee02eda0896242903312d837b6d790 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 73def00017..ec2017ced4 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -1773,7 +1773,10 @@ QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &t) const { - QTransform trans(t); + QTransform trans; + trans.setMatrix(t.m11(), t.m12(), t.m13(), + t.m21(), t.m22(), t.m23(), + 0, 0, t.m33()); const qreal scaleFactor = scalableBitmapScaleFactor.toReal(); trans.scale(scaleFactor, scaleFactor); -- cgit v1.2.3 From 150e5055251ae9a5c40d821d377e72b14e38868d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 26 Nov 2017 23:01:57 -0800 Subject: Stop depending on test.macieira.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have had test.qt-project.org for close to 3 years now. Change-Id: I71488efd29b645f7b228fffd14fadf4627288243 Reviewed-by: Jędrzej Nowacki (cherry picked from commit 5f66f871816d083da9795d71f746413d6f6118f7) Reviewed-by: Frederik Gladhorn --- .../auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp | 4 ++-- tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp index 7874221da9..e302fe8c74 100644 --- a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp +++ b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp @@ -43,7 +43,7 @@ private slots: void tst_QDnsLookup_Appless::noApplication() { QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication"); - QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org"); + QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org"); dns.lookup(); } @@ -53,7 +53,7 @@ void tst_QDnsLookup_Appless::recreateApplication() char **argv = 0; for (int i = 0; i < 10; ++i) { QCoreApplication app(argc, argv); - QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org"); + QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org"); dns.lookup(); if (!dns.isFinished()) { QObject::connect(&dns, SIGNAL(finished()), diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index f5f5146eb5..82825f608c 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -72,7 +72,7 @@ #include "../../../network-settings.h" -#define TEST_DOMAIN ".test.macieira.org" +#define TEST_DOMAIN ".test.qt-project.org" class tst_QHostInfo : public QObject -- cgit v1.2.3 From 275c748ada9d869d803d5f446b48b915d686ab33 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 28 Aug 2017 16:28:03 +0200 Subject: Fix naming of new property QSortFilterProxyModel::recursiveFiltering Add "Enabled" to match Qt API naming rules. + fix \since tag. Change-Id: Iaf312648f7385cd7e8d3d101b561fbd4e955df25 Reviewed-by: Friedemann Kleint Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 8 ++++---- src/corelib/itemmodels/qsortfilterproxymodel.h | 6 +++--- .../tst_qsortfilterproxymodel_recursive.cpp | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index ef3281df30..7dad892606 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -2657,8 +2657,8 @@ void QSortFilterProxyModel::setFilterRole(int role) } /*! - \since 5.9 - \property QSortFilterProxyModel::recursiveFiltering + \since 5.10 + \property QSortFilterProxyModel::recursiveFilteringEnabled \brief whether the filter to be applied recursively on children, and for any matching child, its parents will be visible as well. @@ -2666,13 +2666,13 @@ void QSortFilterProxyModel::setFilterRole(int role) \sa filterAcceptsRow() */ -bool QSortFilterProxyModel::recursiveFiltering() const +bool QSortFilterProxyModel::isRecursiveFilteringEnabled() const { Q_D(const QSortFilterProxyModel); return d->filter_recursive; } -void QSortFilterProxyModel::setRecursiveFiltering(bool recursive) +void QSortFilterProxyModel::setRecursiveFilteringEnabled(bool recursive) { Q_D(QSortFilterProxyModel); if (d->filter_recursive == recursive) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index 6f2e9806ed..9f9b59733d 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -67,7 +67,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel Q_PROPERTY(bool isSortLocaleAware READ isSortLocaleAware WRITE setSortLocaleAware) Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole) Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole) - Q_PROPERTY(bool recursiveFiltering READ recursiveFiltering WRITE setRecursiveFiltering) + Q_PROPERTY(bool recursiveFilteringEnabled READ isRecursiveFilteringEnabled WRITE setRecursiveFilteringEnabled) public: explicit QSortFilterProxyModel(QObject *parent = Q_NULLPTR); @@ -108,8 +108,8 @@ public: int filterRole() const; void setFilterRole(int role); - bool recursiveFiltering() const; - void setRecursiveFiltering(bool recursive); + bool isRecursiveFilteringEnabled() const; + void setRecursiveFilteringEnabled(bool recursive); public Q_SLOTS: void setFilterRegExp(const QString &pattern); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp index 54c79e0893..9cf005af01 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp @@ -100,7 +100,7 @@ public: TestModel(QAbstractItemModel *sourceModel) : QSortFilterProxyModel() { - setRecursiveFiltering(true); + setRecursiveFilteringEnabled(true); setSourceModel(sourceModel); } @@ -213,6 +213,7 @@ private Q_SLOTS: QCOMPARE(treeAsString(model), sourceStr); TestModel proxy(&model); + QVERIFY(proxy.isRecursiveFilteringEnabled()); QCOMPARE(treeAsString(proxy), proxyStr); } -- cgit v1.2.3 From 8298956eb084d8f0e478240a674c5ae131c8be97 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 24 Nov 2017 10:48:36 +0100 Subject: Fix namespaced linux builds Using "struct statx" as argument type is forward declaration which then will expect the namespace where it was first encountered. Change-Id: I2d4ba930bd5b4e264228f2549bd6ef75e5cf3a67 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 5 ++++- src/corelib/io/qfilesystemmetadata_p.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index b1f2fca32b..77d154c6b4 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -102,6 +102,10 @@ static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struc # endif #endif +#ifndef STATX_BASIC_STATS +struct statx { mode_t stx_mode; }; +#endif + QT_BEGIN_NAMESPACE #define emptyFileEntryWarning() emptyFileEntryWarning_(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) @@ -390,7 +394,6 @@ inline void QFileSystemMetaData::fillFromStatxBuf(const struct statx &statxBuffe groupId_ = statxBuffer.stx_gid; } #else -struct statx { mode_t stx_mode; }; static int qt_statx(const char *, struct statx *) { return -ENOSYS; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 55e44d52c7..4d2a5acb9b 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -64,6 +64,10 @@ # endif #endif +#ifdef Q_OS_UNIX +struct statx; +#endif + QT_BEGIN_NAMESPACE class QFileSystemEngine; -- cgit v1.2.3 From 984ad6124992c9831f57c2776aa2ed0a760149e6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 10 Oct 2017 09:42:41 +0200 Subject: Improve readability of code that uses the Qt signed size type During the container BoF session at the Qt Contributor Summit 2017 the name of the signed size type became a subject of discussion in the context of readability of code using this type and the intention of using it for all length, size and count properties throughout the entire framework in future versions of Qt. This change proposes qsizetype as new name for qssize_t to emphasize the readability of code over POSIX compatibility, the former being potentially more relevant than the latter to the majority of users of Qt. Change-Id: Idb99cb4a8782703c054fa463a9e5af23a918e7f3 Reviewed-by: Samuel Gaist Reviewed-by: David Faure --- src/corelib/global/qglobal.cpp | 8 ++--- src/corelib/global/qglobal.h | 4 +-- src/corelib/global/qrandom.cpp | 40 +++++++++++----------- src/corelib/global/qrandom.h | 10 +++--- src/corelib/io/qresource.cpp | 4 +-- src/corelib/io/qtemporaryfile_p.h | 4 +-- src/corelib/tools/qlocale.cpp | 4 +-- src/corelib/tools/qstring.cpp | 4 +-- src/corelib/tools/qstringalgorithms.h | 2 +- src/corelib/tools/qstringiterator.qdoc | 2 +- src/corelib/tools/qstringiterator_p.h | 2 +- src/corelib/tools/qstringview.cpp | 26 +++++++------- src/corelib/tools/qstringview.h | 40 +++++++++++----------- src/gui/image/qbmphandler.cpp | 4 +-- src/gui/image/qimage.cpp | 4 +-- src/gui/image/qimage.h | 2 +- src/gui/image/qimage_conversions.cpp | 28 +++++++-------- src/gui/image/qimage_p.h | 4 +-- src/gui/image/qpixmap_blitter.cpp | 2 +- src/gui/painting/qdrawhelper.cpp | 4 +-- src/gui/painting/qdrawhelper_avx2.cpp | 2 +- src/gui/painting/qdrawhelper_p.h | 4 +-- src/gui/painting/qpaintengine_raster.cpp | 10 +++--- .../corelib/tools/qstringview/tst_qstringview.cpp | 4 +-- tests/auto/gui/image/qimage/tst_qimage.cpp | 4 +-- 25 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 36b7560398..2c2dcb663b 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -160,8 +160,8 @@ Q_STATIC_ASSERT_X(std::numeric_limits::radix == 2, // not required by the definition of size_t, but we depend on this Q_STATIC_ASSERT_X(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size"); -Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qssize_t)); // implied by the definition -Q_STATIC_ASSERT((std::is_same::value)); +Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition +Q_STATIC_ASSERT((std::is_same::value)); /*! \class QFlag @@ -824,7 +824,7 @@ Q_STATIC_ASSERT((std::is_same::value)); */ /*! - \typedef qssize_t + \typedef qsizetype \relates \since 5.10 @@ -833,7 +833,7 @@ Q_STATIC_ASSERT((std::is_same::value)); This type is guaranteed to be the same size as a \c size_t on all platforms supported by Qt. - Note that qssize_t is signed. Use \c size_t for unsigned values. + Note that qsizetype is signed. Use \c size_t for unsigned values. \sa qptrdiff */ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 7b691ca59e..4e7c1b59be 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -439,7 +439,7 @@ namespace QtPrivate { sizeof(void *) == sizeof(quintptr) && sizeof(void *) == sizeof(qptrdiff) - size_t and qssize_t are not guaranteed to be the same size as a pointer, but + size_t and qsizetype are not guaranteed to be the same size as a pointer, but they usually are. */ template struct QIntegerForSize; @@ -456,7 +456,7 @@ typedef QIntegerForSize::Unsigned qregisteruint; typedef QIntegerForSizeof::Unsigned quintptr; typedef QIntegerForSizeof::Signed qptrdiff; typedef qptrdiff qintptr; -using qssize_t = QIntegerForSizeof::Signed; +using qsizetype = QIntegerForSizeof::Signed; /* moc compats (signals/slots) */ #ifndef QT_MOC_COMPAT diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 72ac8d332b..6769190335 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -93,7 +93,7 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando QT_BEGIN_NAMESPACE #if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) -static qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW; +static qsizetype qt_random_cpu(void *buffer, qsizetype count) Q_DECL_NOTHROW; # ifdef Q_PROCESSOR_X86_64 # define _rdrandXX_step _rdrand64_step @@ -101,7 +101,7 @@ static qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW; # define _rdrandXX_step _rdrand32_step # endif -static QT_FUNCTION_TARGET(RDRND) qssize_t qt_random_cpu(void *buffer, qssize_t count) Q_DECL_NOTHROW +static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype count) Q_DECL_NOTHROW { unsigned *ptr = reinterpret_cast(buffer); unsigned *end = ptr + count; @@ -122,7 +122,7 @@ out: return ptr - reinterpret_cast(buffer); } #else -static qssize_t qt_random_cpu(void *, qssize_t) +static qsizetype qt_random_cpu(void *, qsizetype) { return 0; } @@ -136,10 +136,10 @@ enum { struct QRandomGenerator::SystemGenerator { #if QT_CONFIG(getentropy) - static qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW + static qsizetype fillBuffer(void *buffer, qsizetype count) Q_DECL_NOTHROW { // getentropy can read at most 256 bytes, so break the reading - qssize_t read = 0; + qsizetype read = 0; while (count - read > 256) { // getentropy can't fail under normal circumstances int ret = getentropy(reinterpret_cast(buffer) + read, 256); @@ -195,24 +195,24 @@ struct QRandomGenerator::SystemGenerator Q_DECL_CONSTEXPR SystemGenerator() : fdp1 Q_BASIC_ATOMIC_INITIALIZER(0) {} - qssize_t fillBuffer(void *buffer, qssize_t count) + qsizetype fillBuffer(void *buffer, qsizetype count) { int fd = openDevice(); if (Q_UNLIKELY(fd < 0)) return 0; qint64 n = qt_safe_read(fd, buffer, count); - return qMax(n, 0); // ignore any errors + return qMax(n, 0); // ignore any errors } #elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - qssize_t fillBuffer(void *buffer, qssize_t count) Q_DECL_NOTHROW + qsizetype fillBuffer(void *buffer, qsizetype count) Q_DECL_NOTHROW { auto RtlGenRandom = SystemFunction036; return RtlGenRandom(buffer, ULONG(count)) ? count: 0; } #elif defined(Q_OS_WINRT) - qssize_t fillBuffer(void *, qssize_t) Q_DECL_NOTHROW + qsizetype fillBuffer(void *, qsizetype) Q_DECL_NOTHROW { // always use the fallback return 0; @@ -243,7 +243,7 @@ struct QRandomGenerator::SystemGenerator #if defined(Q_OS_WIN) static void fallback_update_seed(unsigned) {} -static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW +static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW { // on Windows, rand_s is a high-quality random number generator // and it requires no seeding @@ -255,14 +255,14 @@ static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW } #elif QT_CONFIG(getentropy) static void fallback_update_seed(unsigned) {} -static void fallback_fill(quint32 *, qssize_t) Q_DECL_NOTHROW +static void fallback_fill(quint32 *, qsizetype) Q_DECL_NOTHROW { // no fallback necessary, getentropy cannot fail under normal circumstances Q_UNREACHABLE(); } #elif defined(Q_OS_BSD4) static void fallback_update_seed(unsigned) {} -static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW +static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW { // BSDs have arc4random(4) and these work even in chroot(2) arc4random_buf(ptr, left * sizeof(*ptr)); @@ -281,7 +281,7 @@ Q_NEVER_INLINE #ifdef Q_CC_GNU __attribute__((cold)) // this function is pretty big, so optimize for size #endif -static void fallback_fill(quint32 *ptr, qssize_t left) Q_DECL_NOTHROW +static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW { quint32 scratch[12]; // see element count below quint32 *end = scratch; @@ -358,7 +358,7 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept) { quint32 *buffer = begin; - qssize_t count = end - begin; + qsizetype count = end - begin; if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) { uint value = uint(qt_randomdevice_control) & RandomDataMask; @@ -366,14 +366,14 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, return; } - qssize_t filled = 0; + qsizetype filled = 0; if (qt_has_hwrng() && (uint(qt_randomdevice_control) & SkipHWRNG) == 0) filled += qt_random_cpu(buffer, count); if (filled != count && (uint(qt_randomdevice_control) & SkipSystemRNG) == 0) { - qssize_t bytesFilled = - fillBuffer(buffer + filled, (count - filled) * qssize_t(sizeof(*buffer))); - filled += bytesFilled / qssize_t(sizeof(*buffer)); + qsizetype bytesFilled = + fillBuffer(buffer + filled, (count - filled) * qsizetype(sizeof(*buffer))); + filled += bytesFilled / qsizetype(sizeof(*buffer)); } if (filled) fallback_update_seed(*buffer); @@ -677,7 +677,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel */ /*! - \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qssize_t len) + \fn QRandomGenerator::QRandomGenerator(const quint32 *seedBuffer, qsizetype len) \overload Initializes this QRandomGenerator object with \a len values found in @@ -853,7 +853,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel */ /*! - \fn void QRandomGenerator::fillRange(UInt *buffer, qssize_t count) + \fn void QRandomGenerator::fillRange(UInt *buffer, qsizetype count) Generates \a count 32- or 64-bit quantities (depending on the type \c UInt) and stores them in the buffer pointed by \a buffer. This is the most diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index 005de0941f..cbeab19a7b 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -55,10 +55,10 @@ public: QRandomGenerator(quint32 seedValue = 1) : QRandomGenerator(&seedValue, 1) {} - template QRandomGenerator(const quint32 (&seedBuffer)[N]) + template QRandomGenerator(const quint32 (&seedBuffer)[N]) : QRandomGenerator(seedBuffer, seedBuffer + N) {} - QRandomGenerator(const quint32 *seedBuffer, qssize_t len) + QRandomGenerator(const quint32 *seedBuffer, qsizetype len) : QRandomGenerator(seedBuffer, seedBuffer + len) {} Q_CORE_EXPORT QRandomGenerator(std::seed_seq &sseq) Q_DECL_NOTHROW; @@ -131,7 +131,7 @@ public: } template = true> - void fillRange(UInt *buffer, qssize_t count) + void fillRange(UInt *buffer, qsizetype count) { _fillRange(buffer, buffer + count); } @@ -215,10 +215,10 @@ public: QRandomGenerator64(quint32 seedValue = 1) : QRandomGenerator(seedValue) {} - template QRandomGenerator64(const quint32 (&seedBuffer)[N]) + template QRandomGenerator64(const quint32 (&seedBuffer)[N]) : QRandomGenerator(seedBuffer) {} - QRandomGenerator64(const quint32 *seedBuffer, qssize_t len) + QRandomGenerator64(const quint32 *seedBuffer, qsizetype len) : QRandomGenerator(seedBuffer, len) {} QRandomGenerator64(std::seed_seq &sseq) Q_DECL_NOTHROW diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index c1187e5145..31f02e977d 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -86,8 +86,8 @@ public: } const QChar *m_data; - qssize_t m_len; - qssize_t m_pos = 0; + qsizetype m_len; + qsizetype m_pos = 0; QChar m_splitChar = QLatin1Char('/'); }; diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index c3a2c01790..fb8887af53 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -74,8 +74,8 @@ QT_BEGIN_NAMESPACE struct QTemporaryFileName { QFileSystemEntry::NativePath path; - qssize_t pos; - qssize_t length; + qsizetype pos; + qsizetype length; QTemporaryFileName(const QString &templateName); QFileSystemEntry::NativePath generateNext(); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 723e63114d..166cbe8dee 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -576,7 +576,7 @@ int qt_repeatCount(QStringView s) if (s.isEmpty()) return 0; const QChar c = s.front(); - qssize_t j = 1; + qsizetype j = 1; while (j < s.size() && s.at(j) == c) ++j; return int(j); @@ -3443,7 +3443,7 @@ bool QLocaleData::validateChars(QStringView str, NumberMode numMode, QByteArray bool dec = false; int decDigitCnt = 0; - for (qssize_t i = 0; i < str.size(); ++i) { + for (qsizetype i = 0; i < str.size(); ++i) { char c = digitToCLocale(str.at(i)); if (c >= '0' && c <= '9') { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c10987a5fe..bba0a85319 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -160,9 +160,9 @@ static inline bool qt_ends_with(QStringView haystack, QStringView needle, Qt::Ca static inline bool qt_ends_with(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs); static inline bool qt_ends_with(QStringView haystack, QChar needle, Qt::CaseSensitivity cs); -qssize_t QtPrivate::qustrlen(const ushort *str) Q_DECL_NOTHROW +qsizetype QtPrivate::qustrlen(const ushort *str) Q_DECL_NOTHROW { - qssize_t result = 0; + qsizetype result = 0; #ifdef __SSE2__ // find the 16-byte alignment immediately prior or equal to str diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/tools/qstringalgorithms.h index 336da87468..aaa702301e 100644 --- a/src/corelib/tools/qstringalgorithms.h +++ b/src/corelib/tools/qstringalgorithms.h @@ -55,7 +55,7 @@ template class QVector; namespace QtPrivate { -Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qssize_t qustrlen(const ushort *str) Q_DECL_NOTHROW; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const ushort *str) Q_DECL_NOTHROW; Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW; Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QLatin1String rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW; diff --git a/src/corelib/tools/qstringiterator.qdoc b/src/corelib/tools/qstringiterator.qdoc index 95c2247bc1..caec8803f3 100644 --- a/src/corelib/tools/qstringiterator.qdoc +++ b/src/corelib/tools/qstringiterator.qdoc @@ -120,7 +120,7 @@ */ /*! - \fn QStringIterator::QStringIterator(QStringView string, qssize_t idx) + \fn QStringIterator::QStringIterator(QStringView string, qsizetype idx) Constructs an iterator over the contents of \a string. The iterator will point before position \a idx in the string. diff --git a/src/corelib/tools/qstringiterator_p.h b/src/corelib/tools/qstringiterator_p.h index 8b1a6a1cd3..219589b6e4 100644 --- a/src/corelib/tools/qstringiterator_p.h +++ b/src/corelib/tools/qstringiterator_p.h @@ -62,7 +62,7 @@ class QStringIterator QString::const_iterator i, pos, e; Q_STATIC_ASSERT((std::is_same::value)); public: - explicit QStringIterator(QStringView string, qssize_t idx = 0) + explicit QStringIterator(QStringView string, qsizetype idx = 0) : i(string.begin()), pos(i + idx), e(string.end()) diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp index 8eefc6d814..bb22239b66 100644 --- a/src/corelib/tools/qstringview.cpp +++ b/src/corelib/tools/qstringview.cpp @@ -131,9 +131,9 @@ QT_BEGIN_NAMESPACE /*! \typedef QStringView::size_type - Alias for qssize_t. Provided for compatibility with the STL. + Alias for qsizetype. Provided for compatibility with the STL. - Unlike other Qt classes, QStringView uses qssize_t as its \c size_type, to allow + Unlike other Qt classes, QStringView uses qsizetype as its \c size_type, to allow accepting data from \c{std::basic_string} without truncation. The Qt API functions, for example length(), return \c int, while the STL-compatible functions, for example size(), return \c size_type. @@ -224,7 +224,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView::QStringView(const Char *str, qssize_t len) + \fn QStringView::QStringView(const Char *str, qsizetype len) Constructs a string view on \a str with length \a len. @@ -486,7 +486,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn qssize_t QStringView::size() const + \fn qsizetype QStringView::size() const Returns the size of this string view, in UTF-16 code points (that is, surrogate pairs count as two for the purposes of this function, the same @@ -510,7 +510,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QChar QStringView::operator[](qssize_t n) const + \fn QChar QStringView::operator[](qsizetype n) const Returns the character at position \a n in this string view. @@ -520,7 +520,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QChar QStringView::at(qssize_t n) const + \fn QChar QStringView::at(qsizetype n) const Returns the character at position \a n in this string view. @@ -582,7 +582,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView QStringView::mid(qssize_t start) const + \fn QStringView QStringView::mid(qsizetype start) const Returns the substring starting at position \a start in this object, and extending to the end of the string. @@ -593,7 +593,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView QStringView::mid(qssize_t start, qssize_t length) const + \fn QStringView QStringView::mid(qsizetype start, qsizetype length) const \overload Returns the substring of length \a length starting at position @@ -606,7 +606,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView QStringView::left(qssize_t length) const + \fn QStringView QStringView::left(qsizetype length) const Returns the substring of length \a length starting at position 0 in this object. @@ -617,7 +617,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView QStringView::right(qssize_t length) const + \fn QStringView QStringView::right(qsizetype length) const Returns the substring of length \a length starting at position size() - \a length in this object. @@ -628,7 +628,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QStringView QStringView::chopped(qssize_t length) const + \fn QStringView QStringView::chopped(qsizetype length) const Returns the substring of length size() - \a length starting at the beginning of this object. @@ -641,7 +641,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn void QStringView::truncate(qssize_t length) + \fn void QStringView::truncate(qsizetype length) Truncates this string view to length \a length. @@ -653,7 +653,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn void QStringView::chop(qssize_t length) + \fn void QStringView::chop(qsizetype length) Truncates this string view by \a length characters. diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h index 14405f325d..903d7ccb24 100644 --- a/src/corelib/tools/qstringview.h +++ b/src/corelib/tools/qstringview.h @@ -111,7 +111,7 @@ public: #endif typedef const QChar value_type; typedef std::ptrdiff_t difference_type; - typedef qssize_t size_type; + typedef qsizetype size_type; typedef value_type &reference; typedef value_type &const_reference; typedef value_type *pointer; @@ -139,24 +139,24 @@ private: using if_compatible_qstring_like = typename std::enable_if::value || std::is_same::value, bool>::type; template - static Q_DECL_CONSTEXPR qssize_t lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW + static Q_DECL_CONSTEXPR qsizetype lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW { - return qssize_t(N - 1); + return qsizetype(N - 1); } template - static qssize_t lengthHelperPointer(const Char *str) Q_DECL_NOTHROW + static qsizetype lengthHelperPointer(const Char *str) Q_DECL_NOTHROW { #if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) if (__builtin_constant_p(*str)) { - qssize_t result = 0; + qsizetype result = 0; while (*str++) ++result; } #endif return QtPrivate::qustrlen(reinterpret_cast(str)); } - static qssize_t lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW + static qsizetype lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW { return QtPrivate::qustrlen(reinterpret_cast(str)); } @@ -174,7 +174,7 @@ public: : QStringView() {} template = true> - Q_DECL_CONSTEXPR QStringView(const Char *str, qssize_t len) + Q_DECL_CONSTEXPR QStringView(const Char *str, qsizetype len) : m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)), m_data(castHelper(str)) {} @@ -204,20 +204,20 @@ public: #else template = true> QStringView(const String &str) Q_DECL_NOTHROW - : QStringView(str.isNull() ? nullptr : str.data(), qssize_t(str.size())) {} + : QStringView(str.isNull() ? nullptr : str.data(), qsizetype(str.size())) {} #endif template = true> QStringView(const StdBasicString &str) Q_DECL_NOTHROW - : QStringView(str.data(), qssize_t(str.size())) {} + : QStringView(str.data(), qsizetype(str.size())) {} Q_REQUIRED_RESULT inline QString toString() const; // defined in qstring.h - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR qssize_t size() const Q_DECL_NOTHROW { return m_size; } + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR qsizetype size() const Q_DECL_NOTHROW { return m_size; } Q_REQUIRED_RESULT const_pointer data() const Q_DECL_NOTHROW { return reinterpret_cast(m_data); } Q_REQUIRED_RESULT Q_DECL_CONSTEXPR const storage_type *utf16() const Q_DECL_NOTHROW { return m_data; } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar operator[](qssize_t n) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar operator[](qsizetype n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n < size()), QChar(m_data[n]); } // @@ -229,22 +229,22 @@ public: Q_REQUIRED_RESULT QByteArray toLocal8Bit() const { return QtPrivate::convertToLocal8Bit(*this); } Q_REQUIRED_RESULT inline QVector toUcs4() const; // defined in qvector.h - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar at(qssize_t n) const { return (*this)[n]; } + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar at(qsizetype n) const { return (*this)[n]; } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qssize_t pos) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos) const { return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QStringView(m_data + pos, m_size - pos); } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qssize_t pos, qssize_t n) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos, qsizetype n) const { return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QStringView(m_data + pos, n); } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView left(qssize_t n) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView left(qsizetype n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, n); } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView right(qssize_t n) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView right(qsizetype n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data + m_size - n, n); } - Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView chopped(qssize_t n) const + Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView chopped(qsizetype n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, m_size - n); } - Q_DECL_RELAXED_CONSTEXPR void truncate(qssize_t n) + Q_DECL_RELAXED_CONSTEXPR void truncate(qsizetype n) { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size = n; } - Q_DECL_RELAXED_CONSTEXPR void chop(qssize_t n) + Q_DECL_RELAXED_CONSTEXPR void chop(qsizetype n) { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size -= n; } Q_REQUIRED_RESULT QStringView trimmed() const Q_DECL_NOTHROW { return QtPrivate::trimmed(*this); } @@ -291,7 +291,7 @@ public: Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar first() const { return front(); } Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar last() const { return back(); } private: - qssize_t m_size; + qsizetype m_size; const storage_type *m_data; }; Q_DECLARE_TYPEINFO(QStringView, Q_PRIMITIVE_TYPE); diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 1ec45a7491..587f375ce7 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -49,10 +49,10 @@ QT_BEGIN_NAMESPACE static void swapPixel01(QImage *image) // 1-bpp: swap 0 and 1 pixels { - qssize_t i; + qsizetype i; if (image->depth() == 1 && image->colorCount() == 2) { uint *p = (uint *)image->bits(); - qssize_t nbytes = static_cast(image->sizeInBytes()); + qsizetype nbytes = static_cast(image->sizeInBytes()); for (i=0; i::max()/depth < width || bytes_per_line <= 0 || height <= 0 - || std::numeric_limits::max()/uint(bytes_per_line) < height + || std::numeric_limits::max()/uint(bytes_per_line) < height || std::numeric_limits::max()/sizeof(uchar *) < uint(height)) return 0; @@ -1470,7 +1470,7 @@ int QImage::byteCount() const \sa byteCount(), bytesPerLine(), bits(), {QImage#Image Information}{Image Information} */ -qssize_t QImage::sizeInBytes() const +qsizetype QImage::sizeInBytes() const { return d ? d->nbytes : 0; } diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index eccff480bb..cddb5fe632 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -217,7 +217,7 @@ public: #if QT_DEPRECATED_SINCE(5, 10) QT_DEPRECATED int byteCount() const; #endif - qssize_t sizeInBytes() const; + qsizetype sizeInBytes() const; uchar *scanLine(int); const uchar *scanLine(int) const; diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 6abaa2887e..4eef617336 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -823,8 +823,8 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve const int depth = 32; - const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qssize_t nbytes = dst_bytes_per_line * data->height; + const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const qsizetype nbytes = dst_bytes_per_line * data->height; uchar *const newData = (uchar *)realloc(data->data, nbytes); if (!newData) return false; @@ -877,8 +877,8 @@ static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversi const int depth = 32; - const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qssize_t nbytes = dst_bytes_per_line * data->height; + const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const qsizetype nbytes = dst_bytes_per_line * data->height; uchar *const newData = (uchar *)realloc(data->data, nbytes); if (!newData) return false; @@ -945,8 +945,8 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers const int depth = 16; - const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qssize_t nbytes = dst_bytes_per_line * data->height; + const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const qsizetype nbytes = dst_bytes_per_line * data->height; uchar *const newData = (uchar *)realloc(data->data, nbytes); if (!newData) return false; @@ -1002,8 +1002,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl const int depth = 16; - const qssize_t dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qssize_t src_bytes_per_line = data->bytes_per_line; + const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const qsizetype src_bytes_per_line = data->bytes_per_line; quint32 *src_data = (quint32 *) data->data; quint16 *dst_data = (quint16 *) data->data; @@ -1257,9 +1257,9 @@ void dither_to_Mono(QImageData *dst, const QImageData *src, } uchar *dst_data = dst->data; - qssize_t dst_bpl = dst->bytes_per_line; + qsizetype dst_bpl = dst->bytes_per_line; const uchar *src_data = src->data; - qssize_t src_bpl = src->bytes_per_line; + qsizetype src_bpl = src->bytes_per_line; switch (dithermode) { case Diffuse: { @@ -1912,8 +1912,8 @@ static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, if (simpleCase) memcpy(dest->data, src->data, src->bytes_per_line * src->height); else { - qssize_t size = src->bytes_per_line * src->height; - for (qssize_t i = 0; i < size; ++i) { + qsizetype size = src->bytes_per_line * src->height; + for (qsizetype i = 0; i < size; ++i) { dest->data[i] = translate[src->data[i]]; } } @@ -1936,8 +1936,8 @@ static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *s if (simpleCase) memcpy(dest->data, src->data, src->bytes_per_line * src->height); else { - qssize_t size = src->bytes_per_line * src->height; - for (qssize_t i = 0; i < size; ++i) { + qsizetype size = src->bytes_per_line * src->height; + for (qsizetype i = 0; i < size; ++i) { dest->data[i] = translate[src->data[i]]; } } diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 9ba4945dc5..befecbfe8b 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -71,12 +71,12 @@ struct Q_GUI_EXPORT QImageData { // internal image data int width; int height; int depth; - qssize_t nbytes; // number of bytes data + qsizetype nbytes; // number of bytes data qreal devicePixelRatio; QVector colortable; uchar *data; QImage::Format format; - qssize_t bytes_per_line; + qsizetype bytes_per_line; int ser_no; // serial number int detach_no; diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index d694352fc1..646e737afa 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -191,7 +191,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image, uchar *mem = thisImg->bits(); const uchar *bits = correctFormatPic.constBits(); - qssize_t bytesCopied = 0; + qsizetype bytesCopied = 0; while (bytesCopied < correctFormatPic.sizeInBytes()) { memcpy(mem,bits,correctFormatPic.bytesPerLine()); mem += thisImg->bytesPerLine(); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5ec570a5db..6a24c02aaa 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -2383,7 +2383,7 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy); const uchar *textureData = image.imageData; - const qssize_t bytesPerLine = image.bytesPerLine; + const qsizetype bytesPerLine = image.bytesPerLine; const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0)); while (b < boundedEnd - 3) { @@ -4959,7 +4959,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us int image_width = data->texture.width; int image_height = data->texture.height; - const qssize_t scanline_offset = data->texture.bytesPerLine / 4; + const qsizetype scanline_offset = data->texture.bytesPerLine / 4; if (data->fast_matrix) { // The increment pr x in the scanline diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index d6c3319c76..2619539788 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -685,7 +685,7 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint * v_fy = _mm256_add_epi32(v_fy, _mm256_mullo_epi32(_mm256_set1_epi32(fdy), v_index)); const uchar *textureData = image.imageData; - const qssize_t bytesPerLine = image.bytesPerLine; + const qsizetype bytesPerLine = image.bytesPerLine; const __m256i vbpl = _mm256_set1_epi16(bytesPerLine/4); while (b < boundedEnd - 7) { diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 2be10d2cfb..df9f762314 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -293,7 +293,7 @@ struct QTextureData int y1; int x2; int y2; - qssize_t bytesPerLine; + qsizetype bytesPerLine; QImage::Format format; const QVector *colorTable; bool hasAlpha; @@ -847,7 +847,7 @@ inline void qt_memfill(T *dest, T value, int count) template Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectfill(T *dest, T value, - int x, int y, int width, int height, qssize_t stride) + int x, int y, int width, int height, qsizetype stride) { char *d = reinterpret_cast(dest + x) + y * stride; if (uint(stride) == (width * sizeof(T))) { diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index d0d948bbb7..1637a933b1 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -994,7 +994,7 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, Q_ASSERT(img.depth() >= 8); - qssize_t srcBPL = img.bytesPerLine(); + qsizetype srcBPL = img.bytesPerLine(); const uchar *srcBits = img.bits(); int srcSize = img.depth() >> 3; // This is the part that is incompatible with lower than 8-bit.. int iw = img.width(); @@ -1043,7 +1043,7 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, // call the blend function... int dstSize = rasterBuffer->bytesPerPixel(); - qssize_t dstBPL = rasterBuffer->bytesPerLine(); + qsizetype dstBPL = rasterBuffer->bytesPerLine(); func(rasterBuffer->buffer() + x * dstSize + y * dstBPL, dstBPL, srcBits, srcBPL, iw, ih, @@ -2318,8 +2318,8 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe clippedSourceRect = clippedSourceRect.intersected(img.rect()); - const qssize_t dbpl = d->rasterBuffer->bytesPerLine(); - const qssize_t sbpl = img.bytesPerLine(); + const qsizetype dbpl = d->rasterBuffer->bytesPerLine(); + const qsizetype sbpl = img.bytesPerLine(); uchar *dst = d->rasterBuffer->buffer(); uint bpp = img.depth() >> 3; @@ -2828,7 +2828,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, cache->fillInPendingGlyphs(); const QImage &image = cache->image(); - qssize_t bpl = image.bytesPerLine(); + qsizetype bpl = image.bytesPerLine(); int depth = image.depth(); int rightShift = 0; diff --git a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp index 4174b85f4c..8a8aa8c6e1 100644 --- a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp @@ -461,9 +461,9 @@ void tst_QStringView::fromLiteral(const Char *arg) const const Char *null = nullptr; const Char empty[] = { 0 }; - QCOMPARE(QStringView(null).size(), qssize_t(0)); + QCOMPARE(QStringView(null).size(), qsizetype(0)); QCOMPARE(QStringView(null).data(), nullptr); - QCOMPARE(QStringView(empty).size(), qssize_t(0)); + QCOMPARE(QStringView(empty).size(), qsizetype(0)); QCOMPARE(static_cast(QStringView(empty).data()), static_cast(empty)); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 54eb8ab99c..7ad4a9e9bb 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -3441,10 +3441,10 @@ void tst_QImage::hugeQImage() QVERIFY(!image.isNull()); QCOMPARE(image.height(), 25000); QCOMPARE(image.width(), 25000); - QCOMPARE(image.sizeInBytes(), qssize_t(25000)*25000*4); + QCOMPARE(image.sizeInBytes(), qsizetype(25000)*25000*4); QCOMPARE(image.bytesPerLine(), 25000 * 4); - QCOMPARE(image.constScanLine(24990), image.constBits() + qssize_t(25000)*24990*4); + QCOMPARE(image.constScanLine(24990), image.constBits() + qsizetype(25000)*24990*4); image.setPixel(20000, 24990, 0xffaabbcc); QCOMPARE(image.pixel(20000, 24990), 0xffaabbcc); -- cgit v1.2.3 From a0871ad225bc0a7ceed67fa2eb5ed16e475ebd93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 27 Nov 2017 11:40:12 +0100 Subject: iOS: Deliver all QWindowSystemInterface events synchronously On iOS we want all delivery of events from the system to be handled synchronously, as that's what the system expects. We don't need to add a delivery template argument to each function in QWindowSystemInterface that we want to delivery synchronously; that's only needed for functions that a platform normally sends asynch, but in some cases want to delivery synchronously. For always delivering events synchronously we just need to change the default delivery method. The only events affected by this are the screen changes, and window state change, which were not synchronous before, but should be. All other events were already synchronous, though either explicit delivery, of a flush. Change-Id: Ib20ca342d1c076be0fbcf018c83735a416769cfe Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationstate.mm | 2 +- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 ++ src/plugins/platforms/ios/qiostextresponder.mm | 1 - src/plugins/platforms/ios/quiview.mm | 14 +++++++------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index 13e7e1150f..7c8e1f9927 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -75,7 +75,7 @@ static void handleApplicationStateChanged(UIApplicationState uiApplicationState) { Qt::ApplicationState state = qtApplicationState(uiApplicationState); qCDebug(lcQpaApplication) << "moved to" << state; - QWindowSystemInterface::handleApplicationStateChanged(state); + QWindowSystemInterface::handleApplicationStateChanged(state); } QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f49f81912e..429b7d9591 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -422,6 +422,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) , m_processEventLevel(0) , m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit) { + // We want all delivery of events from the system to be handled synchronously + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); } bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 001985a128..33a0b6a42e 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -377,7 +377,6 @@ QScopedValueRollback rollback(m_inSendEventToFocusObject, true); QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyPress, key, modifiers); QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers); - QWindowSystemInterface::flushWindowSystemEvents(); } #ifndef QT_NO_SHORTCUT diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index bf26feac9f..a405fecee2 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -166,7 +166,7 @@ QWindow *window = m_qioswindow->window(); qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << actualGeometry; - QWindowSystemInterface::handleGeometryChange(window, actualGeometry, previousGeometry); + QWindowSystemInterface::handleGeometryChange(window, actualGeometry, previousGeometry); if (actualGeometry.size() != previousGeometry.size()) { // Trigger expose event on resize @@ -199,7 +199,7 @@ } qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed(); - QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); + QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); } // ------------------------------------------------------------------------- @@ -230,7 +230,7 @@ } if (qGuiApp->focusWindow() != m_qioswindow->window()) - QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); + QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); else qImDebug() << m_qioswindow->window() << "already active, not sending window activation"; @@ -268,7 +268,7 @@ UIResponder *newResponder = FirstResponderCandidate::currentCandidate(); if ([self responderShouldTriggerWindowDeactivation:newResponder]) - QWindowSystemInterface::handleWindowActivated(0); + QWindowSystemInterface::handleWindowActivated(0); return YES; } @@ -359,7 +359,7 @@ - (void)sendTouchEventWithTimestamp:(ulong)timeStamp { QIOSIntegration *iosIntegration = QIOSIntegration::instance(); - QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -438,7 +438,7 @@ NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime]; QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); - QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice()); } - (int)mapPressTypeToKey:(UIPress*)press @@ -466,7 +466,7 @@ int key = [self mapPressTypeToKey:press]; if (key == Qt::Key_unknown) continue; - if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier)) + if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier)) handled = true; } -- cgit v1.2.3 From 67391f0a572ddc9c53bdff35dac893b07a862fe5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 22 Nov 2017 01:05:52 +0100 Subject: Fix aliasing problem in QVector::removeAll() Since removeAll() takes its argument by cref, if passing a reference to an element of the container to removeAll(), the element may be deleted (overwritten) by anyother value, leading to UB. Add a test that actually happens to fail for me without the patch, even though that might not be guaranteed (we may invoke UB). Change-Id: If8c795113aeb515f4a9bdf1e072395b932295667 Reviewed-by: Thiago Macieira --- src/corelib/tools/qvector.h | 5 +++-- tests/auto/corelib/tools/qvector/tst_qvector.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index da15d401e3..74c37faad0 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -164,9 +164,10 @@ public: const const_iterator ce = this->cend(), cit = std::find(this->cbegin(), ce, t); if (cit == ce) return 0; - // next operation detaches, so ce, cit may become invalidated: + // next operation detaches, so ce, cit, t may become invalidated: + const T tCopy = t; const int firstFoundIdx = std::distance(this->cbegin(), cit); - const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, t); + const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, tCopy); const int result = std::distance(it, e); erase(it, e); return result; diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 374fec221e..6975452d76 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -245,6 +245,7 @@ private slots: void qhashInt() const { qhash(); } void qhashMovable() const { qhash(); } void qhashCustom() const { qhash(); } + void removeAllWithAlias() const; void removeInt() const; void removeMovable() const; void removeCustom() const; @@ -1722,6 +1723,13 @@ void tst_QVector::prependCustom() const QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } +void tst_QVector::removeAllWithAlias() const +{ + QVector strings; + strings << "One" << "Two" << "Three" << "One" /* must be distinct, but equal */; + QCOMPARE(strings.removeAll(strings.front()), 2); // will trigger asan/ubsan +} + template void tst_QVector::remove() const { -- cgit v1.2.3 From 41667f7f14bb6f40d14d240c9f74d87de8435398 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 30 Oct 2017 10:53:03 +0100 Subject: Android: fix scrolling using a touch keyboard on Blackberry This is a follow-up commit to 97eec16e. Blackberry tries sending touchpad events first, and if not consumed, it sends synthetic mouse wheel events as a fallback. This makes touch keyboard scrolling work in native Android ListViews and other views that do not handle SOURCE_TOUCHPAD motion events. Qt apps, however, blindly accepted all generic motion events, so synthesized mouse wheel events were never sent. => Make QtSurface & QtNative accept only those motions events that are actually handled. Task-number: QTBUG-51165 Change-Id: Iefbbf1e3e1cc3da86afc4c87c19671cc6c5fa145 Reviewed-by: Kai Uwe Broulik Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/QtNative.java | 5 +++-- src/android/jar/src/org/qtproject/qt5/android/QtSurface.java | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 902e2f68e7..ab6d556768 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -471,15 +471,16 @@ public class QtNative } } - static public void sendGenericMotionEvent(MotionEvent event, int id) + static public boolean sendGenericMotionEvent(MotionEvent event, int id) { if (event.getActionMasked() != MotionEvent.ACTION_SCROLL || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) { - return; + return false; } mouseWheel(id, (int) event.getX(), (int) event.getY(), event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL)); + return true; } public static Context getContext() { diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java index e994002dd3..08b5a80f7e 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java @@ -116,7 +116,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback @Override public boolean onGenericMotionEvent(MotionEvent event) { - QtNative.sendGenericMotionEvent(event, getId()); - return true; + return QtNative.sendGenericMotionEvent(event, getId()); } } -- cgit v1.2.3 From 60dfd59a606b7c4de0c7fc90d1cda49bc15fe1f0 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 22 Nov 2017 13:22:19 -0800 Subject: gui/configure.json: Make -{system,qt}-xcb force enabling xcb ... just like -xcb does implicitly. Otherwise, failure to detect system-xcb would silently fall back to -no-xcb despite obviously contradicting the user's request (-qt-xcb always worked anyway, as there is no test that can fail). Change-Id: I6f3145fac0881e7847c4a70547fce206e797a9bb Reviewed-by: Jake Petroules --- src/gui/configure.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/configure.json b/src/gui/configure.json index 28c8034c75..0664cb92c6 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1157,6 +1157,7 @@ "label": "XCB", "section": "Platform plugins", "autoDetect": "!config.darwin", + "enable": "input.xcb == 'system' || input.xcb == 'qt'", "condition": "libs.xcb", "output": [ "privateFeature" ] }, -- cgit v1.2.3 From b764c4d0aaab71efec10166a47b31b26f84cf4fb Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Fri, 20 Oct 2017 15:55:34 +0300 Subject: Fix unix QPrintDialog initially selected printer Unix QPrintDialog always set default printer as selected printer even though something was explicitly requested. [ChangeLog][QtPrintSupport][QPrintDialog] Properly pre-select explicitly requested printer on Unix. Task-number: QTBUG-63933 Change-Id: I6289f759d480b4891f4ddd7ff5aad3ae9ab4bc75 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/printsupport/dialogs/qprintdialog_unix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 71312d65f1..a05c9ac83a 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -675,7 +675,9 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter * widget.printers->addItems(printers); - const int idx = printers.indexOf(defaultPrinter); + const QString selectedPrinter = prn && !prn->printerName().isEmpty() ? prn->printerName() : defaultPrinter; + const int idx = printers.indexOf(selectedPrinter); + if (idx >= 0) currentPrinterIndex = idx; } -- cgit v1.2.3 From 3acf5d61a14b70285625bc5276a842fc86f0c7af Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 6 Sep 2017 14:01:39 +0300 Subject: Fix DB2 plugin building on Linux 64bit Task-number: QTBUG-59358 Change-Id: I2e7d52b31f354868c8c4435d8cabe3525d22ede2 Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/db2/db2.pro | 2 ++ src/plugins/sqldrivers/db2/qsql_db2.cpp | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/plugins/sqldrivers/db2/db2.pro b/src/plugins/sqldrivers/db2/db2.pro index eef65fac66..b99fe91fe3 100644 --- a/src/plugins/sqldrivers/db2/db2.pro +++ b/src/plugins/sqldrivers/db2/db2.pro @@ -7,5 +7,7 @@ QMAKE_USE += db2 OTHER_FILES += db2.json +equals(QT_ARCH, x86_64): DEFINES += ODBC64 + PLUGIN_CLASS_NAME = QDB2DriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp index 27d0e7001a..839d80466f 100644 --- a/src/plugins/sqldrivers/db2/qsql_db2.cpp +++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp @@ -268,7 +268,7 @@ static QSqlField qMakeFieldInfo(const QDB2ResultPrivate* d, int i) { SQLSMALLINT colNameLen; SQLSMALLINT colType; - SQLUINTEGER colSize; + SQLULEN colSize; SQLSMALLINT colScale; SQLSMALLINT nullable; SQLRETURN r = SQL_ERROR; @@ -304,7 +304,7 @@ static int qGetIntData(SQLHANDLE hStmt, int column, bool& isNull) { SQLINTEGER intbuf; isNull = false; - SQLINTEGER lengthIndicator = 0; + SQLLEN lengthIndicator = 0; SQLRETURN r = SQLGetData(hStmt, column + 1, SQL_C_SLONG, @@ -322,7 +322,7 @@ static double qGetDoubleData(SQLHANDLE hStmt, int column, bool& isNull) { SQLDOUBLE dblbuf; isNull = false; - SQLINTEGER lengthIndicator = 0; + SQLLEN lengthIndicator = 0; SQLRETURN r = SQLGetData(hStmt, column+1, SQL_C_DOUBLE, @@ -341,7 +341,7 @@ static SQLBIGINT qGetBigIntData(SQLHANDLE hStmt, int column, bool& isNull) { SQLBIGINT lngbuf = Q_INT64_C(0); isNull = false; - SQLINTEGER lengthIndicator = 0; + SQLLEN lengthIndicator = 0; SQLRETURN r = SQLGetData(hStmt, column+1, SQL_C_SBIGINT, @@ -358,7 +358,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& is { QString fieldVal; SQLRETURN r = SQL_ERROR; - SQLINTEGER lengthIndicator = 0; + SQLLEN lengthIndicator = 0; if (colSize <= 0) colSize = 255; @@ -394,12 +394,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& is return fieldVal; } -static QByteArray qGetBinaryData(SQLHANDLE hStmt, int column, SQLINTEGER& lengthIndicator, bool& isNull) +static QByteArray qGetBinaryData(SQLHANDLE hStmt, int column, SQLLEN& lengthIndicator, bool& isNull) { QByteArray fieldVal; SQLSMALLINT colNameLen; SQLSMALLINT colType; - SQLUINTEGER colSize; + SQLULEN colSize; SQLSMALLINT colScale; SQLSMALLINT nullable; SQLRETURN r = SQL_ERROR; @@ -633,9 +633,9 @@ bool QDB2Result::exec() { Q_D(QDB2Result); QList tmpStorage; // holds temporary ptrs - QVarLengthArray indicators(boundValues().count()); + QVarLengthArray indicators(boundValues().count()); - memset(indicators.data(), 0, indicators.size() * sizeof(SQLINTEGER)); + memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN)); setActive(false); setAt(QSql::BeforeFirstRow); SQLRETURN r; @@ -651,7 +651,7 @@ bool QDB2Result::exec() int i; for (i = 0; i < values.count(); ++i) { // bind parameters - only positional binding allowed - SQLINTEGER *ind = &indicators[i]; + SQLLEN *ind = &indicators[i]; if (values.at(i).isNull()) *ind = SQL_NULL_DATA; if (bindValueType(i) & QSql::Out) @@ -996,7 +996,7 @@ QVariant QDB2Result::data(int field) return QVariant(); } SQLRETURN r = 0; - SQLINTEGER lengthIndicator = 0; + SQLLEN lengthIndicator = 0; bool isNull = false; const QSqlField info = d->recInf.field(field); @@ -1109,7 +1109,7 @@ bool QDB2Result::isNull(int i) int QDB2Result::numRowsAffected() { Q_D(const QDB2Result); - SQLINTEGER affectedRowCount = 0; + SQLLEN affectedRowCount = 0; SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) return affectedRowCount; @@ -1238,7 +1238,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas const QString opt(tmp.left(idx)); const QString val(tmp.mid(idx + 1).simplified()); - SQLUINTEGER v = 0; + SQLULEN v = 0; r = SQL_SUCCESS; if (opt == QLatin1String("SQL_ATTR_ACCESS_MODE")) { if (val == QLatin1String("SQL_MODE_READ_ONLY")) { @@ -1622,7 +1622,7 @@ bool QDB2Driver::rollbackTransaction() bool QDB2Driver::setAutoCommit(bool autoCommit) { Q_D(QDB2Driver); - SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF; + SQLULEN ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF; SQLRETURN r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_AUTOCOMMIT, reinterpret_cast(ac), -- cgit v1.2.3 From 203fb838038d4c6c33d9e6ed3a45600c6e064e5a Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Sat, 25 Nov 2017 20:00:18 +0100 Subject: QSqlQuery: Remove temporary variable in navigation functions Change-Id: I33836a75e1d2e5663f81a33a195d0cb21760e1f8 Reviewed-by: Andy Shaw --- src/sql/kernel/qsqlquery.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp index f9cc07daa1..b89d20976f 100644 --- a/src/sql/kernel/qsqlquery.cpp +++ b/src/sql/kernel/qsqlquery.cpp @@ -649,11 +649,10 @@ bool QSqlQuery::next() { if (!isSelect() || !isActive()) return false; - bool b = false; + switch (at()) { case QSql::BeforeFirstRow: - b = d->sqlResult->fetchFirst(); - return b; + return d->sqlResult->fetchFirst(); case QSql::AfterLastRow: return false; default: @@ -703,13 +702,11 @@ bool QSqlQuery::previous() return false; } - bool b = false; switch (at()) { case QSql::BeforeFirstRow: return false; case QSql::AfterLastRow: - b = d->sqlResult->fetchLast(); - return b; + return d->sqlResult->fetchLast(); default: if (!d->sqlResult->fetchPrevious()) { d->sqlResult->setAt(QSql::BeforeFirstRow); @@ -737,9 +734,7 @@ bool QSqlQuery::first() qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query"); return false; } - bool b = false; - b = d->sqlResult->fetchFirst(); - return b; + return d->sqlResult->fetchFirst(); } /*! @@ -758,9 +753,7 @@ bool QSqlQuery::last() { if (!isSelect() || !isActive()) return false; - bool b = false; - b = d->sqlResult->fetchLast(); - return b; + return d->sqlResult->fetchLast(); } /*! -- cgit v1.2.3 From fb880bbdff7b4ff3ef1a3451d868ce595a14c29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Tue, 21 Nov 2017 08:46:57 +0100 Subject: QMenu: Corner case size fix (high DPI + multi screen) We always need to set the QMenu screen explicit also when it is about to be shown on the primary screen. The reason is QWidget::metric (called from style/sizeHint) may use qApp->devicePixelRatioF() when it does not know about the topLevelWindow. That may not be the same value as DPR on primary screen. It can be argued that it likely is a bug in QWidget::metric, but fixing that looks to be a somewhat dangerous behavior change. Task-number: QTBUG-59794 Change-Id: I6ed0e808aa31bee5b77c0e19ce61a77548fdbb38 Reviewed-by: Morten Kristensen Reviewed-by: Richard Moe Gustavsen Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qmenu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 196348f8e8..cf306e63bd 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -853,8 +853,7 @@ void QMenuPrivate::adjustMenuScreen(const QPoint &p) // The windowHandle must point to the screen where the menu will be shown. // The (item) size calculations depend on the menu screen, // so a wrong screen would often cause wrong sizes (on high DPI) - const QScreen *primaryScreen = QApplication::primaryScreen(); - const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : primaryScreen; + const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : nullptr; const int screenNumberForPoint = QApplication::desktop()->screenNumber(p); QScreen *actualScreen = QGuiApplication::screens().at(screenNumberForPoint); if (actualScreen && currentScreen != actualScreen) { -- cgit v1.2.3 From 81908abd5e62d3ee3e24c37801892ef500de2fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 28 Nov 2017 19:28:36 +0100 Subject: iOS: Update screen metrics (physical DPI) for the latest set of devices We were missing some recent iPads, and the iPhone 8 Plus and X. Change-Id: Ib65644a277a1cbd75ccb360b79b9ac8af935c741 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 3514bf63bb..deea4d86a0 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -181,12 +181,12 @@ QT_BEGIN_NAMESPACE /*! Returns the model identifier of the device. - - When running under the simulator, the identifier will not - match the simulated device, but will be x86_64 or i386. */ static QString deviceModelIdentifier() { +#if TARGET_OS_SIMULATOR + return QString::fromLocal8Bit(qgetenv("SIMULATOR_MODEL_IDENTIFIER")); +#else static const char key[] = "hw.machine"; size_t size; @@ -196,6 +196,7 @@ static QString deviceModelIdentifier() sysctlbyname(key, &value, &size, NULL, 0); return QString::fromLatin1(value); +#endif } QIOSScreen::QIOSScreen(UIScreen *screen) @@ -210,19 +211,24 @@ QIOSScreen::QIOSScreen(UIScreen *screen) // Based on https://en.wikipedia.org/wiki/List_of_iOS_devices#Display // iPhone (1st gen), 3G, 3GS, and iPod Touch (1st–3rd gen) are 18-bit devices - if (deviceIdentifier.contains(QRegularExpression("^(iPhone1,[12]|iPhone2,1|iPod[1-3],1)$"))) - m_depth = 18; - else - m_depth = 24; + static QRegularExpression lowBitDepthDevices("^(iPhone1,[12]|iPhone2,1|iPod[1-3],1)$"); + m_depth = deviceIdentifier.contains(lowBitDepthDevices) ? 18 : 24; + + static QRegularExpression iPhoneXModels("^iPhone(10,[36])$"); + static QRegularExpression iPhonePlusModels("^iPhone(7,1|8,2|9,[24]|10,[25])$"); + static QRegularExpression iPadMiniModels("^iPad(2,[567]|4,[4-9]|5,[12])$"); - if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2|9,2|9,4)$"))) { - // iPhone Plus models + if (deviceIdentifier.contains(iPhoneXModels)) { + m_physicalDpi = 458; + } else if (deviceIdentifier.contains(iPhonePlusModels)) { m_physicalDpi = 401; - } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) { - // All iPads except the iPad Mini series - m_physicalDpi = 132 * devicePixelRatio(); + } else if (deviceIdentifier.startsWith("iPad")) { + if (deviceIdentifier.contains(iPadMiniModels)) + m_physicalDpi = 163 * devicePixelRatio(); + else + m_physicalDpi = 132 * devicePixelRatio(); } else { - // All non-Plus iPhones, and iPad Minis + // All normal iPhones, and iPods m_physicalDpi = 163 * devicePixelRatio(); } } else { -- cgit v1.2.3 From 038e473cfac43f80bd8d54bb6c6da5bf6391efa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 28 Nov 2017 19:38:31 +0100 Subject: iOS: Don't treat AppleTV as an iDevice when resolving physical DPI Change-Id: I07ac92a7b2d8c65b7d70a4f2ed5f96f8f4d99ef0 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index deea4d86a0..74e81dedf4 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -205,9 +205,9 @@ QIOSScreen::QIOSScreen(UIScreen *screen) , m_uiWindow(0) , m_orientationListener(0) { - if (screen == [UIScreen mainScreen]) { - QString deviceIdentifier = deviceModelIdentifier(); + QString deviceIdentifier = deviceModelIdentifier(); + if (screen == [UIScreen mainScreen] && !deviceIdentifier.startsWith("AppleTV")) { // Based on https://en.wikipedia.org/wiki/List_of_iOS_devices#Display // iPhone (1st gen), 3G, 3GS, and iPod Touch (1st–3rd gen) are 18-bit devices -- cgit v1.2.3 From 8f3ad56191880f1f16abde2d3eba546d477083c8 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 28 Nov 2017 13:15:09 +0100 Subject: [doc] Document QString{,Ref}::split() behavior with empty 'sep' We actually test for this already in tst_QString::split(). Change-Id: I35fe8f90900ea9c8e6251facdb3326b9226348d0 Reviewed-by: Lars Knoll --- src/corelib/doc/snippets/qstring/main.cpp | 12 ++++++++++++ src/corelib/tools/qstring.cpp | 32 +++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index 41ee5a9cef..c839c10b84 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -793,6 +793,18 @@ void Widget::splitCaseSensitiveFunction() QStringList list2 = str.split(',', QString::SkipEmptyParts); // list2: [ "a", "b", "c" ] //! [62] + + //! [62-empty] + QString str = "abc"; + auto parts = str.split(""); + // parts: {"", "a", "b", "c", ""} + //! [62-empty] + + //! [62-slashes] + QString str = "/a/b/c/"; + auto parts = str.split('/'); + // parts: {"", "a", "b", "c", ""} + //! [62-slashes] } void Widget::sprintfFunction() diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 941532658b..af3d026682 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6878,6 +6878,16 @@ static ResultList splitString(const StringSource &source, const QChar *sep, \snippet qstring/main.cpp 62 + If \a sep is empty, split() returns an empty string, followed + by each of the string's characters, followed by another empty string: + + \snippet qstring/main.cpp 62-empty + + To understand this behavior, recall that the empty string matches + everywhere, so the above is qualitatively the same as: + + \snippet qstring/main.cpp 62-slashes + \sa QStringList::join(), section() */ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const @@ -6887,15 +6897,10 @@ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseS /*! Splits the string into substring references wherever \a sep occurs, and - returns the list of those strings. If \a sep does not match - anywhere in the string, splitRef() returns a single-element vector - containing this string reference. - - \a cs specifies whether \a sep should be matched case - sensitively or case insensitively. + returns the list of those strings. - If \a behavior is QString::SkipEmptyParts, empty entries don't - appear in the result. By default, empty entries are kept. + See QString::split() for how \a sep, \a behavior and \a cs interact to form + the result. \note All references are valid as long this string is alive. Destroying this string will cause all references be dangling pointers. @@ -6926,15 +6931,10 @@ QVector QString::splitRef(QChar sep, SplitBehavior behavior, Qt::Cas /*! Splits the string into substrings references wherever \a sep occurs, and - returns the list of those strings. If \a sep does not match - anywhere in the string, split() returns a single-element vector - containing this string reference. - - \a cs specifies whether \a sep should be matched case - sensitively or case insensitively. + returns the list of those strings. - If \a behavior is QString::SkipEmptyParts, empty entries don't - appear in the result. By default, empty entries are kept. + See QString::split() for how \a sep, \a behavior and \a cs interact to form + the result. \note All references are valid as long this string is alive. Destroying this string will cause all references be dangling pointers. -- cgit v1.2.3 From bc9941db42172b7f55c69bad27a7b6ae378f4e4a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Nov 2017 14:17:58 +0100 Subject: tst_QNetworkReply: Blacklist putToFtpWithInvalidCredentials for Windows Task-number: QTBUG-62860 Change-Id: Ibf4d7de9eedc2236375ad10ca4bea08055c7ae00 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 57f33d5863..d4c83bc40b 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -32,6 +32,8 @@ linux windows [putToFtp] windows ci +[putToFtpWithInvalidCredentials] +windows ci [putWithServerClosingConnectionImmediately] windows [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -- cgit v1.2.3 From 49597a7b584d707f0c093299ec96c3a0f121513b Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Tue, 17 Oct 2017 16:23:30 -0400 Subject: Correct the vertex used to calculate v1/v2Frac The NoClip version of the drawTriangle code had the vertices swapped. Task-number: QTBUG-50845 Change-Id: I731dafee6cc140ea017b3b7d1051a27ad3081aa7 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qdistancefield.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp index 064c2aca7f..4b5d4a48b6 100644 --- a/src/gui/text/qdistancefield.cpp +++ b/src/gui/text/qdistancefield.cpp @@ -177,8 +177,8 @@ void drawTriangle(qint32 *bits, int width, int height, const QPoint *center, const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8; const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8; - const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff; - const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff; + const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v1->y() & 0xff; + const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v2->y() & 0xff; const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff; int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0; -- cgit v1.2.3 From e195620d7164f40050e0d9454f7dd94f1649dce2 Mon Sep 17 00:00:00 2001 From: Robert Szefner Date: Sat, 25 Nov 2017 19:04:48 +0100 Subject: QPSQL: Remove semicolon after Q_DECLARE_SQLDRIVER_PRIVATE The semicolon is unnecessary and QtCreator warns of it. Change-Id: I20f803d1ea0136080ff4dc4f7d9863fd8028992e Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 8f7d261bdc..6ba32a0c71 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -229,7 +229,7 @@ class QPSQLResultPrivate : public QSqlResultPrivate { Q_DECLARE_PUBLIC(QPSQLResult) public: - Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver); + Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver) QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv) : QSqlResultPrivate(q, drv), result(0), -- cgit v1.2.3 From 813fa3f50ff4eb2eef00d5b55366c97651fef3b7 Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Fri, 24 Nov 2017 22:35:17 +0200 Subject: unify windows mkspecs: update description Common changes to mingw-w64, ICC on Windows and MSVC toolchains: - update toolchains description similar to 'gcc-base.conf'. Change-Id: Ie456c6cec86c0d1c0107ca84a0fa7855666df91e Reviewed-by: Oswald Buddenhagen --- mkspecs/common/msvc-desktop.conf | 12 ++++++++---- mkspecs/win32-g++/qmake.conf | 2 +- mkspecs/win32-icc/qmake.conf | 9 +++++---- mkspecs/win32-msvc/qmake.conf | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index f95a3bbdc8..5a26add083 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -1,10 +1,14 @@ # -# qmake configuration for Microsoft Visual Studio C/C++ Compiler -# This mkspec is used by the win32-msvc and win32-clang-msvc specs +# This file is used as a basis for the following compilers: # - +# - Microsoft C/C++ Optimizing Compiler (all desktop versions) +# - Intel C++ Compiler on Windows +# - Clang-cl +# +# Baseline: +# +# - Visual Studio 2005 (8.0), VC++ 14.0 # -# Baseline: Visual Studio 2005 (8.0), VC++ 14.0 # Version-specific settings go in msvc-version.conf (loaded by default_pre) # diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 185afaaa49..cf43797b95 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -1,7 +1,7 @@ # # qmake configuration for win32-g++ # -# Written for MinGW / gcc 4.6 or higher +# Written for MinGW-w64 / gcc 5.3 or higher # # Cross compile example for i686-w64-mingw32-g++: # configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32- diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index ee95f8a866..a25c979d9a 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -1,16 +1,17 @@ # # qmake configuration for win32-icc # -# Written for Intel C++ +# Written for Intel C++ Compiler on Windows / icl 16.0 or higher # -# Use the Visual Studio configuration +# Use the Microsoft (R) C/C++ Optimizing Compiler configuration, +# since ICC on Windows pretends to be MSVC include(../common/msvc-desktop.conf) -# Now override with the Intel compiler settings +# modifications to msvc-desktop.conf -QMAKE_COMPILER += intel_icl # icl pretends to be msvc +QMAKE_COMPILER += intel_icl QMAKE_CC = icl QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373 diff --git a/mkspecs/win32-msvc/qmake.conf b/mkspecs/win32-msvc/qmake.conf index 1d8b8f0e97..5c38330add 100644 --- a/mkspecs/win32-msvc/qmake.conf +++ b/mkspecs/win32-msvc/qmake.conf @@ -1,7 +1,7 @@ # # qmake configuration for win32-msvc # -# Written for Microsoft Visual C++ (all desktop versions) +# Written for Microsoft C/C++ Optimizing Compiler (all desktop versions) # include(../common/msvc-desktop.conf) -- cgit v1.2.3 From 85eef0e5e05e84b1640a1887fe872e3adbc0ac5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 29 Nov 2017 16:12:40 +0100 Subject: iOS: Improve logging during application startup Change-Id: I15c1980d7c532c94b34e612bb781c8ed5bf096a0 Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qioseventdispatcher.mm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 429b7d9591..7194d5bed1 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -294,7 +294,7 @@ static bool rootLevelRunLoopIntegration() { [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(applicationDidFinishLaunching) + selector:@selector(applicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil]; @@ -320,8 +320,10 @@ static bool rootLevelRunLoopIntegration() # error "Unknown processor family" #endif -+ (void)applicationDidFinishLaunching ++ (void)applicationDidFinishLaunching:(NSNotification *)notification { + qCDebug(lcQpaApplication) << "Application launched with options" << notification.userInfo; + if (!isQtApplication()) return; @@ -329,7 +331,7 @@ static bool rootLevelRunLoopIntegration() // We schedule the main-redirection for the next run-loop pass, so that we // can return from this function and let UIApplicationMain finish its job. // This results in running Qt's application eventloop as a nested runloop. - qEventDispatcherDebug() << "Scheduling main() on next run-loop pass"; + qCDebug(lcQpaApplication) << "Scheduling main() on next run-loop pass"; CFRunLoopTimerRef userMainTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, ^(CFRunLoopTimerRef) { user_main_trampoline(); }); CFRunLoopAddTimer(CFRunLoopGetMain(), userMainTimer, kCFRunLoopCommonModes); @@ -339,7 +341,7 @@ static bool rootLevelRunLoopIntegration() switch (setjmp(processEventEnterJumpPoint)) { case kJumpPointSetSuccessfully: - qEventDispatcherDebug() << "Running main() on separate stack"; qIndent(); + qCDebug(lcQpaApplication) << "Running main() on separate stack"; qIndent(); // Redirect the stack pointer to the start of the reserved stack. This ensures // that when we longjmp out of the event dispatcher and continue execution, the @@ -358,7 +360,7 @@ static bool rootLevelRunLoopIntegration() case kJumpedFromEventDispatcherProcessEvents: // We've returned from the longjmp in the event dispatcher, // and the stack has been restored to its old self. - qUnIndent(); qEventDispatcherDebug() << "Returned from processEvents"; + qUnIndent(); qCDebug(lcQpaApplication) << "Returned from processEvents"; if (Q_UNLIKELY(debugStackUsage)) userMainStack.printUsage(); -- cgit v1.2.3 From da50a0b38ceb730ad3c30d600adfe4435a498550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 27 Aug 2017 16:22:08 +0200 Subject: xcb: Set executed drop action when drop is outside the application Task-number: QTBUG-62815 Change-Id: I13ee1a3a7e9515d827d29ada38bc0d396f4800d7 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbdrag.cpp | 11 +++++++++++ src/plugins/platforms/xcb/qxcbdrag.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 60d142157f..51d09d8927 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -170,6 +170,9 @@ void QXcbDrag::init() QXcbCursor::queryPointer(connection(), ¤t_virtual_desktop, 0); drag_types.clear(); + + dropped = false; + canceled = false; } QMimeData *QXcbDrag::platformDropData() @@ -225,6 +228,10 @@ void QXcbDrag::startDrag() void QXcbDrag::endDrag() { QBasicDrag::endDrag(); + if (!dropped && !canceled && canDrop()) { + // Set executed drop action when dropping outside application. + setExecutedDropAction(accepted_drop_action); + } initiatorWindow.clear(); } @@ -1026,6 +1033,8 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e // reset target_time = XCB_CURRENT_TIME; + + dropped = true; } @@ -1124,6 +1133,8 @@ void QXcbDrag::cancel() // remove canceled object currentDrag()->deleteLater(); + + canceled = true; } // find an ancestor with XdndAware on it diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 2d152edf76..9e1ee46593 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -136,6 +136,10 @@ private: QRect source_sameanswer; bool waiting_for_status; + // helpers for setting executed drop action outside application + bool dropped; + bool canceled; + // top-level window we sent position to last. xcb_window_t current_target; // window to send events to (always valid if current_target) -- cgit v1.2.3 From 6508fdca1dcc7105947befadba272d0fd4bbc27f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 28 Nov 2017 13:30:52 +0100 Subject: ANGLE: D3D11: Fix shared handle support detection for WARP when MinGW is used The MinGW version we support supports IsWindows8OrGreater so that we can check the windows version properly. As the OpenGL detection falls back to WARP in case of RDP it was possible, that shared handles were wrongly stated as supported, which caused crashes in users' code. Task-number: QTBUG-64657 Change-Id: Iaca2bd169f2764cf6ec68a1d36112a735246b29a Reviewed-by: Andre de la Rocha Reviewed-by: Andy Shaw --- .../angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 2 +- src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp index 0173311bc6..5118bdbe9c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -2645,7 +2645,7 @@ bool Renderer11::getShareHandleSupport() const if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) { -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__) +#ifndef ANGLE_ENABLE_WINDOWS_STORE if (!IsWindows8OrGreater()) { // WARP on Windows 7 doesn't support shared handles diff --git a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch index dc091b0497..f42ff2141b 100644 --- a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch +++ b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch @@ -405,15 +405,6 @@ index ea84783..62badcc 100644 if (mD3d11Module) { -@@ -2618,7 +2642,7 @@ bool Renderer11::getShareHandleSupport() const - - if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) - { --#ifndef ANGLE_ENABLE_WINDOWS_STORE -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__) - if (!IsWindows8OrGreater()) - { - // WARP on Windows 7 doesn't support shared handles diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h index 62e9816..b4e7761 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h -- cgit v1.2.3 From 58b70c2f1acedad0df6b4de1acf3dea2011e369c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 20 Nov 2017 16:16:55 +0100 Subject: tst_QFileSystemModel: Stabilize readOnly(), sortPersistentIndex() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests start to show flakyness on Linux in 5.10 (rowCount() check failing). This seems to point to a race condition between the files showing up and the file system watchers of QFileSystemModel starting. To fix this, close the file and wait until it shows up in the directory before pointing the QFileSystemModel to it. The tests then no longer rely on the file system watchers. Change-Id: I39cffb4cacf6843e8e4180efb405345307c78dd8 Reviewed-by: Jędrzej Nowacki --- .../dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 31df66e312..979d5c632e 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -239,13 +239,18 @@ void tst_QFileSystemModel::readOnly() QCOMPARE(model->isReadOnly(), true); QTemporaryFile file(flatDirTestPath + QStringLiteral("/XXXXXX.dat")); QVERIFY2(file.open(), qPrintable(file.errorString())); + const QString fileName = file.fileName(); + file.close(); + + const QFileInfo fileInfo(fileName); + QTRY_VERIFY(QDir(flatDirTestPath).entryInfoList().contains(fileInfo)); QModelIndex root = model->setRootPath(flatDirTestPath); QTRY_VERIFY(model->rowCount(root) > 0); - QVERIFY(!(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable)); + QVERIFY(!(model->flags(model->index(fileName)) & Qt::ItemIsEditable)); model->setReadOnly(false); QCOMPARE(model->isReadOnly(), false); - QVERIFY(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable); + QVERIFY(model->flags(model->index(fileName)) & Qt::ItemIsEditable); } class CustomFileIconProvider : public QFileIconProvider @@ -729,6 +734,9 @@ void tst_QFileSystemModel::sortPersistentIndex() { QTemporaryFile file(flatDirTestPath + QStringLiteral("/XXXXXX.dat")); QVERIFY2(file.open(), qPrintable(file.errorString())); + const QFileInfo fileInfo(file.fileName()); + file.close(); + QTRY_VERIFY(QDir(flatDirTestPath).entryInfoList().contains(fileInfo)); QModelIndex root = model->setRootPath(flatDirTestPath); QTRY_VERIFY(model->rowCount(root) > 0); -- cgit v1.2.3 From 37c9d6deca9e7f0812fc38cc9729d58cb2e9d7ed Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 11 Sep 2017 18:14:51 +0200 Subject: Condition QDateTimeParser's time-zone parsing on QT_CONFIG(timezone) It was missing some #if-ery it needed. Change-Id: Ibc12f4a9ee35acb64a39a1c7a15d2934b5710dc0 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 4 ++-- src/corelib/tools/qdatetimeparser.cpp | 41 ++++++++++++++++++++++++++--------- src/corelib/tools/qdatetimeparser_p.h | 5 ++++- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index f6fc672486..050f37dcd2 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2227,7 +2227,7 @@ static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) #endif // Q_OS_WIN } -#ifndef QT_BOOTSTRAPPED +#if QT_CONFIG(datetimeparser) && QT_CONFIG(timezone) /* \internal Implemented here to share qt_tzname() @@ -2245,7 +2245,7 @@ int QDateTimeParser::startsWithLocalTimeZone(const QStringRef name) } return 0; } -#endif // QT_BOOTSTRAPPED +#endif // datetimeparser && timezone // Calls the platform variant of mktime for the given date, time and daylightStatus, // and updates the date, time, daylightStatus and abbreviation with the returned values diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index dd277f7753..6860cd6ef0 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -195,9 +195,11 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const return false; // Preserve zone: - v = (tspec == Qt::TimeZone - ? QDateTime(newDate, newTime, v.timeZone()) - : QDateTime(newDate, newTime, tspec, offset)); + v = +#if QT_CONFIG(timezone) + tspec == Qt::TimeZone ? QDateTime(newDate, newTime, v.timeZone()) : +#endif + QDateTime(newDate, newTime, tspec, offset); return true; } @@ -213,7 +215,9 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const { const SectionNode &sn = sectionNode(s); switch (sn.type) { +#if QT_CONFIG(timezone) case TimeZoneSection: return QTimeZone::MaxUtcOffsetSecs; +#endif case Hour24Section: case Hour12Section: return 23; // this is special-cased in // parseSection. We want it to be @@ -248,7 +252,9 @@ int QDateTimeParser::absoluteMin(int s) const { const SectionNode &sn = sectionNode(s); switch (sn.type) { +#if QT_CONFIG(timezone) case TimeZoneSection: return QTimeZone::MinUtcOffsetSecs; +#endif case Hour24Section: case Hour12Section: case MinuteSection: @@ -766,9 +772,11 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, text->replace(offset, used, sectiontext.constData(), used); break; } case TimeZoneSection: +#if QT_CONFIG(timezone) result = findTimeZone(sectionTextRef, currentValue, absoluteMax(sectionIndex), absoluteMin(sectionIndex)); +#endif break; case MonthSection: case DayOfWeekSectionShort: @@ -1090,17 +1098,21 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, int dayofweek = defaultDate.dayOfWeek(); Qt::TimeSpec tspec = defaultValue.timeSpec(); int zoneOffset = 0; // In seconds; local - UTC +#if QT_CONFIG(timezone) QTimeZone timeZone; +#endif switch (tspec) { case Qt::OffsetFromUTC: // timeZone is ignored zoneOffset = defaultValue.offsetFromUtc(); break; +#if QT_CONFIG(timezone) case Qt::TimeZone: timeZone = defaultValue.timeZone(); if (timeZone.isValid()) zoneOffset = timeZone.offsetFromUtc(defaultValue); // else: is there anything we can do about this ? break; +#endif default: // zoneOffset and timeZone are ignored break; } @@ -1125,9 +1137,11 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, { const QDate date = actualDate(isSet, year, year2digits, month, day, dayofweek); const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec); - sect = parseSection(tspec == Qt::TimeZone - ? QDateTime(date, time, timeZone) - : QDateTime(date, time, tspec, zoneOffset), + sect = parseSection( +#if QT_CONFIG(timezone) + tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) : +#endif + QDateTime(date, time, tspec, zoneOffset), index, pos, input); } @@ -1152,7 +1166,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, case TimeZoneSection: current = &zoneOffset; if (sect.used > 0) { - // Synchronize with what findTimeZone() found: +#if QT_CONFIG(timezone) // Synchronize with what findTimeZone() found: QStringRef zoneName = input->midRef(pos, sect.used); Q_ASSERT(!zoneName.isEmpty()); // sect.used > 0 const QByteArray latinZone(zoneName.toLatin1()); @@ -1162,6 +1176,9 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, ? Qt::TimeZone : Qt::OffsetFromUTC) : (Q_ASSERT(startsWithLocalTimeZone(zoneName)), Qt::LocalTime); +#else + tspec = Qt::LocalTime; +#endif } break; case Hour24Section: current = &hour; break; @@ -1319,9 +1336,11 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, const QDate date(year, month, day); const QTime time(hour, minute, second, msec); - return StateNode(tspec == Qt::TimeZone - ? QDateTime(date, time, timeZone) - : QDateTime(date, time, tspec, zoneOffset), + return StateNode( +#if QT_CONFIG(timezone) + tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) : +#endif + QDateTime(date, time, tspec, zoneOffset), state, padding, conflicts); } @@ -1569,6 +1588,7 @@ QDateTimeParser::ParsedSection QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when, int maxVal, int minVal) const { +#if QT_CONFIG(timezone) int index = startsWithLocalTimeZone(str); int offset; @@ -1607,6 +1627,7 @@ QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when, if (index > 0 && maxVal >= offset && offset >= minVal) return ParsedSection(Acceptable, offset, index); +#endif // timezone return ParsedSection(); } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 75497f5c5a..c3ae08da71 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -223,7 +223,10 @@ private: QString *dayName = 0, int *used = 0) const; ParsedSection findTimeZone(QStringRef str, const QDateTime &when, int maxVal, int minVal) const; - static int startsWithLocalTimeZone(const QStringRef name); // implemented in qdatetime.cpp +#if QT_CONFIG(timezone) + // Implemented in qdatetime.cpp: + static int startsWithLocalTimeZone(const QStringRef name); +#endif enum AmPmFinder { Neither = -1, -- cgit v1.2.3 From dc4b4e9949e49da31efa1fe0f2a5cbb15656292d Mon Sep 17 00:00:00 2001 From: Timo Aarnipuro Date: Thu, 21 Sep 2017 12:09:05 +0300 Subject: Build integrityhid support only if it is available Change-Id: I6e0aa2f74516d4c0a1905b188f195834d395584b Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/integrity/integrity.pro | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/integrity/integrity.pro b/src/plugins/platforms/integrity/integrity.pro index 0fb256793d..54438707eb 100644 --- a/src/plugins/platforms/integrity/integrity.pro +++ b/src/plugins/platforms/integrity/integrity.pro @@ -8,13 +8,18 @@ QT += \ SOURCES = \ main.cpp \ qintegrityfbintegration.cpp \ - qintegrityfbscreen.cpp \ - qintegrityhidmanager.cpp + qintegrityfbscreen.cpp HEADERS = \ qintegrityfbintegration.h \ - qintegrityfbscreen.h \ - qintegrityhidmanager.h + qintegrityfbscreen.h + +qtConfig(integrityhid) { + SOURCES += \ + qintegrityhidmanager.cpp + HEADERS += \ + qintegrityhidmanager.h +} OTHER_FILES += integrity.json -- cgit v1.2.3 From 50117d738af526cbfbd5afa50b9a501acb0fb9ce Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 30 Nov 2017 14:20:32 +0100 Subject: Android: use a canonical data dir for Qt environment variables ApplicationInfo.dataDir holds "/data/user/0" (Blackberry PRIV running Android 6.0.1), which is in fact a soft link to "/data/data". This directory is used as a prefix for various Qt environment variables, including QML2_IMPORT_PATH, which in turn is used for resolving QML type URIs, looking up Qt Quick Controls 2 styles, and so on. The QML engine is not happy with "/data/data" and "/data/user/0" being wildly mixed for QML types in the same module. Use the canonical path instead to avoid such conflicts. Change-Id: I1fd45736728ee662942d7ef48c3fbc553981c59b Task-number: QTBUG-64868 Reviewed-by: Lars Knoll --- src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java index 99c4ecca07..6e92e64028 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java @@ -569,7 +569,8 @@ public abstract class QtLoader { boolean bundlingQtLibs = false; if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { - localPrefix = m_context.getApplicationInfo().dataDir + "/"; + File dataDir = new File(m_context.getApplicationInfo().dataDir); + localPrefix = dataDir.getCanonicalPath() + "/"; pluginsPrefix = localPrefix + "qt-reserved-files/"; if (libsDir == null) -- cgit v1.2.3 From 8d75c6765d070367a1b48bd8982ba0a9948b97ea Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 27 Nov 2017 13:55:47 +0100 Subject: Doc: Complete Simple Anchor Layout Example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60635 Change-Id: I1351df7c514c57ed04ff6e640d7338d62c8f91ac Reviewed-by: Edward Welbourne Reviewed-by: Frederik Gladhorn Reviewed-by: Topi Reiniö --- .../images/graphicssimpleanchorlayout-example.png | Bin 16743 -> 11301 bytes .../doc/src/graphicsview-simpleanchorlayout.qdoc | 46 +++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/examples/widgets/doc/images/graphicssimpleanchorlayout-example.png b/examples/widgets/doc/images/graphicssimpleanchorlayout-example.png index 543670e05c..e4bed44edf 100644 Binary files a/examples/widgets/doc/images/graphicssimpleanchorlayout-example.png and b/examples/widgets/doc/images/graphicssimpleanchorlayout-example.png differ diff --git a/examples/widgets/doc/src/graphicsview-simpleanchorlayout.qdoc b/examples/widgets/doc/src/graphicsview-simpleanchorlayout.qdoc index 866dac442b..fd0427fdc0 100644 --- a/examples/widgets/doc/src/graphicsview-simpleanchorlayout.qdoc +++ b/examples/widgets/doc/src/graphicsview-simpleanchorlayout.qdoc @@ -35,4 +35,50 @@ QGraphicsAnchorLayout class. \image graphicssimpleanchorlayout-example.png + + The example starts by creating a QGraphicsScene (\c scene), 3 widgets + (\c a, \c b, and \c c), and a QGraphicsAnchorlayout (\c layout). + + \quotefromfile graphicsview/simpleanchorlayout/main.cpp + \skipto QGraphicsScene + \printuntil QGraphicsAnchorLayout + + First it anchors the top left corner of item \c a to the top left + corner of \c layout. This can be done in two steps: + + \skipto layout->addAnchor(a + \printto adding + + Or in one step: + + \skipuntil [adding a corner anchor] + \printline layout->addCornerAnchors(a, Qt::T + + Then the right anchor of \c a is anchored to the left anchor of + \c b, and the top of item \c b is anchored to the bottom of \c a. + + \skipuntil [adding anchors] + \printto adding anchors + + Place a third widget \c c under widget \c b: + + \skipuntil third widget + \printline AnchorBottom + + Items \c b and \c c are anchored to each other horizontally: + + \skipto Qt::Horizontal + \printline Qt::Horizontal + + Item c is anchored to the bottom right point of \c layout + + \skipuntil corner of the layout + \printline Qt::BottomRightCorner + + Finally, QGraphicsWidget \c w is displayed in QGraphicsView \c view. + + \skipto QGraphicsWidget + \printuntil app.exec() + + \sa {Anchor Layout Example} */ -- cgit v1.2.3 From dae308d8926ae8c6d8f8484cd7108ae395aa5933 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 08:52:42 +0100 Subject: qprintengine_win.cpp: Fix -Wclazy-range-loop qprintengine_win.cpp:1502: warning: Missing reference in range-for with non trivial type (QPrint::InputSlot) [-Wclazy-range-loop] Change-Id: If6e55c1748e05e32aaa32a16063ba491fe242952 Reviewed-by: Andy Shaw --- src/printsupport/kernel/qprintengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index e399118cc9..b479ecacb1 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -1499,7 +1499,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const QList out; const auto inputSlots = d->m_printDevice.supportedInputSlots(); out.reserve(inputSlots.size()); - for (const QPrint::InputSlot inputSlot : inputSlots) + for (const QPrint::InputSlot &inputSlot : inputSlots) out << QVariant(inputSlot.id == QPrint::CustomInputSlot ? inputSlot.windowsId : int(inputSlot.id)); value = out; break; -- cgit v1.2.3 From 109290753b59e554a70639a9764259a3c61fd58a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 15 Nov 2017 10:35:50 +0100 Subject: Android: Fix note for host architecture mismatch The qtConfAddNotice was a typo, so this note was missing from config.log and the build would fail with no explanation. Change-Id: Iae22f92c1ba6bdf96d41a7cc608b9aedd6863b1f Reviewed-by: Oswald Buddenhagen --- configure.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.pri b/configure.pri index 83c0dee141..dc703ecb14 100644 --- a/configure.pri +++ b/configure.pri @@ -557,7 +557,7 @@ defineTest(qtConfOutput_prepareOptions) { else: \ qtConfFatalError("Cannot detect the Android host." \ "Please use -android-ndk-host option to specify one.") - qtConfAddNotice("Available Android host does not match host architecture.") + qtConfAddNote("Available Android host does not match host architecture.") } } else { !exists($$ndk_tc_pfx/$$ndk_host/*): \ -- cgit v1.2.3 From 1a55c929332cacfc7e3934810fa1a4601f39846b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 24 Nov 2017 17:11:40 +0100 Subject: iOS: Compute screen available geometry based on safe area insets In addition to the (deprecated) applicationFrame property, we base the available geometry on the root view's safe area, which also takes into account system-reserved areas on iPhone X, and the screen's bezel in the case of tvOS. Change-Id: I252d960a0e486dd0c7e30843f88c0bf5684feb24 Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiosscreen.mm | 29 ++++++++++++++++++++++++----- src/plugins/platforms/ios/quiview.h | 1 + src/plugins/platforms/ios/quiview.mm | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 74e81dedf4..1a7004c249 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -175,6 +175,21 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) @end +@interface UIScreen (Compatibility) +@property (nonatomic, readonly) CGRect qt_applicationFrame; +@end + +@implementation UIScreen (Compatibility) +- (CGRect)qt_applicationFrame +{ +#ifdef Q_OS_IOS + return self.applicationFrame; +#else + return self.bounds; +#endif +} +@end + // ------------------------------------------------------------------------- QT_BEGIN_NAMESPACE @@ -271,11 +286,15 @@ void QIOSScreen::updateProperties() QRect previousAvailableGeometry = m_availableGeometry; m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect(); -#ifdef Q_OS_TVOS - m_availableGeometry = m_geometry; -#else - m_availableGeometry = QRectF::fromCGRect(m_uiScreen.applicationFrame).toRect(); -#endif + + // The application frame doesn't take safe area insets into account, and + // the safe area insets are not available before the UIWindow is shown, + // and do not take split-view constraints into account, so we have to + // combine the two to get the correct available geometry. + QRect applicationFrame = QRectF::fromCGRect(m_uiScreen.qt_applicationFrame).toRect(); + UIEdgeInsets safeAreaInsets = m_uiWindow.qt_safeAreaInsets; + m_availableGeometry = m_geometry.adjusted(safeAreaInsets.left, safeAreaInsets.top, + -safeAreaInsets.right, -safeAreaInsets.bottom).intersected(applicationFrame); #ifndef Q_OS_TVOS if (m_uiScreen == [UIScreen mainScreen]) { diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index 1500f0b41c..1ce9007a35 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -77,5 +77,6 @@ QT_END_NAMESPACE - (QWindow *)qwindow; - (UIViewController *)viewController; - (QIOSViewController*)qtViewController; +@property (nonatomic, readonly) UIEdgeInsets qt_safeAreaInsets; @end diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index a405fecee2..79f9d6871a 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -545,6 +545,22 @@ return nil; } +- (UIEdgeInsets)qt_safeAreaInsets +{ +#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA) + if (__builtin_available(iOS 11, tvOS 11, *)) + return self.safeAreaInsets; +#endif + + // Fallback for iOS < 11 + UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; + CGPoint topInset = [self convertPoint:CGPointMake(0, self.viewController.topLayoutGuide.length) fromView:nil]; + CGPoint bottomInset = [self convertPoint:CGPointMake(0, self.viewController.bottomLayoutGuide.length) fromView:nil]; + safeAreaInsets.top = topInset.y; + safeAreaInsets.bottom = bottomInset.y; + return safeAreaInsets; +} + @end #ifndef QT_NO_ACCESSIBILITY -- cgit v1.2.3 From d80fde62ed82493322463d2057a07b6b2ed81a83 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Wed, 22 Nov 2017 11:56:20 +0100 Subject: Fix broken QNAM::networkAccessible() When switching on/off multiple time the wifi (mainly, but not only) on ios/macos the QNAM may wrongly stay on a NotAccessible state while the configuration is Active. This change make sure the QNAM::networkAccessible() is correctly reporting the accessibility. Task-number: QTBUG-49751 Task-number: QTBUG-58275 Task-number: QTBUG-60366 Change-Id: I238ab32030fbaa8072cce341db8da6bcfc346035 Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccessmanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index fba5755b77..0ab3760eed 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1839,7 +1839,8 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession emit q->networkSessionConnected(); lastSessionState = state; - if (online && state == QNetworkSession::Disconnected) { + if (online && (state == QNetworkSession::Disconnected + || state == QNetworkSession::NotAvailable)) { const auto cfgs = networkConfigurationManager.allConfigurations(); for (const QNetworkConfiguration &cfg : cfgs) { if (cfg.state().testFlag(QNetworkConfiguration::Active)) { @@ -1881,9 +1882,9 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { if (online != isOnline) { + online = isOnline; _q_networkSessionClosed(); createSession(q->configuration()); - online = isOnline; } } if (online) { -- cgit v1.2.3 From 0f1b8fd2dcd2db698095a54ca9beff7e27cf1ceb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 27 Nov 2017 10:40:44 +0100 Subject: work around flex bug flex emits code using isatty(), but fails to include the required unistd.h. we can work around it by including the header ourselves. Task-number: QTBUG-64771 Change-Id: I05313eeb79f7a0e25365dee5f05a0142f87209ae Reviewed-by: Thiago Macieira --- src/tools/qlalr/examples/qparser/calc.l | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/qlalr/examples/qparser/calc.l b/src/tools/qlalr/examples/qparser/calc.l index e619e34dab..fe542680a8 100644 --- a/src/tools/qlalr/examples/qparser/calc.l +++ b/src/tools/qlalr/examples/qparser/calc.l @@ -33,6 +33,9 @@ #include "calc_parser.h" #include +// Work around flex bug +#include + #define YY_DECL int CalcParser::nextToken() %} -- cgit v1.2.3 From 6c75857c20972f0d65fc7d556b9dcd81e21060db Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 23 Nov 2017 13:30:54 +0100 Subject: configure: mention quoting requirements in the help text Change-Id: Id79548b8458dfa25fef17cb25688738bb719e7c5 Reviewed-by: Thiago Macieira --- config_help.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config_help.txt b/config_help.txt index 6b1401c618..003752dbe7 100644 --- a/config_help.txt +++ b/config_help.txt @@ -9,6 +9,12 @@ ICU_PREFIX=/opt/icu42 ICU_LIBS="-licui18n -licuuc -licudata". It is also possible to manipulate any QMAKE_* variable, to amend the values from the mkspec for the build of Qt itself, e.g., QMAKE_CXXFLAGS+=-g3. +Note that the *_LIBS* and QMAKE_* assignments manipulate lists, so items +containing meta characters (spaces in particular) need to be quoted according +to qmake rules. On top of that, the assignments as a whole need to be quoted +according to shell rules. It is recommended to use single quotes for the inner +quoting and double quotes for the outer quoting. + Top-level installation directories: -prefix ...... The deployment directory, as seen on the target device. [/usr/local/Qt-$QT_VERSION, $PWD if -developer-build] -- cgit v1.2.3 From 0fbf78250eafc345c2b7925b1dc27056565242b6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 23 Nov 2017 18:07:33 +0100 Subject: configure: fix processing of *_LIBS_{DEBUG|RELEASE}= args qtConfLibrary_inline() used to set $${1}.builds.$${b}.libs, while everything else assumed no such .libs suffix. fix the former. amends 9172143f52. Task-number: QTBUG-61431 Started-by: Konstantin Ritt Change-Id: I0bd81591c46266d81baa9c12315411183bbc7a63 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 1ba96767be..a4ed3f0a72 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -513,8 +513,8 @@ defineTest(qtConfLibrary_inline) { iv = $${input}.libs.$${b} vars += $$eval(config.commandline.rev_assignments.$${iv}) defined(config.input.$${iv}, var) { - $${1}.builds.$${b}.libs = $$eval(config.input.$${iv}) - export($${1}.builds.$${b}.libs) + $${1}.builds.$${b} = $$eval(config.input.$${iv}) + export($${1}.builds.$${b}) any = true } else { all = false -- cgit v1.2.3 From 79a068c3964db79979821bb9e9bad6eb7ab6211c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 23 Nov 2017 18:05:53 +0100 Subject: configure: fix over-quoting in library exporting unlike for the other fields, we forgot to eval() the values of the build-specific library values, leading to over-quoting of values which require any quoting at all. amends c0cc50520. Task-number: QTBUG-62521 Change-Id: I4dfce31040dd09248d3f9dd4294f7fb147c13bdd Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index a4ed3f0a72..658bd59e5e 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -670,9 +670,10 @@ defineTest(qtConfExportLibrary) { NAME = $$upper($$name) # LIBS is emitted even if empty, as this allows the library to be "seen". qtConfOutputVar(assign, $$output, QMAKE_LIBS_$$NAME, $$libs) - for (b, $${spfx}.builds._KEYS_): \ - qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), \ - $$eval($${spfx}.builds.$${b})) + for (b, $${spfx}.builds._KEYS_) { + eval(blibs = $$eval($${spfx}.builds.$${b})) + qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), $$blibs) + } !isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines) !isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes) !isEmpty($${currentConfig}.module): \ -- cgit v1.2.3 From 26e9a6a5149aca056418ad55402231191a48cdbf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 23 Nov 2017 19:19:36 +0100 Subject: configure: make *_LIBS_{DEBUG|RELEASE} always work ... and not only when the source explicitly specifies build variants. Change-Id: Iac6c8fda8f431d5fb50fada8338d1b660ab040d7 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 12 ++++++++---- src/network/configure.json | 8 -------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 658bd59e5e..ecd9233ddd 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -509,20 +509,24 @@ defineTest(qtConfLibrary_inline) { vars = any = false all = true - for (b, $${1}.builds._KEYS_) { + for (b, $$list(debug release)) { iv = $${input}.libs.$${b} vars += $$eval(config.commandline.rev_assignments.$${iv}) defined(config.input.$${iv}, var) { $${1}.builds.$${b} = $$eval(config.input.$${iv}) export($${1}.builds.$${b}) + $${1}.builds._KEYS_ *= $${b} any = true } else { all = false } } - $$any:!$$all { - qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.") - return(false) + $$any { + !$$all { + qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.") + return(false) + } + export($${1}.builds._KEYS_) } # prefix. prepends to (possibly overwritten) inline libs. diff --git a/src/network/configure.json b/src/network/configure.json index 916448a727..2cf90ed94b 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -69,18 +69,10 @@ { "comment": "placeholder for OPENSSL_{PATH,LIBS{,_{DEBUG,RELEASE}}}", "libs": "", - "builds": { - "debug": "", - "release": "" - }, "condition": "config.win32 && !features.shared" }, { "libs": "-lssleay32 -llibeay32", - "builds": { - "debug": "", - "release": "" - }, "condition": "config.win32 && features.shared" }, { "libs": "-lssl -lcrypto", "condition": "!config.win32" } -- cgit v1.2.3 From 8dfcc3b0239ffb8af7254280b0fa51770fd4e75b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 23 Nov 2017 19:33:39 +0100 Subject: configure: reset *_LIBS when *_LIBS_{DEBUG|RELEASE} are specified it could be somewhat surprising that specifying variant-specific libs would not clear the common libs, so do that. of course, the default for the common libs could theoretically contain common deps of the variant-specific libs, in which case clearing them would be surprising in turn - luckily, we have no such case. Change-Id: Ifca08b9e1949c6a0cefed6931ade4021927d7c90 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index ecd9233ddd..dcd87a7a1a 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -499,12 +499,6 @@ defineTest(qtConfLibrary_inline) { # to make them recognize the same input variables. input = $$eval($${2}.alias) - # direct libs. overwrites inline libs. - defined(config.input.$${input}.libs, var) { - $${1}.libs = $$eval(config.input.$${input}.libs) - export($${1}.libs) - } - # build-specific direct libs. overwrites inline libs. vars = any = false @@ -527,6 +521,15 @@ defineTest(qtConfLibrary_inline) { return(false) } export($${1}.builds._KEYS_) + # we also reset the generic libs, to avoid surprises. + $${1}.libs = + export($${1}.libs) + } + + # direct libs. overwrites inline libs. + defined(config.input.$${input}.libs, var) { + $${1}.libs = $$eval(config.input.$${input}.libs) + export($${1}.libs) } # prefix. prepends to (possibly overwritten) inline libs. -- cgit v1.2.3 From 40192995a59fda01bb76fd4181863fae5e0cf8f7 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 10 Oct 2017 10:16:59 +0200 Subject: PrintSupport: convert 0 with nullptr (c++11) Change-Id: I35a8022c78427c9b4d4a9d9941770d22c36c3be8 Reviewed-by: David Faure --- src/printsupport/dialogs/qabstractprintdialog.cpp | 2 +- src/printsupport/dialogs/qabstractprintdialog.h | 4 ++-- src/printsupport/dialogs/qabstractprintdialog_p.h | 2 +- src/printsupport/dialogs/qpagesetupdialog.h | 4 ++-- src/printsupport/dialogs/qpagesetupdialog_p.h | 2 +- src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 4 ++-- src/printsupport/dialogs/qpagesetupdialog_unix_p.h | 4 ++-- src/printsupport/dialogs/qprintdialog.h | 4 ++-- src/printsupport/dialogs/qprintdialog_unix.cpp | 6 +++--- src/printsupport/dialogs/qprintpreviewdialog.cpp | 2 +- src/printsupport/dialogs/qprintpreviewdialog.h | 4 ++-- src/printsupport/kernel/qpaintengine_preview.cpp | 8 ++++---- src/printsupport/kernel/qplatformprintersupport.cpp | 4 ++-- src/printsupport/kernel/qplatformprintplugin.cpp | 4 ++-- src/printsupport/kernel/qprintengine_pdf.cpp | 2 +- src/printsupport/kernel/qprinter.cpp | 2 +- src/printsupport/widgets/qcupsjobwidget_p.h | 2 +- src/printsupport/widgets/qprintpreviewwidget.cpp | 4 ++-- src/printsupport/widgets/qprintpreviewwidget.h | 4 ++-- 19 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp index f982da46d9..71b5500bab 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.cpp +++ b/src/printsupport/dialogs/qabstractprintdialog.cpp @@ -471,7 +471,7 @@ void QPrintDialog::done(int result) if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(accepted(QPrinter*)), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); - d->receiverToDisconnectOnClose = 0; + d->receiverToDisconnectOnClose = nullptr; } d->memberToDisconnectOnClose.clear(); } diff --git a/src/printsupport/dialogs/qabstractprintdialog.h b/src/printsupport/dialogs/qabstractprintdialog.h index eb4dc3eb99..3cc89890fc 100644 --- a/src/printsupport/dialogs/qabstractprintdialog.h +++ b/src/printsupport/dialogs/qabstractprintdialog.h @@ -81,7 +81,7 @@ public: Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption) Q_FLAG(PrintDialogOptions) - explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); + explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = nullptr); ~QAbstractPrintDialog(); int exec() override = 0; @@ -108,7 +108,7 @@ public: QPrinter *printer() const; protected: - QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = Q_NULLPTR); + QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = nullptr); private: Q_DISABLE_COPY(QAbstractPrintDialog) diff --git a/src/printsupport/dialogs/qabstractprintdialog_p.h b/src/printsupport/dialogs/qabstractprintdialog_p.h index 2537fcbf80..a17a28f564 100644 --- a/src/printsupport/dialogs/qabstractprintdialog_p.h +++ b/src/printsupport/dialogs/qabstractprintdialog_p.h @@ -69,7 +69,7 @@ class QAbstractPrintDialogPrivate : public QDialogPrivate public: QAbstractPrintDialogPrivate() - : printer(0), pd(0), ownsPrinter(false) + : printer(nullptr), pd(nullptr), ownsPrinter(false) , options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange | QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize), minPage(0), maxPage(INT_MAX) diff --git a/src/printsupport/dialogs/qpagesetupdialog.h b/src/printsupport/dialogs/qpagesetupdialog.h index 3bd752a413..70517dc844 100644 --- a/src/printsupport/dialogs/qpagesetupdialog.h +++ b/src/printsupport/dialogs/qpagesetupdialog.h @@ -57,8 +57,8 @@ class Q_PRINTSUPPORT_EXPORT QPageSetupDialog : public QDialog Q_DECLARE_PRIVATE(QPageSetupDialog) public: - explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); - explicit QPageSetupDialog(QWidget *parent = Q_NULLPTR); + explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = nullptr); + explicit QPageSetupDialog(QWidget *parent = nullptr); ~QPageSetupDialog(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) diff --git a/src/printsupport/dialogs/qpagesetupdialog_p.h b/src/printsupport/dialogs/qpagesetupdialog_p.h index 6a389b039a..a2b3f8363c 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_p.h @@ -71,7 +71,7 @@ class QPageSetupDialogPrivate : public QDialogPrivate Q_DECLARE_PUBLIC(QPageSetupDialog) public: - QPageSetupDialogPrivate(QPrinter *printer); + explicit QPageSetupDialogPrivate(QPrinter *printer); void setPrinter(QPrinter *newPrinter); diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index b048ba8b29..0715dfa548 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -230,8 +230,8 @@ void QUnixPageSetupDialogPrivate::init() QPageSetupWidget::QPageSetupWidget(QWidget *parent) : QWidget(parent), - m_pagePreview(0), - m_printer(0), + m_pagePreview(nullptr), + m_printer(nullptr), m_outputFormat(QPrinter::PdfFormat), m_units(QPageLayout::Point), m_blockSignals(false) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h index 658f103bea..4322b34690 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h +++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h @@ -69,8 +69,8 @@ class QPagePreview; class QPageSetupWidget : public QWidget { Q_OBJECT public: - explicit QPageSetupWidget(QWidget *parent = 0); - explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = 0); + explicit QPageSetupWidget(QWidget *parent = nullptr); + explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = nullptr); void setPrinter(QPrinter *printer); void selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName); diff --git a/src/printsupport/dialogs/qprintdialog.h b/src/printsupport/dialogs/qprintdialog.h index 5b81440a3c..bbddc296e9 100644 --- a/src/printsupport/dialogs/qprintdialog.h +++ b/src/printsupport/dialogs/qprintdialog.h @@ -59,8 +59,8 @@ class Q_PRINTSUPPORT_EXPORT QPrintDialog : public QAbstractPrintDialog Q_PROPERTY(PrintDialogOptions options READ options WRITE setOptions) public: - explicit QPrintDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR); - explicit QPrintDialog(QWidget *parent = Q_NULLPTR); + explicit QPrintDialog(QPrinter *printer, QWidget *parent = nullptr); + explicit QPrintDialog(QWidget *parent = nullptr); ~QPrintDialog(); int exec() Q_DECL_OVERRIDE; diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index a5f381d0a2..817049ad67 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -608,7 +608,7 @@ QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent) Constructs a print dialog with the given \a parent. */ QPrintDialog::QPrintDialog(QWidget *parent) - : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent) + : QAbstractPrintDialog(*(new QPrintDialogPrivate), nullptr, parent) { Q_D(QPrintDialog); d->init(); @@ -656,7 +656,7 @@ void QPrintDialog::accept() /*! \internal */ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn) - : parent(p), propertiesDialog(0), printer(prn), optionsPane(0), + : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0), filePrintersAdded(false), propertiesDialogShown(false) { q = 0; @@ -788,7 +788,7 @@ void QUnixPrintWidgetPrivate::_q_btnBrowseClicked() QString filename = widget.filename->text(); #if QT_CONFIG(filedialog) filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename, - QString(), 0, QFileDialog::DontConfirmOverwrite); + QString(), nullptr, QFileDialog::DontConfirmOverwrite); #else filename.clear(); #endif diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index 174cfe4dba..af7d499eab 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -79,7 +79,7 @@ class QPrintPreviewMainWindow : public QMainWindow { public: QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {} - QMenu *createPopupMenu() Q_DECL_OVERRIDE { return 0; } + QMenu *createPopupMenu() Q_DECL_OVERRIDE { return nullptr; } }; class ZoomFactorValidator : public QDoubleValidator diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h index 3b8f8a1171..bacafcb734 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.h +++ b/src/printsupport/dialogs/qprintpreviewdialog.h @@ -58,8 +58,8 @@ class Q_PRINTSUPPORT_EXPORT QPrintPreviewDialog : public QDialog Q_DECLARE_PRIVATE(QPrintPreviewDialog) public: - explicit QPrintPreviewDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); - explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = Q_NULLPTR, + explicit QPrintPreviewDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewDialog(); diff --git a/src/printsupport/kernel/qpaintengine_preview.cpp b/src/printsupport/kernel/qpaintengine_preview.cpp index 4c00333097..7179249677 100644 --- a/src/printsupport/kernel/qpaintengine_preview.cpp +++ b/src/printsupport/kernel/qpaintengine_preview.cpp @@ -69,8 +69,8 @@ QPreviewPaintEngine::QPreviewPaintEngine() : QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients)) { Q_D(QPreviewPaintEngine); - d->proxy_print_engine = 0; - d->proxy_paint_engine = 0; + d->proxy_print_engine = nullptr; + d->proxy_paint_engine = nullptr; } QPreviewPaintEngine::~QPreviewPaintEngine() @@ -102,8 +102,8 @@ bool QPreviewPaintEngine::end() Q_D(QPreviewPaintEngine); delete d->painter; - d->painter = 0; - d->engine = 0; + d->painter = nullptr; + d->engine = nullptr; d->state = QPrinter::Idle; return true; } diff --git a/src/printsupport/kernel/qplatformprintersupport.cpp b/src/printsupport/kernel/qplatformprintersupport.cpp index 388dd5ff8e..e12a292aec 100644 --- a/src/printsupport/kernel/qplatformprintersupport.cpp +++ b/src/printsupport/kernel/qplatformprintersupport.cpp @@ -70,12 +70,12 @@ QPlatformPrinterSupport::~QPlatformPrinterSupport() QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode, const QString &) { - return 0; + return nullptr; } QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode) { - return 0; + return nullptr; } QPrintDevice QPlatformPrinterSupport::createPrintDevice(QPlatformPrintDevice *device) diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp index a80f369040..9a7656f7d6 100644 --- a/src/printsupport/kernel/qplatformprintplugin.cpp +++ b/src/printsupport/kernel/qplatformprintplugin.cpp @@ -60,12 +60,12 @@ QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin() { } -static QPlatformPrinterSupport *printerSupport = 0; +static QPlatformPrinterSupport *printerSupport = nullptr; static void cleanupPrinterSupport() { delete printerSupport; - printerSupport = 0; + printerSupport = nullptr; } /*! diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp index 080ff7ccf4..873e146eec 100644 --- a/src/printsupport/kernel/qprintengine_pdf.cpp +++ b/src/printsupport/kernel/qprintengine_pdf.cpp @@ -381,7 +381,7 @@ void QPdfPrintEnginePrivate::closePrintDevice() #endif fd = -1; delete outDevice; - outDevice = 0; + outDevice = nullptr; } } diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 3135836ce7..d439fcbbbc 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -132,7 +132,7 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI { // Default to PdfFormat outputFormat = QPrinter::PdfFormat; - QPlatformPrinterSupport *ps = 0; + QPlatformPrinterSupport *ps = nullptr; QString printerName; // Only set NativeFormat if we have a valid plugin and printer to use diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index 7d3c15938f..d66a472509 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -71,7 +71,7 @@ class QCupsJobWidget : public QWidget Q_OBJECT public: - explicit QCupsJobWidget(QWidget *parent = 0); + explicit QCupsJobWidget(QWidget *parent = nullptr); ~QCupsJobWidget(); void setPrinter(QPrinter *printer); void setupPrinter(); diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp index 9e44603bb8..dc07517397 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.cpp +++ b/src/printsupport/widgets/qprintpreviewwidget.cpp @@ -145,7 +145,7 @@ class GraphicsView : public QGraphicsView { Q_OBJECT public: - GraphicsView(QWidget* parent = 0) + GraphicsView(QWidget* parent = nullptr) : QGraphicsView(parent) { #ifdef Q_OS_MAC @@ -179,7 +179,7 @@ class QPrintPreviewWidgetPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QPrintPreviewWidget) public: QPrintPreviewWidgetPrivate() - : scene(0), curPage(1), + : scene(nullptr), curPage(1), viewMode(QPrintPreviewWidget::SinglePageView), zoomMode(QPrintPreviewWidget::FitInView), zoomFactor(1), initialized(false), fitting(true) diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h index 8735d06072..d45cc1a9fb 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.h +++ b/src/printsupport/widgets/qprintpreviewwidget.h @@ -69,9 +69,9 @@ public: FitInView }; - explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = Q_NULLPTR, + explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); - explicit QPrintPreviewWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QPrintPreviewWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); ~QPrintPreviewWidget(); qreal zoomFactor() const; -- cgit v1.2.3 From 6a3f41aa4622194977b1ae5bc45f4806193c6871 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 10 Oct 2017 10:28:53 +0200 Subject: Printsupport: not necessary to check pointer before to delete it Change-Id: Ib2a7823224c45b6e9110016b2f5756e1b2fd8f3c Reviewed-by: David Faure --- src/printsupport/dialogs/qprintdialog_unix.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 817049ad67..a0c8f54a9c 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -895,8 +895,7 @@ bool QUnixPrintWidgetPrivate::checkFields() void QUnixPrintWidgetPrivate::setupPrinterProperties() { - if (propertiesDialog) - delete propertiesDialog; + delete propertiesDialog; propertiesDialog = new QPrintPropertiesDialog(q); propertiesDialog->setResult(QDialog::Rejected); -- cgit v1.2.3 From 0fe3ff5c517e6dfae26600d79d07e92b1ab86843 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 10 Oct 2017 11:02:12 +0200 Subject: PrintSupport: modernize connection signal/slot Change-Id: I6e482cd9503e96cc43ead21122d3690cdb18151c Reviewed-by: David Faure --- src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 22 +++++++++++----------- src/printsupport/dialogs/qprintdialog_unix.cpp | 4 ++-- src/printsupport/dialogs/qprintpreviewdialog.cpp | 2 +- src/printsupport/widgets/qcupsjobwidget.cpp | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 0715dfa548..ee7bc62491 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -260,21 +260,21 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent) initUnits(); initPagesPerSheet(); - connect(m_ui.unitCombo, SIGNAL(activated(int)), this, SLOT(unitChanged())); + connect(m_ui.unitCombo, QOverload::of(&QComboBox::activated), this, &QPageSetupWidget::unitChanged); - connect(m_ui.pageSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pageSizeChanged())); - connect(m_ui.pageWidth, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged())); - connect(m_ui.pageHeight, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged())); + connect(m_ui.pageSizeCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pageSizeChanged); + connect(m_ui.pageWidth, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged); + connect(m_ui.pageHeight, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged); - connect(m_ui.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(leftMarginChanged(double))); - connect(m_ui.topMargin, SIGNAL(valueChanged(double)), this, SLOT(topMarginChanged(double))); - connect(m_ui.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(rightMarginChanged(double))); - connect(m_ui.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(bottomMarginChanged(double))); + connect(m_ui.leftMargin, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::leftMarginChanged); + connect(m_ui.topMargin, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::topMarginChanged); + connect(m_ui.rightMargin, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::rightMarginChanged); + connect(m_ui.bottomMargin, QOverload::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::bottomMarginChanged); - connect(m_ui.portrait, SIGNAL(clicked()), this, SLOT(pageOrientationChanged())); - connect(m_ui.landscape, SIGNAL(clicked()), this, SLOT(pageOrientationChanged())); + connect(m_ui.portrait, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged); + connect(m_ui.landscape, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged); - connect(m_ui.pagesPerSheetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pagesPerSheetChanged())); + connect(m_ui.pagesPerSheetCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pagesPerSheetChanged); } // Init the Units combo box diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index a0c8f54a9c..3b53e664c6 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -251,8 +251,8 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent) lay->addWidget(content); lay->addWidget(m_buttons); - connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); - connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QPrintPropertiesDialog::accept); + connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QPrintPropertiesDialog::reject); #if QT_CONFIG(cupsjobwidget) m_jobOptions = new QCupsJobWidget(); diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index af7d499eab..906cb19043 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -119,7 +119,7 @@ public: : QLineEdit(parent) { setContextMenuPolicy(Qt::NoContextMenu); - connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed())); + connect(this, &LineEdit::returnPressed, this, &LineEdit::handleReturnPressed); } protected: diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp index 00f2d64df2..39acac020c 100644 --- a/src/printsupport/widgets/qcupsjobwidget.cpp +++ b/src/printsupport/widgets/qcupsjobwidget.cpp @@ -104,7 +104,7 @@ void QCupsJobWidget::initJobHold() m_ui.jobHoldComboBox->addItem(tr("Weekend (Saturday to Sunday)"), QVariant::fromValue(QCUPSSupport::Weekend)); m_ui.jobHoldComboBox->addItem(tr("Specific Time"), QVariant::fromValue(QCUPSSupport::SpecificTime)); - connect(m_ui.jobHoldComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleJobHoldTime())); + connect(m_ui.jobHoldComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &QCupsJobWidget::toggleJobHoldTime); setJobHold(QCUPSSupport::NoHold, QTime()); toggleJobHoldTime(); -- cgit v1.2.3 From 155f954d9941e9eee14d86ee7bc30411aea60dee Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 08:49:35 +0100 Subject: Fix -Wclazy-connect-not-normalized in Windows code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qwindowsxpstyle.cpp(289,35): warning: Signature is not normalized. Use void* instead of void * [-Wclazy-connect-not-normalized] qwindowsxpstyle.cpp(292,35): warning: Signature is not normalized. Use void* instead of void * [-Wclazy-connect-not-normalized] Change-Id: I773530452c0837c5066f9174c25ae37e57086e76 Reviewed-by: Sérgio Martins --- src/plugins/styles/windowsvista/qwindowsxpstyle.cpp | 4 ++-- src/widgets/dialogs/qwizard_win.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 0a47ccf68a..4c982c14f4 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -286,10 +286,10 @@ static inline HWND createTreeViewHelperWindow() void *hwnd = 0; void *wndProc = reinterpret_cast(DefWindowProc); if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, - Q_RETURN_ARG(void *, hwnd), + Q_RETURN_ARG(void*, hwnd), Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")), Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")), - Q_ARG(void *, wndProc)) && hwnd) { + Q_ARG(void*, wndProc)) && hwnd) { return reinterpret_cast(hwnd); } } diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 666b192e9c..bedcd1b0c2 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -263,7 +263,7 @@ static bool getCaptionQFont(int dpi, QFont *result) QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection, Q_RETURN_ARG(QFont, *result), - Q_ARG(const void *, &logFont), + Q_ARG(const void*, &logFont), Q_ARG(int, dpi)); } -- cgit v1.2.3 From 1f1f3a2b889d9192fdb4b53428309ef720cec8ca Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 08:43:30 +0100 Subject: Fix -Wclazy-qstring-arg in Windows code plugin\qlibrary_win.cpp(119,55): warning: Use multi-arg instead [-Wclazy-qstring-arg] plugin\qlibrary_win.cpp(155,55): warning: Use multi-arg instead [-Wclazy-qstring-arg] plugin\qlibrary_win.cpp(168,55): warning: Use multi-arg instead [-Wclazy-qstring-arg] socket\qlocalserver_win.cpp(228,61): warning: Use multi-arg instead [-Wclazy-qstring-arg] Change-Id: I0feadd3a5cce5ac2ba09630a38b867981d48a391 Reviewed-by: Oswald Buddenhagen --- src/corelib/plugin/qlibrary_win.cpp | 7 +++---- src/network/socket/qlocalserver_win.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp index a4d3f67c27..9368e53b3f 100644 --- a/src/corelib/plugin/qlibrary_win.cpp +++ b/src/corelib/plugin/qlibrary_win.cpp @@ -116,7 +116,7 @@ bool QLibraryPrivate::load_sys() #endif if (!pHnd) { errorString = QLibrary::tr("Cannot load library %1: %2").arg( - QDir::toNativeSeparators(fileName)).arg(qt_error_string()); + QDir::toNativeSeparators(fileName), qt_error_string()); } else { // Query the actual name of the library that was loaded errorString.clear(); @@ -152,7 +152,7 @@ bool QLibraryPrivate::unload_sys() { if (!FreeLibrary(pHnd)) { errorString = QLibrary::tr("Cannot unload library %1: %2").arg( - QDir::toNativeSeparators(fileName)).arg(qt_error_string()); + QDir::toNativeSeparators(fileName), qt_error_string()); return false; } errorString.clear(); @@ -164,8 +164,7 @@ QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol) FARPROC address = GetProcAddress(pHnd, symbol); if (!address) { errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg( - QString::fromLatin1(symbol)).arg( - QDir::toNativeSeparators(fileName)).arg(qt_error_string()); + QString::fromLatin1(symbol), QDir::toNativeSeparators(fileName), qt_error_string()); } else { errorString.clear(); } diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 8cb3449343..ced923ced1 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -225,7 +225,7 @@ bool QLocalServerPrivate::addListener() void QLocalServerPrivate::setError(const QString &function) { int windowsError = GetLastError(); - errorString = QString::fromLatin1("%1: %2").arg(function).arg(qt_error_string(windowsError)); + errorString = QString::fromLatin1("%1: %2").arg(function, qt_error_string(windowsError)); error = QAbstractSocket::UnknownSocketError; } -- cgit v1.2.3 From 673762b02e4d112198501e91ab487b04a1ed3a39 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 09:58:13 +0100 Subject: qwindowsmime.cpp: Fix clazy -Wclazy-container-anti-pattern qwindowsmime.cpp(1267,10): warning: allocating an unneeded temporary container [-Wclazy-container-anti-pattern] qwindowsmime.cpp(1274,14): warning: allocating an unneeded temporary container [-Wclazy-container-anti-pattern] qwindowsmime.cpp(1383,10): warning: allocating an unneeded temporary container [-Wclazy-container-anti-pattern] qwindowsmime.cpp(1429,16): warning: allocating an unneeded temporary container [-Wclazy-container-anti-pattern] qwindowsmime.cpp(1450,20): warning: allocating an unneeded temporary container [-Wclazy-container-anti-pattern] Change-Id: I9188a0478b4be0c5c8f064578bbe027e33b67b89 Reviewed-by: Andre de la Rocha Reviewed-by: Miguel Costa Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsmime.cpp | 46 ++++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index b892f1610d..34e6041687 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -52,6 +52,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -1264,15 +1265,16 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData QVector QBuiltInMimes::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const { QVector formatetcs; - if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType)) - formatetcs += setCf(outFormats.key(mimeType)); + const auto mit = std::find(outFormats.cbegin(), outFormats.cend(), mimeType); + if (mit != outFormats.cend() && mimeData->formats().contains(mimeType)) + formatetcs += setCf(mit.key()); return formatetcs; } bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { - return (!inFormats.keys(mimeType).isEmpty()) - && canGetData(inFormats.key(mimeType), pDataObj); + const auto mit = std::find(inFormats.cbegin(), inFormats.cend(), mimeType); + return mit != inFormats.cend() && canGetData(mit.key(), pDataObj); } QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const @@ -1315,7 +1317,7 @@ public: QString mimeForFormat(const FORMATETC &formatetc) const override; private: - QMap formats; + mutable QMap formats; static QStringList ianaTypes; static QStringList excludeList; }; @@ -1380,15 +1382,13 @@ bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeDa QVector QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const { QVector formatetcs; - if (!formats.keys(mimeType).isEmpty()) { - formatetcs += setCf(formats.key(mimeType)); - } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){ - // register any other available formats - int cf = QWindowsMime::registerMimeType(mimeType); - QLastResortMimes *that = const_cast(this); - that->formats.insert(cf, mimeType); - formatetcs += setCf(cf); - } + auto mit = std::find(formats.begin(), formats.end(), mimeType); + // register any other available formats + if (mit == formats.end() && !excludeList.contains(mimeType, Qt::CaseInsensitive)) + mit = formats.insert(QWindowsMime::registerMimeType(mimeType), mimeType); + if (mit != formats.end()) + formatetcs += setCf(mit.key()); + if (!formatetcs.isEmpty()) qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs; return formatetcs; @@ -1426,14 +1426,11 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD QString clipFormat = customMimeType(mimeType); const UINT cf = RegisterClipboardFormat(reinterpret_cast (clipFormat.utf16())); return canGetData(int(cf), pDataObj); - } else if (formats.keys(mimeType).isEmpty()) { - // if it is not in there then register it and see if we can get it - int cf = QWindowsMime::registerMimeType(mimeType); - return canGetData(cf, pDataObj); - } else { - return canGetData(formats.key(mimeType), pDataObj); } - return false; + // if it is not in there then register it and see if we can get it + const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType); + const int cf = mit != formats.cend() ? mit.key() : QWindowsMime::registerMimeType(mimeType); + return canGetData(cf, pDataObj); } QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const @@ -1447,11 +1444,10 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p QString clipFormat = customMimeType(mimeType, &lindex); const UINT cf = RegisterClipboardFormat(reinterpret_cast (clipFormat.utf16())); data = getData(int(cf), pDataObj, lindex); - } else if (formats.keys(mimeType).isEmpty()) { - int cf = QWindowsMime::registerMimeType(mimeType); - data = getData(cf, pDataObj); } else { - data = getData(formats.key(mimeType), pDataObj); + const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType); + const int cf = mit != formats.cend() ? mit.key() : QWindowsMime::registerMimeType(mimeType); + data = getData(cf, pDataObj); } if (!data.isEmpty()) val = data; // it should be enough to return the data and let QMimeData do the rest. -- cgit v1.2.3 From 153311706cd21d91ba06a7f86228dd575bd9672e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 30 Nov 2017 15:00:26 +0100 Subject: macOS/iOS: Fix garbled text under some conditions There seems to be an issue in CoreText which may cause an existing font descriptor to give unreliable results if it refers to one of the system theme fonts. Since we do not know all function calls or events that may trigger this bug, the safe route is to always create fresh font descriptors when creating fonts for these descriptors. The impact on performance should be small, as Qt has its own internal caches. [ChangeLog][macOS/iOS][Text] Fixed an issue where text using one of the system theme fonts would under certain circumstances display random glyphs. Task-number: QTBUG-63476 Change-Id: I9e9b253018c63976345eec1439a6b78de2cab869 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 24 ++++++++++++++-------- .../fontdatabases/mac/qcoretextfontdatabase_p.h | 4 +++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 6347d4d231..237e8a89a5 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -416,7 +416,19 @@ extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef); template <> QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QFontDef &fontDef, void *usrPtr) { - CTFontDescriptorRef descriptor = static_cast(usrPtr); + QCFType descriptor = QCFType::constructFromGet( + static_cast(usrPtr)); + + // CoreText will sometimes invalidate information in font descriptors that refer + // to system fonts in certain function calls or application states. While the descriptor + // looks the same from the outside, some internal plumbing is different, causing the results + // of creating CTFonts from those descriptors unreliable. The work-around for this + // is to copy the attributes of those descriptors each time we make a new CTFont + // from them instead of referring to the original, as that may trigger the CoreText bug. + if (m_systemFontDescriptors.contains(descriptor)) { + QCFType attributes = CTFontDescriptorCopyAttributes(descriptor); + descriptor = CTFontDescriptorCreateWithAttributes(attributes); + } // Since we do not pass in the destination DPI to CoreText when making // the font, we need to pass in a point size which is scaled to include @@ -427,14 +439,10 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine qreal scaledPointSize = fontDef.pixelSize; CGAffineTransform matrix = qt_transform_from_fontdef(fontDef); - CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix); - if (font) { - QFontEngine *engine = new QCoreTextFontEngine(font, fontDef); - CFRelease(font); - return engine; - } + if (QCFType font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix)) + return new QCoreTextFontEngine(font, fontDef); - return NULL; + return nullptr; } #ifndef QT_NO_FREETYPE diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 9612b909f1..e14d1d6e6e 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -91,12 +91,14 @@ public: QFont *themeFont(QPlatformTheme::Font) const; const QHash &themeFonts() const; +protected: + mutable QSet m_systemFontDescriptors; + private: void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString()); mutable QString defaultFontName; - mutable QSet m_systemFontDescriptors; mutable QHash m_themeFonts; bool m_hasPopulatedAliases; }; -- cgit v1.2.3 From 0ebf0cfb6f2e21ceef4f95b54a4a02abd7214dc1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Nov 2017 08:54:03 +0100 Subject: Blacklist tst_QSplitter::replaceWidget(visible, not collapsed) for Linux The test is flaky on Linux. Task-number: QTBUG-64639 Change-Id: Iec56ebce4f656f52187b34c8f655b137e41c3d17 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Gabriel de Dietrich --- tests/auto/widgets/widgets/qsplitter/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/widgets/widgets/qsplitter/BLACKLIST diff --git a/tests/auto/widgets/widgets/qsplitter/BLACKLIST b/tests/auto/widgets/widgets/qsplitter/BLACKLIST new file mode 100644 index 0000000000..1352805cd7 --- /dev/null +++ b/tests/auto/widgets/widgets/qsplitter/BLACKLIST @@ -0,0 +1,2 @@ +[replaceWidget:visible, not collapsed] +xcb -- cgit v1.2.3 From bfef7d12249717555f6d81b54f748d9df10974e9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 23 Nov 2017 09:48:43 +0100 Subject: tests/auto/auto.pro: Use correct null device for DBUS check A mysterious file c:\dev\null appeared when running the auto tests on Windows. Fix by using QMAKE_SYSTEM_NULL_DEVICE. Amends 5f3529be32df3cce81e77c3dbb76cfda7feb320c. Change-Id: I0224a9ccd61c4f10b2ddb8f8d690e1849aa88d8a Reviewed-by: Oswald Buddenhagen --- tests/auto/auto.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index a1ffe5b3ce..fbd89e4045 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -35,7 +35,7 @@ else:!qtConfig(process): SUBDIRS -= tools # Disable the QtDBus tests if we can't connect to the session bus !cross_compile:qtHaveModule(dbus) { - !system("dbus-send --session --type=signal / local.AutotestCheck.Hello >/dev/null 2>&1") { + !system("dbus-send --session --type=signal / local.AutotestCheck.Hello >$$QMAKE_SYSTEM_NULL_DEVICE 2>&1") { qtConfig(dbus-linked): \ error("QtDBus is enabled but session bus is not available. Please check the installation.") else: \ -- cgit v1.2.3 From 6d09db53f7b5161d865f0fe8f832aa3757d66f74 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Oct 2017 09:13:32 +0100 Subject: macOS: Blacklist tst_QPauseAnimation::noTimerUpdates() Task-number: QTBUG-64107 Change-Id: Ie77d2d2525e79fb7e17f1a69d15ef40982f9242d Reviewed-by: Jesus Fernandez --- tests/auto/corelib/animation/qpauseanimation/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST index 8fc1b07502..a49ed2a617 100644 --- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST +++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST @@ -4,3 +4,5 @@ osx-10.9 * [multipleSequentialGroups] osx +[noTimerUpdates] +osx -- cgit v1.2.3 From 92cd3bfa2ebe133651b3d9f4e0c3394bbe79ba6a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Oct 2017 09:14:27 +0100 Subject: macOS: Blacklist: tst_QPropertyAnimation::startWithoutStartValue() Task-number: QTBUG-64108 Change-Id: Id60a9a1bfede9cbe90f378d131a331d726acfdae Reviewed-by: Jesus Fernandez --- tests/auto/corelib/animation/qpropertyanimation/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST index a7e95b1e97..a8719b241a 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST +++ b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST @@ -2,3 +2,5 @@ windows [startBackwardWithoutEndValue] windows +[startWithoutStartValue] +osx -- cgit v1.2.3 From f4498db196c19208236e97ddae448e0ec1a4be04 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Wed, 15 Nov 2017 13:57:22 +0200 Subject: Add configure test for INTEGRITY EGLFS openWFD integration plugin Change-Id: I846f9e555df4f64097b5634707515d45c13a521c Reviewed-by: Laszlo Agocs Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 18 +++++++++++++++++- .../eglfs/deviceintegration/deviceintegration.pro | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 0664cb92c6..9710ee4e20 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -705,6 +705,17 @@ }, "use": "egl" }, + "egl-openwfd": { + "label": "OpenWFD EGL", + "type": "compile", + "test": { + "include": [ "wfd.h" ], + "main": [ + "wfdEnumerateDevices(nullptr, 0, nullptr);" + ] + }, + "use": "egl" + }, "evdev": { "label": "evdev", "type": "compile", @@ -1088,6 +1099,11 @@ "condition": "features.eglfs_viv && libs.wayland_server", "output": [ "privateFeature" ] }, + "eglfs_openwfd": { + "label": "EGLFS OpenWFD", + "condition": "config.integrity && features.eglfs && tests.egl-openwfd", + "output": [ "privateFeature" ] + }, "gif": { "label": "GIF", "condition": "features.imageformatplugin", @@ -1560,7 +1576,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "EGLFS details", "condition": "features.eglfs", "entries": [ - "eglfs_viv", "eglfs_viv_wl", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11" + "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11" ] }, "linuxfb", "vnc", "mirclient", diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 6d759938b5..2cddbe9beb 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -8,7 +8,7 @@ qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm qtConfig(eglfs_mali): SUBDIRS += eglfs_mali qtConfig(eglfs_viv): SUBDIRS += eglfs_viv qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl - +qtConfig(eglfs_openwfd): SUBDIRS += eglfs_openwfd qtConfig(opengl): SUBDIRS += eglfs_emu eglfs_kms_egldevice.depends = eglfs_kms_support -- cgit v1.2.3 From 7b73d455ee8e6e2bca8bd29ac3cd40e4a89eb511 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Wed, 15 Nov 2017 13:23:42 +0200 Subject: Add mkspec for INTEGRITY Qualcomm s820 MSM8996AU Change-Id: Ia3983594d9295ae858efe2289c296cfcc2fe1b78 Reviewed-by: Rolland Dudemaine Reviewed-by: Andy Nichols --- .../devices/integrity-armv8-msm8996au/qmake.conf | 57 ++++++++++++++++++++++ .../integrity-armv8-msm8996au/qplatformdefs.h | 45 +++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 mkspecs/devices/integrity-armv8-msm8996au/qmake.conf create mode 100644 mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h diff --git a/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf b/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf new file mode 100644 index 0000000000..90299bf3e9 --- /dev/null +++ b/mkspecs/devices/integrity-armv8-msm8996au/qmake.conf @@ -0,0 +1,57 @@ +# +# qmake configuration for INTEGRITY Qualcomm s820 Snapdragon MSM8996AU +# + +load(device_config) + +include(../../common/ghs-integrity-armv8.conf) + +QT_QPA_DEFAULT_PLATFORM = eglfs +EGLFS_DEVICE_INTEGRATION = eglfs_openwfd + +bsp_name = $$(INTEGRITY_BSP) +isEmpty(bsp_name): \ + error("This qmakespec requires $INTEGRITY_BSP to be set") + +os_directory = $$(INTEGRITY_DIR) +isEmpty(os_directory): \ + error("This qmakespec requires $INTEGRITY_DIR to be set") + +qclibs_directory = $$(QCLIBS_DIR) +isEmpty(qclibs_directory): \ + error("This qmakespec requires $QCLIBS_DIR to be set") + +qc_multimedia_inc_directory = $$(QC_MULTIMEDIA_INC_DIR) +isEmpty(qc_multimedia_inc_directory): \ + error("This qmakespec requires $QC_MULTIMEDIA_INC_DIR to be set") + +gl_inc_directory = $$(GL_INC_DIR) +isEmpty(gl_inc_directory): \ + error("This qmakespec requires $GL_INC_DIR to be set") + +gl_lib_directory = $$(GL_LIB_DIR) +isEmpty(gl_lib_directory): \ + error("This qmakespec requires $GL_LIB_DIR to be set") + +QMAKE_LIBDIR += $$(QCLIBS_DIR)/base +QMAKE_LIBDIR += $$(QCLIBS_DIR)/multimedia/display + +QMAKE_INCDIR += $$(QC_MULTIMEDIA_INC_DIR) + +QMAKE_LIBS_EGL += -lESXEGL_Adreno -lESXGLESv2_Adreno -ladreno_utils -lGSLUser -lOSUser -lpanel -livfs -lposix -lpmem -ltzbsp -lpaged_alloc -lglnext-llvm -lopenwfd +QMAKE_LIBS_OPENGL_ES2 += $${QMAKE_LIBS_EGL} + +QMAKE_CFLAGS += -DINTEGRITY +QMAKE_CXXFLAGS += -DINTEGRITY + +QMAKE_CFLAGS += -bigswitch +QMAKE_CXXFLAGS += -bigswitch +QMAKE_LFLAGS += -bigswitch + +# OpenGL libraries have a dependency on libEGL +QMAKE_INCDIR_EGL = $$(GL_INC_DIR) +QMAKE_LIBDIR_EGL = $$(GL_LIB_DIR) +QMAKE_INCDIR_OPENGL_ES2 = $$(GL_INC_DIR) +QMAKE_LIBDIR_OPENGL_ES2 = $$(GL_LIB_DIR) + +load(qt_config) diff --git a/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h b/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h new file mode 100644 index 0000000000..c8361113a0 --- /dev/null +++ b/mkspecs/devices/integrity-armv8-msm8996au/qplatformdefs.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +#include "../../common/integrity/qplatformdefs.h" + +#endif // QPLATFORMDEFS_H -- cgit v1.2.3 From de250dd22c698ae1eec4927c87314024c3523c70 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Wed, 15 Nov 2017 13:03:36 +0200 Subject: Add EGLFS integration plugin for Qualcomm msm8996au board Change-Id: I5bed1fd690daa72492e7ec5f24e80198a2592986 Reviewed-by: Janne Koskinen Reviewed-by: Laszlo Agocs --- .../eglfs_openwfd/eglfs_openwfd.json | 3 + .../eglfs_openwfd/eglfs_openwfd.pro | 17 ++ .../eglfs_openwfd/qeglfsopenwfdintegration.cpp | 223 +++++++++++++++++++++ .../eglfs_openwfd/qeglfsopenwfdintegration.h | 69 +++++++ .../eglfs_openwfd/qeglfsopenwfdmain.cpp | 58 ++++++ 5 files changed, 370 insertions(+) create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json new file mode 100644 index 0000000000..cf7cf6b887 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_openwfd" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro new file mode 100644 index 0000000000..448b4cbe21 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/eglfs_openwfd.pro @@ -0,0 +1,17 @@ +TARGET = qeglfs-openwfd-integration + +QT += core-private gui-private eglfsdeviceintegration-private + +INCLUDEPATH += $$PWD/../../api +CONFIG += egl + +SOURCES += $$PWD/qeglfsopenwfdmain.cpp \ + $$PWD/qeglfsopenwfdintegration.cpp + +HEADERS += $$PWD/qeglfsopenwfdintegration.h + +OTHER_FILES += $$PWD/eglfs_openwfd.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSOpenWFDIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp new file mode 100644 index 0000000000..bb176a69d2 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#include "qeglfsopenwfdintegration.h" + +#include "wfd.h" +#include "wfdext2.h" + +QT_BEGIN_NAMESPACE + +#define MAX_NUM_OF_WFD_BUFFERS 3 +#define MAX_NUM_OF_WFD_DEVICES 4 +#define MAX_NUM_OF_WFD_PIPELINES 4 +#define MAX_NUM_OF_WFD_PORT_MODES 64 +#define MAX_NUM_OF_WFD_PORTS 4 + +typedef struct wfd_buffer { + WFD_EGLImageType* image; + WFDSource source; +} wfd_buffer_t; + +typedef struct wfd_window { + WFDDevice dev; + WFDPort port; + WFDPipeline pipeline; + int numBuffers; + wfd_buffer_t buffers[MAX_NUM_OF_WFD_BUFFERS]; +} wfd_window_t; + +void QEglFSOpenWFDIntegration::platformInit() +{ + QEglFSDeviceIntegration::platformInit(); + + mNativeDisplay = EGL_DEFAULT_DISPLAY; + + // Get device list + WFDint numDevs = wfdEnumerateDevices(nullptr, 0, nullptr); + WFDint devIds[MAX_NUM_OF_WFD_DEVICES]; + + if (numDevs > 0) + wfdEnumerateDevices(devIds, numDevs, nullptr); + + // Create device + mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID, nullptr); + + if (WFD_INVALID_HANDLE == mDevice) + qFatal( "Failed to create wfd device"); + + // Get port list + WFDint portIds[MAX_NUM_OF_WFD_PORTS]; + WFDint numPorts = wfdEnumeratePorts(mDevice, nullptr, 0, nullptr); + wfdEnumeratePorts(mDevice, portIds, numPorts, nullptr); + + // Create port + mPort = wfdCreatePort(mDevice, portIds[0], nullptr); + + if (WFD_INVALID_HANDLE == mPort) + qFatal("Failed to create wfd port"); + + // Get port modes + WFDint numPortModes = wfdGetPortModes(mDevice, mPort, nullptr, 0); + WFDPortMode portModes[MAX_NUM_OF_WFD_PORT_MODES]; + wfdGetPortModes(mDevice, mPort, portModes, numPortModes); + + // Get width and height + mScreenSize.setWidth(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_WIDTH)); + mScreenSize.setHeight(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_HEIGHT)); + + // Set port mode + wfdSetPortMode(mDevice, mPort, portModes[0]); + WFDErrorCode eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to set wfd port mode"); + + // Power on + wfdSetPortAttribi(mDevice, mPort, WFD_PORT_POWER_MODE, WFD_POWER_MODE_ON); + eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to power on wfd port"); +} + +QSize QEglFSOpenWFDIntegration::screenSize() const +{ + return mScreenSize; +} + +EGLNativeDisplayType QEglFSOpenWFDIntegration::platformDisplay() const +{ + return mNativeDisplay; +} + +EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow *window, + const QSize &size, + const QSurfaceFormat &format) +{ + Q_UNUSED(window); + Q_UNUSED(format); + + // Get list of pipelines + WFDint numPipelines = wfdEnumeratePipelines(mDevice, nullptr, 0, nullptr); + + WFDint pipelineIds[MAX_NUM_OF_WFD_PIPELINES]; + wfdEnumeratePipelines(mDevice, pipelineIds, numPipelines, nullptr); + + WFDint testId = 0; + testId = pipelineIds[0]; + WFDPipeline pipeline = wfdCreatePipeline(mDevice, testId, nullptr); + if (WFD_INVALID_HANDLE == pipeline) + qFatal("Failed to create wfd pipeline"); + + wfdSetPipelineAttribi(mDevice, pipeline, WFD_PIPELINE_TRANSPARENCY_ENABLE, + (WFD_TRANSPARENCY_SOURCE_ALPHA|WFD_TRANSPARENCY_GLOBAL_ALPHA)); + + WFDErrorCode eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to set WFD_PIPELINE_TRANSPARENCY_ENABLE"); + + wfdSetPipelineAttribi(mDevice, pipeline, WFD_PIPELINE_GLOBAL_ALPHA, 255); + eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to set WFD_PIPELINE_GLOBAL_ALPHA"); + + wfdBindPipelineToPort(mDevice, mPort, pipeline); + eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to bind port to pipeline"); + + // Create buffers + WFDSource source[MAX_NUM_OF_WFD_BUFFERS] = {WFD_INVALID_HANDLE, WFD_INVALID_HANDLE, + WFD_INVALID_HANDLE}; + WFDEGLImage eglImageHandles[MAX_NUM_OF_WFD_BUFFERS]; + WFD_EGLImageType* wfdEglImages[MAX_NUM_OF_WFD_BUFFERS]; + + for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) { + wfdCreateWFDEGLImages(mDevice, mScreenSize.width(), mScreenSize.height(), + WFD_FORMAT_RGBA8888, WFD_USAGE_OPENGL_ES2 | WFD_USAGE_DISPLAY, + 1, &(eglImageHandles[i]), 0); + + wfdEglImages[i] = (WFD_EGLImageType *)(eglImageHandles[i]); + if (WFD_INVALID_HANDLE == wfdEglImages[i]) + qFatal("Failed to create WDFEGLImages"); + + source[i] = wfdCreateSourceFromImage(mDevice, pipeline, eglImageHandles[i], nullptr); + if (WFD_INVALID_HANDLE == source[i]) + qFatal("Failed to create source from EGLImage"); + } + + // Commit port + wfdDeviceCommit(mDevice, WFD_COMMIT_ENTIRE_PORT, mPort); + eError = wfdGetError(mDevice); + if (WFD_ERROR_NONE != eError) + qFatal("Failed to commit port"); + + // Create native window + wfd_window_t* nativeWindow = (wfd_window_t*)malloc(sizeof(wfd_window_t)); + if (nullptr == nativeWindow) + qFatal("Failed to allocate memory for native window"); + + nativeWindow->dev = mDevice; + nativeWindow->port = mPort; + nativeWindow->pipeline = pipeline; + nativeWindow->numBuffers = MAX_NUM_OF_WFD_BUFFERS; + + for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) { + nativeWindow->buffers[i].image = wfdEglImages[i]; + nativeWindow->buffers[i].source = source[i]; + } + + return (EGLNativeWindowType)nativeWindow; +} + +QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const +{ + QSurfaceFormat format; + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + format.setAlphaBufferSize(8); + return format; +} + +void QEglFSOpenWFDIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + free((void*)window); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h new file mode 100644 index 0000000000..189ddd4d7a --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdintegration.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#ifndef QEGLFSOPENWFDINTEGRATION_H +#define QEGLFSOPENWFDINTEGRATION_H + +#include "private/qeglfsdeviceintegration_p.h" +#define WFD_WFDEXT_PROTOTYPES +#include "wfd.h" +#include "wfdext2.h" + +QT_BEGIN_NAMESPACE + +class QEglFSOpenWFDIntegration : public QEglFSDeviceIntegration +{ +public: + void platformInit() override; + QSize screenSize() const override; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override; + void destroyNativeWindow(EGLNativeWindowType window) override; + EGLNativeDisplayType platformDisplay() const override; + virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; + +private: + QSize mScreenSize; + EGLNativeDisplayType mNativeDisplay; + WFDDevice mDevice; + WFDPort mPort; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp new file mode 100644 index 0000000000..1d6132b55e --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_openwfd/qeglfsopenwfdmain.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#include "private/qeglfsdeviceintegration_p.h" +#include "qeglfsopenwfdintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSOpenWFDIntegrationPlugin : public QEglFSDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_openwfd.json") + +public: + QEglFSDeviceIntegration *create() override { + return new QEglFSOpenWFDIntegration; + } +}; + +QT_END_NAMESPACE + +#include "qeglfsopenwfdmain.moc" -- cgit v1.2.3 From 11a2e0aa2dd921e16cbc80479dd3667dc62ff18a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 25 Sep 2017 13:43:05 +0200 Subject: Cocoa: Ensure menus for a dialog's menubar are validated correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the items were enabled for a dialog's menubar they were not appearing as such because Cocoa will query the menu item's target to see if it has a worksWhenModal selector. Therefore to ensure that the menu item will be enabled, we need to add this selector to our delegate and return YES from it when the window for the menubar is the dialog. Task-number: QTBUG-44584 Change-Id: Ic62dc027d563069d2f5c2b7bf9810184bd76de39 Reviewed-by: Morten Johan Sørvig Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.mm | 12 ++++++++++++ src/plugins/platforms/cocoa/qcocoamenubar.h | 1 + src/plugins/platforms/cocoa/qcocoamenubar.mm | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index a54284dbae..1345295ef5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -253,6 +253,18 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return nil; } +// Cocoa will query the menu item's target for the worksWhenModal selector. +// So we need to implement this to allow the items to be handled correctly +// when a modal dialog is visible. +- (BOOL)worksWhenModal +{ + if (!QGuiApplication::modalWindow()) + return YES; + if (auto *mb = qobject_cast(m_menu->menuParent())) + return QGuiApplication::modalWindow()->handle() == mb->cocoaWindow() ? YES : NO; + return YES; +} + @end QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index a4ee531e91..a259147247 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -71,6 +71,7 @@ public: QList merged() const; NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r); + QCocoaWindow *cocoaWindow() const; void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index a4cd465dae..cf9553bcf7 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -452,5 +452,10 @@ NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r) return Q_NULLPTR; } +QCocoaWindow *QCocoaMenuBar::cocoaWindow() const +{ + return m_window.data(); +} + QT_END_NAMESPACE -- cgit v1.2.3 From fbda8acc922217745bb3e7754d1cd450a0e0165a Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 30 Nov 2017 15:08:48 +0300 Subject: QFutureWatcher: Use nullptr as a default value in constructor ... to make user code buildable with gcc [-Werror=zero-as-null-pointer-constant]. Change-Id: I309953acd7154511660302aa9826410276cfe41b Reviewed-by: Marc Mutz --- src/corelib/thread/qfuturewatcher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/thread/qfuturewatcher.h b/src/corelib/thread/qfuturewatcher.h index 3357e27037..8a6716a8f7 100644 --- a/src/corelib/thread/qfuturewatcher.h +++ b/src/corelib/thread/qfuturewatcher.h @@ -115,7 +115,7 @@ template class QFutureWatcher : public QFutureWatcherBase { public: - explicit QFutureWatcher(QObject *_parent = 0) + explicit QFutureWatcher(QObject *_parent = nullptr) : QFutureWatcherBase(_parent) { } ~QFutureWatcher() -- cgit v1.2.3 From 306c32f50e289c401e4636976c97dc2b40fdd69b Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 28 Nov 2017 11:44:11 +0100 Subject: Fix out of bounds reads in qdnslookup_unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the response from res_nquery is too big for the buffer used to receive it (of size PACKETSZ, a mere 512 bytes), the returned responseLength is the size of the data that would have been delivered, had there been enough space. Trying to process all of the data, including what wasn't delivered, leads to reading past the end of the buffer, which either causes a crash or leads to rubbish (from the stack) in the resulting QDnsRecords. Easy to reproduce using many long TXT records. Replace the array with a QVarLengthArray; when the response is big, resize() and retry, so as to actually get all of the data, so that we can process it all. A follow-up patch will fix the case when even the second call/resize buffer is not enough and we have to use TCP. Task-number: QTBUG-64742 Change-Id: I173beb531e11a3828fd9c97f437afc192766035e Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/kernel/qdnslookup_unix.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index 1da00813ce..ce1ec6442a 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -42,6 +42,7 @@ #if QT_CONFIG(library) #include #endif +#include #include #include #include @@ -58,6 +59,8 @@ # include #endif +#include + QT_BEGIN_NAMESPACE #if QT_CONFIG(library) @@ -137,7 +140,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN // Initialize state. struct __res_state state; - memset(&state, 0, sizeof(state)); + std::memset(&state, 0, sizeof(state)); if (local_res_ninit(&state) < 0) { reply->error = QDnsLookup::ResolverError; reply->errorString = tr("Resolver initialization failed"); @@ -189,11 +192,25 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN QScopedPointer state_ptr(&state); // Perform DNS query. - unsigned char response[PACKETSZ]; - memset(response, 0, sizeof(response)); - const int responseLength = local_res_nquery(&state, requestName, C_IN, requestType, response, sizeof(response)); + QVarLengthArray buffer(PACKETSZ); + std::memset(buffer.data(), 0, buffer.size()); + int responseLength = local_res_nquery(&state, requestName, C_IN, requestType, buffer.data(), buffer.size()); + if (Q_UNLIKELY(responseLength > PACKETSZ)) { + buffer.resize(responseLength); + std::memset(buffer.data(), 0, buffer.size()); + responseLength = local_res_nquery(&state, requestName, C_IN, requestType, buffer.data(), buffer.size()); + if (Q_UNLIKELY(responseLength > buffer.size())) { + // Ok, we give up. + reply->error = QDnsLookup::ResolverError; + reply->errorString.clear(); // We cannot be more specific, alas. + return; + } + } - // Check the response header. + unsigned char *response = buffer.data(); + // Check the response header. Though res_nquery returns -1 as a + // responseLength in case of error, we still can extract the + // exact error code from the response. HEADER *header = (HEADER*)response; const int answerCount = ntohs(header->ancount); switch (header->rcode) { -- cgit v1.2.3 From 22ec92a201beb9ec4bb6a7e21fcfdc8cd9b884f9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Nov 2017 17:36:58 +0100 Subject: QSettings/QConfFile: Fix reading on NTFS symbolic links The code checked on QFileInfo::size() whether the file had any content. The check failed for NTFS symbolic links since QFileInfo::size() returns 0 for them. Workaround by using QFile::size() instead. Task-number: QTBUG-64121 Change-Id: I303414b5a560d1ed8fbc53d969e53f9e2899ae5c Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index d0cbc82c56..bbc66120b5 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1451,7 +1451,7 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) Files that we can't read (because of permissions or because they don't exist) are treated as empty files. */ - if (file.isReadable() && fileInfo.size() != 0) { + if (file.isReadable() && file.size() != 0) { bool ok = false; #ifdef Q_OS_MAC if (format == QSettings::NativeFormat) { -- cgit v1.2.3 From 0c9e379dd8c57fab9d8e6ba8d35a0dca8ac05a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Fri, 1 Dec 2017 11:19:28 +0100 Subject: Use a custom QAnimationDriver to take control over time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should reduce flakyness of tests. Change-Id: I26e0a97f7cd3e7cee2ffb44188300c37578cddd7 Reviewed-by: Jędrzej Nowacki --- src/corelib/animation/qabstractanimation.cpp | 4 +- .../qpropertyanimation/qpropertyanimation.pro | 2 +- .../qpropertyanimation/tst_qpropertyanimation.cpp | 235 ++++++++++++++------- 3 files changed, 165 insertions(+), 76 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 2041b8816e..e445037efb 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -299,13 +299,13 @@ void QUnifiedTimer::stopAnimationDriver() driver->stop(); } -void QUnifiedTimer::updateAnimationTimers(qint64) +void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) { //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations if(insideTick) return; - qint64 totalElapsed = elapsed(); + qint64 totalElapsed = currentTick > 0 ? currentTick : elapsed(); // ignore consistentTiming in case the pause timer is active qint64 delta = (consistentTiming && !pauseTimer.isActive()) ? diff --git a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro b/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro index bfeb183abf..72a36876b7 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro +++ b/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qpropertyanimation -QT = core gui widgets testlib +QT = core gui widgets testlib core-private SOURCES = tst_qpropertyanimation.cpp diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp index cf4c4e1bdb..41a051a719 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,80 @@ public: MyObject o; }; +class TestAnimationDriver : public QAnimationDriver +{ +public: + TestAnimationDriver() + : QAnimationDriver() + , m_elapsed(0) + { + QUnifiedTimer::instance()->installAnimationDriver(this); + } + + ~TestAnimationDriver() + { + // This is to ensure that running animations are removed from the list of actual running + // animations. + QCoreApplication::sendPostedEvents(); + QUnifiedTimer::instance()->uninstallAnimationDriver(this); + } + + void wait(qint64 ms) + { + /* + * When QAbstractAnimation::start() is called it will end up calling + * QAnimationTimer::registerAnimation(). This will do + * + * QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection); // typeof(inst) == QAnimationTimer + * + * startAnimations() will again fire a queued connection to actually add the animation + * to the list of running animations: + * + * QMetaObject::invokeMethod(inst, "startTimers", Qt::QueuedConnection); // typeof(inst) == QUnifiedTimer + * + * We therefore have to call QCoreApplication::sendPostedEvents() twice here. + */ + QCoreApplication::sendPostedEvents(); + QCoreApplication::sendPostedEvents(); + + // Simulates the ideal animation update freqency (approx. 60Hz) + static const int interval = 1000/60; + qint64 until = m_elapsed + ms; + while (m_elapsed < until) { + advanceAnimation(m_elapsed); + m_elapsed += interval; + } + advanceAnimation(m_elapsed); + // This is to make sure that animations that were started with DeleteWhenStopped + // will actually delete themselves within the test function. + // Normally, they won't be deleted until the main event loop is processed. + // Therefore, have to explicitly say that we want to process DeferredDelete events. Same + // trick is used by QTest::qWait(). + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); + } + + qint64 elapsed() const override + { + return m_elapsed; + } + + void start() override + { + d_func()->running = true; + m_elapsed = 0; + emit started(); + } + + void stop() override + { + d_func()->running = false; + emit stopped(); + } + +private: + qint64 m_elapsed; + Q_DECLARE_PRIVATE(QAnimationDriver) +}; class tst_QPropertyAnimation : public QObject { @@ -261,40 +336,44 @@ void tst_QPropertyAnimation::statesAndSignals() QCOMPARE(currentLoopSpy.count(), 2); runningSpy.clear(); - anim->start(); - QTest::qWait(1000); - QTRY_COMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(runningSpy.count(), 2); //started and stopped again - runningSpy.clear(); - QCOMPARE(finishedSpy.count(), 1); - QCOMPARE(anim->currentLoopTime(), 100); - QCOMPARE(anim->currentLoop(), 2); - QCOMPARE(currentLoopSpy.count(), 4); - - anim->start(); // auto-rewinds - QCOMPARE(anim->state(), QAnimationGroup::Running); - QCOMPARE(anim->currentTime(), 0); - QCOMPARE(anim->currentLoop(), 0); - QCOMPARE(currentLoopSpy.count(), 5); - QCOMPARE(runningSpy.count(), 1); // anim has started - QCOMPARE(finishedSpy.count(), 1); - QCOMPARE(anim->currentLoop(), 0); - runningSpy.clear(); - - QTest::qWait(1000); - - QCOMPARE(currentLoopSpy.count(), 7); - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(anim->currentLoop(), 2); - QCOMPARE(runningSpy.count(), 1); // anim has stopped - QCOMPARE(finishedSpy.count(), 2); - QCOMPARE(anim->currentLoopTime(), 100); - - delete anim; + { + TestAnimationDriver timeDriver; + anim->start(); + timeDriver.wait(1000); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(runningSpy.count(), 2); //started and stopped again + runningSpy.clear(); + QCOMPARE(finishedSpy.count(), 1); + QCOMPARE(anim->currentLoopTime(), 100); + QCOMPARE(anim->currentLoop(), 2); + QCOMPARE(currentLoopSpy.count(), 4); + + anim->start(); // auto-rewinds + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(anim->currentTime(), 0); + QCOMPARE(anim->currentLoop(), 0); + QCOMPARE(currentLoopSpy.count(), 5); + QCOMPARE(runningSpy.count(), 1); // anim has started + QCOMPARE(finishedSpy.count(), 1); + QCOMPARE(anim->currentLoop(), 0); + runningSpy.clear(); + + timeDriver.wait(1000); + + QCOMPARE(currentLoopSpy.count(), 7); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(anim->currentLoop(), 2); + QCOMPARE(runningSpy.count(), 1); // anim has stopped + QCOMPARE(finishedSpy.count(), 2); + QCOMPARE(anim->currentLoopTime(), 100); + + delete anim; + } } void tst_QPropertyAnimation::deletion1() { + TestAnimationDriver timeDriver; QObject *object = new QWidget; QPointer anim = new QPropertyAnimation(object, "minimumWidth"); @@ -312,23 +391,23 @@ void tst_QPropertyAnimation::deletion1() QVERIFY(anim); QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(100); + timeDriver.wait(100); QVERIFY(anim); QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(150); + timeDriver.wait(150); QVERIFY(anim); //The animation should not have been deleted - QTRY_COMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); QCOMPARE(runningSpy.count(), 2); QCOMPARE(finishedSpy.count(), 1); anim->start(QVariantAnimation::DeleteWhenStopped); QVERIFY(anim); QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(100); + timeDriver.wait(100); QVERIFY(anim); QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(150); - QTRY_COMPARE(runningSpy.count(), 4); + timeDriver.wait(150); + QCOMPARE(runningSpy.count(), 4); QCOMPARE(finishedSpy.count(), 2); QVERIFY(!anim); //The animation must have been deleted delete object; @@ -336,6 +415,7 @@ void tst_QPropertyAnimation::deletion1() void tst_QPropertyAnimation::deletion2() { + TestAnimationDriver timeDriver; //test that the animation get deleted if the object is deleted QObject *object = new QWidget; QPointer anim = new QPropertyAnimation(object,"minimumWidth"); @@ -354,7 +434,7 @@ void tst_QPropertyAnimation::deletion2() anim->setDuration(200); anim->start(); - QTest::qWait(50); + timeDriver.wait(50); QVERIFY(anim); QCOMPARE(anim->state(), QAnimationGroup::Running); @@ -363,7 +443,7 @@ void tst_QPropertyAnimation::deletion2() //we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop QTimer::singleShot(0, object, SLOT(deleteLater())); - QTest::qWait(50); + timeDriver.wait(50); QVERIFY(!anim->targetObject()); } @@ -371,6 +451,7 @@ void tst_QPropertyAnimation::deletion2() void tst_QPropertyAnimation::deletion3() { //test that the stopped signal is emit when the animation is destroyed + TestAnimationDriver timeDriver; QObject *object = new QWidget; QPropertyAnimation *anim = new QPropertyAnimation(object,"minimumWidth"); anim->setStartValue(10); @@ -385,7 +466,7 @@ void tst_QPropertyAnimation::deletion3() anim->start(); - QTest::qWait(50); + timeDriver.wait(50); QCOMPARE(anim->state(), QAnimationGroup::Running); QCOMPARE(runningSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); @@ -432,6 +513,7 @@ public: void tst_QPropertyAnimation::noStartValue() { + TestAnimationDriver timeDriver; StartValueTester o; o.setProperty("ole", 42); o.values.clear(); @@ -441,7 +523,8 @@ void tst_QPropertyAnimation::noStartValue() a.setDuration(250); a.start(); - QTRY_COMPARE(o.values.value(o.values.size() - 1, -1), 420); + timeDriver.wait(a.duration()); + QCOMPARE(o.values.value(o.values.size() - 1, -1), 420); QCOMPARE(o.values.first(), 42); } @@ -471,6 +554,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() StartValueTester o; o.setProperty("ole", 42); o.values.clear(); + TestAnimationDriver timeDriver; { //normal case: the animation finishes and is deleted @@ -479,18 +563,17 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged); QVERIFY(runningSpy.isValid()); anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration() + 100); - QTRY_COMPARE(runningSpy.count(), 2); //started and then stopped + timeDriver.wait(anim->duration()); + QCOMPARE(runningSpy.count(), 2); //started and then stopped QVERIFY(!anim); } - { QPointer anim = new QPropertyAnimation(&o, "ole"); anim->setEndValue(100); QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged); QVERIFY(runningSpy.isValid()); anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration()/2); + timeDriver.wait(anim->duration()/2); QPointer anim2 = new QPropertyAnimation(&o, "ole"); anim2->setEndValue(100); QCOMPARE(runningSpy.count(), 1); @@ -498,11 +581,11 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() //anim2 will interrupt anim1 QMetaObject::invokeMethod(anim2, "start", Qt::QueuedConnection, Q_ARG(QAbstractAnimation::DeletionPolicy, QVariantAnimation::DeleteWhenStopped)); - QTest::qWait(50); + timeDriver.wait(50); QVERIFY(!anim); //anim should have been deleted QVERIFY(anim2); - QTest::qWait(anim2->duration()); - QTRY_VERIFY(!anim2); //anim2 is finished: it should have been deleted by now + timeDriver.wait(anim2->duration()); + QVERIFY(!anim2); //anim2 is finished: it should have been deleted by now QVERIFY(!anim); } @@ -559,6 +642,7 @@ void tst_QPropertyAnimation::easingcurve() void tst_QPropertyAnimation::startWithoutStartValue() { + TestAnimationDriver timeDriver; QObject o; o.setProperty("ole", 42); QCOMPARE(o.property("ole").toInt(), 42); @@ -568,14 +652,14 @@ void tst_QPropertyAnimation::startWithoutStartValue() anim.start(); - QTest::qWait(100); + timeDriver.wait(100); int current = anim.currentValue().toInt(); //it is somewhere in the animation QVERIFY(current > 42); QVERIFY(current < 100); - QTest::qWait(200); - QTRY_COMPARE(anim.state(), QVariantAnimation::Stopped); + timeDriver.wait(200); + QCOMPARE(anim.state(), QVariantAnimation::Stopped); current = anim.currentValue().toInt(); QCOMPARE(current, 100); QCOMPARE(o.property("ole").toInt(), current); @@ -586,7 +670,7 @@ void tst_QPropertyAnimation::startWithoutStartValue() // the default start value will reevaluate the current property // and set it to the end value of the last iteration QCOMPARE(current, 100); - QTest::qWait(100); + timeDriver.wait(100); current = anim.currentValue().toInt(); //it is somewhere in the animation QVERIFY(current >= 100); @@ -595,6 +679,7 @@ void tst_QPropertyAnimation::startWithoutStartValue() void tst_QPropertyAnimation::startBackwardWithoutEndValue() { + TestAnimationDriver timeDriver; QObject o; o.setProperty("ole", 42); QCOMPARE(o.property("ole").toInt(), 42); @@ -608,14 +693,14 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue() QCOMPARE(anim.state(), QAbstractAnimation::Running); QCOMPARE(o.property("ole").toInt(), 42); //the initial value - QTest::qWait(100); + timeDriver.wait(100); int current = anim.currentValue().toInt(); //it is somewhere in the animation QVERIFY(current > 42); QVERIFY(current < 100); - QTest::qWait(200); - QTRY_COMPARE(anim.state(), QVariantAnimation::Stopped); + timeDriver.wait(200); + QCOMPARE(anim.state(), QVariantAnimation::Stopped); current = anim.currentValue().toInt(); QCOMPARE(current, 100); QCOMPARE(o.property("ole").toInt(), current); @@ -626,7 +711,7 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue() // the default start value will reevaluate the current property // and set it to the end value of the last iteration QCOMPARE(current, 100); - QTest::qWait(100); + timeDriver.wait(100); current = anim.currentValue().toInt(); //it is somewhere in the animation QVERIFY(current >= 100); @@ -636,6 +721,7 @@ void tst_QPropertyAnimation::startBackwardWithoutEndValue() void tst_QPropertyAnimation::playForwardBackward() { + TestAnimationDriver timeDriver; QObject o; o.setProperty("ole", 0); QCOMPARE(o.property("ole").toInt(), 0); @@ -644,16 +730,16 @@ void tst_QPropertyAnimation::playForwardBackward() anim.setStartValue(0); anim.setEndValue(100); anim.start(); - QTest::qWait(anim.duration() + 100); - QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped); + timeDriver.wait(anim.duration()); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); //the animation is at the end anim.setDirection(QVariantAnimation::Backward); anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); - QTest::qWait(anim.duration() + 100); - QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped); + timeDriver.wait(anim.duration()); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); //the direction is backward @@ -661,8 +747,8 @@ void tst_QPropertyAnimation::playForwardBackward() anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); QCOMPARE(anim.currentTime(), anim.duration()); - QTest::qWait(anim.duration() + 100); - QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped); + timeDriver.wait(anim.duration()); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); } @@ -1106,21 +1192,21 @@ void tst_QPropertyAnimation::restart() void tst_QPropertyAnimation::valueChanged() { - + TestAnimationDriver timeDriver; //we check that we receive the valueChanged signal MyErrorObject o; o.setOle(0); QCOMPARE(o.property("ole").toInt(), 0); QPropertyAnimation anim(&o, "ole"); anim.setEndValue(5); - anim.setDuration(1000); + anim.setDuration(200); QSignalSpy spy(&anim, &QPropertyAnimation::valueChanged); QVERIFY(spy.isValid()); anim.start(); + // Drive animation forward to its end + timeDriver.wait(anim.duration()); - QTest::qWait(anim.duration() + 100); - - QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); //let's check that the values go forward @@ -1153,6 +1239,7 @@ public: void tst_QPropertyAnimation::twoAnimations() { + TestAnimationDriver timeDriver; MySyncObject o1, o2; o1.setOle(0); o2.setOle(0); @@ -1169,8 +1256,8 @@ void tst_QPropertyAnimation::twoAnimations() o1.anim.start(); o2.anim.start(); - QTest::qWait(o1.anim.duration() + 100); - QTRY_COMPARE(o1.anim.state(), QAbstractAnimation::Stopped); + timeDriver.wait(o1.anim.duration()); + QCOMPARE(o1.anim.state(), QAbstractAnimation::Stopped); QCOMPARE(o2.anim.state(), QAbstractAnimation::Stopped); QCOMPARE(o1.ole(), 1000); @@ -1209,6 +1296,7 @@ public: void tst_QPropertyAnimation::deletedInUpdateCurrentTime() { + TestAnimationDriver timeDriver; // this test case reproduces an animation being deleted in the updateCurrentTime of // another animation(was causing segfault). // the deleted animation must have been started after the animation that is deleting. @@ -1219,9 +1307,9 @@ void tst_QPropertyAnimation::deletedInUpdateCurrentTime() MyComposedAnimation composedAnimation(&o, "value", "realValue"); composedAnimation.start(); QCOMPARE(composedAnimation.state(), QAbstractAnimation::Running); - QTest::qWait(composedAnimation.duration() + 100); + timeDriver.wait(composedAnimation.duration()); - QTRY_COMPARE(composedAnimation.state(), QAbstractAnimation::Stopped); + QCOMPARE(composedAnimation.state(), QAbstractAnimation::Stopped); QCOMPARE(o.value(), 1000); } @@ -1293,6 +1381,7 @@ public: void tst_QPropertyAnimation::recursiveAnimations() { + TestAnimationDriver timeDriver; RecursiveObject o; QPropertyAnimation anim; anim.setTargetObject(&o); @@ -1301,9 +1390,9 @@ void tst_QPropertyAnimation::recursiveAnimations() anim.setEndValue(4000); anim.start(); - QTest::qWait(anim.duration() + o.animation.duration()); - QTRY_COMPARE(anim.state(), QAbstractAnimation::Stopped); - QTRY_COMPARE(o.animation.state(), QAbstractAnimation::Stopped); + timeDriver.wait(anim.duration() + o.animation.duration()); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(o.animation.state(), QAbstractAnimation::Stopped); QCOMPARE(o.y(), qreal(4000)); } -- cgit v1.2.3 From c9f68a5858f053aa5a0b1e8fd4c751ed441e0338 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Tue, 21 Nov 2017 14:38:15 +0100 Subject: QFusionStyle: fix the checkbox rendering in HiDPI situation 1. Make the checkbox's box size hidpi scale-able. Making the size not only anchored to icon size, but also the menuItem's rect height in empty or too small icon cases. 2. Make the checkmark's pen width in propotion to the box's size to keep consistent visual effects among different dpi settings 3. Also make the radio button hidpi scale-able. Task-number: QTBUG-63576 Change-Id: I4369aaa18ee68908a26a118cf04292ee4c3e9847 Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qfusionstyle.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 774eca1018..0b56c1e3a8 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -786,7 +786,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->drawRect(rect); QColor checkMarkColor = option->palette.text().color().darker(120); - const int checkMarkPadding = QStyleHelper::dpiScaled(3); + const int checkMarkPadding = 1 + rect.width() * 0.2; // at least one pixel padding if (checkbox->state & State_NoChange) { gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()); @@ -800,18 +800,20 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding)); } else if (checkbox->state & (State_On)) { - QPen checkPen = QPen(checkMarkColor, QStyleHelper::dpiScaled(1.8)); + qreal penWidth = QStyleHelper::dpiScaled(1.8); + penWidth = qMax(penWidth , 0.18 * rect.height()); + penWidth = qMin(penWidth , 0.30 * rect.height()); + QPen checkPen = QPen(checkMarkColor, penWidth); checkMarkColor.setAlpha(210); - painter->translate(-1, 0.5); + painter->translate(-0.8, 0.5); painter->setPen(checkPen); painter->setBrush(Qt::NoBrush); - painter->translate(0.2, 0.0); // Draw checkmark QPainterPath path; - path.moveTo(2 + checkMarkPadding, rect.height() / 2.0); + path.moveTo(1.33 * checkMarkPadding, rect.height() / 2.0); path.lineTo(rect.width() / 2.0, rect.height() - checkMarkPadding); - path.lineTo(rect.width() - checkMarkPadding - 0.5, checkMarkPadding); + path.lineTo(rect.width() - checkMarkPadding * 0.92, checkMarkPadding); painter->drawPath(path.translated(rect.topLeft())); } } @@ -1580,8 +1582,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio bool enabled = menuItem->state & State_Enabled; bool ignoreCheckMark = false; - int checkcol = qMax(menuItem->maxIconWidth, 20); - + const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1; + int checkcol = qMax(menuItem->rect.height() * 0.7, + qMax(menuItem->maxIconWidth * 1.0, dpiScaled(17))); // icon checkbox's highlihgt column width if ( #if QT_CONFIG(combobox) qobject_cast(widget) || @@ -1591,7 +1594,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio if (!ignoreCheckMark) { // Check - QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 14, 14); + const int boxMargin = dpiScaled(4); + const int boxWidth = checkcol - 2 * boxMargin; + QRect checkRect(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth); checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect); if (checkable) { if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) { @@ -1603,7 +1608,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QPalette::ColorRole textRole = !enabled ? QPalette::Text: selected ? QPalette::HighlightedText : QPalette::ButtonText; painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole)); - painter->drawEllipse(checkRect.adjusted(4, 4, -4, -4)); + const int adjustment = checkRect.height() * 0.3; + painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment)); } } else { // Check box @@ -1632,7 +1638,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QPainter *p = painter; QRect vCheckRect = visualRect(opt->direction, menuitem->rect, - QRect(menuitem->rect.x() + 4, menuitem->rect.y(), + QRect(menuitem->rect.x() + checkColHOffset, menuitem->rect.y(), checkcol, menuitem->rect.height())); if (!menuItem->icon.isNull()) { QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; @@ -1683,7 +1689,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio discol = menuitem->palette.text().color(); p->setPen(discol); } - int xm = windowsItemFrame + checkcol + windowsItemHMargin + 2; + int xm = checkColHOffset + checkcol + windowsItemHMargin; int xpos = menuitem->rect.x() + xm; QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); -- cgit v1.2.3 From 29104c85db53e7c0c0aaf3fe78f84b737fce4886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 17 Nov 2017 12:28:55 +0100 Subject: =?UTF-8?q?Cocoa:=20Disable=20=E2=80=9CHide=E2=80=9D=20menu=20item?= =?UTF-8?q?=20on=20open=20popups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow native behavior and disable ⌘H and the “Hide” menu item if there are any open popup windows. Task-number: QTBUG-58727 Change-Id: Iad38cc5cce29e0081613417c53b154ae0f05857e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 0d9bb5009d..b986833f6d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -43,6 +43,7 @@ #include "qcocoahelpers.h" #include "qcocoamenubar.h" #include "qcocoamenuitem.h" +#include "qcocoaintegration.h" #include #include @@ -343,10 +344,13 @@ - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { - if ([menuItem action] == @selector(hide:) - || [menuItem action] == @selector(hideOtherApplications:) + if ([menuItem action] == @selector(hideOtherApplications:) || [menuItem action] == @selector(unhideAllApplications:)) { return [NSApp validateMenuItem:menuItem]; + } else if ([menuItem action] == @selector(hide:)) { + if (QCocoaIntegration::instance()->activePopupWindow()) + return NO; + return [NSApp validateMenuItem:menuItem]; } else if ([menuItem tag]) { QCocoaMenuItem *cocoaItem = reinterpret_cast([menuItem tag]); return cocoaItem->isEnabled(); -- cgit v1.2.3 From bcd0e43eb98885f0562efddee45b11ca7ec1d546 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 4 Dec 2017 16:00:16 +0100 Subject: xcb: fix regression with missing XI_PropertyEvent Wacom stylus proximity detection had stopped working: it was not detecting which type of tool is in use, so all stylus types acted as a generic drawing stylus. Selecting XI_PropertyEvent on a root window fixes the problem. There is nothing in the XI2 specification that says that this property would not be supported on non-root windows. Possibly it is bug in the X server. Anyways, selecting XI_PropertyEvent on a root window in this case actually is better. Property event contains a global state information, there is nothing window specific in it, so there is no need to select it for every native sub-window. It is worth noting that XI_HierarchyChanged also seems to work only when selected on the root window (according to my testing results). And on XI2 author's blog post about XI_HierarchyChanged it says [1]: "These events are sent to all windows, so it doesn't really matter where you register. The traditional approach is to register on the root window." This kind of further confirms that it might be bug in X Server's implementation. [1] http://who-t.blogspot.no/2009/06/xi2-recipies-part-2.html Task-number: QTBUG-64911 Change-Id: I8582675bf835239932e23f4596966dc167495e30 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 30 ++++++++++++++---------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index f90f189146..ce6dd7c035 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -100,6 +100,7 @@ void QXcbConnection::xi2SelectStateEvents() XIEventMask xiEventMask; bitMask = XI_HierarchyChangedMask; bitMask |= XI_DeviceChangedMask; + bitMask |= XI_PropertyEventMask; xiEventMask.deviceid = XIAllDevices; xiEventMask.mask_len = sizeof(bitMask); xiEventMask.mask = xiBitMask; @@ -121,7 +122,6 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window) // core enter/leave events will be ignored in this case. bitMask |= XI_EnterMask; bitMask |= XI_LeaveMask; - bitMask |= XI_PropertyEventMask; #ifdef XCB_USE_XINPUT22 if (isAtLeastXI22()) { bitMask |= XI_TouchBeginMask; @@ -378,24 +378,25 @@ void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window) unsigned int mask = 0; unsigned char *bitMask = reinterpret_cast(&mask); - mask |= XI_PropertyEventMask; + Display *dpy = static_cast(m_xlib_display); + #ifdef XCB_USE_XINPUT22 if (isAtLeastXI22()) { mask |= XI_TouchBeginMask; mask |= XI_TouchUpdateMask; mask |= XI_TouchEndMask; + + XIEventMask xiMask; + xiMask.mask_len = sizeof(mask); + xiMask.mask = bitMask; + xiMask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(dpy, window, &xiMask, 1); + if (result == Success) + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + else + qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result); } #endif - XIEventMask xiMask; - xiMask.mask_len = sizeof(mask); - xiMask.mask = bitMask; - xiMask.deviceid = XIAllMasterDevices; - Display *dpy = static_cast(m_xlib_display); - Status result = XISelectEvents(dpy, window, &xiMask, 1); - if (result == Success) - QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); - else - qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result); mask = XI_ButtonPressMask; mask |= XI_ButtonReleaseMask; @@ -434,6 +435,11 @@ void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window) XISelectEvents(dpy, window, xiEventMask.data(), i); } #endif + +#if !QT_CONFIG(tabletevent) && !defined(XCB_USE_XINPUT21) + Q_UNUSED(bitMask); + Q_UNUSED(dpy); +#endif } QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id) -- cgit v1.2.3 From 2c6c044500a92a3a125ce4b5d936992bdf02a487 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 13:27:52 +0100 Subject: Fix qdoc warnings for 5.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/corelib/global/qrandom.cpp:915: warning: Cannot find 'bounded(...)' in '\fn' qreal QRandomGenerator::bounded(qreal highest) src/corelib/tools/qstring.cpp:774: warning: Command '\snippet (//! [qCompareStrings-QSV-QSV])' failed at end of file 'qstring/main.cpp' src/corelib/tools/qstring.cpp:5281: warning: Cannot find 'qTrimmed(...)' in '\fn' QStringView qTrimmed(QStringView s) src/corelib/tools/qstring.cpp:5281: warning: Cannot find 'qTrimmed(...)' in '\fn' QLatin1String qTrimmed(QLatin1String s) src/corelib/global/qrandom.h:171: warning: No documentation for 'QRandomGenerator::System' src/corelib/global/qrandom.h:105: warning: No documentation for 'QRandomGenerator::bounded(double highest)' src/corelib/global/qrandom.h:84: warning: No documentation for 'QRandomGenerator::generate64()' src/corelib/global/qrandom.h:77: warning: No documentation for 'QRandomGenerator::generate()' src/corelib/global/qrandom.cpp:799: warning: No such parameter 'sseq' in QRandomGenerator::seed() src/corelib/global/qrandom.cpp:1096: warning: Can't link to 'operator()()' src/corelib/tools/qstring.cpp:8982: warning: Can't link to 'qStartsWith()' src/corelib/tools/qstring.cpp:9203: warning: Can't link to 'qTrimmed()' src/corelib/tools/qstring.cpp:4798: warning: Can't link to 'qConvertToLatin1()' src/corelib/tools/qstring.cpp:4825: warning: Can't link to 'qConvertToLocal8Bit()' src/corelib/tools/qstring.cpp:4928: warning: Can't link to 'qConvertToUcs4()' src/corelib/tools/qstring.cpp:4884: warning: Can't link to 'qConvertToUtf8()' Change-Id: I5c7c89b230d3d1de8a679c10833319a470a44e80 Reviewed-by: Mårten Nordheim Reviewed-by: Thiago Macieira --- src/corelib/global/qrandom.cpp | 33 +++++++++++++++++++++++++++------ src/corelib/tools/qstring.cpp | 18 +++++++----------- src/corelib/tools/qstringview.cpp | 8 +++----- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 72ac8d332b..b6e8e03909 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -655,6 +655,11 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \sa QRandomGenerator64, qrand() */ +/*! + \enum QRandomGenerator::System + \internal +*/ + /*! \fn QRandomGenerator::QRandomGenerator(quint32 seedValue) @@ -694,7 +699,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel */ /*! - \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quin32 *end) + \fn QRandomGenerator::QRandomGenerator(const quint32 *begin, const quint32 *end) \overload Initializes this QRandomGenerator object with the values found in the range @@ -762,7 +767,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel A typedef to the type that operator()() returns. That is, quint32. - \sa operator()() + \sa {QRandomGenerator::operator()}{operator()()} */ /*! @@ -773,6 +778,22 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \sa generate(), generate64() */ +/*! + \fn quint32 QRandomGenerator::generate() + + Generates a 32-bit random quantity and returns it. + + \sa {QRandomGenerator::operator()}{operator()()}, generate64() + */ + +/*! + \fn quint64 QRandomGenerator::generate64() + + Generates a 64-bit random quantity and returns it. + + \sa {QRandomGenerator::operator()}{operator()()}, generate() + */ + /*! \fn result_type QRandomGenerator::min() @@ -800,7 +821,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \fn void QRandomGenerator::seed(std::seed_seq &seed) \overload - Reseeds this object using the seed sequence \a sseq as the seed. + Reseeds this object using the seed sequence \a seed as the seed. */ /*! @@ -913,9 +934,9 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel */ /*! - \fn qreal QRandomGenerator::bounded(qreal highest) + \fn double QRandomGenerator::bounded(double highest) - Generates one random qreal in the range between 0 (inclusive) and \a + Generates one random double in the range between 0 (inclusive) and \a highest (exclusive). This function is equivalent to and is implemented as: \code @@ -1098,7 +1119,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel A typedef to the type that operator()() returns. That is, quint64. - \sa operator()() + \sa {QRandomGenerator64::operator()}{operator()()} */ /*! diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c10987a5fe..c01052e152 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -769,8 +769,6 @@ static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSens Case-sensitive comparison is based exclusively on the numeric Unicode values of the characters and is very fast, but is not what a human would expect. Consider sorting user-visible strings with QString::localeAwareCompare(). - - \snippet qstring/main.cpp qCompareStrings-QSV-QSV */ int QtPrivate::compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW { @@ -4837,7 +4835,7 @@ static QByteArray qt_convert_to_local_8bit(QStringView string); locale, the returned byte array is undefined. Those characters may be suppressed or replaced by another. - \sa fromLocal8Bit(), toLatin1(), toUtf8(), QTextCodec, qConvertToLocal8Bit() + \sa fromLocal8Bit(), toLatin1(), toUtf8(), QTextCodec */ QByteArray QString::toLocal8Bit_helper(const QChar *data, int size) @@ -4871,8 +4869,7 @@ static QByteArray qt_convert_to_local_8bit(QStringView string) The behavior is undefined if \a string contains characters not supported by the locale's 8-bit encoding. - \sa QString::toLocal8Bit(), QStringView::toLocal8Bit(), QtPrivate::vonvertToLatin1(), - QtPrivate::convertToUtf8(), QtPrivate::convertToUcs4() + \sa QString::toLocal8Bit(), QStringView::toLocal8Bit() */ QByteArray QtPrivate::convertToLocal8Bit(QStringView string) { @@ -4915,8 +4912,7 @@ static QByteArray qt_convert_to_utf8(QStringView str) UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QStringView. - \sa QString::toUtf8(), QStringView::toUtf8(), QtPrivate::convertToLatin1(), - QtPrivate::convertToLocal8Bit(), QtPrivate::convertToUcs4() + \sa QString::toUtf8(), QStringView::toUtf8() */ QByteArray QtPrivate::convertToUtf8(QStringView string) { @@ -5279,8 +5275,8 @@ namespace { } /*! - \fn QStringView qTrimmed(QStringView s) - \fn QLatin1String qTrimmed(QLatin1String s) + \fn QStringView QtPrivate::trimmed(QStringView s) + \fn QLatin1String QtPrivate::trimmed(QLatin1String s) \internal \relates QStringView \since 5.10 @@ -8996,7 +8992,7 @@ QString &QString::setRawData(const QChar *unicode, int size) If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive; otherwise the search is case-insensitive. - \sa endsWith(), qStartsWith() + \sa endsWith() */ /*! @@ -9016,7 +9012,7 @@ QString &QString::setRawData(const QChar *unicode, int size) If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive; otherwise the search is case-insensitive. - \sa startsWith(), qEndsWith() + \sa startsWith() */ /*! diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp index 8eefc6d814..f510f44ce7 100644 --- a/src/corelib/tools/qstringview.cpp +++ b/src/corelib/tools/qstringview.cpp @@ -672,8 +672,6 @@ QT_BEGIN_NAMESPACE Whitespace means any character for which QChar::isSpace() returns \c true. This includes the ASCII characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '. - - \sa qTrimmed() */ /*! @@ -689,7 +687,7 @@ QT_BEGIN_NAMESPACE If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive; otherwise the search is case-insensitive. - \sa endsWith(), qStartsWith() + \sa endsWith() */ /*! @@ -705,7 +703,7 @@ QT_BEGIN_NAMESPACE If \a cs is Qt::CaseSensitive (the default), the search is case-sensitive; otherwise the search is case-insensitive. - \sa startsWith(), qEndsWith() + \sa startsWith() */ /*! @@ -730,7 +728,7 @@ QT_BEGIN_NAMESPACE The behavior is undefined if the string contains characters not supported by the locale's 8-bit encoding. - \sa toLatin1(), toUtf8(), QTextCodec, qConvertToLocal8Bit() + \sa toLatin1(), toUtf8(), QTextCodec */ /*! -- cgit v1.2.3 From b8a6e2b6e8e4b5ea0734285f485c03c22022c30e Mon Sep 17 00:00:00 2001 From: Dongmei Wang Date: Fri, 18 Aug 2017 11:24:13 -0700 Subject: QColor: write signed 64-bit integer in a platform-independent way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building Qt 5.6.2 with gcc 4.1.2 on Fedora 8, a compilation error happened when compiling the code below QColor::name() { ... case HexArgb: return QLatin1Char('#') + QString::number(rgba() | 0x100000000, 16).rightRef(8); ... } qtbase/src/gui/painting/qcolor.cpp:527: error: integer constant is too large for ‘long’ type gcc 4.1.2 was unable to handle 0x100000000. The patch is to use Q_INT64_C to append "LL" to 0x100000000 to avoid the compilation error. Change-Id: I000e65a5c897ef2d78fcfe4e212d832eb488a762 Reviewed-by: Gabriel de Dietrich --- src/gui/painting/qcolor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 9e1785c11d..6e0e348a67 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -853,7 +853,7 @@ QString QColor::name(NameFormat format) const return QLatin1Char('#') + QString::number(rgba() | 0x1000000, 16).rightRef(6); case HexArgb: // it's called rgba() but it does return AARRGGBB - return QLatin1Char('#') + QString::number(rgba() | 0x100000000, 16).rightRef(8); + return QLatin1Char('#') + QString::number(rgba() | Q_INT64_C(0x100000000), 16).rightRef(8); } return QString(); } -- cgit v1.2.3 From 77687bc64e9ae7172586271de91b266be7ab19ce Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 29 Aug 2017 09:02:31 +0200 Subject: QFileSystemModel::index(): Add a list size check This prevents an out of range assert when monitoring directory with activity (for example, temp). Task-number: QTBUG-62841 Change-Id: Id3aa4098e9bbd665c7b17a667516885fa7c7f473 Reviewed-by: Jesus Fernandez Reviewed-by: Martin Rotter Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qfilesystemmodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index bf14b5c6fd..179c5861c9 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -260,7 +260,10 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare Q_ASSERT(parentNode); // now get the internal pointer for the index - const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row)); + const int i = d->translateVisibleLocation(parentNode, row); + if (i >= parentNode->visibleChildren.size()) + return QModelIndex(); + const QString &childName = parentNode->visibleChildren.at(i); const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName); Q_ASSERT(indexNode); -- cgit v1.2.3 From ff7dbda3b0eaedf857de3913c2be2f880909ee82 Mon Sep 17 00:00:00 2001 From: Dongmei Wang Date: Fri, 18 Aug 2017 11:32:25 -0700 Subject: xcb_qpa_lib: Fix "undefined reference to `dlsym'" error Change-Id: I37515542571ef37f4361e72b8db4547ff1e1b86a Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 284711075e..55007b43a7 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -85,4 +85,6 @@ include(gl_integrations/gl_integrations.pri) QMAKE_USE += xkbcommon } +qtConfig(dlopen): QMAKE_USE += libdl + load(qt_module) -- cgit v1.2.3 From 637e8ebcc3c2394d01827043d1a410866234fd0c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 13:35:58 -0800 Subject: tst_QUdpSocket: Don't test for .bytesAvailable on untrusted platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FreeBSD, for example, does not have SO_NREAD and its FIONREAD returns the full socket buffer size, including IP and UDP headers. Change-Id: Ifb5969bf206e4cd7b14efffd14fb5d8ca778d16a Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 0f46caa7c2..aa71f7e94d 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -60,6 +60,13 @@ #include #endif +#ifdef Q_OS_UNIX +# include +#endif +#if defined(Q_OS_LINUX) || defined(Q_OS_WIN) || defined(SO_NREAD) +# define RELIABLE_BYTES_AVAILABLE +#endif + Q_DECLARE_METATYPE(QHostAddress) QT_FORWARD_DECLARE_CLASS(QUdpSocket) @@ -1806,7 +1813,9 @@ void tst_QUdpSocket::readyRead() // make sure only one signal was emitted QCOMPARE(spy.count(), 1); QVERIFY(receiver.hasPendingDatagrams()); +#ifdef RELIABLE_BYTES_AVAILABLE QCOMPARE(receiver.bytesAvailable(), qint64(2)); +#endif QCOMPARE(receiver.pendingDatagramSize(), qint64(2)); // write another datagram @@ -1828,7 +1837,9 @@ void tst_QUdpSocket::readyRead() QTest::qWait(100); QCOMPARE(spy.count(), 2); QVERIFY(receiver.hasPendingDatagrams()); +#ifdef RELIABLE_BYTES_AVAILABLE QCOMPARE(receiver.bytesAvailable(), qint64(3)); +#endif QCOMPARE(receiver.pendingDatagramSize(), qint64(3)); } @@ -1860,7 +1871,9 @@ void tst_QUdpSocket::readyReadForEmptyDatagram() char buf[1]; QVERIFY(receiver.hasPendingDatagrams()); QCOMPARE(receiver.pendingDatagramSize(), qint64(0)); +#ifdef RELIABLE_BYTES_AVAILABLE QCOMPARE(receiver.bytesAvailable(), qint64(0)); +#endif QCOMPARE(receiver.readDatagram(buf, sizeof buf), qint64(0)); } @@ -1869,7 +1882,9 @@ void tst_QUdpSocket::async_readDatagramSlot() char buf[1]; QVERIFY(m_asyncReceiver->hasPendingDatagrams()); QCOMPARE(m_asyncReceiver->pendingDatagramSize(), qint64(1)); +#ifdef RELIABLE_BYTES_AVAILABLE QCOMPARE(m_asyncReceiver->bytesAvailable(), qint64(1)); +#endif QCOMPARE(m_asyncReceiver->readDatagram(buf, sizeof(buf)), qint64(1)); if (buf[0] == '2') { -- cgit v1.2.3 From 81a88639acf8e7dfe4312733635c138abe51b828 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 14:59:12 -0800 Subject: tst_QUdpSocket: fix linkLocalIPv4 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I broke it in commit 4da2dda2aa1f710177157dc1cf841e0bf0b9d829. It wasn't flaky or anything: it was plain broken and would never pass. That indicates no node in the CI has an IPv4 link-local address (and apparently neither did I at the time). Change-Id: Ifb5969bf206e4cd7b14efffd14fb62176546916e Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index aa71f7e94d..5c5dfc881d 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1723,7 +1723,7 @@ void tst_QUdpSocket::linkLocalIPv4() foreach (QNetworkAddressEntry addr, iface.addressEntries()) { if (addr.ip().isInSubnet(localMask, 16)) { addresses << addr.ip(); - qDebug() << addr.ip(); + qDebug() << "Found IPv4 link local address" << addr.ip(); } } } @@ -1748,7 +1748,6 @@ void tst_QUdpSocket::linkLocalIPv4() QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData()); - QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData()); QNetworkDatagram dgram = neutral.receiveDatagram(testData.length() * 2); QVERIFY(dgram.isValid()); QCOMPARE(dgram.senderAddress(), s->localAddress()); @@ -1771,7 +1770,7 @@ void tst_QUdpSocket::linkLocalIPv4() } QVERIFY(neutral.writeDatagram(dgram.makeReply(testData))); - + QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData()); dgram = s->receiveDatagram(testData.length() * 2); QVERIFY(dgram.isValid()); QCOMPARE(dgram.data(), testData); -- cgit v1.2.3 From 138d34b9c8aa368dd252d0c46393816c7e372837 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 1 Dec 2017 19:38:20 -0800 Subject: QFileSystemEngine: Work around Android bug in rejecting hardlinks Android Marshmellow intentionally forbids use of hard links. See https://code.google.com/archive/p/android-developer-preview/issues/3150 However, instead of using EPERM or another error code that indicates the hard linking operation itself has a problem but there are no other problems, Android developers stupidly chose to use EACCES, an errno code that only indicates permission problems. In any case, since the call will never succeed, we shouldn't even try. Task-number: QTBUG-64103 Change-Id: I9e2892cb6c374e93bcb7fffd14fc5d1082bd60a3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/io/qfilesystemengine_unix.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index d77cdc123c..75d0c60288 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -104,6 +104,16 @@ static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struc QT_BEGIN_NAMESPACE +enum { +#ifdef Q_OS_ANDROID + // On Android, the link(2) system call has been observed to always fail + // with EACCES, regardless of whether there are permission problems or not. + SupportsHardlinking = false +#else + SupportsHardlinking = true +#endif +}; + #define emptyFileEntryWarning() emptyFileEntryWarning_(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC) static void emptyFileEntryWarning_(const char *file, int line, const char *function) { @@ -1278,7 +1288,7 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy } #endif - if (::link(srcPath, tgtPath) == 0) { + if (SupportsHardlinking && ::link(srcPath, tgtPath) == 0) { if (::unlink(srcPath) == 0) return true; @@ -1292,6 +1302,11 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy error = QSystemError(savedErrno, QSystemError::StandardLibraryError); return false; + } else if (!SupportsHardlinking) { + // man 2 link on Linux has: + // EPERM The filesystem containing oldpath and newpath does not + // support the creation of hard links. + errno = EPERM; } switch (errno) { -- cgit v1.2.3 From 87efdd8c7f997e16ff5a35a44dce9b967d23f09b Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 5 Dec 2017 13:45:13 +0100 Subject: Android: Reserve space for the QVarLengthArray, so we can use append MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the QVarLengthArray was initialized with a size then append would add to the end of that. Therefore we need to use reserve to get the desired effect. Task-number: QTBUG-64905 Change-Id: Ia1ebeb26cd31bc5e92bd7f81079506a266b845bf Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/android/androidjniaccessibility.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index a3bc58bb89..309e41bfd6 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -106,7 +106,8 @@ namespace QtAndroidAccessibility QAccessibleInterface *iface = interfaceFromId(objectId); if (iface && iface->isValid()) { const int childCount = iface->childCount(); - QVarLengthArray ifaceIdArray(childCount); + QVarLengthArray ifaceIdArray; + ifaceIdArray.reserve(childCount); for (int i = 0; i < childCount; ++i) { QAccessibleInterface *child = iface->child(i); if (child && child->isValid()) -- cgit v1.2.3 From 1853aeb50a41062d8585065c97edd3e58db1fba7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 11:28:59 -0800 Subject: tst_QUdpSocket: remove Bearer portions of the test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test fails to start on FreeBSD: FAIL! : tst_QUdpSocket::initTestCase() 'networkSession->waitForOpened(30000)' returned FALSE. () Loc: [/usr/home/tjmaciei/src/qt/qt5/qtbase/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp(234)] This commit is basically a revert of the Qt 4.8 commit a951fb79139498774d021759d0466b4b2ff50e68. FORCE_SESSION was only used by manual testing, as the commit message said > 8. For manual testing, added the FORCE_SESSION macro to test behaviour > of UDP sockets when they have an explicit network session associated So I doubt it has been tested recently. Change-Id: Ifb5969bf206e4cd7b14efffd14fb569ebf53497b Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 122 --------------------- 1 file changed, 122 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 0f46caa7c2..6dff9f3420 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -47,12 +47,6 @@ #include "../../../network-settings.h" #include "emulationdetector.h" -#ifndef QT_NO_BEARERMANAGEMENT -#include -#include -#include -#endif - #if defined(Q_OS_LINUX) #define SHOULD_CHECK_SYSCALL_SUPPORT #include @@ -130,11 +124,6 @@ private: bool m_skipUnsupportedIPv6Tests; QList allAddresses; -#ifndef QT_NO_BEARERMANAGEMENT - QNetworkConfigurationManager *netConfMan; - QNetworkConfiguration networkConfiguration; - QSharedPointer networkSession; -#endif QUdpSocket *m_asyncSender; QUdpSocket *m_asyncReceiver; }; @@ -210,16 +199,6 @@ void tst_QUdpSocket::initTestCase_data() if (!newTestServer) QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); #endif - -#ifndef QT_NO_BEARERMANAGEMENT - netConfMan = new QNetworkConfigurationManager(this); - networkConfiguration = netConfMan->defaultConfiguration(); - networkSession = QSharedPointer::create(networkConfiguration); - if (!networkSession->isOpen()) { - networkSession->open(); - QVERIFY(networkSession->waitForOpened(30000)); - } -#endif } void tst_QUdpSocket::initTestCase() @@ -261,9 +240,6 @@ void tst_QUdpSocket::cleanup() void tst_QUdpSocket::constructing() { QUdpSocket socket; -#ifdef FORCE_SESSION - socket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(socket.isSequential()); QVERIFY(!socket.isOpen()); @@ -281,9 +257,6 @@ void tst_QUdpSocket::constructing() void tst_QUdpSocket::unconnectedServerAndClientTest() { QUdpSocket serverSocket; -#ifdef FORCE_SESSION - serverSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif qRegisterMetaType("QAbstractSocket::SocketState"); @@ -296,9 +269,6 @@ void tst_QUdpSocket::unconnectedServerAndClientTest() QHostAddress serverAddress = makeNonAny(serverSocket.localAddress()); for (int i = 0; i < 3; ++i) { QUdpSocket clientSocket; -#ifdef FORCE_SESSION - clientSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QCOMPARE(int(clientSocket.writeDatagram(message[i], strlen(message[i]), serverAddress, serverSocket.localPort())), int(strlen(message[i]))); @@ -352,9 +322,6 @@ void tst_QUdpSocket::broadcasting() QSKIP("No interface can broadcast"); for (int i = 0; i < 4; ++i) { QUdpSocket serverSocket; -#ifdef FORCE_SESSION - serverSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(serverSocket.bind(QHostAddress(QHostAddress::AnyIPv4), 0), serverSocket.errorString().toLatin1().constData()); quint16 serverPort = serverSocket.localPort(); @@ -363,9 +330,6 @@ void tst_QUdpSocket::broadcasting() connect(&serverSocket, SIGNAL(readyRead()), SLOT(empty_readyReadSlot())); QUdpSocket broadcastSocket; -#ifdef FORCE_SESSION - broadcastSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif broadcastSocket.bind(QHostAddress(QHostAddress::AnyIPv4), 0); for (int j = 0; j < 10; ++j) { @@ -444,10 +408,6 @@ void tst_QUdpSocket::loop() QUdpSocket peter; QUdpSocket paul; -#ifdef FORCE_SESSION - peter.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // make sure we bind to IPv4 QHostAddress localhost = QHostAddress::LocalHost; @@ -518,10 +478,6 @@ void tst_QUdpSocket::ipv6Loop() QUdpSocket peter; QUdpSocket paul; -#ifdef FORCE_SESSION - peter.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif int peterPort; int paulPort; @@ -745,10 +701,6 @@ void tst_QUdpSocket::connectToHost() { QUdpSocket socket1; QUdpSocket socket2; -#ifdef FORCE_SESSION - socket1.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(socket1.bind(), socket1.errorString().toLatin1().constData()); @@ -763,11 +715,6 @@ void tst_QUdpSocket::bindAndConnectToHost() QUdpSocket socket1; QUdpSocket socket2; QUdpSocket dummysocket; -#ifdef FORCE_SESSION - socket1.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - dummysocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // we use the dummy socket to use up a file descriptor dummysocket.bind(); @@ -791,16 +738,10 @@ void tst_QUdpSocket::bindAndConnectToHost() void tst_QUdpSocket::pendingDatagramSize() { QUdpSocket server; -#ifdef FORCE_SESSION - server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = makeNonAny(server.localAddress()); QUdpSocket client; -#ifdef FORCE_SESSION - client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(client.writeDatagram("this is", 7, serverAddress, server.localPort()) == 7); QVERIFY(client.writeDatagram(0, 0, serverAddress, server.localPort()) == 0); QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); @@ -839,16 +780,10 @@ void tst_QUdpSocket::pendingDatagramSize() void tst_QUdpSocket::writeDatagram() { QUdpSocket server; -#ifdef FORCE_SESSION - server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = makeNonAny(server.localAddress()); QUdpSocket client; -#ifdef FORCE_SESSION - client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif qRegisterMetaType("QAbstractSocket::SocketError"); @@ -886,16 +821,10 @@ void tst_QUdpSocket::performance() QByteArray arr(8192, '@'); QUdpSocket server; -#ifdef FORCE_SESSION - server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = makeNonAny(server.localAddress()); QUdpSocket client; -#ifdef FORCE_SESSION - client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif client.connectToHost(serverAddress, server.localPort()); QVERIFY(client.waitForConnected(10000)); @@ -932,14 +861,8 @@ void tst_QUdpSocket::bindMode() } QUdpSocket socket; -#ifdef FORCE_SESSION - socket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY2(socket.bind(), socket.errorString().toLatin1().constData()); QUdpSocket socket2; -#ifdef FORCE_SESSION - socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(!socket2.bind(socket.localPort())); #if defined(Q_OS_UNIX) QVERIFY(!socket2.bind(socket.localPort(), QUdpSocket::ReuseAddressHint)); @@ -991,9 +914,6 @@ void tst_QUdpSocket::writeDatagramToNonExistingPeer() quint16 peerPort = 33533 + int(bind); QUdpSocket sUdp; -#ifdef FORCE_SESSION - sUdp.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QSignalSpy sReadyReadSpy(&sUdp, SIGNAL(readyRead())); if (bind) QVERIFY(sUdp.bind()); @@ -1026,9 +946,6 @@ void tst_QUdpSocket::writeToNonExistingPeer() qRegisterMetaType("QAbstractSocket::SocketError"); QUdpSocket sConnected; -#ifdef FORCE_SESSION - sConnected.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QSignalSpy sConnectedReadyReadSpy(&sConnected, SIGNAL(readyRead())); QSignalSpy sConnectedErrorSpy(&sConnected, SIGNAL(error(QAbstractSocket::SocketError))); sConnected.connectToHost(peerAddress, peerPort, QIODevice::ReadWrite); @@ -1198,18 +1115,12 @@ void tst_QUdpSocket::zeroLengthDatagram() return; QUdpSocket receiver; -#ifdef FORCE_SESSION - receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(receiver.bind()); QVERIFY(!receiver.waitForReadyRead(100)); QVERIFY(!receiver.hasPendingDatagrams()); QUdpSocket sender; -#ifdef FORCE_SESSION - sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QCOMPARE(sender.writeDatagram(QNetworkDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort())), qint64(0)); QVERIFY2(receiver.waitForReadyRead(1000), QtNetworkSettings::msgSocketError(receiver).constData()); @@ -1262,9 +1173,6 @@ void tst_QUdpSocket::multicastTtlOption() } QUdpSocket udpSocket; -#ifdef FORCE_SESSION - udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // bind, but ignore the result, we are only interested in initializing the socket (void) udpSocket.bind(bindAddress, 0); udpSocket.setSocketOption(QUdpSocket::MulticastTtlOption, ttl); @@ -1315,9 +1223,6 @@ void tst_QUdpSocket::multicastLoopbackOption() } QUdpSocket udpSocket; -#ifdef FORCE_SESSION - udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // bind, but ignore the result, we are only interested in initializing the socket (void) udpSocket.bind(bindAddress, 0); udpSocket.setSocketOption(QUdpSocket::MulticastLoopbackOption, loopback); @@ -1341,9 +1246,6 @@ void tst_QUdpSocket::multicastJoinBeforeBind() QFETCH(QHostAddress, groupAddress); QUdpSocket udpSocket; -#ifdef FORCE_SESSION - udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // cannot join group before binding QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::joinMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); QVERIFY(!udpSocket.joinMulticastGroup(groupAddress)); @@ -1376,9 +1278,6 @@ void tst_QUdpSocket::multicastLeaveAfterClose() } QUdpSocket udpSocket; -#ifdef FORCE_SESSION - udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QHostAddress bindAddress = QHostAddress::AnyIPv4; if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) bindAddress = QHostAddress::AnyIPv6; @@ -1487,9 +1386,6 @@ void tst_QUdpSocket::multicast() } QUdpSocket receiver; -#ifdef FORCE_SESSION - receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif // bind first, then verify that we can join the multicast group QVERIFY2(receiver.bind(bindAddress, 0) == bindResult, @@ -1515,9 +1411,6 @@ void tst_QUdpSocket::multicast() << QByteArray("cdef"); QUdpSocket sender; -#ifdef FORCE_SESSION - sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif sender.bind(); foreach (const QByteArray &datagram, datagrams) { QCOMPARE(int(sender.writeDatagram(datagram, groupAddress, receiver.localPort())), @@ -1563,9 +1456,6 @@ void tst_QUdpSocket::echo() QHostAddress remote = info.addresses().first(); QUdpSocket sock; -#ifdef FORCE_SESSION - sock.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif if (connect) { sock.connectToHost(remote, 7); QVERIFY(sock.waitForConnected(10000)); @@ -1785,10 +1675,6 @@ void tst_QUdpSocket::readyRead() char buf[1]; QUdpSocket sender, receiver; -#ifdef FORCE_SESSION - sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(receiver.bind(QHostAddress(QHostAddress::AnyIPv4), 0)); quint16 port = receiver.localPort(); @@ -1839,10 +1725,6 @@ void tst_QUdpSocket::readyReadForEmptyDatagram() return; QUdpSocket sender, receiver; -#ifdef FORCE_SESSION - sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); - receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(receiver.bind(QHostAddress(QHostAddress::AnyIPv4), 0)); quint16 port = receiver.localPort(); @@ -1891,10 +1773,6 @@ void tst_QUdpSocket::asyncReadDatagram() m_asyncSender = new QUdpSocket; m_asyncReceiver = new QUdpSocket; -#ifdef FORCE_SESSION - m_asyncSender->setProperty("_q_networksession", QVariant::fromValue(networkSession)); - m_asyncReceiver->setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif QVERIFY(m_asyncReceiver->bind(QHostAddress(QHostAddress::AnyIPv4), 0)); quint16 port = m_asyncReceiver->localPort(); -- cgit v1.2.3 From b08c19526491c7dcb46961491649ff532a7a9ab0 Mon Sep 17 00:00:00 2001 From: Eric Lemanissier Date: Tue, 5 Dec 2017 21:23:48 +0100 Subject: fixup oversight in QStringView::lengthHelperPointer amends 3b61cd6ad738b8479bf216dcf736bb935e8812df Change-Id: I3afa008299b8fcccae8943e545b536a68b17bd1a Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/tools/qstringview.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h index 14405f325d..6ff287a570 100644 --- a/src/corelib/tools/qstringview.h +++ b/src/corelib/tools/qstringview.h @@ -152,6 +152,7 @@ private: qssize_t result = 0; while (*str++) ++result; + return result; } #endif return QtPrivate::qustrlen(reinterpret_cast(str)); -- cgit v1.2.3 From d02a6b938e8987fa95fbe9e3f085f319518e05ab Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 2 Dec 2017 19:22:00 +0200 Subject: QAbstractSocket: clear error code to match the error description Since 5.10, QIODevice resets the error string on opening. So, we should set the error code to UnknownSocketError accordingly. Change-Id: I0dd314788ffc182d6837f9d06b51e41d6de59d7e Reviewed-by: Timur Pocheptsov --- src/network/socket/qabstractsocket.cpp | 4 ++++ src/network/socket/qabstractsocket_p.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 7284b124c5..ec88851589 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1694,6 +1694,8 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, } #endif + // Sync up with error string, which open() shall clear. + d->socketError = UnknownSocketError; if (openMode & QIODevice::Unbuffered) d->isBuffered = false; else if (!d_func()->isBuffered) @@ -1929,6 +1931,8 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState return false; } + // Sync up with error string, which open() shall clear. + d->socketError = UnknownSocketError; if (d->threadData->hasEventDispatcher()) d->socketEngine->setReceiver(d); diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 5411133ea9..3873b50864 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -153,6 +153,7 @@ public: QAbstractSocket::SocketType socketType; QAbstractSocket::SocketState state; + // Must be kept in sync with QIODevicePrivate::errorString. QAbstractSocket::SocketError socketError; QAbstractSocket::NetworkLayerProtocol preferredNetworkLayerProtocol; -- cgit v1.2.3 From 58a409c6dce920feb5c746a9319d0e0f1d02a233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 5 Dec 2017 19:30:12 +0100 Subject: iOS: Implement QPlatformScreen::name for easier debugging Change-Id: I077bec93fe2086c38ebe986b322977a50a1ab27d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 2 ++ src/plugins/platforms/ios/qiosscreen.mm | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 9fcce42825..7f10b08492 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -56,6 +56,8 @@ public: QIOSScreen(UIScreen *screen); ~QIOSScreen(); + QString name() const override; + QRect geometry() const Q_DECL_OVERRIDE; QRect availableGeometry() const Q_DECL_OVERRIDE; int depth() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 1a7004c249..67970ba59e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -280,6 +280,16 @@ QIOSScreen::~QIOSScreen() [m_uiWindow release]; } +QString QIOSScreen::name() const +{ + if (m_uiScreen == [UIScreen mainScreen]) { + return QString::fromNSString([UIDevice currentDevice].model) + + QLatin1String(" built-in display"); + } else { + return QLatin1String("External display"); + } +} + void QIOSScreen::updateProperties() { QRect previousGeometry = m_geometry; -- cgit v1.2.3 From 77942a1bdf9fe22d8f076e59ce19fe9a9d7870d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 5 Dec 2017 18:09:50 +0100 Subject: iOS: Try to detect and deal with delayed touch delivery due to gestures A UIGestureRecognizer may have its delaysTouchesBegan or delaysTouchesEnded properties set, which causes iOS to not deliver touch events to the view until the recognizer has failed recognition of its gesture. In that case, the touch event is not delivered via [UIWindow sendEvent:] as usual, but via _UIGestureEnvironmentSortAndSendDelayedTouches. The latter function is apparently not reentrant, as opening a native alert dialog in response to the touch delivery will result in the dialogs's buttons to stop working, probably because they themselves use gestures. Unfortunately iOS maintains two internal gesture recognizers on iPad, of type _UISystemGestureGateGestureRecognizer, probably related to the swipe-from-bottom gesture used for multitasking. Without any workaround, these two recognizers will result in any tap on the bottom part of the screen to be delivered delayed, which may introduce stuck alert dialogs as described above. UITouch has a gestureRecognizers property, but unfortunately this property does not give us any information in the cases where we need it, so we have to use an heuristic involving a UIWindow subclass to detect the case where event delivery is delayed. As there is no way to prevent the user from recursing into an event loop when delivering the event, our only hope is to deliver the event asynchronously. Task-number: QTBUG-64577 Change-Id: I11d9caa8c4542dc80426a9e58ea555914bed433e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 4 ++++ src/plugins/platforms/ios/qiosscreen.mm | 22 +++++++++++++++++++++- src/plugins/platforms/ios/quiview.mm | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 7f10b08492..d63fa29ec3 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -46,6 +46,10 @@ @class QIOSOrientationListener; +@interface QUIWindow : UIWindow +@property (nonatomic, readonly) BOOL sendingEvent; +@end + QT_BEGIN_NAMESPACE class QIOSScreen : public QObject, public QPlatformScreen diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 67970ba59e..0d3826fc4c 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -192,6 +192,26 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) // ------------------------------------------------------------------------- +@implementation QUIWindow + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) + self->_sendingEvent = NO; + + return self; +} + +- (void)sendEvent:(UIEvent *)event +{ + QScopedValueRollback(self->_sendingEvent, YES); + [super sendEvent:event]; +} + +@end + +// ------------------------------------------------------------------------- + QT_BEGIN_NAMESPACE /*! @@ -261,7 +281,7 @@ QIOSScreen::QIOSScreen(UIScreen *screen) if (!m_uiWindow) { // Create a window and associated view-controller that we can use - m_uiWindow = [[UIWindow alloc] initWithFrame:[m_uiScreen bounds]]; + m_uiWindow = [[QUIWindow alloc] initWithFrame:[m_uiScreen bounds]]; m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease]; } diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 79f9d6871a..1dbacad6e7 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -43,6 +43,7 @@ #include "qiosintegration.h" #include "qiosviewcontroller.h" #include "qiostextresponder.h" +#include "qiosscreen.h" #include "qioswindow.h" #ifndef Q_OS_TVOS #include "qiosmenu.h" @@ -359,7 +360,21 @@ - (void)sendTouchEventWithTimestamp:(ulong)timeStamp { QIOSIntegration *iosIntegration = QIOSIntegration::instance(); - QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + if (!static_cast(self.window).sendingEvent) { + // The event is likely delivered as part of delayed touch delivery, via + // _UIGestureEnvironmentSortAndSendDelayedTouches, due to one of the two + // _UISystemGestureGateGestureRecognizer instances on the top level window + // having its delaysTouchesBegan set to YES. During this delivery, it's not + // safe to spin up a recursive event loop, as our calling function is not + // reentrant, so any gestures used by the recursive code, e.g. a native + // alert dialog, will fail to recognize. To be on the safe side, we deliver + // the event asynchronously. + QWindowSystemInterface::handleTouchEvent( + m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + } else { + QWindowSystemInterface::handleTouchEvent( + m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -- cgit v1.2.3 From e37c9d5d5f4ba9874808a4e565c36b2953eb96da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 4 Dec 2017 14:41:36 +0100 Subject: iOS: Harden application state change logic Make sure we catch application state changes as early as possible, and deal properly with any changes delivered before we have an app to send them to. Change-Id: I6d0ea0398f9fab88fc182342769b075cb144227f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationstate.h | 18 ++-- src/plugins/platforms/ios/qiosapplicationstate.mm | 110 ++++++++++------------ src/plugins/platforms/ios/qiosintegration.h | 3 +- 3 files changed, 65 insertions(+), 66 deletions(-) diff --git a/src/plugins/platforms/ios/qiosapplicationstate.h b/src/plugins/platforms/ios/qiosapplicationstate.h index 1c77b26da1..a68147a72a 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.h +++ b/src/plugins/platforms/ios/qiosapplicationstate.h @@ -40,20 +40,24 @@ #ifndef QIOSAPPLICATIONSTATE_H #define QIOSAPPLICATIONSTATE_H -#include -#include +#include -Q_FORWARD_DECLARE_OBJC_CLASS(NSObject); +#include QT_BEGIN_NAMESPACE -class QIOSApplicationState +class QIOSApplicationState : public QObject { + Q_OBJECT public: QIOSApplicationState(); - ~QIOSApplicationState(); -private: - QVector m_observers; + + static void handleApplicationStateChanged(UIApplicationState state, const QString &reason); + static Qt::ApplicationState toQtApplicationState(UIApplicationState state); + +Q_SIGNALS: + void applicationStateWillChange(Qt::ApplicationState); + void applicationStateDidChange(Qt::ApplicationState); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index 7c8e1f9927..fed09999b5 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -40,82 +40,76 @@ #include "qiosapplicationstate.h" #include "qiosglobal.h" +#include "qiosintegration.h" #include #include #include -#import +QT_BEGIN_NAMESPACE -static Qt::ApplicationState qtApplicationState(UIApplicationState uiApplicationState) +static void qRegisterApplicationStateNotifications() { - switch (uiApplicationState) { - case UIApplicationStateActive: - // The application is visible in front, and receiving events - return Qt::ApplicationActive; - case UIApplicationStateInactive: - // The app is running in the foreground but is not receiving events. This - // typically happens while transitioning to/from active/background, like - // upon app launch or when receiving incoming calls. - return Qt::ApplicationInactive; - case UIApplicationStateBackground: - // Normally the app would enter this state briefly before it gets - // suspeded (you have five seconds, according to Apple). - // You can request more time and start a background task, which would - // normally map closer to Qt::ApplicationHidden. But since we have no - // API for doing that yet, we handle this state as "about to be suspended". - // Note: A screen-shot for the SpringBoard will also be taken after this - // call returns. - return Qt::ApplicationSuspended; + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; + + // Map between notifications and corresponding application state. Note that + // there's no separate notification for moving to UIApplicationStateInactive, + // so we use UIApplicationWillResignActiveNotification as an intermediate. + static QMap notifications { + { UIApplicationDidBecomeActiveNotification, UIApplicationStateActive }, + { UIApplicationWillResignActiveNotification, UIApplicationStateInactive }, + { UIApplicationDidEnterBackgroundNotification, UIApplicationStateBackground }, + }; + + for (auto i = notifications.constBegin(); i != notifications.constEnd(); ++i) { + [notificationCenter addObserverForName:i.key() object:nil queue:mainQueue + usingBlock:^void(NSNotification *notification) { + NSRange nameRange = NSMakeRange(2, notification.name.length - 14); + QString reason = QString::fromNSString([notification.name substringWithRange:nameRange]); + QIOSApplicationState::handleApplicationStateChanged(i.value(), reason); + }]; } -} -static void handleApplicationStateChanged(UIApplicationState uiApplicationState) -{ - Qt::ApplicationState state = qtApplicationState(uiApplicationState); - qCDebug(lcQpaApplication) << "moved to" << state; - QWindowSystemInterface::handleApplicationStateChanged(state); + // Initialize correct startup state, which may not be the Qt default (inactive) + UIApplicationState startupState = [UIApplication sharedApplication].applicationState; + QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application loaded")); } - -QT_BEGIN_NAMESPACE +Q_CONSTRUCTOR_FUNCTION(qRegisterApplicationStateNotifications) QIOSApplicationState::QIOSApplicationState() { - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - - m_observers.push_back([notificationCenter addObserverForName:UIApplicationDidBecomeActiveNotification - object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) { - handleApplicationStateChanged(UIApplicationStateActive); - } - ]); - - m_observers.push_back([notificationCenter addObserverForName:UIApplicationWillResignActiveNotification - object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) { - // Note: UIApplication is still UIApplicationStateActive at this point, - // but since there is no separate notification for the inactive state, - // we report UIApplicationStateInactive now. - handleApplicationStateChanged(UIApplicationStateInactive); - } - ]); - - m_observers.push_back([notificationCenter addObserverForName:UIApplicationDidEnterBackgroundNotification - object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) { - handleApplicationStateChanged(UIApplicationStateBackground); - } - ]); - - // Initialize correct startup state, which may not be the Qt default (inactive) UIApplicationState startupState = [UIApplication sharedApplication].applicationState; - QGuiApplicationPrivate::applicationState = qtApplicationState(startupState); + QIOSApplicationState::handleApplicationStateChanged(startupState, QLatin1String("Application launched")); } -QIOSApplicationState::~QIOSApplicationState() +void QIOSApplicationState::handleApplicationStateChanged(UIApplicationState uiState, const QString &reason) { - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - foreach (const NSObject* observer, m_observers) - [notificationCenter removeObserver:observer]; + Qt::ApplicationState state = toQtApplicationState(uiState); + qCDebug(lcQpaApplication) << qPrintable(reason) + << "- moving from" << QGuiApplication::applicationState() << "to" << state; + + if (QIOSIntegration *integration = QIOSIntegration::instance()) { + emit integration->applicationState.applicationStateWillChange(state); + QWindowSystemInterface::handleApplicationStateChanged(state); + emit integration->applicationState.applicationStateDidChange(state); + qCDebug(lcQpaApplication) << "done moving to" << state; + } else { + qCDebug(lcQpaApplication) << "no platform integration yet, setting state directly"; + QGuiApplicationPrivate::applicationState = state; + } } -QT_END_NAMESPACE +Qt::ApplicationState QIOSApplicationState::toQtApplicationState(UIApplicationState state) +{ + switch (state) { + case UIApplicationStateActive: return Qt::ApplicationActive; + case UIApplicationStateInactive: return Qt::ApplicationInactive; + case UIApplicationStateBackground: return Qt::ApplicationSuspended; + } +} +#include "moc_qiosapplicationstate.cpp" + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 54c1a1dcb7..1d53734096 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -109,6 +109,8 @@ public: QFactoryLoader *optionalPlugins() { return m_optionalPlugins; } + QIOSApplicationState applicationState; + private: QPlatformFontDatabase *m_fontDatabase; #ifndef Q_OS_TVOS @@ -116,7 +118,6 @@ private: #endif QPlatformInputContext *m_inputContext; QTouchDevice *m_touchDevice; - QIOSApplicationState m_applicationState; QIOSServices *m_platformServices; mutable QPlatformAccessibility *m_accessibility; QFactoryLoader *m_optionalPlugins; -- cgit v1.2.3 From 933497bace2ddfd9920100ccf155658cd2030c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 30 Nov 2017 16:46:41 +0100 Subject: iOS: Ignore view layouts while in the background Despite the OpenGL ES Programming Guide telling us to avoid all use of OpenGL while in the background, iOS will perform its view snapshotting for the app switcher after the application has been backgrounded; once for each orientation. Presumably the expectation is that no rendering needs to be done to provide an alternate orientation snapshot, just relayouting of views. But in our case, or any non-stretchable content case such as a OpenGL based game, this is not true. Instead of continuing layout, which will send potentially expensive geometry changes (with isExposed false, since we're in the background), we short-circuit the snapshotting. iOS will still use the latest rendered frame to create the application switcher thumbnail, but it will be based on the last active orientation of the application. To ensure that we pick up the right geometry when rotating the device while the app is in the background, we treat applicationWillEnterForeground as Qt::ApplicationInactive, which matches the recommendations of the OpenGL ES Programming Guide to "re-create any objects and restart your animation timers". Change-Id: Ia9c27f85f996ecf30284c825b43447aa7099224e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationstate.mm | 1 + src/plugins/platforms/ios/qiosviewcontroller.mm | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index fed09999b5..3407aebf8f 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -58,6 +58,7 @@ static void qRegisterApplicationStateNotifications() // there's no separate notification for moving to UIApplicationStateInactive, // so we use UIApplicationWillResignActiveNotification as an intermediate. static QMap notifications { + { UIApplicationWillEnterForegroundNotification, UIApplicationStateInactive }, { UIApplicationDidBecomeActiveNotification, UIApplicationStateActive }, { UIApplicationWillResignActiveNotification, UIApplicationStateInactive }, { UIApplicationDidEnterBackgroundNotification, UIApplicationStateBackground }, diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index c47b6d68b1..a9fdfaf9f1 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -157,6 +157,26 @@ - (void)layoutSubviews { + if (QGuiApplication::applicationState() == Qt::ApplicationSuspended) { + // Despite the OpenGL ES Programming Guide telling us to avoid all + // use of OpenGL while in the background, iOS will perform its view + // snapshotting for the app switcher after the application has been + // backgrounded; once for each orientation. Presumably the expectation + // is that no rendering needs to be done to provide an alternate + // orientation snapshot, just relayouting of views. But in our case, + // or any non-stretchable content case such as a OpenGL based game, + // this is not true. Instead of continuing layout, which will send + // potentially expensive geometry changes (with isExposed false, + // since we're in the background), we short-circuit the snapshotting + // here. iOS will still use the latest rendered frame to create the + // application switcher thumbnail, but it will be based on the last + // active orientation of the application. + QIOSScreen *screen = self.qtViewController->m_screen; + qCDebug(lcQpaWindow) << "ignoring layout of subviews while suspended," + << "likely system snapshot of" << screen->screen()->primaryOrientation(); + return; + } + for (int i = int(self.subviews.count) - 1; i >= 0; --i) { UIView *view = static_cast([self.subviews objectAtIndex:i]); if (![view isKindOfClass:[QUIView class]]) -- cgit v1.2.3 From a73de7ce2dde1128a14e968bcdd6c17b3d2d17f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 20 Nov 2017 12:04:50 +0100 Subject: iOS: Harden logic for when it's safe to use the graphics hardware To fix QTBUG-52493 we tied the exposed state of a window to the application being in the foreground. This has the result of a visible flash of black between hiding the launch screen and showing the first frame of the application, as the application is still waiting for UIApplicationStateActive to begin rendering, which happens after iOS hides the launch screen. According to the iOS OpenGL ES Programming Guide, it should be safe to render GL in UIApplicationStateInactive as well, and even in UIApplicationStateBackground, as long as the rendering finishes before the UIApplicationDidEnterBackgroundNotification returns. To ensure that we catch any bugs in this area, checks have been added that verify that no rendering happens while in the background state. Task-number: QTBUG-63229 Task-number: QTBUG-52493 Task-number: QTBUG-55205 Change-Id: Ib42bedbeddd7479ab0fb5e5b7de9f5805658e111 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qopenglcontext.cpp | 4 +- src/plugins/platforms/ios/qioscontext.h | 1 + src/plugins/platforms/ios/qioscontext.mm | 66 +++++++++++++++++++++++++++----- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index cd6f011fcb..ad5e0b518d 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -937,7 +937,9 @@ GLuint QOpenGLContext::defaultFramebufferObject() const /*! Makes the context current in the current thread, against the given - \a surface. Returns \c true if successful. + \a surface. Returns \c true if successful; otherwise returns \c false. + The latter may happen if the surface is not exposed, or the graphics + hardware is not available due to e.g. the application being suspended. If \a surface is 0 this is equivalent to calling doneCurrent(). diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 5b7917f7b4..ce50eff1d9 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -87,6 +87,7 @@ private: bool isComplete; }; + static bool verifyGraphicsHardwareAvailability(); static void deleteBuffers(const FramebufferObject &framebufferObject); FramebufferObject &backingFramebufferObjectFor(QPlatformSurface *) const; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 6a6cbb4324..03643c19a9 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -38,10 +38,13 @@ ****************************************************************************/ #include "qioscontext.h" + +#include "qiosintegration.h" #include "qioswindow.h" #include +#include #include #import @@ -136,6 +139,9 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) { Q_ASSERT_IS_GL_SURFACE(surface); + if (!verifyGraphicsHardwareAvailability()) + return false; + [EAGLContext setCurrentContext:m_eaglContext]; // For offscreen surfaces we don't prepare a default FBO @@ -214,18 +220,12 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) { Q_ASSERT_IS_GL_SURFACE(surface); + if (!verifyGraphicsHardwareAvailability()) + return; + if (surface->surface()->surfaceClass() == QSurface::Offscreen) return; // Nothing to do - // When using threaded rendering, the render-thread may not have picked up - // yet on the fact that a window is no longer exposed, and will try to swap - // a non-exposed window. This may in some cases result in crashes, e.g. when - // iOS is suspending an application, so we have an extra guard here. - if (!static_cast(surface)->isExposed()) { - qCDebug(lcQpaGLContext, "Detected swapBuffers on a non-exposed window, skipping flush"); - return; - } - FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface); Q_ASSERT_X(framebufferObject.isComplete, "QIOSContext", "swapBuffers on incomplete FBO"); @@ -287,6 +287,54 @@ bool QIOSContext::needsRenderbufferResize(QPlatformSurface *surface) const return false; } +bool QIOSContext::verifyGraphicsHardwareAvailability() +{ + // Per the iOS OpenGL ES Programming Guide, background apps may not execute commands on the + // graphics hardware. Specifically: "In your app delegate’s applicationDidEnterBackground: + // method, your app may want to delete some of its OpenGL ES objects to make memory and + // resources available to the foreground app. Call the glFinish function to ensure that + // the resources are removed immediately. After your app exits its applicationDidEnterBackground: + // method, it must not make any new OpenGL ES calls. If it makes an OpenGL ES call, it is + // terminated by iOS.". + static bool applicationBackgrounded = QGuiApplication::applicationState() == Qt::ApplicationSuspended; + + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState; + connect(applicationState, &QIOSApplicationState::applicationStateWillChange, [](Qt::ApplicationState state) { + if (applicationBackgrounded && state != Qt::ApplicationSuspended) { + qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled"; + applicationBackgrounded = false; + } + }); + connect(applicationState, &QIOSApplicationState::applicationStateDidChange, [](Qt::ApplicationState state) { + if (state != Qt::ApplicationSuspended) + return; + + qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled"; + applicationBackgrounded = true; + + // By the time we receive this signal the application has moved into + // Qt::ApplactionStateSuspended, and all windows have been obscured, + // which should stop all rendering. If there's still an active GL context, + // we follow Apple's advice and call glFinish before making it inactive. + if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) { + qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext; + glFinish(); + currentContext->doneCurrent(); + } + }); + }); + + if (applicationBackgrounded) { + static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded"; + Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning); + qCWarning(lcQpaGLContext, warning); + } + + return !applicationBackgrounded; +} + void QIOSContext::windowDestroyed(QObject *object) { QIOSWindow *window = static_cast(object); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index fb161febda..e934cb90fa 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -225,7 +225,7 @@ void QIOSWindow::applyGeometry(const QRect &rect) bool QIOSWindow::isExposed() const { - return qApp->applicationState() >= Qt::ApplicationActive + return qApp->applicationState() != Qt::ApplicationSuspended && window()->isVisible() && !window()->geometry().isEmpty(); } -- cgit v1.2.3 From 79d78d814acad4e183e281aea9b131f396abe3fb Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 7 Dec 2017 11:49:49 +0100 Subject: xcb: verify if xrandr present before using xcb_randr* APIs Not doing so might break the connection. We have had similar issues before, e.g. QTBUG-45312. Change-Id: I95f15d24773fc92b052578bd72d1ba264d0a5f63 Reviewed-by: Laszlo Agocs Reviewed-by: Uli Schlachter --- src/plugins/platforms/xcb/qxcbscreen.cpp | 35 +++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index ec0f9ba561..67c96b2d80 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -446,17 +446,24 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe m_cursor = new QXcbCursor(connection, this); - // Parse EDID - if (m_edid.parse(getEdid())) - qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f", - name().toLatin1().constData(), - m_edid.identifier.toLatin1().constData(), - m_edid.manufacturer.toLatin1().constData(), - m_edid.model.toLatin1().constData(), - m_edid.serialNumber.toLatin1().constData(), - m_edid.physicalSize.width(), m_edid.physicalSize.height()); - else - qCDebug(lcQpaScreen) << "Failed to parse EDID data for output" << name(); // keep this debug, not warning + if (connection->hasXRandr()) { // Parse EDID + QByteArray edid = getEdid(); + if (m_edid.parse(edid)) { + qCDebug(lcQpaScreen, "EDID data for output \"%s\": identifier '%s', manufacturer '%s'," + "model '%s', serial '%s', physical size: %.2fx%.2f", + name().toLatin1().constData(), + m_edid.identifier.toLatin1().constData(), + m_edid.manufacturer.toLatin1().constData(), + m_edid.model.toLatin1().constData(), + m_edid.serialNumber.toLatin1().constData(), + m_edid.physicalSize.width(), m_edid.physicalSize.height()); + } else { + // This property is defined by the xrandr spec. Parsing failure indicates a valid error, + // but keep this as debug, for details see 4f515815efc318ddc909a0399b71b8a684962f38. + qCDebug(lcQpaScreen) << "Failed to parse EDID data for output" << name() << + "edid data: " << edid; + } + } } QXcbScreen::~QXcbScreen() @@ -899,9 +906,13 @@ QByteArray QXcbScreen::getOutputProperty(xcb_atom_t atom) const QByteArray QXcbScreen::getEdid() const { + QByteArray result; + if (!connection()->hasXRandr()) + return result; + // Try a bunch of atoms xcb_atom_t atom = connection()->internAtom("EDID"); - QByteArray result = getOutputProperty(atom); + result = getOutputProperty(atom); if (result.isEmpty()) { atom = connection()->internAtom("EDID_DATA"); result = getOutputProperty(atom); -- cgit v1.2.3 From dbabe27b5b6402fb7d3c984eed685d5de1ffcc73 Mon Sep 17 00:00:00 2001 From: Michael Dippold Date: Tue, 14 Nov 2017 20:43:29 -0800 Subject: Android: Support caps lock MetaKeyKeyListener augments the meta state of the keyboard, we need to also check the KeyEvent.getMetaState(). Task-number: QTBUG-61369 Change-Id: I07a5d7b1b741a958bc94e1f1677dc1f2256220b6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0f02304f9e..952bf04971 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -1127,7 +1127,7 @@ public class QtActivityDelegate return false; m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event); - int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState)); + int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState) | event.getMetaState()); int lc = c; m_metaState = MetaKeyKeyListener.adjustMetaAfterKeypress(m_metaState); -- cgit v1.2.3 From f0d226e4c5ddace02640e3b41d392e84dcd2ed02 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 22 Sep 2017 00:35:24 -0700 Subject: Add a "shim" to allow use of Clang 5's __builtin_available everywhere This is mostly relevant for Apple platforms, where we can use the new unguarded availability warnings to guarantee that proper version checks are present when using APIs that are not necessarily available on the deployment target. Change-Id: Ie408704b2924e1220491a9ea30f0141dfa4867d9 Reviewed-by: Thiago Macieira (cherry-picked from 70422449ef892d7cc3086d88e5e9e43c771e2bc3) --- src/corelib/global/global.pri | 5 +- src/corelib/global/qglobal.cpp | 3 + src/corelib/global/qglobal_p.h | 73 ++++++++++++++++++++++ src/corelib/global/qoperatingsystemversion_p.h | 8 --- src/corelib/global/qoperatingsystemversion_win.cpp | 3 + src/corelib/global/qoperatingsystemversion_win_p.h | 63 +++++++++++++++++++ src/tools/bootstrap/bootstrap.pro | 1 + 7 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 src/corelib/global/qoperatingsystemversion_win_p.h diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index a3c1c4d65e..eee01341a5 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -38,7 +38,10 @@ SOURCES += \ VERSIONTAGGING_SOURCES = global/qversiontagging.cpp darwin: SOURCES += global/qoperatingsystemversion_darwin.mm -win32: SOURCES += global/qoperatingsystemversion_win.cpp +win32 { + SOURCES += global/qoperatingsystemversion_win.cpp + HEADERS += global/qoperatingsystemversion_win_p.h +} # qlibraryinfo.cpp includes qconfig.cpp INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 8d614b4f91..d609f6a30a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -47,6 +47,9 @@ #include "qdatetime.h" #include "qoperatingsystemversion.h" #include "qoperatingsystemversion_p.h" +#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT) +#include "qoperatingsystemversion_win_p.h" +#endif #include #include diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h index b1d2836783..5f5891bcff 100644 --- a/src/corelib/global/qglobal_p.h +++ b/src/corelib/global/qglobal_p.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2015 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -59,5 +60,77 @@ #include #endif +#if defined(__cplusplus) +#if !QT_HAS_BUILTIN(__builtin_available) +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct qt_clang_builtin_available_os_version_data { + QOperatingSystemVersion::OSType type; + const char *version; +}; + +static inline bool qt_clang_builtin_available( + const std::initializer_list &versions) +{ + for (auto it = versions.begin(); it != versions.end(); ++it) { + if (currentType() == it->type) { + const auto current = QOperatingSystemVersion::current(); + return QVersionNumber( + current.majorVersion(), + current.minorVersion(), + current.microVersion()) >= QVersionNumber::fromString( + QString::fromLatin1(it->version)); + } + } + + // Result is true if the platform is not any of the checked ones; this matches behavior of + // LLVM __builtin_available and @available constructs + return true; +} + +QT_END_NAMESPACE + +#define QT_AVAILABLE_OS_VER(os, ver) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available_os_version_data){\ + QT_PREPEND_NAMESPACE(QOperatingSystemVersion)::os, #ver} +#define QT_AVAILABLE_CAT(L, R) QT_AVAILABLE_CAT_(L, R) +#define QT_AVAILABLE_CAT_(L, R) L ## R +#define QT_AVAILABLE_EXPAND(...) QT_AVAILABLE_OS_VER(__VA_ARGS__) +#define QT_AVAILABLE_SPLIT(os_ver) QT_AVAILABLE_EXPAND(QT_AVAILABLE_CAT(QT_AVAILABLE_SPLIT_, os_ver)) +#define QT_AVAILABLE_SPLIT_macOS MacOS, +#define QT_AVAILABLE_SPLIT_iOS IOS, +#define QT_AVAILABLE_SPLIT_tvOS TvOS, +#define QT_AVAILABLE_SPLIT_watchOS WatchOS, +#define QT_BUILTIN_AVAILABLE0(e) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({}) +#define QT_BUILTIN_AVAILABLE1(a, e) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a)}) +#define QT_BUILTIN_AVAILABLE2(a, b, e) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ + QT_AVAILABLE_SPLIT(b)}) +#define QT_BUILTIN_AVAILABLE3(a, b, c, e) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ + QT_AVAILABLE_SPLIT(b), \ + QT_AVAILABLE_SPLIT(c)}) +#define QT_BUILTIN_AVAILABLE4(a, b, c, d, e) \ + QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ + QT_AVAILABLE_SPLIT(b), \ + QT_AVAILABLE_SPLIT(c), \ + QT_AVAILABLE_SPLIT(d)}) +#define QT_BUILTIN_AVAILABLE_ARG(arg0, arg1, arg2, arg3, arg4, arg5, ...) arg5 +#define QT_BUILTIN_AVAILABLE_CHOOSER(...) QT_BUILTIN_AVAILABLE_ARG(__VA_ARGS__, \ + QT_BUILTIN_AVAILABLE4, \ + QT_BUILTIN_AVAILABLE3, \ + QT_BUILTIN_AVAILABLE2, \ + QT_BUILTIN_AVAILABLE1, \ + QT_BUILTIN_AVAILABLE0, ) +#define __builtin_available(...) QT_BUILTIN_AVAILABLE_CHOOSER(__VA_ARGS__)(__VA_ARGS__) +#endif // !QT_HAS_BUILTIN(__builtin_available) +#endif // defined(__cplusplus) + #endif // QGLOBAL_P_H diff --git a/src/corelib/global/qoperatingsystemversion_p.h b/src/corelib/global/qoperatingsystemversion_p.h index 78d0daf0c6..77f19d27c5 100644 --- a/src/corelib/global/qoperatingsystemversion_p.h +++ b/src/corelib/global/qoperatingsystemversion_p.h @@ -53,16 +53,8 @@ #include "qoperatingsystemversion.h" -#ifdef Q_OS_WIN -#include -#endif - QT_BEGIN_NAMESPACE -#ifdef Q_OS_WIN -OSVERSIONINFOEX qWindowsVersionInfo(); -#endif - static inline QOperatingSystemVersion::OSType currentType() { #if defined(Q_OS_WIN) diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp index 060ca2f7da..f3662ae1f9 100644 --- a/src/corelib/global/qoperatingsystemversion_win.cpp +++ b/src/corelib/global/qoperatingsystemversion_win.cpp @@ -37,7 +37,10 @@ ** ****************************************************************************/ +#include "qoperatingsystemversion_win_p.h" + #include "qoperatingsystemversion_p.h" + #include #include diff --git a/src/corelib/global/qoperatingsystemversion_win_p.h b/src/corelib/global/qoperatingsystemversion_win_p.h new file mode 100644 index 0000000000..446bd286fc --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion_win_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module 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$ +** +****************************************************************************/ + +#ifndef QOPERATINGSYSTEMVERSION_WIN_P_H +#define QOPERATINGSYSTEMVERSION_WIN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +OSVERSIONINFOEX qWindowsVersionInfo(); + +QT_END_NAMESPACE + +#endif // QOPERATINGSYSTEMVERSION_WIN_P_H diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 521dd5f0f2..50f669cd23 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -80,6 +80,7 @@ SOURCES += \ ../../corelib/tools/qstringbuilder.cpp \ ../../corelib/tools/qstring_compat.cpp \ ../../corelib/tools/qstringlist.cpp \ + ../../corelib/tools/qversionnumber.cpp \ ../../corelib/tools/qvsnprintf.cpp \ ../../corelib/xml/qxmlutils.cpp \ ../../corelib/xml/qxmlstream.cpp \ -- cgit v1.2.3 From d2d6c6f7813fa38ced6b80ead763ed6e6daaa951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Thu, 7 Dec 2017 11:19:40 +0100 Subject: QWidgetResizeHandler - undo (potential) move break When the mode is center we are typically moving the dock widget, but we should however not stop if the mode is Center. Though the regression (in commit e662b4ed721ee36f0a17cc413494b7d09395d52e) is not easy to reproduce it is clear that the code later may call "mouseMoveEvent(e)" and the mode is also checked for being Center and in that case the eventfilter (function) returns true (not false). Change-Id: I3936ec56833d613f78920d9ccf8ddb66e19e9802 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qwidgetresizehandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp index 09c5e52219..8a1f26dbc2 100644 --- a/src/widgets/widgets/qwidgetresizehandler.cpp +++ b/src/widgets/widgets/qwidgetresizehandler.cpp @@ -120,7 +120,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) break; const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range)); const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos()); - if (!widgetRect.contains(cursorPoint) || mode == Center || mode == Nowhere) + if (!widgetRect.contains(cursorPoint) || mode == Nowhere) return false; if (e->button() == Qt::LeftButton) { #if 0 // Used to be included in Qt4 for Q_WS_X11 -- cgit v1.2.3 From fefd9de52aaaae58d3c0150cbd19f0e403ba92ce Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 Dec 2017 10:17:59 +0100 Subject: Windows QPA: Emulate aboutToHide(), aboutToShow() signals of QPlatformMenu Wrap the call to TrackPopupMenu accordingly. Complements 7849aa6e96aa923fca5523afc8cf88edcc0bcf90. Task-number: QTBUG-64628 Change-Id: Ia370e566266e96ab690ce5ed41d06dea7cafd4e4 Reviewed-by: J-P Nurmi Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsmenu.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp index 4e1997c4f8..72f11d54b4 100644 --- a/src/plugins/platforms/windows/qwindowsmenu.cpp +++ b/src/plugins/platforms/windows/qwindowsmenu.cpp @@ -686,9 +686,16 @@ void QWindowsPopupMenu::showPopup(const QWindow *parentWindow, const QRect &targ bool QWindowsPopupMenu::trackPopupMenu(HWND windowHandle, int x, int y) { lastShownPopupMenu = this; - return TrackPopupMenu(menuHandle(), + // Emulate Show()/Hide() signals. Could be implemented by catching the + // WM_EXITMENULOOP, WM_ENTERMENULOOP messages; but they do not carry + // information telling which menu was opened. + emit aboutToShow(); + const bool result = + TrackPopupMenu(menuHandle(), QGuiApplication::layoutDirection() == Qt::RightToLeft ? UINT(TPM_RIGHTALIGN) : UINT(0), x, y, 0, windowHandle, nullptr) == TRUE; + emit aboutToHide(); + return result; } bool QWindowsPopupMenu::notifyTriggered(uint id) -- cgit v1.2.3 From 3d720f38faec4c1c600e128d5d8da5a4435ec1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 5 Dec 2017 00:22:05 +0100 Subject: iOS: Implement QIOSScreen::refreshRate to account for 120Hz displays Task-number: QTBUG-64968 Change-Id: If96f6cde8f2fc6d91beb842d82a881fe057260b5 Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index d63fa29ec3..be0f301710 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -69,6 +69,7 @@ public: QSizeF physicalSize() const Q_DECL_OVERRIDE; QDpi logicalDpi() const Q_DECL_OVERRIDE; qreal devicePixelRatio() const Q_DECL_OVERRIDE; + qreal refreshRate() const override; Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE; Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 0d3826fc4c..521495b42f 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -459,6 +459,16 @@ qreal QIOSScreen::devicePixelRatio() const return [m_uiScreen scale]; } +qreal QIOSScreen::refreshRate() const +{ +#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 100300, 110000, __WATCHOS_NA) + if (__builtin_available(iOS 10.3, tvOS 11, *)) + return m_uiScreen.maximumFramesPerSecond; +#endif + + return 60.0; +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { CGRect nativeBounds = -- cgit v1.2.3 From b0f142e3533599466f15f1303b063ee35b18e4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 8 Dec 2017 02:06:31 +0100 Subject: iOS: Ensure that the cursor rect doesn't trigger an inverted scroll If the cursor is at the top of the screen, it may end up with a cursor rect that extends beyond the screen after we pad it. We need to make sure it's constrained by the screen geometry before checking if it's within the available geometry. Task-number: QTBUG-65041 Change-Id: I115f49d359b3c2e10219a6b8aa5ad051f44256a7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosinputcontext.mm | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 237077400b..050c592aca 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -500,23 +500,25 @@ void QIOSInputContext::scrollToCursor() QWindow *focusWindow = qApp->focusWindow(); QRect cursorRect = qApp->inputMethod()->cursorRectangle().translated(focusWindow->geometry().topLeft()).toRect(); - if (cursorRect.isNull()) { - scroll(0); - return; - } - - // Add some padding so that the cusor does not end up directly above the keyboard - static const int kCursorRectPadding = 20; - cursorRect.adjust(0, -kCursorRectPadding, 0, kCursorRectPadding); // We explicitly ask for the geometry of the screen instead of the availableGeometry, - // as we hide the statusbar when scrolling the screen, so the available geometry will + // as we hide the status bar when scrolling the screen, so the available geometry will // include the space taken by the status bar at the moment. QRect screenGeometry = focusWindow->screen()->geometry(); + + if (!cursorRect.isNull()) { + // Add some padding so that the cursor does not end up directly above the keyboard + static const int kCursorRectPadding = 20; + cursorRect.adjust(0, -kCursorRectPadding, 0, kCursorRectPadding); + + // Make sure the cursor rect is still within the screen geometry after padding + cursorRect &= screenGeometry; + } + QRect keyboardGeometry = QRectF::fromCGRect(m_keyboardState.keyboardEndRect).toRect(); QRect availableGeometry = (QRegion(screenGeometry) - keyboardGeometry).boundingRect(); - if (!availableGeometry.contains(cursorRect, true)) { + if (!cursorRect.isNull() && !availableGeometry.contains(cursorRect)) { qImDebug() << "cursor rect" << cursorRect << "not fully within" << availableGeometry; int scrollToCenter = -(availableGeometry.center() - cursorRect.center()).y(); int scrollToBottom = focusWindow->screen()->geometry().bottom() - availableGeometry.bottom(); @@ -528,6 +530,8 @@ void QIOSInputContext::scrollToCursor() void QIOSInputContext::scroll(int y) { + Q_ASSERT(y >= 0); + UIView *rootView = scrollableRootView(); if (!rootView) return; -- cgit v1.2.3 From e055efb4457cd361c5b3b3caf2b236951ee1706d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 Dec 2017 09:06:52 +0100 Subject: Do not allow drag events when window is blocked by modal window Check for QWindowPrivate::blockedByModalWindow in QGuiApplicationPrivate::processDrag(). Task-number: QTBUG-46287 Change-Id: I8f43de8389f34458f9e10b37b94806b47a50d40a Reviewed-by: Gatis Paeglis Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qguiapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f43329afd0..6d37014b38 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2868,7 +2868,7 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM static QPointer currentDragWindow; static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction; QPlatformDrag *platformDrag = platformIntegration()->drag(); - if (!platformDrag) { + if (!platformDrag || (w && w->d_func()->blockedByModalWindow)) { lastAcceptedDropAction = Qt::IgnoreAction; return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect()); } -- cgit v1.2.3 From 48d677365a1061aa973b38d7b640498830bda452 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 9 Dec 2017 22:18:02 -0800 Subject: QStandardPaths: fall back to a default if PATH isn't set Change 28666d167aa8e602c0bea25ebc4d51b55005db13 simplified QProcess::start{Process,Detached} by using findExecutable() instead of using execvp, but this introduced an unintended side effect when the PATH environment variable isn't set. It turns out that most libc have a default fallback in that situation, which we didn't apply. This commit applies the default directly to findExecutable(), which seems sensible. [ChangeLog][QtCore][QProcess] Fixed a regression that made QProcess be unable to find executables when the PATH environment variable on some Unix systems wasn't set. This behavior should not be relied upon since many systems do not have sensible fallback values for PATH. [ChangeLog][QtCore][QStandardPaths] findExecutable() will now apply the default value for the PATH environment variable (as returned by the POSIX confstr(3) function or found in ) if the variable isn't set in the environment. Task-number: QTBUG-65076 Change-Id: I9407dcf22de6407c83b5fffd14feda6c1f509210 Reviewed-by: Oswald Buddenhagen Reviewed-by: David Faure --- src/corelib/io/qstandardpaths.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index c3d45caf0e..b3a5bd797a 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -48,6 +48,14 @@ #include #endif +#if QT_HAS_INCLUDE() +#include +#endif + +#ifdef Q_OS_UNIX +#include +#endif + #ifndef QT_NO_STANDARDPATHS QT_BEGIN_NAMESPACE @@ -509,6 +517,27 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr QStringList searchPaths = paths; if (paths.isEmpty()) { QByteArray pEnv = qgetenv("PATH"); + if (Q_UNLIKELY(pEnv.isNull())) { + // Get a default path. POSIX.1 does not actually require this, but + // most Unix libc fall back to confstr(_CS_PATH) if the PATH + // environment variable isn't set. Let's try to do the same. +#if defined(_PATH_DEFPATH) + // BSD API. + pEnv = _PATH_DEFPATH; +#elif defined(_CS_PATH) + // POSIX API. + size_t n = confstr(_CS_PATH, nullptr, 0); + if (n) { + pEnv.resize(n); + // size()+1 is ok because QByteArray always has an extra NUL-terminator + confstr(_CS_PATH, pEnv.data(), pEnv.size() + 1); + } +#else + // Windows SDK's execvpe() does not have a fallback, so we won't + // apply one either. +#endif + } + // Remove trailing slashes, which occur on Windows. const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts); searchPaths.reserve(rawPaths.size()); -- cgit v1.2.3 From eff7a5f38cd2814c57a8214dbd53bd6fd345023b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 10 Dec 2017 18:06:05 +0100 Subject: QFileSystemModel: properly align file size column The file size column was not properly horizontally aligned. The model only returned Qt::AlignRight with no horizontal alignment. This lead to a top alignment within QStyle::alignedRect(). Task-number: QTBUG-64098 Change-Id: Iaef30200a63bd0975c88a67d0af2eb1d5254f588 Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 179c5861c9..7458cfdd80 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -747,7 +747,7 @@ QVariant QFileSystemModel::data(const QModelIndex &index, int role) const break; case Qt::TextAlignmentRole: if (index.column() == 1) - return Qt::AlignRight; + return QVariant(Qt::AlignTrailing | Qt::AlignVCenter); break; case FilePermissions: int p = permissions(index); -- cgit v1.2.3 From 26aa20407d2e3feb97d80dabc1d922d4ef21a433 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 30 Nov 2017 21:45:32 +0100 Subject: QHeaderView: Fix painting vertical headers in rtl mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In rtl mode, the headers were not painted correctly. The style option selectedPosition was not filled correctly and the paint rect needed to be adjusted by one pixel to fit the table grid. Task-number: QTBUG-56520 Change-Id: Ib92d5ab6ff730bba67eca35c83cd638e613f58b9 Reviewed-by: Friedemann Kleint Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 4e4c9572a3..9eb6c3465f 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2319,18 +2319,20 @@ void QHeaderView::paintEvent(QPaintEvent *e) d->prepareSectionSelected(); // clear and resize the bit array QRect currentSectionRect; - int logical; const int width = d->viewport->width(); const int height = d->viewport->height(); + const int rtlHorizontalOffset = d->reverse() ? 1 : 0; for (int i = start; i <= end; ++i) { if (d->isVisualIndexHidden(i)) continue; painter.save(); - logical = logicalIndex(i); + const int logical = logicalIndex(i); if (d->orientation == Qt::Horizontal) { - currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height); + currentSectionRect.setRect(sectionViewportPosition(logical) + rtlHorizontalOffset, + 0, sectionSize(logical), height); } else { - currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical)); + currentSectionRect.setRect(0, sectionViewportPosition(logical), + width, sectionSize(logical)); } currentSectionRect.translate(offset); @@ -2776,9 +2778,9 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical if (first && last) opt.position = QStyleOptionHeader::OnlyOneSection; else if (first) - opt.position = QStyleOptionHeader::Beginning; + opt.position = d->reverse() ? QStyleOptionHeader::End : QStyleOptionHeader::Beginning; else if (last) - opt.position = QStyleOptionHeader::End; + opt.position = d->reverse() ? QStyleOptionHeader::Beginning : QStyleOptionHeader::End; else opt.position = QStyleOptionHeader::Middle; opt.orientation = d->orientation; -- cgit v1.2.3 From 06e903cf684a829716736702b95b66846c713fd5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 9 Dec 2017 22:41:41 +0100 Subject: QHeaderView: Use correct font for drag'n'drop indicator pixmap QHeaderViewPrivate::setupSectionIndicator() did not honor the font set for the QHeaderView which results in a wrong font in the indicator pixmap. Fix it by using the correct font for the dragged section as it is done in paintEvent() Task-number: QTBUG-65017 Change-Id: I5393c6861073de22f30ffa13e12c5e2cf8aa7776 Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 9eb6c3465f..0905a20812 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3159,6 +3159,15 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position) QRect rect(0, 0, w, h); QPainter painter(&pm); + const QVariant variant = model->headerData(section, orientation, + Qt::FontRole); + if (variant.isValid() && variant.canConvert()) { + const QFont sectionFont = qvariant_cast(variant); + painter.setFont(sectionFont); + } else { + painter.setFont(q->font()); + } + painter.setOpacity(0.75); q->paintSection(&painter, rect, section); painter.end(); -- cgit v1.2.3 From 495833b7965330cc1db5fdce0a3c86f7ec15e836 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 11 Dec 2017 15:50:21 +0100 Subject: [ChangeLog][QPA][eglfs] Fix crash when using cursors and multiple GL contexts The hash from QOpenGLContext* to cursor texture/shader data can accumulate dangling pointers if the program uses multiple contexts on the same screen. This is fixed by moving the cursor data into the platform context. The code for deleting the texture and shader program is omitted as it is tied to the life time of the context and the GL context deletes its resources automatically upon destruction. Task-number: QTBUG-65119 Change-Id: Ic3b8e5669d14949af811bdf047e7d47000216180 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/api/qeglfscontext_p.h | 3 +++ src/plugins/platforms/eglfs/api/qeglfscursor.cpp | 15 ++++----------- src/plugins/platforms/eglfs/api/qeglfscursor_p.h | 22 ++++++++++------------ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h index 96f7f01381..af8725b6b3 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h @@ -52,6 +52,7 @@ // #include "qeglfsglobal_p.h" +#include "qeglfscursor_p.h" #include #include @@ -68,6 +69,8 @@ public: void runGLChecks() override; void swapBuffers(QPlatformSurface *surface) override; + QEglFSCursorData cursorData; + private: EGLNativeWindowType m_tempWindow; }; diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp index f46206cab5..22319fcc66 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp @@ -40,10 +40,10 @@ #include "qeglfscursor_p.h" #include "qeglfsintegration_p.h" #include "qeglfsscreen_p.h" +#include "qeglfscontext_p.h" #include #include -#include #include #include #include @@ -115,13 +115,6 @@ void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::Device void QEglFSCursor::resetResources() { - if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) { - GraphicsContextData &gfx(m_gfx[ctx]); - delete gfx.program; - glDeleteTextures(1, &gfx.customCursorTexture); - glDeleteTextures(1, &gfx.atlasTexture); - gfx = GraphicsContextData(); - } m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); } @@ -144,8 +137,8 @@ void QEglFSCursor::createShaderPrograms() " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" "}\n"; - GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]); - gfx.program = new QOpenGLShaderProgram; + QEglFSCursorData &gfx = static_cast(QOpenGLContext::currentContext()->handle())->cursorData; + gfx.program.reset(new QOpenGLShaderProgram); gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); gfx.program->bindAttributeLocation("vertexCoordEntry", 0); @@ -475,7 +468,7 @@ void QEglFSCursor::draw(const QRectF &r) { StateSaver stateSaver; - GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]); + QEglFSCursorData &gfx = static_cast(QOpenGLContext::currentContext()->handle())->cursorData; if (!gfx.program) { // one time initialization initializeOpenGLFunctions(); diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h index aaeb83cb99..89c2e89f58 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -56,6 +56,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -81,6 +82,15 @@ private: #if QT_CONFIG(opengl) +struct QEglFSCursorData { + QScopedPointer program; + int textureEntry = 0; + int matEntry = 0; + uint customCursorTexture = 0; + uint atlasTexture = 0; + qint64 customCursorKey = 0; +}; + class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor , protected QOpenGLFunctions { @@ -143,18 +153,6 @@ private: QEglFSCursorDeviceListener *m_deviceListener; bool m_updateRequested; QMatrix4x4 m_rotationMatrix; - - struct GraphicsContextData { - GraphicsContextData() : program(nullptr), textureEntry(0), matEntry(0), - customCursorTexture(0), atlasTexture(0), customCursorKey(0) { } - QOpenGLShaderProgram *program; - int textureEntry; - int matEntry; - uint customCursorTexture; - uint atlasTexture; - qint64 customCursorKey; - }; - QHash m_gfx; }; #endif // QT_CONFIG(opengl) -- cgit v1.2.3 From 280b8b79c0f8a75bf580c76cf61b43061b842aaa Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 28 Nov 2017 14:56:02 +0200 Subject: Allow the users to disable the text handles The user can set QT_QPA_NO_TEXT_HANDLES to 1 to disable the text handles. Change-Id: I974af4d79c86259288035fe20b6a9d0c6d047af8 Reviewed-by: J-P Nurmi --- src/plugins/platforms/android/qandroidinputcontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 7fa809f3f8..ccc7f06b6b 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -526,6 +526,10 @@ void QAndroidInputContext::updateCursorPosition() void QAndroidInputContext::updateSelectionHandles() { + static bool noHandles = qEnvironmentVariableIntValue("QT_QPA_NO_TEXT_HANDLES"); + if (noHandles) + return; + auto im = qGuiApp->inputMethod(); if (!m_focusObject || (m_cursorHandleShown == CursorHandleNotShown)) { // Hide the handles -- cgit v1.2.3 From e55c7974db42a2c5bc5e6a8a1ef88ea5602ae266 Mon Sep 17 00:00:00 2001 From: Heikki Haveri Date: Wed, 29 Nov 2017 12:57:28 +0200 Subject: Fix Android Service thread getting stuck in service startup This change allows services using QAndroidService to function properly. A service using a plain QCoreApplication is still affected. The original code uses postfix decrement, causing an off-by-one error in reference counting, which, in turn, fails to properly release a semaphore. Fix by using deref() instead, which is also more readable, and consistent with the use of ref() elsewhere in the code. Task-number: QTBUG-64728 Change-Id: I99b59307638d619506c594f86de6d7d202d755f2 Reviewed-by: Marc Mutz Reviewed-by: BogDan Vatra --- src/corelib/kernel/qjnihelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 02c58858ff..0d7c143999 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -592,7 +592,7 @@ void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *liste { QMutexLocker lock(g_onBindListenerMutex); *g_onBindListener = listener; - if (!(*g_serviceSetupLockers)--) + if (!g_serviceSetupLockers->deref()) g_waitForServiceSetupSemaphore->release(); } -- cgit v1.2.3 From 141bca90e16073086124e542cdb0b91556fe06c5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 Dec 2017 10:20:52 +0100 Subject: Windows QPA: Fix handling of override cursors Override cursors were not restored when nested or in a dual monitor setups. The default cursor stored in QWindowsCursor::m_overriddenCursor was clobbered by subsequent calls to QWindowsCursor::setOverrideCursor(). This caused for example the wait cursor to remain active when switching to Help Mode in Qt Creator. Add a check preventing that. Make the variable static so that it is shared between the cursors of multiple screens. Amends b05d1c2ebfebf0f427a92668c0a7b177d0952012. Task-number: QTBUG-65001 Change-Id: Iead5804d317f73dedd78d22c1c85c62b5349ab83 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 6 +++++- src/plugins/platforms/windows/qwindowscursor.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index e7ba08b719..1da7de7451 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -548,6 +548,8 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle); } +HCURSOR QWindowsCursor::m_overriddenCursor = nullptr; + /*! \brief Return cached pixmap cursor or create new one. */ @@ -623,7 +625,9 @@ void QWindowsCursor::setOverrideCursor(const QCursor &cursor) { const CursorHandlePtr wcursor = cursorHandle(cursor); if (wcursor->handle()) { - m_overriddenCursor = SetCursor(wcursor->handle()); + const HCURSOR previousCursor = SetCursor(wcursor->handle()); + if (m_overriddenCursor == nullptr) + m_overriddenCursor = previousCursor; } else { qWarning("%s: Unable to obtain system cursor for %d", __FUNCTION__, cursor.shape()); diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 9aa9523ac8..28c7e88a6e 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -141,7 +141,7 @@ private: mutable QPixmap m_linkDragCursor; mutable QPixmap m_ignoreDragCursor; - HCURSOR m_overriddenCursor = nullptr; + static HCURSOR m_overriddenCursor; }; QT_END_NAMESPACE -- cgit v1.2.3 From 9b597a09f1b96071fb1e2ee72aafc9dfed76ed14 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 Dec 2017 09:53:44 +0100 Subject: QtGui/Windows: Fix wait cursors remaining active In QWindowPrivate::applyCursor(), do not apply override cursors when the platform supports QPlatformCursor::OverrideCursor. Complements b05d1c2ebfebf0f427a92668c0a7b177d0952012. Task-number: QTBUG-65001 Change-Id: Ie84cc30ad99b22e037aae829a2ce847ec4bf900f Reviewed-by: Oliver Wolff --- src/gui/kernel/qwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index fea55e459d..3e5777ad49 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2790,6 +2790,8 @@ bool QWindowPrivate::applyCursor() if (!platformWindow) return true; QCursor *c = QGuiApplication::overrideCursor(); + if (c != nullptr && platformCursor->capabilities().testFlag(QPlatformCursor::OverrideCursor)) + return true; if (!c && hasCursor) c = &cursor; platformCursor->changeCursor(c, q); -- cgit v1.2.3 From 4a4efd5693d42a0d5ece0fb166357b0255cb205d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 08:46:18 +0100 Subject: qwindowsopengltester.cpp: Fix -Wclazy-strict-iterators Change-Id: Id22096197aa5bf406ea1f072e8b5ca2a90578eec Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowsopengltester.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 5283d6b260..a511cc6164 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -214,7 +214,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c #else QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description); SupportedRenderersCache *srCache = supportedRenderersCache(); - SupportedRenderersCache::const_iterator it = srCache->find(qgpu); + SupportedRenderersCache::const_iterator it = srCache->constFind(qgpu); if (it != srCache->cend()) return *it; -- cgit v1.2.3 From 6a5ca7240a03cce4e490b493bb6185df019e7d87 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 Dec 2017 13:23:38 +0100 Subject: Fix QEGLPbuffer::isValid() with surfaceless contexts Task-number: QTBUG-65125 Change-Id: Idcd87804ab63031e48ff2f72eb98c986bfa39f25 Reviewed-by: Andy Nichols --- src/platformsupport/eglconvenience/qeglpbuffer.cpp | 11 ++++++++--- src/platformsupport/eglconvenience/qeglpbuffer_p.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp index 67d7204734..15fc089778 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp +++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp @@ -62,7 +62,7 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { - bool hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless) + m_hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless) && q_hasEglExtension(display, "EGL_KHR_surfaceless_context"); // Disable surfaceless contexts on Mesa for now. As of 10.6.0 and Intel at least, some @@ -72,9 +72,9 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs // read/draw surface in the Intel backend. const char *vendor = eglQueryString(display, EGL_VENDOR); // hard to check for GL_ strings here, so blacklist all Mesa if (vendor && strstr(vendor, "Mesa")) - hasSurfaceless = false; + m_hasSurfaceless = false; - if (hasSurfaceless) + if (m_hasSurfaceless) return; EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT); @@ -100,4 +100,9 @@ QEGLPbuffer::~QEGLPbuffer() eglDestroySurface(m_display, m_pbuffer); } +bool QEGLPbuffer::isValid() const +{ + return m_pbuffer != EGL_NO_SURFACE || m_hasSurfaceless; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h index 38370c0e62..76233967e7 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h +++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h @@ -64,7 +64,7 @@ public: ~QEGLPbuffer(); QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } - bool isValid() const Q_DECL_OVERRIDE { return m_pbuffer != EGL_NO_SURFACE; } + bool isValid() const Q_DECL_OVERRIDE; EGLSurface pbuffer() const { return m_pbuffer; } @@ -72,6 +72,7 @@ private: QSurfaceFormat m_format; EGLDisplay m_display; EGLSurface m_pbuffer; + bool m_hasSurfaceless; }; QT_END_NAMESPACE -- cgit v1.2.3 From 7257862fb2edfab0219d6cd45c83677049404f7d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 Dec 2017 16:55:02 +0100 Subject: Set sharedPainter correctly for QGraphicsEffect Autotest is taken from the previously reverted 8b1377fde16a2049a1c27f6d005bff84a8f85f28. Task-number: QTBUG-60231 Change-Id: I44dd79cba22b6baefdd6d95c176790bef0b7eafe Reviewed-by: Andy Nichols --- src/widgets/kernel/qwidget.cpp | 4 ++-- .../effects/qgraphicseffect/tst_qgraphicseffect.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index de734b6f51..125f1cf246 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5528,11 +5528,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP setSystemClip(pdev, rgn.translated(offset)); QPainter p(pdev); p.translate(offset); - context.painter = &p; + context.painter = context.sharedPainter = &p; graphicsEffect->draw(&p); setSystemClip(pdev, QRegion()); } else { - context.painter = sharedPainter; + context.painter = context.sharedPainter = sharedPainter; if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { sourced->invalidateCache(); sourced->lastEffectTransform = sharedPainter->worldTransform(); diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp index a1cb729849..dfe5baba71 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp @@ -52,6 +52,7 @@ private slots: void boundingRect2(); void draw(); void opacity(); + void nestedOpaqueOpacity(); void grayscale(); void colorize(); void drawPixmapItem(); @@ -407,6 +408,26 @@ void tst_QGraphicsEffect::opacity() QCOMPARE(effect->m_opacity, qreal(0.5)); } +void tst_QGraphicsEffect::nestedOpaqueOpacity() +{ + // QTBUG-60231: Nesting widgets with a QGraphicsEffect on a toplevel with + // QGraphicsOpacityEffect caused crashes due to constructing several + // QPainter instances on a device in the fast path for + // QGraphicsOpacityEffect::opacity=1 + QWidget topLevel; + topLevel.setWindowTitle(QTest::currentTestFunction()); + topLevel.resize(320, 200); + QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect; + opacityEffect->setOpacity(1); + topLevel.setGraphicsEffect(opacityEffect); + QWidget *child = new QWidget(&topLevel); + child->resize(topLevel.size() / 2); + QGraphicsDropShadowEffect *childEffect = new QGraphicsDropShadowEffect; + child->setGraphicsEffect(childEffect); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); +} + void tst_QGraphicsEffect::grayscale() { if (qApp->desktop()->depth() < 24) -- cgit v1.2.3 From 782eb1a114c0aaa729925899b2061d47f494435f Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 Dec 2017 15:15:56 +0100 Subject: Report modifiers correctly in mouse events with evdev and libinput Task-number: QTBUG-60694 Change-Id: I7b1625e5f31e49cd2ab18a83bbd0f65f9b58088d Reviewed-by: Andy Nichols --- src/gui/kernel/qinputdevicemanager.cpp | 44 ++++++++++++++++++++++ src/gui/kernel/qinputdevicemanager_p.h | 3 ++ src/gui/kernel/qinputdevicemanager_p_p.h | 2 + .../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 7 ++++ .../input/libinput/qlibinputkeyboard.cpp | 6 +++ .../input/libinput/qlibinputpointer.cpp | 17 ++++++--- 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index 2d231ae26f..37b1450d5a 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -92,4 +92,48 @@ void QInputDeviceManager::setCursorPos(const QPoint &pos) emit cursorPositionChangeRequested(pos); } +/*! + \return the keyboard modifier state stored in the QInputDeviceManager object. + + Keyboard input handlers are expected to keep this up-to-date via + setKeyboardModifiers(). + + Querying the state via this function (e.g. from a mouse handler that needs + to include the modifier state in mouse events) is the preferred alternative + over QGuiApplication::keyboardModifiers() since the latter may not report + the current state due to asynchronous QPA event processing. + */ +Qt::KeyboardModifiers QInputDeviceManager::keyboardModifiers() const +{ + Q_D(const QInputDeviceManager); + return d->keyboardModifiers; +} + +void QInputDeviceManager::setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key) +{ + Q_D(QInputDeviceManager); + Qt::KeyboardModifiers mods; + switch (key) { + case Qt::Key_Shift: + mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ShiftModifier); + break; + case Qt::Key_Control: + mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ControlModifier); + break; + case Qt::Key_Alt: + mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::AltModifier); + break; + case Qt::Key_Meta: + mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::MetaModifier); + break; + case Qt::Key_AltGr: + mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::GroupSwitchModifier); + break; + default: + mods = modsBeforeEvent; + break; + } + d->keyboardModifiers = mods; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index db9d0596b6..ddf1e6befa 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -78,6 +78,9 @@ public: void setCursorPos(const QPoint &pos); + Qt::KeyboardModifiers keyboardModifiers() const; + void setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key); + signals: void deviceListChanged(QInputDeviceManager::DeviceType type); void cursorPositionChangeRequested(const QPoint &pos); diff --git a/src/gui/kernel/qinputdevicemanager_p_p.h b/src/gui/kernel/qinputdevicemanager_p_p.h index ae91f3a2ab..0a91252fbc 100644 --- a/src/gui/kernel/qinputdevicemanager_p_p.h +++ b/src/gui/kernel/qinputdevicemanager_p_p.h @@ -69,6 +69,8 @@ public: void setDeviceCount(QInputDeviceManager::DeviceType type, int count); QMap m_deviceCount; + + Qt::KeyboardModifiers keyboardModifiers; }; QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 5c87cb7c9c..a069a48388 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -49,6 +49,9 @@ #include #include +#include +#include + #ifdef Q_OS_FREEBSD #include #else @@ -222,6 +225,8 @@ void QEvdevKeyboardHandler::readKeycode() void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat) { + QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiers, qtcode); + QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease), qtcode, modifiers, nativecode + 8, 0, int(modifiers), (unicode != 0xffff ) ? QString(unicode) : QString(), autoRepeat); @@ -403,6 +408,8 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint Qt::KeyboardModifiers qtmods = Qt::KeyboardModifiers(qtcode & modmask); qtcode &= ~modmask; + // qtmods here is the modifier state before the event, i.e. not + // including the current key in case it is a modifier. qCDebug(qLcEvdevKeyMap, "Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode, int(qtmods)); // If NumLockOff and keypad key pressed remap event sent diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp index f14a2e8f04..3722c1ceca 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp +++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp @@ -40,6 +40,8 @@ #include "qlibinputkeyboard_p.h" #include #include +#include +#include #include #include #ifndef QT_NO_XKBCOMMON_EVDEV @@ -196,6 +198,8 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e) const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k); + // mods here is the modifier state before the event, i.e. not + // including the current key in case it is a modifier. Qt::KeyboardModifiers mods = Qt::NoModifier; const int qtkey = keysymToQtKey(sym, &mods, text); @@ -211,6 +215,8 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e) xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP); + QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(mods, qtkey); + QWindowSystemInterface::handleExtendedKeyEvent(Q_NULLPTR, pressed ? QEvent::KeyPress : QEvent::KeyRelease, qtkey, mods, k, sym, mods, text); diff --git a/src/platformsupport/input/libinput/qlibinputpointer.cpp b/src/platformsupport/input/libinput/qlibinputpointer.cpp index bdeac8db7e..734d2fbbc0 100644 --- a/src/platformsupport/input/libinput/qlibinputpointer.cpp +++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include @@ -78,7 +80,8 @@ void QLibInputPointer::processButton(libinput_event_pointer *e) m_buttons.setFlag(button, pressed); - QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, + QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers()); } void QLibInputPointer::processMotion(libinput_event_pointer *e) @@ -91,7 +94,8 @@ void QLibInputPointer::processMotion(libinput_event_pointer *e) m_pos.setX(qBound(g.left(), qRound(m_pos.x() + dx), g.right())); m_pos.setY(qBound(g.top(), qRound(m_pos.y() + dy), g.bottom())); - QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleMouseEvent(Q_NULLPTR, m_pos, m_pos, m_buttons, + QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers()); } void QLibInputPointer::processAxis(libinput_event_pointer *e) @@ -100,15 +104,18 @@ void QLibInputPointer::processAxis(libinput_event_pointer *e) const double v = libinput_event_pointer_get_axis_value(e) * 120; const Qt::Orientation ori = libinput_event_pointer_get_axis(e) == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL ? Qt::Vertical : Qt::Horizontal; - QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), ori, QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), ori, + QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers()); #else if (libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) * 120; - QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Vertical, QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Vertical, + QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers()); } if (libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) * 120; - QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Horizontal, QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleWheelEvent(Q_NULLPTR, m_pos, m_pos, qRound(-v), Qt::Horizontal, + QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers()); } #endif } -- cgit v1.2.3 From 98b7ad7682c6bf0e944fb01e17b8ea4ac78a5a7b Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Tue, 12 Dec 2017 11:34:42 +0200 Subject: QNX: fix slog2 for QNX7 Change the include header to sys/slog2.h, which is available in both QNX 6.6.0 and 7. Task-number: QTBUG-64033 Change-Id: I26d8c5451376bab33e11f4784ca772f84cd6fc28 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/configure.json | 2 +- src/corelib/global/qlogging.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/configure.json b/src/corelib/configure.json index a5b69a2df6..3db9942123 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -178,7 +178,7 @@ "slog2": { "label": "slog2", "test": { - "include": "slog2.h", + "include": "sys/slog2.h", "main": "slog2_set_default_buffer((slog2_buffer_t)-1);" }, "export": "", diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index b5ba935194..1307118bdf 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -61,7 +61,7 @@ #include #endif #if QT_CONFIG(slog2) -#include +#include #endif #ifdef Q_OS_ANDROID -- cgit v1.2.3 From ae55e75b1b6c2c07f4ef084ee27448fc0262c7c0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 11 Dec 2017 15:48:41 +0100 Subject: Paint text decoration where the text is For multi text-item texts we should render the text decoration at the same position as the text-item part is, and not always from the beginning of the line. Task-number: QTBUG-60422 Change-Id: I9aa58fc164122ad1fae9716b8b18bdfbbbd778a9 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpainter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b95f9b18aa..6e84a3f384 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6482,7 +6482,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText extended->drawTextItem(QPointF(x, y), ti2); else engine->drawTextItem(QPointF(x, y), ti2); - drawTextItemDecoration(q, p, ti2.fontEngine, textEngine, ti2.underlineStyle, + drawTextItemDecoration(q, QPointF(x, y), ti2.fontEngine, textEngine, ti2.underlineStyle, ti2.flags, ti2.width.toReal(), ti2.charFormat); if (!rtl) @@ -6515,7 +6515,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText extended->drawTextItem(QPointF(x, y), ti2); else engine->drawTextItem(QPointF(x,y), ti2); - drawTextItemDecoration(q, p, ti2.fontEngine, textEngine, ti2.underlineStyle, + drawTextItemDecoration(q, QPointF(x, y), ti2.fontEngine, textEngine, ti2.underlineStyle, ti2.flags, ti2.width.toReal(), ti2.charFormat); // reset the high byte for all glyphs -- cgit v1.2.3 From 91996d4ec4d9f54a4506b92aa06c097a7bb965a5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 Dec 2017 09:25:31 +0100 Subject: Bump version Change-Id: I752089caa4f2a0cb91d1c4bfa2c53fe25b6bb34e Reviewed-by: Oswald Buddenhagen --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index ace04b0970..135d1f7de1 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.9.3 +MODULE_VERSION = 5.9.4 -- cgit v1.2.3 From 27aacfb61e85a332394c7996f5c6603f07c28cd2 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 11 Dec 2017 12:46:11 +0100 Subject: QString: fix documentation of NUL-termination of unicode(), data(), constData() (or lack thereof). * `QString::utf16()` reallocates if `*this` has been constructed using `fromRawData()`. * `QString::data()` ensures a writable string, so will detach from raw data. * `QString::unicode()`, `constData()`, and `data() const` do not. They just return `QStringData::data()`, which may point to raw, non-NUL-terminated data. These functions can therefore not possibly have the same behavior, but were documented the same. Fix. Also drop the discussion of operator[](size()), as that, too, was not correct, and anyone who indexes with op[] beyond size() - 1 should not rely on proper behavior. [ChangeLog][QtCore][QString] QString::unicode(), constData() and `data() const` do not return a NUL-terminated string. This was true before, but the documentation claimed the opposite. Change-Id: I1437f57cd02bdf80264e8559608b46aa749c23a8 Reviewed-by: Thiago Macieira --- src/corelib/doc/snippets/qstring/main.cpp | 1 - src/corelib/tools/qstring.cpp | 32 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index c839c10b84..2ea75526df 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -733,7 +733,6 @@ void Widget::sizeFunction() int n = str.size(); // n == 5 str.data()[0]; // returns 'W' str.data()[4]; // returns 'd' - str.data()[5]; // returns '\0' //! [58] } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index af3d026682..c0a03e0011 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5138,14 +5138,9 @@ QString& QString::fill(QChar ch, int size) Returns the number of characters in this string. - The last character in the string is at position size() - 1. In - addition, QString ensures that the character at position size() - is always '\\0', so that you can use the return value of data() - and constData() as arguments to functions that expect - '\\0'-terminated strings. + The last character in the string is at position size() - 1. Example: - \snippet qstring/main.cpp 58 \sa isEmpty(), resize() @@ -5674,10 +5669,13 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1, /*! \fn const QChar *QString::unicode() const - Returns a '\\0'-terminated Unicode representation of the string. + Returns a Unicode representation of the string. The result remains valid until the string is modified. - \sa utf16() + \note The returned string may not be '\\0'-terminated. + Use size() to determine the length of the array. + + \sa utf16(), fromRawData() */ /*! @@ -8077,7 +8075,10 @@ bool QString::isRightToLeft() const Returns a pointer to the data stored in the QString. The pointer can be used to access and modify the characters that compose the - string. For convenience, the data is '\\0'-terminated. + string. + + Unlike constData() and unicode(), the returned data is always + '\\0'-terminated. Example: @@ -8093,18 +8094,25 @@ bool QString::isRightToLeft() const /*! \fn const QChar *QString::data() const \overload + + \note The returned string may not be '\\0'-terminated. + Use size() to determine the length of the array. + + \sa fromRawData() */ /*! \fn const QChar *QString::constData() const Returns a pointer to the data stored in the QString. The pointer - can be used to access the characters that compose the string. For - convenience, the data is '\\0'-terminated. + can be used to access the characters that compose the string. Note that the pointer remains valid only as long as the string is not modified. - \sa data(), operator[]() + \note The returned string may not be '\\0'-terminated. + Use size() to determine the length of the array. + + \sa data(), operator[](), fromRawData() */ /*! \fn void QString::push_front(const QString &other) -- cgit v1.2.3 From 27c840f5d45747da7f4d989afba172805ce1fb51 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 13 Dec 2017 10:57:46 +0100 Subject: Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If6111c59b958ba03f6ec5966af5cf443cae5cf9b Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qloggingregistry.cpp | 4 ++-- src/corelib/io/qloggingregistry_p.h | 2 +- tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 1bf61017f6..b5f8e30b80 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -255,7 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line) QLoggingRegistry::QLoggingRegistry() : categoryFilter(defaultCategoryFilter) { - initalizeRules(); // Init on first use + initializeRules(); // Init on first use } static bool qtLoggingDebug() @@ -284,7 +284,7 @@ static QVector loadRulesFromFile(const QString &filePath) Initializes the rules database by loading $QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini. */ -void QLoggingRegistry::initalizeRules() +void QLoggingRegistry::initializeRules() { QVector er, qr, cr; // get rules from environment diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h index a3857d3588..12a1f166b3 100644 --- a/src/corelib/io/qloggingregistry_p.h +++ b/src/corelib/io/qloggingregistry_p.h @@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry public: QLoggingRegistry(); - void initalizeRules(); + void initializeRules(); void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel); void unregisterCategory(QLoggingCategory *category); diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp index 15c63d4acd..a74ea3a89e 100644 --- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp +++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp @@ -212,7 +212,7 @@ private slots: qunsetenv("QT_LOGGING_RULES"); qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit()); - registry.initalizeRules(); + registry.initializeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0); @@ -220,7 +220,7 @@ private slots: // check that QT_LOGGING_RULES take precedence qputenv("QT_LOGGING_RULES", "Digia.*=true"); - registry.initalizeRules(); + registry.initializeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true); } @@ -246,7 +246,7 @@ private slots: file.close(); QLoggingRegistry registry; - registry.initalizeRules(); + registry.initializeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1); // remove file again -- cgit v1.2.3 From 457fe3e8e2f27d773032f4406d5f933ae155e8ff Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 29 Aug 2016 09:48:28 +0200 Subject: ANGLE: Fix resizing of windows Use the correct height/width values when calculating the vector for resizing the window content and the new size as viewport size. Task-number: QTBUG-62475 Change-Id: I33a8dc1379a908e991b04bc31dfc6254a6d005c9 Reviewed-by: Andre de la Rocha Reviewed-by: Miguel Costa Reviewed-by: Friedemann Kleint --- .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 20 ++++---- .../0016-ANGLE-Fix-resizing-of-windows.patch | 57 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index 785a83cd77..42c336c8cf 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -707,15 +707,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); // Create a quad in homogeneous coordinates - float x1 = (x / float(mWidth)) * 2.0f - 1.0f; - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + float x1 = (x / float(width)) * 2.0f - 1.0f; + float y1 = (y / float(height)) * 2.0f - 1.0f; + float x2 = ((x + width) / float(width)) * 2.0f - 1.0f; + float y2 = ((y + height) / float(height)) * 2.0f - 1.0f; - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); - float v2 = (y + height) / float(mHeight); + float u1 = x / float(width); + float v1 = y / float(height); + float u2 = (x + width) / float(width); + float v2 = (y + height) / float(height); // Invert the quad vertices depending on the surface orientation. if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) @@ -760,8 +760,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = static_cast(mWidth); - viewport.Height = static_cast(mHeight); + viewport.Width = static_cast(width); + viewport.Height = static_cast(height); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); diff --git a/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch b/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch new file mode 100644 index 0000000000..7ba92052f2 --- /dev/null +++ b/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch @@ -0,0 +1,57 @@ +From 55821d34b2208e7858dbba5648760b83c66b58a5 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Mon, 29 Aug 2016 09:48:28 +0200 +Subject: [PATCH] ANGLE: Fix resizing of windows + +Use the correct height/width values when calculating +the vector for resizing the window content and the +new size as viewport size. + +Task-number: QTBUG-62475 +Change-Id: I33a8dc1379a908e991b04bc31dfc6254a6d005c9 +--- + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 35 +++++++++++----------- + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +index 785a83cd77..fe72bc935d 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +@@ -707,15 +706,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + + // Create a quad in homogeneous coordinates +- float x1 = (x / float(mWidth)) * 2.0f - 1.0f; +- float y1 = (y / float(mHeight)) * 2.0f - 1.0f; +- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; +- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; ++ float x1 = (x / float(width)) * 2.0f - 1.0f; ++ float y1 = (y / float(height)) * 2.0f - 1.0f; ++ float x2 = ((x + width) / float(width)) * 2.0f - 1.0f; ++ float y2 = ((y + height) / float(height)) * 2.0f - 1.0f; + +- float u1 = x / float(mWidth); +- float v1 = y / float(mHeight); +- float u2 = (x + width) / float(mWidth); +- float v2 = (y + height) / float(mHeight); ++ float u1 = x / float(width); ++ float v1 = y / float(height); ++ float u2 = (x + width) / float(width); ++ float v2 = (y + height) / float(height); + + // Invert the quad vertices depending on the surface orientation. + if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) +@@ -760,8 +759,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; +- viewport.Width = static_cast(mWidth); +- viewport.Height = static_cast(mHeight); ++ viewport.Width = static_cast(width); ++ viewport.Height = static_cast(height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); +-- +2.15.0.windows.1 + -- cgit v1.2.3 From 59febb49e45b009b740ff8b67bba30c4a285a2f2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 11 Dec 2017 11:28:11 +0100 Subject: Fix a bug in the generation of the Unicode joining property data The code that was supposed to initialize the joining property of characters to the correct defaults was actually applied after reading in the data from the Unicode file, and was in a couple of cases overwriting explicitly specified data in ArabicShaping.txt Task-number: QTBUG-63191 Change-Id: Ie35261039b2211a827322ca11afacd9555ccefc7 Reviewed-by: Konstantin Ritt --- src/corelib/tools/qunicodetables.cpp | 20 ++++++++++---------- src/corelib/tools/qunicodetables_p.h | 4 ++-- util/unicode/main.cpp | 30 ++++++++++++++++-------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp index ecab750833..01fa8b2102 100644 --- a/src/corelib/tools/qunicodetables.cpp +++ b/src/corelib/tools/qunicodetables.cpp @@ -6083,9 +6083,9 @@ static const Properties uc_properties[] = { { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 13, 7 }, { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 7 }, { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 7 }, - { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 }, - { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 }, - { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3, 4, 4, 12, 2 }, + { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 }, + { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 }, + { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 3, 4, 4, 12, 2 }, { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 }, { 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 }, { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 8 }, @@ -6146,7 +6146,7 @@ static const Properties uc_properties[] = { { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 8 }, { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 8 }, { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 }, - { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 }, + { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 }, { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 }, { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 }, { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 }, @@ -6749,7 +6749,7 @@ static const Properties uc_properties[] = { { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 33 }, { 25, 10, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 }, { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 }, - { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 4, 33 }, + { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 4, 33 }, { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 }, { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 }, { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 }, @@ -7058,7 +7058,7 @@ static const Properties uc_properties[] = { { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 17, 2 }, { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 }, { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 }, - { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 }, + { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 }, { 10, 18, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 }, { 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 }, { 10, 1, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 }, @@ -7108,10 +7108,10 @@ static const Properties uc_properties[] = { { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 12, 2 }, { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 4, 4, 12, 2 }, { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 }, - { 10, 19, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, - { 10, 20, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, - { 10, 21, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, - { 10, 22, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, + { 10, 19, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, + { 10, 20, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, + { 10, 21, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, + { 10, 22, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 }, { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 }, { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 }, { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 6, 12, 3 }, diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h index 5a422ea4eb..be2f44f0c3 100644 --- a/src/corelib/tools/qunicodetables_p.h +++ b/src/corelib/tools/qunicodetables_p.h @@ -50,11 +50,11 @@ // We mean it. // -#include - #ifndef QUNICODETABLES_P_H #define QUNICODETABLES_P_H +#include + #include QT_BEGIN_NAMESPACE diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index c995a40343..fe6d4fbca1 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -1293,6 +1293,18 @@ static void readArabicShaping() { qDebug("Reading ArabicShaping.txt"); + // Initialize defaults: + // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U: + // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T. + // - All others not explicitly listed have joining type U. + for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) { + UnicodeData &d = UnicodeData::valueRef(codepoint); + if (d.p.joining == QChar::Joining_None) { + if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format) + d.p.joining = QChar::Joining_Transparent; + } + } + QFile f("data/ArabicShaping.txt"); if (!f.exists()) qFatal("Couldn't find ArabicShaping.txt"); @@ -1338,17 +1350,6 @@ static void readArabicShaping() break; } } - - // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U: - // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T. - // - All others not explicitly listed have joining type U. - for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) { - UnicodeData &d = UnicodeData::valueRef(codepoint); - if (d.p.joining == QChar::Joining_None) { - if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format) - d.p.joining = QChar::Joining_Transparent; - } - } } static void readDerivedAge() @@ -2525,7 +2526,7 @@ static QByteArray createSpecialCaseMap() out.chop(1); out += "\n};\n\n"; - qDebug(" memory usage: %d bytes", specialCaseMap.size()*sizeof(unsigned short)); + qDebug(" memory usage: %ld bytes", specialCaseMap.size()*sizeof(unsigned short)); return out; } @@ -3021,7 +3022,7 @@ int main(int, char **) "****************************************************************************/\n\n"; QByteArray note = - "/* This file is autogenerated from the Unicode "DATA_VERSION_S" database. Do not edit */\n\n"; + "/* This file is autogenerated from the Unicode " DATA_VERSION_S " database. Do not edit */\n\n"; QByteArray warning = "//\n" @@ -3062,9 +3063,10 @@ int main(int, char **) f.write(warning); f.write("#ifndef QUNICODETABLES_P_H\n" "#define QUNICODETABLES_P_H\n\n" + "#include \n\n" "#include \n\n" "QT_BEGIN_NAMESPACE\n\n"); - f.write("#define UNICODE_DATA_VERSION "DATA_VERSION_STR"\n\n"); + f.write("#define UNICODE_DATA_VERSION " DATA_VERSION_STR "\n\n"); f.write("namespace QUnicodeTables {\n\n"); f.write(property_string); f.write(grapheme_break_class_string); -- cgit v1.2.3 From ba44cdae38406c429c7fb43863a6883bd0f79cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 1 Dec 2017 19:03:05 +0100 Subject: Teach QPlatformWindow about safe area margins and implement for iOS The safe area margins of a window represent the area that is safe to place content within, without intersecting areas of the screen where system UI is placed, or where a screen bezel may cover the content. QWidget will incorporate the safe area margins into its contents margins, so that they are are never smaller than the safe area margins. This can be disabled by unsetting the Qt::WA_ContentsMarginsRespectsSafeArea widget attribute, which is set by default. QLayouts will automatically use the contents area of a widget for their layout, unless the Qt::WA_LayoutOnEntireRect attribute has been set. This can be used, along with a contents margin of 0 on the actual layout, to allow e.g. a background image to underlay the status bar and other system areas on an iOS device, while still allowing child widgets of that background to be inset based on the safe area. [ChangeLog][iOS/tvOS] Qt will now take the safe area margins of the device into account when computing layouts for QtWidgets. Change-Id: Ife3827ab663f0625c1451e75b14fb8eeffb00754 Reviewed-by: Richard Moe Gustavsen --- src/corelib/global/qnamespace.h | 2 + src/gui/kernel/qguiapplication.cpp | 14 +++ src/gui/kernel/qguiapplication_p.h | 2 + src/gui/kernel/qplatformwindow.cpp | 10 ++ src/gui/kernel/qplatformwindow.h | 1 + src/gui/kernel/qwindow_p.h | 2 + src/gui/kernel/qwindowsysteminterface.cpp | 7 ++ src/gui/kernel/qwindowsysteminterface.h | 3 + src/gui/kernel/qwindowsysteminterface_p.h | 12 ++- src/plugins/platforms/ios/qioswindow.h | 2 + src/plugins/platforms/ios/qioswindow.mm | 7 ++ src/plugins/platforms/ios/quiview.mm | 39 ++++++++ src/widgets/kernel/qwidget.cpp | 154 ++++++++++++++++++++++++------ src/widgets/kernel/qwidget_p.h | 3 + src/widgets/kernel/qwidgetwindow.cpp | 7 ++ 15 files changed, 234 insertions(+), 31 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index da44c01594..bd6b667aab 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -474,6 +474,8 @@ public: WA_TabletTracking = 129, + WA_ContentsMarginsRespectsSafeArea = 130, + // Add new attributes before this line WA_AttributeCount }; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 6d37014b38..cff11367f7 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1759,6 +1759,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv case QWindowSystemInterfacePrivate::WindowScreenChanged: QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast(e)); break; + case QWindowSystemInterfacePrivate::SafeAreaMarginsChanged: + QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(static_cast(e)); + break; case QWindowSystemInterfacePrivate::ApplicationStateChanged: { QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast(e); QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); } @@ -2212,6 +2215,17 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf } } +void QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *wse) +{ + if (wse->window.isNull()) + return; + + // Handle by forwarding directly to QWindowPrivate, instead of sending spontaneous + // QEvent like most other functions, as there's no QEvent type for the safe area + // change, and we don't want to add one until we know that this is a good API. + qt_window_private(wse->window)->processSafeAreaMarginsChanged(); +} + void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce) { if (self) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 3804667ef3..d67ab61ff8 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -133,6 +133,8 @@ public: static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e); static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e); + static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e); + static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e); static void updateFilteredScreenOrientation(QScreen *screen); diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 5062bd1e77..23e492ee7a 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -146,6 +146,16 @@ QMargins QPlatformWindow::frameMargins() const return QMargins(); } +/*! + The safe area margins of a window represent the area that is safe to + place content within, without intersecting areas of the screen where + system UI is placed, or where a screen bezel may cover the content. +*/ +QMargins QPlatformWindow::safeAreaMargins() const +{ + return QMargins(); +} + /*! Reimplemented in subclasses to show the surface if \a visible is \c true, and hide it if \a visible is \c false. diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 8af8791bb4..2bee55c7e0 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -86,6 +86,7 @@ public: virtual QRect normalGeometry() const; virtual QMargins frameMargins() const; + virtual QMargins safeAreaMargins() const; virtual void setVisible(bool visible); virtual void setWindowFlags(Qt::WindowFlags flags); diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index dd282a671d..568aa1e2fc 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -147,6 +147,8 @@ public: virtual void clearFocusObject(); virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; + virtual void processSafeAreaMarginsChanged() {}; + bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; } static QWindowPrivate *get(QWindow *window) { return window->d_func(); } diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 3f27094845..13f45d236e 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -265,6 +265,13 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *window, QScreen QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } +QT_DEFINE_QPA_EVENT_HANDLER(void, handleSafeAreaMarginsChanged, QWindow *window) +{ + QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e = + new QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent(window); + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} + QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate) { Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)); diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index e91c79749d..fb428233ab 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -179,6 +179,9 @@ public: static void handleWindowStateChanged(QWindow *window, Qt::WindowState newState, int oldState = -1); static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen); + template + static void handleSafeAreaMarginsChanged(QWindow *window); + template static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 0f350fb2d2..5b41ccc3a5 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -98,7 +98,8 @@ public: #endif ApplicationStateChanged = 0x19, FlushEvents = 0x20, - WindowScreenChanged = 0x21 + WindowScreenChanged = 0x21, + SafeAreaMarginsChanged = 0x22 }; class WindowSystemEvent { @@ -187,6 +188,15 @@ public: QPointer screen; }; + class SafeAreaMarginsChangedEvent : public WindowSystemEvent { + public: + SafeAreaMarginsChangedEvent(QWindow *w) + : WindowSystemEvent(SafeAreaMarginsChanged), window(w) + { } + + QPointer window; + }; + class ApplicationStateChangedEvent : public WindowSystemEvent { public: ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 81fad420f6..85c60f61df 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -71,6 +71,8 @@ public: bool isExposed() const Q_DECL_OVERRIDE; void propagateSizeHints() Q_DECL_OVERRIDE {} + QMargins safeAreaMargins() const override; + void raise() Q_DECL_OVERRIDE{ raiseOrLower(true); } void lower() Q_DECL_OVERRIDE { raiseOrLower(false); } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e934cb90fa..4ce73d7b5d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -223,6 +223,13 @@ void QIOSWindow::applyGeometry(const QRect &rect) [m_view layoutIfNeeded]; } +QMargins QIOSWindow::safeAreaMargins() const +{ + UIEdgeInsets safeAreaInsets = m_view.qt_safeAreaInsets; + return QMargins(safeAreaInsets.left, safeAreaInsets.top, + safeAreaInsets.right, safeAreaInsets.bottom); +} + bool QIOSWindow::isExposed() const { return qApp->applicationState() != Qt::ApplicationSuspended diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 1dbacad6e7..ed8af8e290 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -56,6 +56,24 @@ @implementation QUIView ++ (void)load +{ + if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 11)) { + // iOS 11 handles this though [UIView safeAreaInsetsDidChange], but there's no signal for + // the corresponding top and bottom layout guides that we use on earlier versions. Note + // that we use the _will_ change version of the notification, because we want to react + // to the change as early was possible. But since the top and bottom layout guides have + // not been updated at this point we use asynchronous delivery of the event, so that the + // event is processed by QtGui just after iOS has updated the layout margins. + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillChangeStatusBarFrameNotification + object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *) { + for (QWindow *window : QGuiApplication::allWindows()) + QWindowSystemInterface::handleSafeAreaMarginsChanged(window); + } + ]; + } +} + + (Class)layerClass { return [CAEAGLLayer class]; @@ -100,6 +118,22 @@ self.layer.borderColor = colorWithBrightness(1.0); self.layer.borderWidth = 1.0; } + +#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA) + if (qEnvironmentVariableIsSet("QT_IOS_DEBUG_WINDOW_SAFE_AREAS")) { + if (__builtin_available(iOS 11, tvOS 11, *)) { + UIView *safeAreaOverlay = [[UIView alloc] initWithFrame:CGRectZero]; + [safeAreaOverlay setBackgroundColor:[UIColor colorWithRed:0.3 green:0.7 blue:0.9 alpha:0.3]]; + [self addSubview:safeAreaOverlay]; + + safeAreaOverlay.translatesAutoresizingMaskIntoConstraints = NO; + [safeAreaOverlay.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES; + [safeAreaOverlay.leftAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leftAnchor].active = YES; + [safeAreaOverlay.rightAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.rightAnchor].active = YES; + [safeAreaOverlay.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES; + } + } +#endif } return self; @@ -203,6 +237,11 @@ QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); } +- (void)safeAreaInsetsDidChange +{ + QWindowSystemInterface::handleSafeAreaMarginsChanged(m_qioswindow->window()); +} + // ------------------------------------------------------------------------- - (BOOL)canBecomeFirstResponder diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 125f1cf246..f279453ebd 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1198,6 +1198,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() adjustQuitOnCloseAttribute(); + q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea); q->setAttribute(Qt::WA_WState_Hidden); //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later @@ -1423,8 +1424,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO Q_UNUSED(initializeWindow); Q_UNUSED(destroyOldWindow); - Qt::WindowFlags flags = data.window_flags; - if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) return; // we only care about real toplevels @@ -1442,12 +1441,19 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win->setProperty(propertyName, q->property(propertyName)); } + Qt::WindowFlags &flags = data.window_flags; + +#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) + if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea)) + flags |= Qt::MaximizeUsingFullscreenGeometryHint; +#endif + if (q->testAttribute(Qt::WA_ShowWithoutActivating)) win->setProperty("_q_showWithoutActivating", QVariant(true)); if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow)) win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true))); setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set - win->setFlags(data.window_flags); + win->setFlags(flags); fixPosIncludesFrame(); if (q->testAttribute(Qt::WA_Moved) || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) @@ -7588,21 +7594,7 @@ void QWidget::setContentsMargins(int left, int top, int right, int bottom) d->rightmargin = right; d->bottommargin = bottom; - if (QLayout *l=d->layout) - l->update(); //force activate; will do updateGeometry - else - updateGeometry(); - - if (isVisible()) { - update(); - QResizeEvent e(data->crect.size(), data->crect.size()); - QApplication::sendEvent(this, &e); - } else { - setAttribute(Qt::WA_PendingResizeEvent, true); - } - - QEvent e(QEvent::ContentsRectChange); - QApplication::sendEvent(this, &e); + d->updateContentsRect(); } /*! @@ -7627,6 +7619,27 @@ void QWidget::setContentsMargins(const QMargins &margins) margins.right(), margins.bottom()); } +void QWidgetPrivate::updateContentsRect() +{ + Q_Q(QWidget); + + if (layout) + layout->update(); //force activate; will do updateGeometry + else + q->updateGeometry(); + + if (q->isVisible()) { + q->update(); + QResizeEvent e(q->data->crect.size(), q->data->crect.size()); + QApplication::sendEvent(q, &e); + } else { + q->setAttribute(Qt::WA_PendingResizeEvent, true); + } + + QEvent e(QEvent::ContentsRectChange); + QApplication::sendEvent(q, &e); +} + /*! Returns the widget's contents margins for \a left, \a top, \a right, and \a bottom. @@ -7635,15 +7648,22 @@ void QWidget::setContentsMargins(const QMargins &margins) */ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const { - Q_D(const QWidget); + QMargins m = contentsMargins(); if (left) - *left = d->leftmargin; + *left = m.left(); if (top) - *top = d->topmargin; + *top = m.top(); if (right) - *right = d->rightmargin; + *right = m.right(); if (bottom) - *bottom = d->bottommargin; + *bottom = m.bottom(); +} + +// FIXME: Move to qmargins.h for next minor Qt release +QMargins operator|(const QMargins &m1, const QMargins &m2) +{ + return QMargins(qMax(m1.left(), m2.left()), qMax(m1.top(), m2.top()), + qMax(m1.right(), m2.right()), qMax(m1.bottom(), m2.bottom())); } /*! @@ -7656,10 +7676,11 @@ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) c QMargins QWidget::contentsMargins() const { Q_D(const QWidget); - return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin); + QMargins userMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin); + return testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea) ? + userMargins | d->safeAreaMargins() : userMargins; } - /*! Returns the area inside the widget's margins. @@ -7667,14 +7688,87 @@ QMargins QWidget::contentsMargins() const */ QRect QWidget::contentsRect() const { - Q_D(const QWidget); - return QRect(QPoint(d->leftmargin, d->topmargin), - QPoint(data->crect.width() - 1 - d->rightmargin, - data->crect.height() - 1 - d->bottommargin)); - + return rect() - contentsMargins(); } +QMargins QWidgetPrivate::safeAreaMargins() const +{ + Q_Q(const QWidget); + QWidget *nativeWidget = q->window(); + if (!nativeWidget->windowHandle()) + return QMargins(); + + QPlatformWindow *platformWindow = nativeWidget->windowHandle()->handle(); + if (!platformWindow) + return QMargins(); + + QMargins safeAreaMargins = platformWindow->safeAreaMargins(); + + if (!q->isWindow()) { + // In theory the native parent widget already has a contents rect reflecting + // the safe area of that widget, but we can't be sure that the widget or child + // widgets of that widget have respected the contents rect when setting their + // geometry, so we need to manually compute the safe area. + + // Unless the native widget doesn't have any margins, in which case there's + // nothing for us to compute. + if (safeAreaMargins.isNull()) + return QMargins(); + + // Or, if one of our ancestors are in a layout that does not have WA_LayoutOnEntireRect + // set, then we know that the layout has already taken care of placing us inside the + // safe area, by taking the contents rect of its parent widget into account. + const QWidget *assumedSafeWidget = nullptr; + for (const QWidget *w = q; w != nativeWidget; w = w->parentWidget()) { + QWidget *parentWidget = w->parentWidget(); + if (parentWidget->testAttribute(Qt::WA_LayoutOnEntireRect)) + continue; // Layout not going to help us + + QLayout *layout = parentWidget->layout(); + if (!layout) + continue; + if (layout->geometry().isNull()) + continue; // Layout hasn't been activated yet + + if (layout->indexOf(const_cast(w)) < 0) + continue; // Widget is not in layout + + assumedSafeWidget = w; + break; + } + +#if !defined(QT_DEBUG) + if (assumedSafeWidget) { + // We found a layout that we assume will take care of keeping us within the safe area + // For debug builds we still map the safe area using the fallback logic, so that we + // can detect any misbehaving layouts. + return QMargins(); + } +#endif + + // In all other cases we need to map the safe area of the native parent to the widget. + // This depends on the widget being positioned and sized already, which means the initial + // layout will be wrong, but the layout will then adjust itself. + QPoint topLeftMargins = q->mapFrom(nativeWidget, QPoint(safeAreaMargins.left(), safeAreaMargins.top())); + QRect widgetRect = q->isVisible() ? q->visibleRegion().boundingRect() : q->rect(); + QPoint bottomRightMargins = widgetRect.bottomRight() - q->mapFrom(nativeWidget, + nativeWidget->rect().bottomRight() - QPoint(safeAreaMargins.right(), safeAreaMargins.bottom())); + + // Margins should never be negative + safeAreaMargins = QMargins(qMax(0, topLeftMargins.x()), qMax(0, topLeftMargins.y()), + qMax(0, bottomRightMargins.x()), qMax(0, bottomRightMargins.y())); + + if (!safeAreaMargins.isNull() && assumedSafeWidget) { + QLayout *layout = assumedSafeWidget->parentWidget()->layout(); + qWarning() << layout << "is laying out" << assumedSafeWidget + << "outside of the contents rect of" << layout->parentWidget(); + return QMargins(); // Return empty margin to visually highlight the error + } + } + + return safeAreaMargins; +} /*! \fn void QWidget::customContextMenuRequested(const QPoint &pos) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index a24d13e0e1..0c012d1932 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -513,6 +513,9 @@ public: void setLayoutItemMargins(int left, int top, int right, int bottom); void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0); + void updateContentsRect(); + QMargins safeAreaMargins() const; + // aboutToDestroy() is called just before the contents of // QWidget::destroy() is executed. It's used to signal QWidget // sub-classes that their internals are about to be released. diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index abaebad821..165dce04e9 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -87,6 +87,13 @@ public: } QRectF closestAcceptableGeometry(const QRectF &rect) const Q_DECL_OVERRIDE; + + void processSafeAreaMarginsChanged() override + { + Q_Q(QWidgetWindow); + if (QWidget *widget = q->widget()) + QWidgetPrivate::get(widget)->updateContentsRect(); + } }; QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const -- cgit v1.2.3 From 9dc7904556a261e9373bebc9060de62fcdab52a3 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 11 Dec 2017 09:55:53 +0100 Subject: xcb: update libXi version requirement in the README file ... from 1.7.4 to 1.7.5 (released Sep, 2015). Some more locking issues were fixed after 1.7.4. Testing for a prolonged period of time has showed that 1.7.5 does not cause a system lock-up. [ChangeLog][Platform Specific Changes][X11 / XCB] Minimal libXi version requirement has been updated from 1.7.4 to 1.7.5. This is because XIAllowTouchEvents is known to deadlock with libXi 1.7.4 and earlier. When touch events are never received, this is not an issue. Plain mouse / keyboard systems are not affected. Task-number: QTBUG-62224 Change-Id: Ie70264b9af0390df33c417f660350d4bce48c6d3 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/README | 3 +-- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README index 5efc9b7f99..8308db46dc 100644 --- a/src/plugins/platforms/xcb/README +++ b/src/plugins/platforms/xcb/README @@ -25,9 +25,8 @@ This should allow for binaries that are portable across most modern Linux distri PACKAGE VERSION REQUIREMENTS When using touch input via XInput 2.2 or higher, there is a potential issue on systems that ship with -a libXi older than 1.7.4. This is because XIAllowTouchEvents can deadlock with libXi 1.7.3 and earlier. +a libXi older than 1.7.5. This is because XIAllowTouchEvents can deadlock with libXi 1.7.4 and earlier. When touch events are never received, this is not an issue, so plain mouse/keyboard systems are not affected. -See http://lists.x.org/archives/xorg-devel/2014-July/043059.html for details on the libXi patch. Qt versions before 5.8 attempted to recognize this scenario based on the pkg-config package version and skip the call. This has been removed starting from 5.8 since relying on pkg-config package versions is unsafe given that Qt must also support systems with limited or incomplete pkg-config setups. diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 26a9ba8d26..d1d97affe8 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -700,8 +700,9 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo // Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence // will get replayed when the grab ends. if (m_xiGrab) { - // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2) - // http://lists.x.org/archives/xorg-devel/2014-July/043059.html + // Note that XIAllowTouchEvents is known to deadlock with older libXi versions, + // for details see qtbase/src/plugins/platforms/xcb/README. This has nothing to + // do with the XInput protocol version, but is a bug in libXi implementation instead. XIAllowTouchEvents(static_cast(m_xlib_display), xiDeviceEvent->deviceid, xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch); } -- cgit v1.2.3 From 2086c183c12afa50ed1e046da9580b0ea0081bf0 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 7 Dec 2017 17:01:38 +0100 Subject: Fix/workaround a quirk in SecureTransport We set anchors from QSslConfiguration::caCertificates. On macOS these anchors are by default copied from the system store, so I expected setting 'trust those anchors only' should not break anything. Somehow, on 10.11 SecTrustEvaluate fails to evaluate a valid certificate chain (apparently because it has an intermediate certificate, it's just a guess, since their API/docs are too poor to explain well what was the real cause) as I can see connecting, for example, to google.com - we have a chain with a valid root, say it's GetTrust CA and we have it also in our list of anchors we set on trust, but evaluation fails with: kSecTrustResultRecoverableTrustFailure: "This means that you should not trust the chain as-is, but that the chain could be trusted with some minor change to the evaluation context, such as ignoring expired certificates or adding an additional anchor to the set of trusted anchors." Since none of certs is expired, and the required anchor already set, this must be some bug in SecureTransport. For macOS (deployment target) < 10.12 we fallback to the original version of the code (the one that unfortunately does not allow us to limit the set of trusted anchors by what client code wants to trust). Change-Id: Ie42fd77c3eb6ef7469812aa0d7efff88a003c0b8 Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket_mac.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 2ba988fb70..f0742fe634 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -47,6 +47,7 @@ #include "qsslkey_p.h" #include +#include #include #include #include @@ -1247,13 +1248,17 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() // actual system CA certificate list (which most use-cases need) other than // by letting SecTrustEvaluate fall through to the system list; so, in this case // (even though the client code may have provided its own certs), we retain - // the default behavior. + // the default behavior. Note, with macOS SDK below 10.12 using 'trust my + // anchors only' may result in some valid chains rejected, apparently the + // ones containing intermediated certificates; so we use this functionality + // on more recent versions only. + + bool anchorsFromConfigurationOnly = false; #ifdef Q_OS_MACOS - const bool anchorsFromConfigurationOnly = true; -#else - const bool anchorsFromConfigurationOnly = false; -#endif + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSierra) + anchorsFromConfigurationOnly = true; +#endif // Q_OS_MACOS SecTrustSetAnchorCertificatesOnly(trust, anchorsFromConfigurationOnly); -- cgit v1.2.3 From 6a2609f3799c4f52e8ad28495f9846b057743575 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Tue, 12 Dec 2017 20:13:28 -0800 Subject: Stop blocking the ability to generate dSYM debug symbols with Xcode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Xcode, the default value for GCC_GENERATE_DEBUGGING_SYMBOLS is YES, which causes Xcode to emit debug symbol bundles (.dSYM) on macOS and iOS *if* DEBUG_INFORMATION_FORMAT is also set to dwarf-with-dsym. Since that setting is already set to an appropriate value with debug vs release builds, the default Xcode value for GCC_GENERATE_DEBUGGING_SYMBOLS is already correct and in effect the only thing qmake was doing was always setting GCC_GENERATE_DEBUGGING_SYMBOLS to a wrong value for release builds - it should be YES in all cases, to allow the .dSYM bundles to be generated in release mode, which is in fact the only case where they're really needed in the first place. Task-number: QTBUG-41246 Task-number: QTBUG-50896 Change-Id: I07639a3c4ff9f62d591cde3ad66748767d475e3b Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 63926e7ef0..0622ace71b 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -280,8 +280,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) QMap settings; settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); - if(as_release) - settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK")) settings.insert("SDKROOT", project->first("QMAKE_MAC_SDK").toQString()); { @@ -1499,7 +1497,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) settings.insert("APPLICATION_EXTENSION_API_ONLY", project->isActiveConfig("app_extension_api_only") ? "YES" : "NO"); // required for tvOS (and watchos), optional on iOS (deployment target >= iOS 6.0) settings.insert("ENABLE_BITCODE", project->isActiveConfig("bitcode") ? "YES" : "NO"); - settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES"); if(!as_release) settings.insert("GCC_OPTIMIZATION_LEVEL", "0"); if(project->isActiveConfig("sdk") && !project->isEmpty("QMAKE_MAC_SDK")) -- cgit v1.2.3 From 9832f0ab857904a88c9b5e71a9e447abbebca8fb Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 15 Feb 2017 09:38:28 +0100 Subject: Copy argv[0] to prevent it pointing to invalid memory later If QCoreApplication is recreated, it is possible the previous argv[0] pointer has become invalid, so we should not rely on it. So to prevent that, we copy the original argv[0] to a static QByteArray. Task-number: QTBUG-58919 Change-Id: Idadd4cb78e4281830165fb681ea7925109f316ff Reviewed-by: Edward Welbourne Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qcoreapplication.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index bf423cef21..db40b37da9 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2149,11 +2149,11 @@ QString QCoreApplication::applicationFilePath() QCoreApplicationPrivate *d = self->d_func(); if (d->argc) { - static const char *procName = d->argv[0]; - if (qstrcmp(procName, d->argv[0]) != 0) { + static QByteArray procName = QByteArray(d->argv[0]); + if (procName != d->argv[0]) { // clear the cache if the procname changes, so we reprocess it. QCoreApplicationPrivate::clearApplicationFilePath(); - procName = d->argv[0]; + procName = QByteArray(d->argv[0]); } } -- cgit v1.2.3 From 3d65284b60bfc8e01c4ea4b86344a508b6f49358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 14 Dec 2017 11:55:16 +0100 Subject: QWidget: Remove dead code for handling painting without a backingstore Change-Id: Iacf852c8620ea06d790cddcf6774b772f754e08a Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 67 ++++++++++++------------------------------ 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f279453ebd..a82f97270d 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -127,15 +127,6 @@ QT_BEGIN_NAMESPACE -static bool qt_enable_backingstore = true; -#if 0 // Used to be included in Qt4 for Q_WS_X11 -// for compatibility with Qt 4.0 -Q_WIDGETS_EXPORT void qt_x11_set_global_double_buffer(bool enable) -{ - qt_enable_backingstore = enable; -} -#endif - #if 0 // Used to be included in Qt4 for Q_WS_MAC bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false; #endif @@ -146,11 +137,6 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2) qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom())); } -static inline bool hasBackingStoreSupport() -{ - return true; -} - #if 0 // Used to be included in Qt4 for Q_WS_MAC # define QT_NO_PAINT_DEBUG #endif @@ -1351,8 +1337,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { d->topData()->backingStoreTracker.destroy(); - if (hasBackingStoreSupport()) - d->topData()->backingStoreTracker.create(this); + d->topData()->backingStoreTracker.create(this); } d->setModal_sys(); @@ -2339,7 +2324,7 @@ bool QWidgetPrivate::paintOnScreen() const return true; } - return !qt_enable_backingstore; + return false; #endif } @@ -11036,15 +11021,11 @@ void QWidget::repaint(const QRect &rect) if (!isVisible() || !updatesEnabled() || rect.isEmpty()) return; - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } - } else { - d->repaint_sys(rect); + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); + tlwExtra->inRepaint = false; } } @@ -11065,15 +11046,11 @@ void QWidget::repaint(const QRegion &rgn) if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) return; - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } - } else { - d->repaint_sys(rgn); + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); + tlwExtra->inRepaint = false; } } @@ -11127,13 +11104,9 @@ void QWidget::update(const QRect &rect) return; } - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); - } else { - d_func()->repaint_sys(r); - } + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) + tlwExtra->backingStoreTracker->markDirty(r, this); } /*! @@ -11156,13 +11129,9 @@ void QWidget::update(const QRegion &rgn) return; } - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); - } else { - d_func()->repaint_sys(r); - } + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) + tlwExtra->backingStoreTracker->markDirty(r, this); } -- cgit v1.2.3 From d48c502ce535c913424440557cdfe7fa6e383dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 14 Dec 2017 12:14:11 +0100 Subject: Share QWidget update and repaint code for QRect and QRegion QWidgetBackingStore::markDirty has an optimization for QRect, so we don't want to unify these two functions by calling update/repaint(QRegion(rect)). Change-Id: Id2a42f478f71863da45697041e0ab0130c74b9d2 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 74 ++++++++++++++++-------------------------- src/widgets/kernel/qwidget_p.h | 7 ++++ 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a82f97270d..b57a0d4779 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -11012,21 +11012,7 @@ void QWidget::repaint(int x, int y, int w, int h) void QWidget::repaint(const QRect &rect) { Q_D(QWidget); - - if (testAttribute(Qt::WA_WState_ConfigPending)) { - update(rect); - return; - } - - if (!isVisible() || !updatesEnabled() || rect.isEmpty()) - return; - - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } + d->repaint(rect); } /*! @@ -11037,19 +11023,21 @@ void QWidget::repaint(const QRect &rect) void QWidget::repaint(const QRegion &rgn) { Q_D(QWidget); + d->repaint(rgn); +} - if (testAttribute(Qt::WA_WState_ConfigPending)) { - update(rgn); - return; - } +template +void QWidgetPrivate::repaint(T r) +{ + Q_Q(QWidget); - if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) + if (!q->isVisible() || !q->updatesEnabled() || r.isEmpty()) return; - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); + tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow); tlwExtra->inRepaint = false; } } @@ -11091,22 +11079,8 @@ void QWidget::update() */ void QWidget::update(const QRect &rect) { - if (!isVisible() || !updatesEnabled()) - return; - - QRect r = rect & QWidget::rect(); - - if (r.isEmpty()) - return; - - if (testAttribute(Qt::WA_WState_InPaintEvent)) { - QApplication::postEvent(this, new QUpdateLaterEvent(r)); - return; - } - - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); + Q_D(QWidget); + d->update(rect); } /*! @@ -11116,25 +11090,33 @@ void QWidget::update(const QRect &rect) */ void QWidget::update(const QRegion &rgn) { - if (!isVisible() || !updatesEnabled()) + Q_D(QWidget); + d->update(rgn); +} + +template +void QWidgetPrivate::update(T r) +{ + Q_Q(QWidget); + + if (!q->isVisible() || !q->updatesEnabled()) return; - QRegion r = rgn & QWidget::rect(); + T clipped = r & q->rect(); - if (r.isEmpty()) + if (clipped.isEmpty()) return; - if (testAttribute(Qt::WA_WState_InPaintEvent)) { - QApplication::postEvent(this, new QUpdateLaterEvent(r)); + if (q->testAttribute(Qt::WA_WState_InPaintEvent)) { + QApplication::postEvent(q, new QUpdateLaterEvent(clipped)); return; } - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); + tlwExtra->backingStoreTracker->markDirty(clipped, q); } - /*! \internal diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 0c012d1932..15704f32c9 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -342,6 +342,13 @@ public: QPainter *sharedPainter() const; void setSharedPainter(QPainter *painter); QWidgetBackingStore *maybeBackingStore() const; + + template + void repaint(T t); + + template + void update(T t); + void init(QWidget *desktopWidget, Qt::WindowFlags f); void create_sys(WId window, bool initializeWindow, bool destroyOldWindow); void createRecursively(); -- cgit v1.2.3 From 345be581007c05164052e27f90fcfaf27a41c743 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Wed, 6 Dec 2017 19:46:31 +0100 Subject: Fix assert when emitting a signal from a different thread If a signal is emitted more than once in a multithreaded application the QSignalEventGenerator::execute function asserts in the check for a valid signal index. It happens after abandoning the state and all the connections are disconnected. If we have pending signal to be processed the QObject::sender() won't be able to resolve the sender object. Task-number: QTBUG-61463 Change-Id: I9d4b7266c6dddc9ff2e7453b05a6989876ccb332 Reviewed-by: Edward Welbourne --- src/corelib/statemachine/qstatemachine.cpp | 6 ++-- .../qstatemachine/tst_qstatemachine.cpp | 32 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 2808ba2ced..c2b5afd241 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -3096,10 +3096,12 @@ int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a) void QSignalEventGenerator::execute(void **_a) { + auto machinePrivate = QStateMachinePrivate::get(qobject_cast(parent())); + if (machinePrivate->state != QStateMachinePrivate::Running) + return; int signalIndex = senderSignalIndex(); Q_ASSERT(signalIndex != -1); - QStateMachine *machine = qobject_cast(parent()); - QStateMachinePrivate::get(machine)->handleTransitionSignal(sender(), signalIndex, _a); + machinePrivate->handleTransitionSignal(sender(), signalIndex, _a); } QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 8f0d83ce32..7ea467b6ef 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -101,6 +101,7 @@ Q_OBJECT public: SignalEmitter(QObject *parent = 0) : QObject(parent) {} +public Q_SLOTS: void emitSignalWithNoArg() { emit signalWithNoArg(); } void emitSignalWithIntArg(int arg) @@ -251,6 +252,7 @@ private slots: void qtbug_46059(); void qtbug_46703(); void postEventFromBeginSelectTransitions(); + void dontProcessSlotsWhenMachineIsNotRunning(); }; class TestState : public QState @@ -6658,5 +6660,35 @@ void tst_QStateMachine::postEventFromBeginSelectTransitions() QVERIFY(machine.isRunning()); } +void tst_QStateMachine::dontProcessSlotsWhenMachineIsNotRunning() +{ + QStateMachine machine; + QState initialState; + QFinalState finalState; + + struct Emitter : SignalEmitter + { + QThread thread; + Emitter(QObject *parent = nullptr) : SignalEmitter(parent) + { + moveToThread(&thread); + thread.start(); + } + } emitter; + + initialState.addTransition(&emitter, &Emitter::signalWithNoArg, &finalState); + QTimer::singleShot(0, [&]() { + metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg"); + metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg"); + }); + machine.addState(&initialState); + machine.addState(&finalState); + machine.setInitialState(&initialState); + machine.start(); + connect(&machine, &QStateMachine::finished, &emitter.thread, &QThread::quit); + QSignalSpy signalSpy(&machine, &QStateMachine::finished); + QTRY_COMPARE_WITH_TIMEOUT(signalSpy.count(), 1, 100); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v1.2.3 From af70d4ee85246031ff631488a9191034bf3baa7a Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 14 Dec 2017 15:26:31 +0100 Subject: Allow empty namespace URI W3C Namespaces Standard states that "The attribute value in a default namespace declaration MAY be empty" (secion 6.2). Analysis and fix thanks to Eugenio Rustico. Task-number: QTBUG-63538 Change-Id: Icd8d4df639b9737d8e0d215bf2bea56fe1e161ac Reviewed-by: Edward Welbourne --- src/corelib/xml/qxmlstream.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index af35193b13..a55d16ed88 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -3708,7 +3708,6 @@ void QXmlStreamWriter::writeEntityReference(const QString &name) void QXmlStreamWriter::writeNamespace(const QString &namespaceUri, const QString &prefix) { Q_D(QXmlStreamWriter); - Q_ASSERT(!namespaceUri.isEmpty()); Q_ASSERT(prefix != QLatin1String("xmlns")); if (prefix.isEmpty()) { d->findNamespace(namespaceUri, d->inStartElement); -- cgit v1.2.3 From fd3423bfb82f44723fd59991ba56adc3ed112412 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 4 Dec 2017 21:00:38 +0100 Subject: configure: support discarding selected test results with -recheck especially during debugging, it is often necessary to re-run only one (or a few) tests, where -recheck-all would be wasteful. Task-number: QTBUG-64059 Change-Id: I9410894dec4289ff832d7f75e04f9b60fe76c57c Reviewed-by: Lars Knoll --- config_help.txt | 4 +++- mkspecs/features/data/configure.json | 2 +- mkspecs/features/qt_configure.prf | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/config_help.txt b/config_help.txt index 003752dbe7..9c424391a9 100644 --- a/config_help.txt +++ b/config_help.txt @@ -66,8 +66,10 @@ Configure meta: -redo ................ Re-configure with previously used options. Additional options may be passed, but will not be saved for later use by -redo. - -recheck ............. Discard cached negative configure test results. + -recheck [test,...] .. Discard cached negative configure test results. Use this after installing missing dependencies. + Alternatively, if tests are specified, only their + results are discarded. -recheck-all ......... Discard all cached configure test results. -feature- ... Enable diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json index 38623d46a4..167c502e82 100644 --- a/mkspecs/features/data/configure.json +++ b/mkspecs/features/data/configure.json @@ -9,7 +9,7 @@ "continue": "void", - "recheck": { "type": "void", "name": "cache_use", "value": "positive" }, + "recheck": { "type": "optionalString", "name": "cache_recheck" }, "recheck-all": { "type": "void", "name": "cache_use", "value": "none" }, "redo": { "type": "redo" }, diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index dcd87a7a1a..6ab40e53ec 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -2041,14 +2041,28 @@ qtConfCheckErrors() QMAKE_CONFIG_CACHE = $$OUT_PWD/config.cache QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use) +cache_recheck = $$eval(config.input.cache_recheck) +equals(cache_recheck, yes) { + QMAKE_CONFIG_CACHE_USE = positive + cache_recheck = +} isEmpty(QMAKE_CONFIG_CACHE_USE): \ QMAKE_CONFIG_CACHE_USE = all !equals(QMAKE_CONFIG_CACHE_USE, none) { include($$QMAKE_CONFIG_CACHE, , true) # this crudely determines when to discard the cache. this also catches the case # of no cache being there in the first place. - !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]): \ + !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]) { QMAKE_CONFIG_CACHE_USE = none + } else: !isEmpty(cache_recheck) { + for (cr, $$list($$split(cache_recheck, ","))) { + !isEmpty(cache.$${cr}._KEYS_) { + cache.$${cr}._KEYS_ = + } else { + qtConfAddWarning("Attempting to discard non-cached result '$$cr'.") + } + } + } } equals(QMAKE_CONFIG_CACHE_USE, none) { cont = \ -- cgit v1.2.3 From ff1c8baf4a441e10ddce8469c94b95b6897133d5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 Dec 2017 18:37:36 +0100 Subject: configure: make cached results immediately available otherwise test de-duplication between modules doesn't work. Change-Id: I2c6222d853108df223758aa8907dc8d004efd87f Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 6ab40e53ec..d5dcda22ac 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1052,8 +1052,13 @@ defineTest(qtConfSaveResult) { return() keys = result $$eval($${1}.cache) cont = "cache.$${2}._KEYS_ = $$keys" - for (k, keys): \ + cache.$${2}._KEYS_ = $$keys + export(cache.$${2}._KEYS_) + for (k, keys) { cont += "cache.$${2}.$${k} = $$val_escape($${1}.$${k})" + cache.$${2}.$${k} = $$eval($${1}.$${k}) + export(cache.$${2}.$${k}) + } write_file($$QMAKE_CONFIG_CACHE, cont, append)|error() } -- cgit v1.2.3 From 5dd76ba31c3c7cb9c0d9d97cd62f0d2f535a23f7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 Jun 2017 12:30:01 +0200 Subject: update sqldriver docs - adjusted to new configure system realities - centralized 'make install' instructions - fixed 'make' command for mingw - externalized the license compatibility question - removed dated information about postgresql client libs - removed dated claim that freetds is not stable yet - updated official sybase client link to point to sap support - removed apparently bogus "demo" include path from oci instructions, based on the archive content description - removed troubleshooting item about static builds - one can use static "plugins" with a static build just fine. and building dynamic plugins for a static build is plain impossible to start with. - removed troubleshooting item about build key mismatch, as build keys have been removed in qt5 - removed "general info" sub-section titles, as that's bad style - misc language and minor content fixes Task-number: QTBUG-62479 Change-Id: Ic4efa9e20a5966b6fc646062aec6d1a8d4ff4158 Reviewed-by: Leena Miettinen Reviewed-by: Thiago Macieira --- src/sql/doc/snippets/code/doc_src_sql-driver.cpp | 6 - src/sql/doc/snippets/code/doc_src_sql-driver.qdoc | 160 ++++++++++----------- src/sql/doc/src/sql-driver.qdoc | 164 ++++++++-------------- 3 files changed, 131 insertions(+), 199 deletions(-) diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.cpp b/src/sql/doc/snippets/code/doc_src_sql-driver.cpp index f25ad4f2b0..75ac9fe134 100644 --- a/src/sql/doc/snippets/code/doc_src_sql-driver.cpp +++ b/src/sql/doc/snippets/code/doc_src_sql-driver.cpp @@ -84,9 +84,3 @@ q.exec("execute procedure my_procedure"); q.next(); qDebug() << q.value(0); // outputs the first RETURN/OUT value //! [26] - - -//! [31] -QSqlDatabase: QMYSQL driver not loaded -QSqlDatabase: available drivers: QMYSQL -//! [31] diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc index 87c1d0c69b..04ea30915d 100644 --- a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc +++ b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc @@ -49,14 +49,16 @@ ****************************************************************************/ //! [0] --no-sql- ... Disable SQL entirely. --qt-sql- ... Enable a SQL in the Qt Library, by default - none are turned on. --plugin-sql- Enable SQL as a plugin to be linked to - at run time. - - Possible values for : - [ db2 ibase mysql oci odbc psql sqlite sqlite2 tds ] +[...] + +Database options: + + -sql- ........ Enable SQL plugin. Supported drivers: + db2 ibase mysql oci odbc psql sqlite2 sqlite tds + [all auto] + -sqlite .............. Select used sqlite3 [system/qt] + +[...] //! [0] @@ -70,9 +72,9 @@ END //! [3] -cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql -qmake "INCLUDEPATH+=/usr/local/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- MYSQL_PREFIX=/usr/local +make sub-mysql //! [3] @@ -83,32 +85,30 @@ make install //! [5] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\mysql -qmake "INCLUDEPATH+=C:/MySQL/include" "LIBS+=C:/MYSQL/MySQL Server /lib/opt/libmysql.lib" mysql.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- MYSQL_INCDIR=C:/MySQL/include "MYSQL_LIBDIR=C:/MYSQL/MySQL Server /lib/opt" +nmake sub-mysql //! [5] //! [6] -cd $QTDIR/qtbase/src/plugins/sqldrivers/oci -qmake "INCLUDEPATH+=$ORACLE_HOME/rdbms/public $ORACLE_HOME/rdbms/demo" "LIBS+=-L$ORACLE_HOME/lib -lclntsh -lwtc9" oci.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- "OCI_INCDIR=$ORACLE_HOME/rdbms/public" OCI_LIBDIR=$ORACLE_HOME/lib "OCI_LIBS=-lclntsh -lwtc9" +make sub-oci //! [6] //! [7] -cd $QTDIR/qtbase/src/plugins/sqldrivers/oci -qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client/" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -lclntsh" oci.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib +make sub-oci //! [7] //! [8] -set INCLUDE=%INCLUDE%;c:\oracle\oci\include -set LIB=%LIB%;c:\oracle\oci\lib\msvc -cd %QTDIR%\qtbase\src\plugins\sqldrivers\oci -qmake oci.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- OCI_INCDIR=c:/oracle/oci/include OCI_LIBDIR=c:/oracle/oci/lib/msvc +nmake sub-oci //! [8] @@ -118,128 +118,110 @@ set PATH=%PATH%;c:\oracle\bin //! [11] -cd $QTDIR/qtbase/src/plugins/sqldrivers/odbc -qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc" -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- ODBC_PREFIX=/usr/local/unixODBC +make sub-odbc //! [11] //! [12] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\odbc -qmake odbc.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake +nmake sub-odbc //! [12] //! [13] -cd $QTDIR/qtbase/src/plugins/sqldrivers/psql -qmake "INCLUDEPATH+=/usr/include/pgsql" "LIBS+=-L/usr/lib -lpq" psql.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- PSQL_INCDIR=/usr/include/pgsql +make sub-psql //! [13] -//! [14] -cd $QTDIR/qtbase/src/plugins/sqldrivers/psql -make install -//! [14] - - //! [15] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\psql -qmake "INCLUDEPATH+=C:/psql/include" "LIBS+=C:/psql/lib/ms/libpq.lib" psql.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- PSQL_INCDIR=C:/psql/include PSQL_LIBDIR=C:/psql/lib/ms +nmake sub-psql //! [15] //! [16] -cd $QTDIR/qtbase/src/plugins/sqldrivers/tds -qmake "INCLUDEPATH=$SYBASE/include" "LIBS=-L$SYBASE/lib -lsybdb" -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- TDS_PREFIX=$SYBASE +make sub-tds //! [16] //! [17] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\tds -qmake "LIBS+=NTWDBLIB.LIB" tds.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake +nmake sub-tds //! [17] //! [18] -cd $QTDIR/qtbase/src/plugins/sqldrivers/db2 -qmake "INCLUDEPATH+=$DB2DIR/include" "LIBS+=-L$DB2DIR/lib -ldb2" -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- DB2_PREFIX=$DB2DIR +make sub-db2 //! [18] -//! [19] -cd $QTDIR/qtbase/src/plugins/sqldrivers/db2 -make install -//! [19] - - //! [20] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\db2 -qmake "INCLUDEPATH+=/sqllib/include" "LIBS+=/sqllib/lib/db2cli.lib" -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- "DB2_PREFIX=/sqllib" +nmake sub-db2 //! [20] //! [21] -cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite -qmake "INCLUDEPATH+=$SQLITE/include" "LIBS+=-L$SQLITE/lib -lsqlite" -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- -system-sqlite SQLITE3_PREFIX=$SQLITE +make sub-sqlite //! [21] -//! [22] -cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite -make install -//! [22] - - //! [23] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\sqlite -qmake "INCLUDEPATH+=C:/SQLITE/INCLUDE" "LIBS+=C:/SQLITE/LIB/SQLITE3.LIB" sqlite.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- -system-sqlite SQLITE3_PREFIX=C:/SQLITE +nmake sub-sqlite //! [23] //! [27] -cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase -qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib" ibase.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- IBASE_PREFIX=/opt/interbase +make sub-ibase //! [27] //! [28] -cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase -qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib -lfbclient" ibase.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- IBASE_PREFIX=/opt/interbase IBASE_LIBS=-lfbclient +make sub-ibase //! [28] //! [29] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase -qmake "INCLUDEPATH+=C:/interbase/include" ibase.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- IBASE_INCDIR=C:/interbase/include +nmake sub-ibase //! [29] //! [30] -cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase -qmake "INCLUDEPATH+=C:/interbase/include" "LIBS+=-lfbclient" ibase.pro -nmake +cd %QTDIR%\qtbase\src\plugins\sqldrivers +qmake -- IBASE_INCDIR=C:/interbase/include IBASE_LIBS=-lfbclient +nmake sub-ibase //! [30] //! [32] -configure -I /usr/include/oracle/10.1.0.3/client -L /usr/lib/oracle/10.1.0.3/client/lib -R /usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10 +configure OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib -R /usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-lclntsh -lnnz10" make //! [32] //! [33] -cd $QTDIR/qtbase/src/plugins/sqldrivers/oci -qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10" oci.pro -make +cd $QTDIR/qtbase/src/plugins/sqldrivers +qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10" +make sub-oci //! [33] diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc index 4f3f2ce007..c8de78dd79 100644 --- a/src/sql/doc/src/sql-driver.qdoc +++ b/src/sql/doc/src/sql-driver.qdoc @@ -34,7 +34,7 @@ Plugins}{plugins} to communicate with the different database APIs. Since Qt's SQL Module API is database-independent, all database-specific code is contained within these drivers. Several - drivers are supplied with Qt and other drivers can be added. The + drivers are supplied with Qt, and other drivers can be added. The driver source code is supplied and can be used as a model for \l{#development}{writing your own drivers}. @@ -42,9 +42,7 @@ \section1 Supported Databases - The table below lists the drivers included with Qt. Due to - license incompatibilities with the GPL, not all of the plugins - are provided with Open Source Versions of Qt. + The table below lists the drivers included with Qt: \table \header \li Driver name \li DBMS @@ -74,10 +72,14 @@ libraries", and these are what you need. These libraries are responsible for the low-level communication with the DBMS. + \note When using Qt under Open Source terms but with a proprietary + database, verify the client library's license compatibility with + the LGPL. + \target building - \section1 Building the Drivers Using Configure + \section1 Building the Drivers - On Unix and \macos, the Qt \c configure script tries to + The Qt \c configure script tries to automatically detect the available client libraries on your machine. Run \c{configure -help} to see what drivers can be built. You should get an output similar to this: @@ -86,23 +88,28 @@ The \c configure script cannot detect the necessary libraries and include files if they are not in the standard paths, so it - may be necessary to specify these paths using the \c -I and \c -L - command-line options. For example, if your MySQL include files - are installed in \c /usr/local/mysql (or in \c{C:\mysql\include} - on Windows), then pass the following parameter to configure: \c - -I/usr/local/mysql (or \c{-I C:\mysql\include} for Windows). - - On Windows, the \c -I parameter doesn't accept spaces in - filenames, so use the 8.3 name instead; for example, use - \c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}. + may be necessary to specify these paths using the \c *_INCDIR=, + \c *_LIBDIR=, or \c *_PREFIX= command-line options. For example, + if your MySQL files are installed in \c /usr/local/mysql (or in + \c{C:\mysql} on Windows), then pass the following parameter to + configure: \c MYSQL_PREFIX=/usr/local/mysql + (or \c{MYSQL_PREFIX=C:\mysql} for Windows). + The particulars for each driver are explained below. + + Due to the practicalities of dealing with external dependencies, + only the SQLite3 plugin is shipped with binary builds of Qt. + To be able to add additional drivers to the Qt installation + without re-building all of Qt, it is possible to configure + and build the \c qtbase/src/plugins/sqldrivers directory outside + of a full Qt build directory. Note that it is not possible to + \e configure each driver separately, only all of them at once. + Drivers can be \e built separately, though. + If the Qt build is configured with \c{-prefix}, it is necessary to + install the plugins after building them, too. For example: - Use the \c{-qt-sql-} parameter to build the database driver - statically into your Qt library or \c{-plugin-sql-} to build - the driver as a plugin. Look at the sections that follow for - additional information about required libraries. + \snippet code/doc_src_sql-driver.qdoc 4 - \target buildingmanually - \section1 Building the Plugins Manually + \section1 Driver Specifics \target QMYSQL \section2 QMYSQL for MySQL 4 and higher @@ -132,9 +139,8 @@ not required to use MySQL functionality. To use the embedded MySQL server, simply link the Qt plugin to \c - libmysqld instead of libmysqlclient. This can be done by replacing - \c -lmysqlclient_r by \c -lmysqld in the \c qmake command in the - section below. + libmysqld instead of \c libmysqlclient. This can be done by adding + \c MYSQL_LIBS=-lmysqld to the configure command line. Please refer to the MySQL documentation, chapter "libmysqld, the Embedded MySQL Server Library" for more information about the MySQL embedded server. @@ -151,11 +157,6 @@ \snippet code/doc_src_sql-driver.qdoc 3 - After installing Qt, you also need to install the plugin in the standard - location: - - \snippet code/doc_src_sql-driver.qdoc 4 - \section3 How to Build the QMYSQL Plugin on Windows You need to get the MySQL installation files. Run \c SETUP.EXE and @@ -166,18 +167,11 @@ \snippet code/doc_src_sql-driver.qdoc 5 If you are not using a Microsoft compiler, replace \c nmake with \c - make in the line above. - - \note Including \c{"-o Makefile"} as an argument to \l qmake, to - tell it where to build the makefile, can cause the plugin to be - built in release mode only. If you intend to build a debug version - as well, don't use the \c{"-o Makefile"} option. + mingw32-make in the line above. \target QOCI \section2 QOCI for the Oracle Call Interface (OCI) - \section3 General Information about the OCI plugin - The Qt OCI plugin supports Oracle 9i, 10g and higher. After connecting to the Oracle server, the plugin will auto-detect the database version and enable features accordingly. @@ -252,7 +246,7 @@ \snippet code/doc_src_sql-driver.qdoc 8 If you are not using a Microsoft compiler, replace \c nmake with \c - make in the line above. + mingw32-make in the line above. When you run your application, you will also need to add the \c oci.dll path to your \c PATH environment variable: @@ -262,8 +256,6 @@ \target QODBC \section2 QODBC for Open Database Connectivity (ODBC) - \section3 General Information about the ODBC plugin - ODBC is a general interface that allows you to connect to multiple DBMSs using a common interface. The QODBC driver allows you to connect to an ODBC driver manager and access the available data sources. Note @@ -277,7 +269,7 @@ On Windows, an ODBC driver manager should be installed by default. For Unix systems, there are some implementations which must be - installed first. Note that every client that uses your application is + installed first. Note that every end user of your application is required to have an ODBC driver manager installed, otherwise the QODBC plugin will not work. @@ -290,7 +282,7 @@ but do not offer all the necessary functionality. The QODBC plugin therefore checks whether the data source can be used after a connection has been established, and refuses to work if the check - fails. If you don't like this behavior, you can remove the \c{#define + fails. If you do not like this behavior, you can remove the \c{#define ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at your own risk! @@ -310,7 +302,7 @@ If you experience very slow access of the ODBC datasource, make sure that ODBC call tracing is turned off in the ODBC datasource manager. - Some drivers don't support scrollable cursors. In that case case only + Some drivers do not support scrollable cursors. In that case, only queries in forwardOnly mode can be used successfully. \section3 ODBC Stored Procedure Support @@ -331,7 +323,7 @@ Windows NT based systems, this is the default. Note that the ODBC driver and the DBMS must also support Unicode. - Some driver managers and drivers don't support UNICODE. To use the + Some driver managers and drivers do not support UNICODE. To use the QODBC plugin with such drivers, it has to be compiled with Q_ODBC_VERSION_2 defined. @@ -359,18 +351,12 @@ \snippet code/doc_src_sql-driver.qdoc 12 If you are not using a Microsoft compiler, replace \c nmake with \c - make in the line above. + mingw32-make in the line above. \target QPSQL \section2 QPSQL for PostgreSQL (Version 7.3 and Above) - \section3 General Information about the QPSQL driver - The QPSQL driver supports version 7.3 and higher of the PostgreSQL server. - We recommend that you use a client library from version 7.3.15, 7.4.13, - 8.0.8, 8.1.4, or more recent, as these versions contain security fixes, and - as the QPSQL driver might not build with older versions of the client - library, depending on your platform. For more information about PostgreSQL visit \l http://www.postgresql.org. @@ -404,11 +390,6 @@ \snippet code/doc_src_sql-driver.qdoc 13 - After installing Qt, you also need to install the plugin in the standard - location: - - \snippet code/doc_src_sql-driver.qdoc 14 - \section3 How to Build the QPSQL Plugin on Windows Install the appropriate PostgreSQL developer libraries for your @@ -426,8 +407,6 @@ \note TDS is no longer used by MS Sql Server, and is superceded by \l{QODBC}{ODBC}. QTDS is obsolete from Qt 4.7. - \section3 General Information about QTDS - It is not possible to set the port with QSqlDatabase::setPort() due to limitations in the Sybase client library. Refer to the Sybase documentation for information on how to set up a Sybase client configuration file to enable connections to databases on non-default ports. @@ -438,12 +417,9 @@ \list \li FreeTDS, a free implementation of the TDS protocol - (\l{http://www.freetds.org}). Note that FreeTDS is not yet stable, - so some functionality may not work as expected. + (\l{http://www.freetds.org}). - \li Sybase Open Client, available from \l{http://www.sybase.com}. - Note for Linux users: Get the Open Client RPM from - \l{http://linux.sybase.com}. + \li Sybase Open Client, available from \l{https://support.sap.com}. \endlist Regardless of which library you use, the shared object file @@ -456,22 +432,21 @@ \section3 How to Build the QDTS Plugin on Windows You can either use the DB-Library supplied by Microsoft or the Sybase - Open Client (\l{http://www.sybase.com}). You must include \c + Open Client (\l{https://support.sap.com}). Configure will try to find NTWDBLIB.LIB to build the plugin: \snippet code/doc_src_sql-driver.qdoc 17 - By default the Microsoft library is used on Windows, if you want to + By default, the Microsoft library is used on Windows. If you want to force the use of the Sybase Open Client, you must define \c - Q_USE_SYBASE in \c{%QTDIR%\qtbase\src\sql\drivers\tds\qsql_tds.cpp}. If you - are not using a Microsoft compiler, replace \c nmake with \c make in - the line above. + Q_USE_SYBASE in \c{%QTDIR%\qtbase\src\plugins\sqldrivers\tds\qsql_tds.cpp}. + + If you are not using a Microsoft compiler, replace \c nmake + with \c mingw32-make in the line above. \target QDB2 \section2 QDB2 for IBM DB2 (Version 7.1 and Above) - \section3 General Information about QDB2 - The Qt DB2 plugin makes it possible to access IBM DB2 databases. It has been tested with IBM DB2 v7.1 and 7.2. You must install the IBM DB2 development client library, which contains the header and library @@ -487,11 +462,6 @@ \snippet code/doc_src_sql-driver.qdoc 18 - After installing Qt, you also need to install the plugin in the standard - location: - - \snippet code/doc_src_sql-driver.qdoc 19 - \section3 How to Build the QDB2 Plugin on Windows The DB2 header and include files should already be installed in the @@ -500,7 +470,7 @@ \snippet code/doc_src_sql-driver.qdoc 20 If you are not using a Microsoft compiler, replace \c nmake - with \c make in the line above. + with \c mingw32-make in the line above. \target QSQLITE2 \section2 QSQLITE2 for SQLite Version 2 @@ -512,8 +482,6 @@ \target QSQLITE \section2 QSQLITE for SQLite (Version 3 and Above) - \section3 General Information about QSQLITE - The Qt SQLite plugin makes it possible to access SQLite databases. SQLite is an in-process database, which means that it is not necessary to have a database server. SQLite operates on a @@ -548,21 +516,19 @@ \section3 How to Build the QSQLITE Plugin SQLite version 3 is included as a third-party library within Qt. - It can be built by passing the following parameters to the - configure script: \c{-plugin-sql-sqlite} (build as a plugin) or - \c{-qt-sql-sqlite} (linked directly into the Qt library). - - If you don't want to use the SQLite library included with Qt, you - can pass \c{-system-sqlite} to the configure script to use sqlite - libraries in the operating system. Alternatively, you can build - it manually (replace \c $SQLITE with the directory where - SQLite resides): + It can be built by passing the \c{-qt-sqlite} parameter to the + configure script. - \snippet code/doc_src_sql-driver.qdoc 21 + If you do not want to use the SQLite library included with Qt, you + can pass \c{-system-sqlite} to the configure script to use the SQLite + libraries of the operating system. This is recommended whenever possible, + as it reduces the installation size and removes one component for which + you need to track security advisories. - After installing Qt, you also need to install the plugin in the standard location: + On Unix and \macos (replace \c $SQLITE with the directory where + SQLite resides): - \snippet code/doc_src_sql-driver.qdoc 22 + \snippet code/doc_src_sql-driver.qdoc 21 On Windows: @@ -588,8 +554,6 @@ \target QIBASE \section2 QIBASE for Borland InterBase - \section3 General Information about QIBASE - The Qt InterBase plugin makes it possible to access the InterBase and Firebird databases. InterBase can either be used as a client/server or without a server in which case it operates on local files. The @@ -617,7 +581,7 @@ \snippet code/doc_src_sql-driver.cpp 25 - If Qt doesn't support the given text encoding the driver will issue a + If Qt does not support the given text encoding the driver will issue a warning message and connect to the database using UNICODE_FSS. Note that if the text encoding set when connecting to the database is @@ -658,7 +622,7 @@ \snippet code/doc_src_sql-driver.qdoc 30 If you are not using a Microsoft compiler, replace \c nmake - with \c make in the line above. + with \c mingw32-make in the line above. Note that \c{C:\interbase\bin} must be in the \c PATH. @@ -678,14 +642,12 @@ make sure that the following requirements are met: \list - \li Ensure that you are using a shared Qt library; you cannot use the - plugins with a static build. \li Ensure that the plugin is in the correct directory. You can use QApplication::libraryPaths() to determine where Qt looks for plugins. \li Ensure that the client libraries of the DBMS are available on the system. On Unix, run the command \c{ldd} and pass the name of the plugin as parameter, for example \c{ldd libqsqlmysql.so}. You will - get a warning if any of the client libraries couldn't be found. + get a warning if any of the client libraries could not be found. On Windows, you can use Visual Studio's dependency walker. With Qt Creator, you can update the \c PATH environment variable in the \gui Run section of the \gui Project panel to include the path to @@ -695,12 +657,6 @@ \endlist Make sure you have followed the guide to \l{Deploying Plugins}. - If you experience plugin load problems and see output like this: - - \snippet code/doc_src_sql-driver.cpp 31 - - the problem is usually that the plugin had the wrong build key. - This might require removing an entry from the plugin cache. \target development \section1 How to Write Your Own Database Driver @@ -737,7 +693,7 @@ must use the Q_PLUGIN_METADATA() macro. Read \l{How to Create Qt Plugins} for more information on this. You can also check out how this is done in the SQL plugins that are provided with Qt in - \c{QTDIR/qtbase/src/plugins/sqldrivers} and \c{QTDIR/qtbase/src/sql/drivers}. + \c{QTDIR/qtbase/src/plugins/sqldrivers}. The following code can be used as a skeleton for a SQL driver: -- cgit v1.2.3 From e291f6774339ada7a495b24664c4906d46233272 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 1 Dec 2017 21:22:53 +0100 Subject: unbreak plugin dependency tracking use the correct operator. amends 623b191c10. Change-Id: Ice8b2a82b1c7828587cccc7d464f9313e176d536 Reviewed-by: Jake Petroules --- mkspecs/features/qt_plugin.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 62e1b69fde..14fc5f9a94 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -48,7 +48,7 @@ CONFIG(static, static|shared)|prefix_build { !build_pass { qt_plugin_deps = $$QT $$QT_PRIVATE - qt_plugin_deps = s,-private$,_private,g + qt_plugin_deps ~= s,-private$,_private,g MODULE_PRI_CONT = \ "QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \ -- cgit v1.2.3 From fb326ae1268aa5e5fd0c9369ccbe30fe5d6d8b62 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 1 Dec 2017 13:04:06 +0100 Subject: qmake: print compiler output if detection phase fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit helps enormously with debugging. Change-Id: Ic8876e74a4dbb14006d8b48658eb141a3f0e0fbf Reviewed-by: Tor Arne Vestbø --- mkspecs/features/toolchain.prf | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index ba41598be1..eb592badf4 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -19,7 +19,13 @@ defineTest(qtCompilerErrror) { what = " host" else: \ what = " target" - error("Cannot run$$what compiler '$$1'. Maybe you forgot to setup the environment?") + msg = \ + "Cannot run$$what compiler '$$1'. Output:" \ + "===================" \ + $$2 \ + "===================" \ + "Maybe you forgot to setup the environment?" + error($$join(msg, $$escape_expand(\\n))) } cross_compile:host_build: \ @@ -64,7 +70,7 @@ isEmpty($${target_prefix}.INCDIRS) { cxx_flags += -E -v output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX) + !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output) rim_qcc { for (line, output) { @@ -124,7 +130,7 @@ isEmpty($${target_prefix}.INCDIRS) { # What's more, -print-search-dirs can't be used on clang on Apple because it # won't print all the library paths (only the clang-internal ones). output = $$system("$$cmd_prefix $$QMAKE_CXX -print-search-dirs", lines, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX) + !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output) for (line, output) { contains(line, "^libraries: .*") { @@ -166,14 +172,14 @@ isEmpty($${target_prefix}.INCDIRS) { defineReplace(qtVariablesFromMSVC) { ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) NUL", lines, ec) - !equals(ec, 0): qtCompilerErrror($$1) + !equals(ec, 0): qtCompilerErrror($$1, $$ret) return($$ret) } defineReplace(qtVariablesFromGCC) { ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ <$$QMAKE_SYSTEM_NULL_DEVICE 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) - !equals(ec, 0): qtCompilerErrror($$1) + !equals(ec, 0): qtCompilerErrror($$1, $$ret) return($$ret) } -- cgit v1.2.3 From 0a8a7598223993c77985e99d46b20d7ea34fe8c2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 4 Dec 2017 18:32:32 +0100 Subject: fix namespaced build Change-Id: Ibd16658ef800afe1dec01311cc4ef1a9a6d83929 Reviewed-by: Timur Pocheptsov --- src/network/bearer/qbearerengine.cpp | 4 ++-- src/network/bearer/qnetworkconfigmanager.cpp | 4 ++-- src/network/bearer/qnetworksession.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp index 215cd3fddd..677da08cb6 100644 --- a/src/network/bearer/qbearerengine.cpp +++ b/src/network/bearer/qbearerengine.cpp @@ -93,8 +93,8 @@ bool QBearerEngine::configurationsInUse() const || hasUsedConfiguration(userChoiceConfigurations); } +QT_END_NAMESPACE + #include "moc_qbearerengine_p.cpp" #endif // QT_NO_BEARERMANAGEMENT - -QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index 7d7b7cc5b0..81b5e01d6a 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -378,8 +378,8 @@ void QNetworkConfigurationManager::updateConfigurations() priv->performAsyncConfigurationUpdate(); } -#include "moc_qnetworkconfigmanager.cpp" - QT_END_NAMESPACE +#include "moc_qnetworkconfigmanager.cpp" + #endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index bbcd191041..e5562e3a0b 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -749,8 +749,8 @@ void QNetworkSession::disconnectNotify(const QMetaMethod &signal) d->setALREnabled(false); } -#include "moc_qnetworksession.cpp" - QT_END_NAMESPACE +#include "moc_qnetworksession.cpp" + #endif // QT_NO_BEARERMANAGEMENT -- cgit v1.2.3 From 7830cdd8337e3ee9bade2e2c945ce3a2a068e442 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 6 Dec 2017 11:02:07 +0100 Subject: configure: during early setup, skip all of default_pre.prf ... instead of only toolchain.prf. the license check could go haywire, and everything else that file does is meaningless in configure context anyway. Task-number: QTBUG-63452 Change-Id: I5e31c87fe717fda40978c0317556070637e537e2 Reviewed-by: Jake Petroules --- mkspecs/features/default_pre.prf | 3 +++ mkspecs/features/toolchain.prf | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf index 2d52525190..07a9b1c401 100644 --- a/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -2,6 +2,9 @@ # Note that evaluating variable assignments from the command line # still happens in between these two steps. +# In early configure setup; nothing useful to be done here. +isEmpty(QMAKE_CXX): return() + load(exclusive_builds) CONFIG = \ lex yacc debug exceptions depend_includepath \ diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index eb592badf4..fdf3d1cdd3 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,7 +1,4 @@ -# In early configure setup; nothing useful to be done here. -isEmpty(QMAKE_CXX): return() - defineReplace(qtMakeExpand) { out = "$$1" for(ever) { -- cgit v1.2.3 From 81b5155e8234747658d0cce210f205fd6c4736ff Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 12 Dec 2017 20:48:17 +0100 Subject: fix "make clean" of qmake in a builddir with spaces on mingw Change-Id: Ice61a11250694afa66f263fa79a74ff9642ef285 Reviewed-by: Thiago Macieira --- qmake/Makefile.unix.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/Makefile.unix.mingw b/qmake/Makefile.unix.mingw index 2c52c07dca..6480171c69 100644 --- a/qmake/Makefile.unix.mingw +++ b/qmake/Makefile.unix.mingw @@ -9,7 +9,7 @@ # sh-compatible shell. This is not a problem, because configure.bat # will not do that. ifeq ($(SHELL), sh.exe) - ifeq ($(wildcard $(CURDIR)/sh.exe), ) + ifeq ($(wildcard ./sh.exe), ) SH = 0 else SH = 1 -- cgit v1.2.3 From 9e1b6b6e53d01bed76dc624e4b6c0d5f7748bf85 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 28 Jul 2017 09:00:18 +0200 Subject: QFileSystemModel: Enable experimental code path for per-file watching QFileSystemModel had a #ifdefed out experimental code path for watching single files to track changes in size, which got outdated over time. Replace the #ifdef 0 by a check for the environment variable QT_FILESYSTEMMODEL_WATCH_FILES, fix it up and apply some fixes to related code to make it work: - Split file names signaled by QFileSystemWatcher on '/' always. - Do not instantiate QDirIterator on "", which means "current directory" and results in mixed-up directories. - Check on lastModified() in QExtendedInformation::operator==() so that changes trigger an update in _q_fileSystemChanged(). - Fix the #ifdefed out part to compile and not to add directories to the watcher. [ChangeLog][QtWidgets][QFileSystemModel] It is now possible to enable per-file watching by setting the environment variable QT_FILESYSTEMMODEL_WATCH_FILES, allowing to track for example changes in file size. Task-number: QTBUG-46684 Change-Id: Ia5da9170866416c9529251f889814b23d7a7d069 Reviewed-by: Edward Welbourne --- src/widgets/dialogs/qfileinfogatherer.cpp | 35 ++++++++++++++++--------------- src/widgets/dialogs/qfileinfogatherer_p.h | 3 ++- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index 710ee611b9..aef13a563f 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -196,7 +196,7 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr */ void QFileInfoGatherer::updateFile(const QString &filePath) { - QString dir = filePath.mid(0, filePath.lastIndexOf(QDir::separator())); + QString dir = filePath.mid(0, filePath.lastIndexOf(QLatin1Char('/'))); QString fileName = filePath.mid(dir.length() + 1); fetchExtendedInformation(dir, QStringList(fileName)); } @@ -267,19 +267,19 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const info.icon = m_iconProvider->icon(fileInfo); info.displayType = m_iconProvider->type(fileInfo); #ifndef QT_NO_FILESYSTEMWATCHER - // ### Not ready to listen all modifications - #if 0 - // Enable the next two commented out lines to get updates when the file sizes change... + // ### Not ready to listen all modifications by default + static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES"); + if (watchFiles) { if (!fileInfo.exists() && !fileInfo.isSymLink()) { - info.size = -1; - //watcher->removePath(fileInfo.absoluteFilePath()); + watcher->removePath(fileInfo.absoluteFilePath()); } else { - if (!fileInfo.absoluteFilePath().isEmpty() && fileInfo.exists() && fileInfo.isReadable() - && !watcher->files().contains(fileInfo.absoluteFilePath())) { - //watcher->addPath(fileInfo.absoluteFilePath()); + const QString path = fileInfo.absoluteFilePath(); + if (!path.isEmpty() && fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() + && !watcher->files().contains(path)) { + watcher->addPath(path); } } - #endif + } #endif #ifdef Q_OS_WIN @@ -329,14 +329,15 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil QVector > updatedFiles; QStringList filesToCheck = files; - QString itPath = QDir::fromNativeSeparators(files.isEmpty() ? path : QLatin1String("")); - QDirIterator dirIt(itPath, QDir::AllEntries | QDir::System | QDir::Hidden); QStringList allFiles; - while (!abort.load() && dirIt.hasNext()) { - dirIt.next(); - fileInfo = dirIt.fileInfo(); - allFiles.append(fileInfo.fileName()); - fetch(fileInfo, base, firstTime, updatedFiles, path); + if (files.isEmpty()) { + QDirIterator dirIt(path, QDir::AllEntries | QDir::System | QDir::Hidden); + while (!abort.load() && dirIt.hasNext()) { + dirIt.next(); + fileInfo = dirIt.fileInfo(); + allFiles.append(fileInfo.fileName()); + fetch(fileInfo, base, firstTime, updatedFiles, path); + } } if (!allFiles.isEmpty()) emit newListOfFiles(path, allFiles); diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 52578126de..0cf2ed1f58 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -84,7 +84,8 @@ public: bool operator ==(const QExtendedInformation &fileInfo) const { return mFileInfo == fileInfo.mFileInfo && displayType == fileInfo.displayType - && permissions() == fileInfo.permissions(); + && permissions() == fileInfo.permissions() + && lastModified() == fileInfo.lastModified(); } #ifndef QT_NO_FSFILEENGINE -- cgit v1.2.3 From 1adb1ef6bab6247f5914e94380f8b05e11cb8d7e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Oct 2017 15:16:33 +0100 Subject: QStyleSheetStyle: Draw menu item also when font is set Task-number: QTBUG-64055 Change-Id: I0674e7b43bb56aa1834c8df10794714dbcc4e5e3 Reviewed-by: Andy Shaw --- src/widgets/styles/qstylesheetstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 6a99d21988..e8b90b87b3 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3655,7 +3655,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) { subRule.drawRule(p, opt->rect); } else if ((pseudo == PseudoElement_Item) - && (allRules.hasBox() || allRules.hasBorder() + && (allRules.hasBox() || allRules.hasBorder() || subRule.hasFont || (allRules.background() && !allRules.background()->pixmap.isNull()))) { subRule.drawRule(p, opt->rect); if (subRule.hasBackground()) { -- cgit v1.2.3 From dc0bb57f8600374b7279d5c14456a33a9d0c0476 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 11 Dec 2017 21:59:42 -0800 Subject: Fix an issue causing asset catalogs to be miscompiled with iOS simulator This works around the inability to build iOS apps for a "generic" simulator by explicitly setting the Xcode build setting ENABLE_ONLY_ACTIVE_RESOURCES to NO in order to ensure that all variants of assets in an asset catalog are built when targeting iOS simulator devices. Otherwise, we will simply build for whatever the first simulator in the list happens to be. If the application is then deployed to a different simulator, some of the assets needed for that device variant may be missing. This "helps" QTCREATORBUG-19447 but is not a workaround since this fix is necessary for command line builds anyways, even though it's unlikely to crop up in practice there, since one would have to manually deploy the built application bundle to the simulator using simctl rather than going through Xcode (which would rebuild for the appropriate device). Change-Id: Ia41c48dcc715fe79a2c50db66a0ca7a1fea159c2 Reviewed-by: Vikas Pachdha Reviewed-by: Oswald Buddenhagen --- mkspecs/features/uikit/xcodebuild.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/uikit/xcodebuild.mk b/mkspecs/features/uikit/xcodebuild.mk index 0b3ad632b6..7d3275df65 100644 --- a/mkspecs/features/uikit/xcodebuild.mk +++ b/mkspecs/features/uikit/xcodebuild.mk @@ -90,7 +90,7 @@ DESTINATION_MESSAGE = "Running $(call tolower,$(CONFIGURATION)) $(ACTION) \ xcodebuild-%: @$(if $(DESTINATION_NAME), echo $(DESTINATION_MESSAGE),) - xcodebuild $(ACTION) $(XCODEBUILD_FLAGS) -project $(TARGET).xcodeproj -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) $(if $(INSTALL_ROOT), DSTROOT=$(INSTALL_ROOT),) + xcodebuild $(ACTION) $(XCODEBUILD_FLAGS) -project $(TARGET).xcodeproj -scheme $(TARGET) $(if $(SDK), -sdk $(SDK),) $(if $(CONFIGURATION), -configuration $(CONFIGURATION),) $(if $(DESTINATION), -destination $(DESTINATION) -destination-timeout 1,) $(if $(DESTINATION_ID),, ENABLE_ONLY_ACTIVE_RESOURCES=NO) $(if $(INSTALL_ROOT), DSTROOT=$(INSTALL_ROOT),) xcodebuild-check-device_%: DESTINATION_ID=$(lastword $(subst _, ,$@)) -- cgit v1.2.3 From fddc5a27b180d7afde37e2c004cee95302e907ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 14 Dec 2017 12:32:35 +0100 Subject: macOS: Enable using CoreGraphics helper functions from C++ sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If32c96d224bfb90ba22661b6f5ac3c920acb39d2 Reviewed-by: Morten Johan Sørvig --- src/gui/painting/qcoregraphics_p.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index d74c4d0711..6b6a1e800e 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -56,13 +56,15 @@ #include #include -#ifdef Q_OS_MACOS + +#if defined(__OBJC__) && defined(Q_OS_MACOS) #include +#define HAVE_APPKIT #endif QT_BEGIN_NAMESPACE -#ifdef Q_OS_MACOS +#ifdef HAVE_APPKIT Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm); Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize = 0); Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size); @@ -78,7 +80,7 @@ Q_GUI_EXPORT CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice * Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); -#ifdef Q_OS_MACOS +#ifdef HAVE_APPKIT Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color); Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); #endif @@ -124,4 +126,6 @@ private: QT_END_NAMESPACE +#undef HAVE_APPKIT + #endif // QCOREGRAPHICS_P_H -- cgit v1.2.3 From 039ac7d20c1643246f9041204d59096e143127a7 Mon Sep 17 00:00:00 2001 From: Timo Aarnipuro Date: Tue, 21 Nov 2017 13:12:24 +0200 Subject: Add mkspec for INTEGRITY Multivisor on the Renesas Salvator-X Change-Id: Ie8d2f5c022a6a2396534cebf1f17cbb8df92cb27 Reviewed-by: Oswald Buddenhagen Reviewed-by: Kimmo Ollila Reviewed-by: Laszlo Agocs --- mkspecs/integrity-armv8-rcar/qmake.conf | 33 +++++++++++++++++++++++ mkspecs/integrity-armv8-rcar/qplatformdefs.h | 39 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 mkspecs/integrity-armv8-rcar/qmake.conf create mode 100644 mkspecs/integrity-armv8-rcar/qplatformdefs.h diff --git a/mkspecs/integrity-armv8-rcar/qmake.conf b/mkspecs/integrity-armv8-rcar/qmake.conf new file mode 100644 index 0000000000..46091f6a91 --- /dev/null +++ b/mkspecs/integrity-armv8-rcar/qmake.conf @@ -0,0 +1,33 @@ +# +# qmake configuration for INTEGRITY armv7 targets +# + +# armv7 common includes work for armv8-A as well +include(../common/ghs-integrity-armv7.conf) + +DEFINES += INTEGRITY + +# This define is used because the RCar INTEGRITY EGL library expects same +# parameter types as Symbian. The parameter types are defined in eglplatform.h. +DEFINES += __WINSCW__ + +QTPLUGIN.platforms += qeglfs +QT_QPA_DEFAULT_PLATFORM = eglfs + +QMAKE_LIBS_EGL += -lEGL -lIMGegl -lsrv_um -lsrv_init -lpvrWSEGL_WM -lncg_usr.a -lmmgr_usr -lwm_usr -lprr_usr +QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lIMGegl -lglslcompiler -lusc -lsrv_um -lsrv_init -lpvrWSEGL_WM -lncg_usr.a -lmmgr_usr -lwm_usr -lprr_usr +QMAKE_LIBS_GUI = -lmmgr_usr -lwm_usr -lprr_usr + +QMAKE_CFLAGS += -bigswitch +QMAKE_CXXFLAGS += -bigswitch +QMAKE_LFLAGS += -bigswitch + +EGLFS_DEVICE_INTEGRATION = eglfs_rcar + +# OpenGL libraries have a dependency on libEGL +dirs = $$(GL_INC_DIR) +QMAKE_INCDIR_EGL = $$split(dirs, $$QMAKE_DIRLIST_SEP) +QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_EGL +dirs = $$(GL_LIB_DIR) +QMAKE_LIBDIR_EGL = $$split(dirs, $$QMAKE_DIRLIST_SEP) +QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_EGL diff --git a/mkspecs/integrity-armv8-rcar/qplatformdefs.h b/mkspecs/integrity-armv8-rcar/qplatformdefs.h new file mode 100644 index 0000000000..55afd0c3c7 --- /dev/null +++ b/mkspecs/integrity-armv8-rcar/qplatformdefs.h @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Green Hills Software. All rights reserved. +** 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 + +#include "../common/integrity/qplatformdefs.h" + +#endif // QPLATFORMDEFS_H -- cgit v1.2.3 From e739e984c3006ed2e88ef8f087455116cf9c4ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 7 Aug 2017 19:54:41 +0200 Subject: macOS: Make retina OpenGL work on VMware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt requests full resolution OpenGL surfaces by default. However, when running as a VMware guest it looks like the OS silently creates low-resolution surfaces. This is not possible to detect using the standard NSWindow APIs for converting to backing coordinates or for reading the backing scale factor. The result of this is that Qt will incorrectly display one quarter of the window content only. Fall back to detecting if the OpenGL renderer is the Apple software renderer, which it will be on VMware. Cancel the high-resolution surface request if this is the case. This needs to be done while we have a valid OpenGL context. Task-number: QTBUG-62357 Change-Id: I33bf12b3bb0408249e6d66e0a8ca86b044bea781 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaglcontext.h | 1 + src/plugins/platforms/cocoa/qcocoaglcontext.mm | 19 ++++++++++++++++++- src/plugins/platforms/cocoa/qcocoawindow.mm | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 1a66cec0e3..732b50d29e 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -84,6 +84,7 @@ private: NSOpenGLContext *m_shareContext; QSurfaceFormat m_format; QPointer m_currentWindow; + bool m_didCheckForSoftwareContext; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index be5029b7e0..b656025ec7 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -121,7 +121,8 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo const QVariant &nativeHandle) : m_context(nil), m_shareContext(nil), - m_format(format) + m_format(format), + m_didCheckForSoftwareContext(false) { if (!nativeHandle.isNull()) { if (!nativeHandle.canConvert()) { @@ -262,6 +263,22 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface) QWindow *window = static_cast(surface)->window(); setActiveWindow(window); + + // Disable high-resolution surfaces when using the software renderer, which has the + // problem that the system silently falls back to a to using a low-resolution buffer + // when a high-resolution buffer is requested. This is not detectable using the NSWindow + // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt + // will display a quarter of the window content when running in a virtual machine. + if (!m_didCheckForSoftwareContext) { + m_didCheckForSoftwareContext = true; + + const GLubyte* renderer = glGetString(GL_RENDERER); + if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) { + NSView *view = static_cast(surface)->m_view; + [view setWantsBestResolutionOpenGLSurface:NO]; + } + } + update(); return true; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index d1f19f2de9..e86cc2d955 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -198,6 +198,7 @@ void QCocoaWindow::initialize() BOOL enable = qt_mac_resolveOption(YES, window(), "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); [m_view setWantsBestResolutionOpenGLSurface:enable]; + // See also QCocoaGLContext::makeCurrent for software renderer workarounds. } BOOL enable = qt_mac_resolveOption(NO, window(), "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER"); -- cgit v1.2.3 From f2f75c02287f936067e3e04ea452fbe8bbab14d1 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 12 Dec 2017 13:45:39 +0100 Subject: Doc: Fix paths to 3rdparty license files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix paths added in 870423f98ba4a3a. This caused havoc on case sensitive file systems. [ChangeLog][Third-Party Code] Fixed glitch in attribution documentation for Freetype licenses / Qt Gui. Task-number: QTBUG-65138 Change-Id: Idb20a1ead772337f97a1262da42c62f6aef04a54 Reviewed-by: Topi Reiniö --- src/3rdparty/freetype/qt_attribution.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json index e00f2062b0..4be86e92b6 100644 --- a/src/3rdparty/freetype/qt_attribution.json +++ b/src/3rdparty/freetype/qt_attribution.json @@ -9,7 +9,7 @@ "Homepage": "http://www.freetype.org", "License": "Freetype Project License or GNU General Public License v2.0 only", "LicenseId": "FTL OR GPL-2.0", - "LicenseFile": "LICENSE.TXT", + "LicenseFile": "LICENSE.txt", "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." }, { @@ -22,7 +22,7 @@ "Homepage": "http://www.freetype.org", "License": "zlib License", "LicenseId": "Zlib", - "LicenseFile": "ZLIB-LICENSE.TXT", + "LicenseFile": "ZLIB-LICENSE.txt", "Copyright": "Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler" }, { @@ -35,7 +35,7 @@ "Homepage": "http://www.freetype.org", "License": "MIT License", "LicenseId": "MIT", - "LicenseFile": "BDF-LICENSE.TXT", + "LicenseFile": "BDF-LICENSE.txt", "Copyright": "Copyright (C) 2001-2002 by Francesco Zappa Nardelli Copyright 2000 Computing Research Labs, New Mexico State University Copyright 2001-2002, 2011 Francesco Zappa Nardelli" @@ -50,7 +50,7 @@ Copyright 2001-2002, 2011 Francesco Zappa Nardelli" "Homepage": "http://www.freetype.org", "License": "MIT License", "LicenseId": "MIT", - "LicenseFile": "PCF-LICENSE.TXT", + "LicenseFile": "PCF-LICENSE.txt", "Copyright": "Copyright (C) 2000 by Francesco Zappa Nardelli" } ] -- cgit v1.2.3 From 034e92b0f4f49432e170184fb84e29c315d3f279 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 14 Dec 2017 13:15:05 +0100 Subject: Android: Set correct input hints when queried through getCursorCapsMode getCursorCapsMode() now matches the Java implementation in QtActivityDelegate.showSoftwareKeyboard() which is given to the Android keyboard on InputConnection creation. The reason we only saw this bug with some Android keyboards was that many keyboards never call getCursorCapsMode and just rely on the initial hints. Task-number: QTBUG-51865 Change-Id: I2aae024d9c77ea14e087e3f51a413d15a684179c Reviewed-by: Paul Olav Tvete Reviewed-by: Christian Stromme --- src/plugins/platforms/android/qandroidinputcontext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index ccc7f06b6b..fe4c5be4cb 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -847,11 +847,11 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt(); - if (qtInputMethodHints & Qt::ImhPreferUppercase) - res = CAP_MODE_SENTENCES; + if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase)) + res |= CAP_MODE_SENTENCES; if (qtInputMethodHints & Qt::ImhUppercaseOnly) - res = CAP_MODE_CHARACTERS; + res |= CAP_MODE_CHARACTERS; return res; } -- cgit v1.2.3 From dffa01a438f971089f6609bc8c2406ca19fba724 Mon Sep 17 00:00:00 2001 From: Timo Aarnipuro Date: Tue, 21 Nov 2017 13:09:09 +0200 Subject: Add EGLFS integration plugin for Salvator-X on INTEGRITY Multivisor This plugin uses the Renesas RISP Window Manager. Change-Id: If813c46ab8d39e966c0a969610841867885dd473 Reviewed-by: Laszlo Agocs --- src/gui/configure.json | 23 ++- .../eglfs/deviceintegration/deviceintegration.pro | 1 + .../deviceintegration/eglfs_rcar/eglfs_rcar.json | 3 + .../deviceintegration/eglfs_rcar/eglfs_rcar.pro | 19 +++ .../eglfs_rcar/qeglfsrcarintegration.cpp | 159 +++++++++++++++++++++ .../eglfs_rcar/qeglfsrcarintegration.h | 66 +++++++++ .../eglfs_rcar/qeglfsrcarmain.cpp | 57 ++++++++ 7 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp diff --git a/src/gui/configure.json b/src/gui/configure.json index 9710ee4e20..23ed9487a8 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -716,6 +716,22 @@ }, "use": "egl" }, + "egl-rcar": { + "label": "RCAR EGL", + "type": "compile", + "test": { + "include": [ "EGL/egl.h" ], + "tail": [ + "extern \"C\" {", + "extern unsigned long PVRGrfxServerInit(void);", + "}" + ], + "main": [ + "PVRGrfxServerInit();" + ] + }, + "use": "egl opengl_es2" + }, "evdev": { "label": "evdev", "type": "compile", @@ -1094,6 +1110,11 @@ "condition": "features.eglfs && tests.egl-viv", "output": [ "privateFeature" ] }, + "eglfs_rcar": { + "label": "EGLFS RCAR", + "condition": "config.integrity && features.eglfs && tests.egl-rcar", + "output": [ "privateFeature" ] + }, "eglfs_viv_wl": { "label": "EGLFS i.Mx6 Wayland", "condition": "features.eglfs_viv && libs.wayland_server", @@ -1576,7 +1597,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "EGLFS details", "condition": "features.eglfs", "entries": [ - "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11" + "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_mali", "eglfs_brcm", "egl_x11" ] }, "linuxfb", "vnc", "mirclient", diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 2cddbe9beb..92ee83fd8f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -7,6 +7,7 @@ qtConfig(eglfs_egldevice): SUBDIRS *= eglfs_kms_support eglfs_kms_egldevice qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm qtConfig(eglfs_mali): SUBDIRS += eglfs_mali qtConfig(eglfs_viv): SUBDIRS += eglfs_viv +qtConfig(eglfs_rcar): SUBDIRS += eglfs_rcar qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl qtConfig(eglfs_openwfd): SUBDIRS += eglfs_openwfd qtConfig(opengl): SUBDIRS += eglfs_emu diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json new file mode 100644 index 0000000000..77b3083eef --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_rcar" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro new file mode 100644 index 0000000000..04236449a0 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/eglfs_rcar.pro @@ -0,0 +1,19 @@ +TARGET = qeglfs-rcar-integration + +QT += core-private gui-private eglfsdeviceintegration-private + +INCLUDEPATH += $$PWD/../../api +CONFIG += egl +DEFINES += LINUX=1 EGL_API_FB=1 +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsrcarmain.cpp \ + $$PWD/qeglfsrcarintegration.cpp + +HEADERS += $$PWD/qeglfsrcarintegration.h + +OTHER_FILES += $$PWD/eglfs_rcar.json + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSRcarIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp new file mode 100644 index 0000000000..98cf1d3bfb --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#include +#include +#include +#include "INTEGRITY.h" +#include "qeglfsrcarintegration.h" + +#define RCAR_DEFAULT_DISPLAY 1 +#define RCAR_DEFAULT_WM_LAYER 2 + +extern "C" unsigned long PVRGrfxServerInit(void); + +QT_BEGIN_NAMESPACE + +void QEglFSRcarIntegration::platformInit() +{ + QEglFSDeviceIntegration::platformInit(); + + PVRGrfxServerInit(); + + mScreenSize = q_screenSizeFromFb(0); + mNativeDisplay = (NativeDisplayType)EGL_DEFAULT_DISPLAY; +} + +QSize QEglFSRcarIntegration::screenSize() const +{ + return mScreenSize; +} + +EGLNativeDisplayType QEglFSRcarIntegration::platformDisplay() const +{ + return mNativeDisplay; +} + +static r_wm_WinColorFmt_t getWMColorFormat(const QSurfaceFormat &format) +{ + const int a = format.alphaBufferSize(); + const int r = format.redBufferSize(); + const int g = format.greenBufferSize(); + const int b = format.blueBufferSize(); + + switch (r) { + case 4: + if (g == 4 && b == 4 && a == 4) + return R_WM_COLORFMT_ARGB4444; + break; + case 5: + if (g == 6 && b == 5 && a == 0) + return R_WM_COLORFMT_RGB565; + else if (g == 5 && b == 5 && a == 1) + return R_WM_COLORFMT_ARGB1555; + break; + case 8: + if (g == 8 && b == 8 && a == 0) + return R_WM_COLORFMT_RGB0888; + else if (g == 8 && b == 8 && a == 8) + return R_WM_COLORFMT_ARGB8888; + break; + } + + qFatal("Unsupported color format: R:%d G:%d B:%d A:%d", r, g, b, a); + return R_WM_COLORFMT_LAST; +} + +EGLNativeWindowType QEglFSRcarIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) +{ + bool ok; + + mNativeDisplayID = qEnvironmentVariableIntValue("QT_QPA_WM_DISP_ID", &ok); + if (!ok) + mNativeDisplayID = RCAR_DEFAULT_DISPLAY; + + r_wm_Error_t wm_err = R_WM_DevInit(mNativeDisplayID); + if (wm_err != R_WM_ERR_OK) + qFatal("Failed to init WM Dev: %d, error: %d", mNativeDisplayID, wm_err); + + mNativeWindow = (EGLNativeWindowTypeREL*)malloc(sizeof(EGLNativeWindowTypeREL)); + memset(mNativeWindow, 0, sizeof(EGLNativeWindowTypeREL)); + + mNativeWindow->ColorFmt = getWMColorFormat(format); + mNativeWindow->PosX = 0; + mNativeWindow->PosY = 0; + mNativeWindow->PosZ = qEnvironmentVariableIntValue("QT_QPA_WM_LAYER", &ok); + if (!ok) + mNativeWindow->PosZ = RCAR_DEFAULT_WM_LAYER; + mNativeWindow->Pitch = size.width(); + mNativeWindow->Width = size.width(); + mNativeWindow->Height = size.height(); + mNativeWindow->Alpha = format.alphaBufferSize(); + + if (format.swapBehavior() == QSurfaceFormat::DefaultSwapBehavior) + mNativeWindow->Surface.BufNum = 3; + else + mNativeWindow->Surface.BufNum = format.swapBehavior(); + + mNativeWindow->Surface.Type = R_WM_SURFACE_FB; + mNativeWindow->Surface.BufMode = R_WM_WINBUF_ALLOC_INTERNAL; + + wm_err = R_WM_WindowCreate(mNativeDisplayID, mNativeWindow); + if (wm_err != R_WM_ERR_OK) + qFatal("Failed to create window layer: %d", wm_err); + wm_err = R_WM_DevEventRegister(mNativeDisplayID, R_WM_EVENT_VBLANK, 0); + if (wm_err != R_WM_ERR_OK) + qFatal("Failed to Register vsync event: %d", wm_err); + wm_err = R_WM_WindowEnable(mNativeDisplayID, mNativeWindow); + if (wm_err != R_WM_ERR_OK) + qFatal("Failed to Enable window surface: %d", wm_err); + + return static_cast(mNativeWindow); +} + +void QEglFSRcarIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + R_WM_WindowDisable(mNativeDisplayID, mNativeWindow); + usleep(100000); //Needed to allow Window Manager make the window transparent + R_WM_WindowDelete(mNativeDisplayID, mNativeWindow); + R_WM_DevDeinit(mNativeDisplayID); + free(mNativeWindow); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h new file mode 100644 index 0000000000..08911594f9 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarintegration.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#ifndef QEGLFSVIVINTEGRATION_H +#define QEGLFSVIVINTEGRATION_H + +#include "private/qeglfsdeviceintegration_p.h" +#include "EGL/eglext_REL.h" + +QT_BEGIN_NAMESPACE + +class QEglFSRcarIntegration : public QEglFSDeviceIntegration +{ +public: + void platformInit() override; + QSize screenSize() const override; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override; + void destroyNativeWindow(EGLNativeWindowType window) override; + EGLNativeDisplayType platformDisplay() const override; + +private: + QSize mScreenSize; + EGLNativeDisplayType mNativeDisplay; + EGLNativeWindowTypeREL *mNativeWindow; + int mNativeDisplayID; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp new file mode 100644 index 0000000000..6cf3e1387d --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_rcar/qeglfsrcarmain.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins 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$ +** +****************************************************************************/ + +#include "INTEGRITY.h" +#include "private/qeglfsdeviceintegration_p.h" +#include "qeglfsrcarintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSRcarIntegrationPlugin : public QEglFSDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_rcar.json") + +public: + QEglFSDeviceIntegration *create() override { return new QEglFSRcarIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsrcarmain.moc" -- cgit v1.2.3 From c10f2aaeb77c3da609be0f7d88ed6641a256953d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 11 Dec 2017 10:18:44 +0100 Subject: Disable WiFi bearer plugins on macOS and Windows Scanning for WiFi networks is causing network disruptions in the form of higher latency, sometimes globally for all running applications. In practice, the default configuration selection algorithm in QNetworkConfigurationManager prefers configurations from the generic bearer plugin, due to the way the plugins are ordered. Removing the platform WiFi bearers should have no effect on default network configuration selection. Task-number: QTBUG-40332 Change-Id: I778281c41a1aaec1949c220a9266677bd788a57a Reviewed-by: Timur Pocheptsov --- src/plugins/bearer/bearer.pro | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index b362722b28..824fd0388f 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -6,11 +6,6 @@ QT_FOR_CONFIG += network-private SUBDIRS += connman networkmanager } -#win32:SUBDIRS += nla -win32:SUBDIRS += generic -win32:!winrt: SUBDIRS += nativewifi -darwin:qtConfig(corewlan): SUBDIRS += corewlan -mac:SUBDIRS += generic android:SUBDIRS += android isEmpty(SUBDIRS):SUBDIRS = generic -- cgit v1.2.3 From 9fbd9e066e6df19fef8eed77ec27c74124330c0a Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Fri, 15 Dec 2017 13:01:58 +0200 Subject: Derive QPpsObjectPrivate from QObjectPrivate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes 5d4089299ab4c39463e228e5896a3010268a36f2 commit, which was causing a build break if qnx pps is enabled. Change-Id: I8c29f48bde0187a9db02d6325e8a9a0fae760bcb Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qppsobjectprivate_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qppsobjectprivate_p.h b/src/corelib/kernel/qppsobjectprivate_p.h index e1d54e58de..dae44e3609 100644 --- a/src/corelib/kernel/qppsobjectprivate_p.h +++ b/src/corelib/kernel/qppsobjectprivate_p.h @@ -57,13 +57,15 @@ #include #include +#include QT_BEGIN_NAMESPACE class QSocketNotifier; -class QPpsObjectPrivate +class QPpsObjectPrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QPpsObject) public: explicit QPpsObjectPrivate(const QString &path); -- cgit v1.2.3 From 3dd030863435e058468df66c696e1608b71e1fd2 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 12 Dec 2017 11:35:25 +0100 Subject: Mask potentially undefined alpha in blend_transformed_argb Makes sure the ARGB32PM that is painted on always have a defined alpha. Task-number: QTBUG-55645 Change-Id: Ifcf5fcc2127d255518eca4763845a197da6c7914 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qdrawhelper.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 6a24c02aaa..6bfdc940ac 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4719,6 +4719,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode]; uint buffer[buffer_size]; + quint32 mask = (data->texture.format == QImage::Format_RGB32) ? 0xff000000 : 0; const int image_x1 = data->texture.x1; const int image_y1 = data->texture.y1; @@ -4752,7 +4753,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData while (b < end) { int px = qBound(image_x1, x >> 16, image_x2); int py = qBound(image_y1, y >> 16, image_y2); - *b = reinterpret_cast(data->texture.scanLine(py))[px]; + *b = reinterpret_cast(data->texture.scanLine(py))[px] | mask; x += fdx; y += fdy; @@ -4793,7 +4794,7 @@ static void blend_transformed_argb(int count, const QSpan *spans, void *userData const int px = qBound(image_x1, int(tx) - (tx < 0), image_x2); const int py = qBound(image_y1, int(ty) - (ty < 0), image_y2); - *b = reinterpret_cast(data->texture.scanLine(py))[px]; + *b = reinterpret_cast(data->texture.scanLine(py))[px] | mask; x += fdx; y += fdy; w += fdw; -- cgit v1.2.3 From 93dabeba9dc5f6cbab60e65b3cc8df5fe48745a9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 17 Nov 2017 20:57:00 +0100 Subject: QTreeView: Make sure QHeaderView is notified on layoutChanged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QHeaderViewPrivate::_q_layoutChanged() was not called when used in a QTreeView because it was explicitly disconnected in setModel(). The disconnect was added sometime prio to Qt 4.3, but there the signal was connected to the doItemsLayout() slot. This was correct since QTreeView::doItemsLayout() is calling header->doItemsLayout(). In Qt 4.3.0 _q_layoutChanged() was introduced and the disconnect was adjusted. But since _q_layoutChanged() is doing much more than doItemsLayout() (e.g. restoring hidden sections), functionality was lost. The problem was already observed for Qt 4.6 (QTBUG-18196) but only partially fixed. Task-number: QTBUG-41124 Task-number: QTBUG-54610 Change-Id: Id13a9930d0163812e12a0287016bab9c3aa02068 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qtreeview.cpp | 3 --- .../widgets/itemviews/qtreeview/tst_qtreeview.cpp | 24 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index bbbadecff8..20e99d2aee 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -237,9 +237,6 @@ void QTreeView::setModel(QAbstractItemModel *model) // QAbstractItemView connects to a private slot disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - // do header layout after the tree - disconnect(d->model, SIGNAL(layoutChanged()), - d->header, SLOT(_q_layoutChanged())); // QTreeView has a public slot for this connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsRemoved(QModelIndex,int,int))); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index dfcaa9b5b9..5de0ca6c22 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -313,6 +313,17 @@ public: endRemoveColumns(); } + void removeAddLastColumnLayoutChanged() // for taskQTBUG_41124 + { + // make sure QHeaderView::_q_layoutChanged() is called + emit layoutAboutToBeChanged(); + --cols; + emit layoutChanged(); + emit layoutAboutToBeChanged(); + ++cols; + emit layoutChanged(); + } + void removeAllColumns() { beginRemoveColumns(QModelIndex(), 0, cols - 1); @@ -1306,6 +1317,19 @@ void tst_QTreeView::columnHidden() for (int c = 0; c < model.columnCount(); ++c) QCOMPARE(view.isColumnHidden(c), true); view.update(); + + // QTBUG_41124: + // QHeaderViewPrivate::_q_layoutChanged was not called because it was + // disconnected in QTreeView::setModel(). _q_layoutChanged restores + // the hidden sections which is tested here + view.setColumnHidden(model.cols - 1, true); + model.removeAddLastColumnLayoutChanged(); + // we removed the last column and added a new one + // (with layoutToBeChanged/layoutChanged() for both) so column + // 1 is a new column and therefore must not be hidden when + // _q_layoutChanged() is called and is doing the right stuff + QCOMPARE(view.isColumnHidden(model.cols - 1), false); + } void tst_QTreeView::rowHidden() -- cgit v1.2.3 From 3841a7dd49667ceabdcbc416fa1e149bed7ed86e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 12 Dec 2017 15:53:44 +0100 Subject: Prevent infinite relayout when adding scrollbars When one scrollbar is added, this may cause the other to be needed as well. This change does a second calculation immediately instead of relying on a signal through a QueuedConnection. Task-number: QTBUG-62818 Task-number: QTBUG-56280 Change-Id: Iee9a083e3a6cd3765e6bb9206687a8a6e7f99cff Reviewed-by: Paul Olav Tvete Reviewed-by: Andy Nichols --- src/widgets/widgets/qabstractscrollarea.cpp | 25 +++++++++++++++++++------ src/widgets/widgets/qabstractscrollarea_p.h | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 249ebd35d3..c6d66bafd4 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -333,17 +333,28 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on) #endif void QAbstractScrollAreaPrivate::layoutChildren() +{ + bool needH = false; + bool needV = false; + layoutChildren_helper(&needH, &needV); + // Call a second time if one scrollbar was needed and not the other to + // check if it needs to readjust accordingly + if (needH != needV) + layoutChildren_helper(&needH, &needV); +} + +void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar) { Q_Q(QAbstractScrollArea); bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar); - bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient) - || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient) - && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())); + bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient) + || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient) + && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()))); bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar); - bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient) - || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient) - && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())); + bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient) + || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient) + && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()))); QStyleOption opt(0); opt.init(q); @@ -522,6 +533,8 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewportRect.adjust(left, top, -right, -bottom); viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last + *needHorizontalScrollbar = needh; + *needVerticalScrollbar = needv; } /*! diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h index c52e7f9fd4..49f97bcb61 100644 --- a/src/widgets/widgets/qabstractscrollarea_p.h +++ b/src/widgets/widgets/qabstractscrollarea_p.h @@ -95,6 +95,7 @@ public: void init(); void layoutChildren(); + void layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar); // ### Fix for 4.4, talk to Bjoern E or Girish. virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} bool canStartScrollingAt( const QPoint &startPos ); -- cgit v1.2.3 From 0857db89bf2d36a1501c708521daacdbc83d5c5b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 Dec 2017 17:45:53 +0100 Subject: Widgets: check if parent exists before calling parent->locale() If a top level, parentless widget has Qt::WA_WindowPropagation set, Qt will crash when trying to resolve the widgets locale. The reason is that we try to access the QLocale of the non-existing parent. This patch will add a check if a parent exists before trying to access it. Task-number: QTBUG-61213 Change-Id: I09a6351a12dc1fffab3069b70e3d7b3932317c85 Reviewed-by: Edward Welbourne --- src/widgets/kernel/qwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b57a0d4779..b38565493e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6007,9 +6007,9 @@ void QWidgetPrivate::resolveLocale() Q_Q(const QWidget); if (!q->testAttribute(Qt::WA_SetLocale)) { - setLocale_helper(q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation) - ? QLocale() - : q->parentWidget()->locale()); + QWidget *parent = q->parentWidget(); + setLocale_helper(!parent || (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) + ? QLocale() : parent->locale()); } } -- cgit v1.2.3 From b0938cb6c1fa29ec2d2a4fb9273e515cd0d6c08e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 17 Dec 2017 11:42:41 +0100 Subject: QGestureManager: fix UB (invalid pointer comparison) Comparing pointers with op< that do not point into the same array is UB. Fix, in the usual way, by using std::less. Change-Id: Id2c957557719887b2016632d683dbab8af07b34c Reviewed-by: Thiago Macieira --- src/widgets/kernel/qgesturemanager_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h index e57652afba..3df80bab55 100644 --- a/src/widgets/kernel/qgesturemanager_p.h +++ b/src/widgets/kernel/qgesturemanager_p.h @@ -59,6 +59,8 @@ #ifndef QT_NO_GESTURES +#include + QT_BEGIN_NAMESPACE class QBasicTimer; @@ -112,7 +114,7 @@ private: ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { } inline bool operator<(const ObjectGesture &rhs) const { - if (object < rhs.object) + if (std::less{}(object, rhs.object)) return true; if (object == rhs.object) return gesture < rhs.gesture; -- cgit v1.2.3 From 51a956366f5f39799759d317e675da11a09744c5 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 13 Nov 2017 11:54:48 +0100 Subject: Doc: move notepad example to qtbase and improve it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Edited gettingstartedqt.qdoc - update .pro files - replaced snippet statements by \quotefromfile - removed second version of notepad.h and notepad.cpp that were made only for quoting snippets (\quotefromfile reads from the program code) - show current filename in header of window - added checking routine on filename in Save method Task-number: QTBUG-63984 Change-Id: I5298d761763a4dfeb705a1d9b77354be853ada88 Reviewed-by: Topi Reiniö --- examples/widgets/doc/images/notepad.png | Bin 0 -> 12418 bytes examples/widgets/doc/images/notepad1.png | Bin 0 -> 12418 bytes examples/widgets/doc/images/notepad2.png | Bin 0 -> 22700 bytes examples/widgets/doc/images/notepad3.png | Bin 0 -> 40584 bytes examples/widgets/doc/images/notepad4.png | Bin 0 -> 9494 bytes examples/widgets/doc/images/notepad_menu.png | Bin 0 -> 8657 bytes examples/widgets/tutorials/gettingstartedqt.qdoc | 559 +++++++++++++++++++++ examples/widgets/tutorials/notepad/images/copy.png | Bin 0 -> 1633 bytes .../widgets/tutorials/notepad/images/create.png | Bin 0 -> 459 bytes examples/widgets/tutorials/notepad/images/cut.png | Bin 0 -> 9554 bytes .../widgets/tutorials/notepad/images/edit_redo.png | Bin 0 -> 7463 bytes .../widgets/tutorials/notepad/images/edit_undo.png | Bin 0 -> 8424 bytes examples/widgets/tutorials/notepad/images/exit.png | Bin 0 -> 379 bytes examples/widgets/tutorials/notepad/images/font.png | Bin 0 -> 6983 bytes examples/widgets/tutorials/notepad/images/info.png | Bin 0 -> 557 bytes examples/widgets/tutorials/notepad/images/new.png | Bin 0 -> 7422 bytes examples/widgets/tutorials/notepad/images/open.png | Bin 0 -> 5437 bytes .../widgets/tutorials/notepad/images/paste.png | Bin 0 -> 3597 bytes .../widgets/tutorials/notepad/images/pencil.png | Bin 0 -> 3780 bytes .../widgets/tutorials/notepad/images/print.png | Bin 0 -> 331 bytes examples/widgets/tutorials/notepad/images/save.png | Bin 0 -> 2699 bytes .../widgets/tutorials/notepad/images/save_as.png | Bin 0 -> 8209 bytes examples/widgets/tutorials/notepad/main.cpp | 61 +++ examples/widgets/tutorials/notepad/notepad.cpp | 182 +++++++ examples/widgets/tutorials/notepad/notepad.h | 114 +++++ examples/widgets/tutorials/notepad/notepad.pro | 20 + examples/widgets/tutorials/notepad/notepad.qrc | 19 + examples/widgets/tutorials/notepad/notepad.ui | 196 ++++++++ examples/widgets/tutorials/tutorials.pro | 2 +- 29 files changed, 1152 insertions(+), 1 deletion(-) create mode 100644 examples/widgets/doc/images/notepad.png create mode 100644 examples/widgets/doc/images/notepad1.png create mode 100644 examples/widgets/doc/images/notepad2.png create mode 100644 examples/widgets/doc/images/notepad3.png create mode 100644 examples/widgets/doc/images/notepad4.png create mode 100644 examples/widgets/doc/images/notepad_menu.png create mode 100644 examples/widgets/tutorials/gettingstartedqt.qdoc create mode 100644 examples/widgets/tutorials/notepad/images/copy.png create mode 100644 examples/widgets/tutorials/notepad/images/create.png create mode 100644 examples/widgets/tutorials/notepad/images/cut.png create mode 100644 examples/widgets/tutorials/notepad/images/edit_redo.png create mode 100644 examples/widgets/tutorials/notepad/images/edit_undo.png create mode 100644 examples/widgets/tutorials/notepad/images/exit.png create mode 100644 examples/widgets/tutorials/notepad/images/font.png create mode 100644 examples/widgets/tutorials/notepad/images/info.png create mode 100644 examples/widgets/tutorials/notepad/images/new.png create mode 100644 examples/widgets/tutorials/notepad/images/open.png create mode 100644 examples/widgets/tutorials/notepad/images/paste.png create mode 100644 examples/widgets/tutorials/notepad/images/pencil.png create mode 100644 examples/widgets/tutorials/notepad/images/print.png create mode 100644 examples/widgets/tutorials/notepad/images/save.png create mode 100644 examples/widgets/tutorials/notepad/images/save_as.png create mode 100644 examples/widgets/tutorials/notepad/main.cpp create mode 100644 examples/widgets/tutorials/notepad/notepad.cpp create mode 100644 examples/widgets/tutorials/notepad/notepad.h create mode 100644 examples/widgets/tutorials/notepad/notepad.pro create mode 100644 examples/widgets/tutorials/notepad/notepad.qrc create mode 100644 examples/widgets/tutorials/notepad/notepad.ui diff --git a/examples/widgets/doc/images/notepad.png b/examples/widgets/doc/images/notepad.png new file mode 100644 index 0000000000..40d13269b9 Binary files /dev/null and b/examples/widgets/doc/images/notepad.png differ diff --git a/examples/widgets/doc/images/notepad1.png b/examples/widgets/doc/images/notepad1.png new file mode 100644 index 0000000000..40d13269b9 Binary files /dev/null and b/examples/widgets/doc/images/notepad1.png differ diff --git a/examples/widgets/doc/images/notepad2.png b/examples/widgets/doc/images/notepad2.png new file mode 100644 index 0000000000..9cec1f9a58 Binary files /dev/null and b/examples/widgets/doc/images/notepad2.png differ diff --git a/examples/widgets/doc/images/notepad3.png b/examples/widgets/doc/images/notepad3.png new file mode 100644 index 0000000000..426861ab06 Binary files /dev/null and b/examples/widgets/doc/images/notepad3.png differ diff --git a/examples/widgets/doc/images/notepad4.png b/examples/widgets/doc/images/notepad4.png new file mode 100644 index 0000000000..fc08eab204 Binary files /dev/null and b/examples/widgets/doc/images/notepad4.png differ diff --git a/examples/widgets/doc/images/notepad_menu.png b/examples/widgets/doc/images/notepad_menu.png new file mode 100644 index 0000000000..2dd771111a Binary files /dev/null and b/examples/widgets/doc/images/notepad_menu.png differ diff --git a/examples/widgets/tutorials/gettingstartedqt.qdoc b/examples/widgets/tutorials/gettingstartedqt.qdoc new file mode 100644 index 0000000000..921dd7a32d --- /dev/null +++ b/examples/widgets/tutorials/gettingstartedqt.qdoc @@ -0,0 +1,559 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tutorials/notepad + \title Getting Started Programming with Qt Widgets + \brief A tutorial for Qt Widgets based on a notepad application + + In this topic, we teach basic Qt knowledge by implementing a simple + Notepad application using C++ and the \l{Qt Widgets} module. The + application is a small text editor which allows you to create a text + file, save it, print it, + or reopen and edit it again. You can also set the font to be used. + + \image notepad1.png "Notepad application" + + You can find the final Notepad source files in the qtdoc repository + in the tutorials/notepad directory. You can either fetch + the Qt 5 sources from Qt Project or install them as part of Qt 5. + The application is also available in the example list of Qt Creator's + Welcome mode. + + \section1 Creating the Notepad Project + + Setting up a new project in Qt Creator is aided by a wizard that + guides you step-by-step through the project creation process. The + wizard prompts you to enter the settings needed for that particular + type of project and creates the project for you. + + \image notepad2.png "Qt Creator New File or Project dialog" + + To create the Notepad project, select \b File > \b{New File or + Project} > \b Applications > \b {Qt Widgets Application} > \b Choose, + and follow the instructions of the wizard. In the + \b{Class Information} + dialog, type \b Notepad as the class name and select \b QMainWindow + as the base class. + + \image notepad3.png "Class Information Dialog" + + The \b {Qt Widgets Application} wizard creates a project that contains + a main source file and a set of files that specify a user interface + (Notepad widget): + + \list + \li notepad.pro - the project file. + \li main.cpp - the main source file for the application. + \li notepad.cpp - the source file of the notepad class of the + Notepad widget. + \li notepad.h - the header file of the notepad class for the + Notepad widget. + \li notepad.ui - the UI form for the Notepad widget. + \endlist + + The .cpp, .h, and .ui files come with the necessary boiler plate code + for you to be able to build and run the project. The .pro file is + complete. + We will take a closer look at the file contents in the following + sections. + + \b{Learn More} + + \table + \header + \li About + \li Here + \row + \li Using Qt Creator + \li \l{Qt Creator Manual}{Qt Creator} + \row + \li Creating other kind of applications with Qt Creator + \li \l{Qt Creator: Tutorials}{Qt Creator Tutorials} + \endtable + + + \section1 Main Source File + + The wizard generates the following code in the main.cpp file: + + \quotefromfile tutorials/notepad/main.cpp + \skipto "notepad.h" + \printuntil EditorApp.exec() + \printuntil } + + We will go through the code line by line. The following lines include + the header files for the Notepad widget and QApplication. All Qt classes + have a header file named after them. + + \quotefromfile tutorials/notepad/main.cpp + \skipto notepad.h + \printuntil QApplication + + The following line defines the main function that is the entry point + for all C and C++ based applications: + + \printline main + + The following line creates a QApplication object. This object manages + application-wide resources and is necessary to run any Qt program + that uses Qt Widgets. It constructs an application object with \c argc + command line arguments run in \c argv. (For GUI applications that + do not use Qt Widgets, you can use QGuiApplication instead.) + + \skipuntil { + \printuntil QApplication + + The following line creates the Notepad object. This is the object for + which the wizard created the class and the UI file. The user interface + contains visual elements that are called \c widgets in Qt. Examples + of widgets are text edits, scroll bars, labels, and radio buttons. A + widget can also be a container for other widgets; a dialog or a main + application window, for example. + + \printline Notepad + + The following line shows the Notepad widget on the screen in its own + window. Widgets can also function as containers. An example of this + is QMainWindow which often contains several types of widgets. Widgets + are not visible by default; the function \l{QWidget::}{show()} makes + the widget visible. + + \printline Editor.show + + The following line makes the QApplication enter its event loop. When + a Qt application is running, events are generated and sent to the + widgets of the application. Examples of events are mouse presses + and key strokes. + + \printline EditorApp.exec + + \b{Learn More} + + \table + \header + \li About + \li Here + \row + \li Widgets and Window Geometry + \li \l{Window and Dialog Widgets} + \row + \li Events and event handling + \li \l{The Event System} + \endtable + + \section1 Designing a UI + + The wizard generates a user interface definition in XML format: notepad.ui. + When you open the notepad.ui file in Qt Creator, it automatically + opens in the integrated Qt Designer. + + When you build the application, Qt Creator launches the Qt + \l{User Interface Compiler (uic)} that reads the .ui file and creates + a corresponding C++ header file, ui_notepad.h. + + \section2 Using Qt Designer + + The wizard creates an application that uses a QMainWindow. It has + its own layout to which you can add a menu bar, dock widgets, toolbars, + and a status bar. The center area can be occupied by any kind of widget. + The wizard places the Notepad widget there. + + To add widgets in Qt Designer: + + \list 1 + \li In the Qt Creator \b Editor mode, double-click the notepad.ui + file in the \b Projects view to launch the file in the integrated + Qt Designer. + \li Drag and drop widgets Text Edit (QTextEdit) to the form. + \li Press \b {Ctrl+A} (or \b {Cmd+A}) to select the widgets and click + \b {Lay out Vertically} (or press \b {Ctrl+L}) to apply a vertical + layout (QVBoxLayout). + \li Press \b {Ctrl+S} (or \b {Cmd+S}) to save your changes. + \endlist + + The UI now looks as follows in Qt Designer: + + \image notepad4.png + + You can view the generated XML file in the code editor: + + \quotefromfile tutorials/notepad/notepad.ui + + \printuntil QMenuBar + \dots + + The following line contains the XML declaration, which specifies the + XML version and character encoding used in the document: + + \code + + \endcode + + The rest of the file specifies an \c ui element that defines a + Notepad widget: + + \code + + \endcode + + The UI file is used together with the header and source file of the + Notepad class. We will look at the rest of the UI file in the later + sections. + + \section2 Notepad Header File + + The wizard generated a header file for the Notepad class that has the + necessary #includes, a constructor, a destructor, and the Ui object. + The file looks as follows: + + \snippet tutorials/notepad/notepad.h all + + The following line includes QMainWindow that provides a main application + window: + + \snippet tutorials/notepad/notepad.h 1 + + The following lines declare the Notepad class in the Ui namespace, + which is the standard namespace for the UI classes generated from + .ui files by the \c uic tool: + + \snippet tutorials/notepad/notepad.h 2 + + The class declaration contains the \c Q_OBJECT macro. It must come + first in the class definition, and declares our class as a QObject. + Naturally, it must also inherit from QObject. A QObject adds several + abilities to a normal C++ class. Notably, the class name and slot + names can be queried at runtime. It is also possible to query a slot's + parameter types and invoke it. + + \snippet tutorials/notepad/notepad.h 3 + + The following lines declare a constructor that has a default argument + called \c parent. + The value 0 indicates that the widget has no parent (it is a top-level + widget). + + \snippet tutorials/notepad/notepad.h 4 + + The following line declares a virtual destructor to free the resources + that were acquired by the object during its life-cycle. According to + the C++ naming convention, destructors have the same name as the class + they are associated with, prefixed with a tilde (~). In QObject, + destructors are virtual to ensure that the destructors of derived + classes are invoked properly when an object is deleted through a + pointer-to-base-class. + + \snippet tutorials/notepad/notepad.h 5 + + The following lines declare a member variable which is a pointer to + the Notepad UI class. A member variable is associated with a specific + class, and accessible for all its methods. + + \snippet tutorials/notepad/notepad.h 6 + + \section2 Notepad Source File + + The source file that the wizard generated for the Notepad class looks + as follows: + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto notepad.h + \printuntil ui->textEdit->setFont(font) + \printuntil } + + The following lines include the Notepad class header file that was + generated by the wizard and the UI header file that was generated + by the \c uic tool: + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto notepad.h + \printuntil ui_notepad + + The following line defines the \c {Notepad} constructor: + + \skipto Notepad::Notepad + \printline Notepad::Notepad + + The following line calls the QMainWindow constructor, which is + the base class for the Notepad class: + + \printline QMainWindow + + The following line creates the UI class instance and assigns it to + the \c ui member: + + \printline ui(new + + The following line sets up the UI: + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto ui->setupUi + \printline ui->setupUi(this) + + In the destructor, we delete the \c ui: + + \skipto Notepad::~Notepad + \printuntil } + + In order to have the text edit field occupy the whole screen, we add + \c setCentralWidget to the main window. + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto Notepad::Notepad(QWidget *parent) + \printuntil } + + \section2 Project File + + The wizard generates the following project file, \c {notepad.pro}, for + us: + + \quotefile tutorials/notepad/notepad.pro + + The project file specifies the application name and the \c qmake + template to use for generating the project, as well as the source, + header, and UI files included in the project. + + You could also use \c qmake's \c -project option to generate the \.pro + file. Although, in that case, you have to remember to add the line + \c{QT += widgets} to the generated file in order to link against the + Qt Widgets Module. + + \b{Learn More} + + \table + \header + \li About + \li Here + \row + \li Using Qt Designer + \li \l{Qt Designer Manual} + \row + \li Layouts + \li \l{Layout Management}, + \l{Widgets and Layouts}, + \l{Layout Examples} + \row + \li The widgets that come with Qt + \li \l{Qt Widget Gallery} + \row + \li Main windows and main window classes + \li \l{Application Main Window}, + \l{Main Window Examples} + \row + \li QObjects and the Qt Object model (This is essential to + understand Qt) + \li \l{Object Model} + \row + \li qmake and the Qt build system + \li \l{qmake Manual} + \endtable + + \section1 Adding User Interaction + + + To add functionality to the editor, we start by adding menu items + and buttons on a toolbar. + + Click on "Type Here", and add the options New, Open, Save, Save as, + Print and Exit. This creates 5 lines in the Action Editor below. + To connect the actions to slots, right-click an action and select + Go to slot > triggered(), and complete the code for that given slot. + + If we also want to add the actions to a toolbar, we can assign an + icon to each QAction, and then drag the QAction to the toolbar. You + assign an icon by entering an icon name in the Icon property of the + action concerned. When the QAction has been dragged to the toolbar, + clicking the icon will launch the associated slot. + + Complete the method \c on_actionNew_triggered(): + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto on_actionNew_triggered() + \printuntil } + + \c current_file is a global variable containing the file presently + being edited. + It is defined in the private part of notepad.h: + + \quotefromfile tutorials/notepad/notepad.h + \skipto private: + \printuntil currentFile; + + \c clear() clears the text buffer. + + \section2 Opening a file + + In \c notepad.ui, right click on \c actionOpen and select \c {Go to + slot} + + Complete method \c on_actionOpen_triggered(). + + \quotefromfile tutorials/notepad/notepad.cpp + \skipto on_actionOpen_triggered() + \printuntil file.close + \printuntil } + + + \c QFileDialog::getOpenFileName opens a dialog enabling you to select + a file. QFile object \c myfile has the selected \c file_name as + parameter. We store the selected file also into the global variable + \c current_file for later purposes. We open the file with \c file.open + as a readonly text file. If it cannot be opened, a warning is issued, + and the program stops. + + We define a QTextStream \c instream for parameter \c myfile. + The contents of file \c myfile is copied into QString \a text. + \c setText(text) fille the buffer of our editor with \c text. + + \c section2 Saving a file + + We create the method for saving a file in the same way as for + \l {Opening a file}, by right clicking on \c actionSave, and + selecting \c {Go to Slot}. + + \skipto Notepad::on_actionSave_triggered + \printuntil file.close + \printuntil } + + QFile object \c myfile is linked to global variable \c current_file, + the variable that contains the file we were working with. + If we cannot open \c myfile, an error message is issued and the + method stops. We create a QTextStream \c outstream. The contents + of the editor buffer is converted to plain text, and then written + to \c outstream. + + \section2 Saving a file with \c {Save as} + + \skipto Notepad::on_actionSave_as_triggered + \printuntil file.close + \printuntil } + + This is the same procedure as for \c {Saving a file}, the only + difference being that here you need to enter a new file name for + the file to be created. + + + \section2 Print a File + + If you want to use print functionalities, you need to add + \c printsupport to the project file: + + \badcode + QT += printsupport + \endcode + + We declare a QPrinter object called \c printer. + We launch a printer dialog box and store the selected printer in + object \c printer. If we clicked on \c Cancel and did not select + a printer, the methods returns. The actual printer command is given + with \a ui->textEdit->print with our QPrinter object as parameter. + + \section2 Select a Font + + \skipto Notepad::on_actionFont_triggered + \printuntil ui->textEdit->setFont + \printline } + + We declare a boolean indicating if we did select a font with + QFontDialog. If so, we set the font with \c ui->textEdit->setFont(myfont). + + \section2 Copy, Cut, Paste, Undo, and Redo + + If you select some text, and want to copy it to the clipboard, + you call the appropriate method of ui->textEdit. The same counts + for cut, paste, undo, and redo. + + This table shows the method name to use. + + \table + \header + \li Task + \li Method called + \row + \li Copy + \li ui->textEdit->copy() + \row + \li Cut + \li ui->textEdit->cut() + \row + \li Paste + \li ui->textEdit->paste() + \row + \li Undo + \li ui->textEdit->undo() + \row + \li Redo + \li ui->textEdit->redo() + \endtable + + \b{Learn More} + + \table + \header + \li About + \li Here + \row + \li MDI applications + \li QMdiArea, + \l{MDI Example} + \row + \li Files and I/O devices + \li QFile, QIODevice + \row + \li tr() and internationalization + \li \l{Qt Linguist Manual}, + \l{Writing Source Code for Translation}, + \l{Internationalization with Qt} + \endtable + + \section1 Building and Running Notepad + + Now that you have all the necessary files, select \b Build > + \b {Build Project Notepad} to build and run the application. Qt + Creator uses \c qmake and \c make to create an executable in the + directory specified in the build settings of the project and runs + it. + + \section2 Building and Running from the Command Line + + To build the application from the command line, switch to the + directory in which you have the \c .cpp file of the application + and add the project file (suffixed .pro) described earlier. The + following shell commands then build the application: + + \badcode + qmake + make (or nmake on Windows) + \endcode + + The commands create an executable in the project directory. The + \c qmake tool reads the project file and produces a \c Makefile + with instructions on how to build the application. + The \c make tool (or the \c nmake tool) then reads the \c Makefile + and produces the executable binary. +*/ diff --git a/examples/widgets/tutorials/notepad/images/copy.png b/examples/widgets/tutorials/notepad/images/copy.png new file mode 100644 index 0000000000..cb3442c04c Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/copy.png differ diff --git a/examples/widgets/tutorials/notepad/images/create.png b/examples/widgets/tutorials/notepad/images/create.png new file mode 100644 index 0000000000..fdfd4b438a Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/create.png differ diff --git a/examples/widgets/tutorials/notepad/images/cut.png b/examples/widgets/tutorials/notepad/images/cut.png new file mode 100644 index 0000000000..74b15301ff Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/cut.png differ diff --git a/examples/widgets/tutorials/notepad/images/edit_redo.png b/examples/widgets/tutorials/notepad/images/edit_redo.png new file mode 100644 index 0000000000..8a7725463c Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/edit_redo.png differ diff --git a/examples/widgets/tutorials/notepad/images/edit_undo.png b/examples/widgets/tutorials/notepad/images/edit_undo.png new file mode 100644 index 0000000000..852f5e3b29 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/edit_undo.png differ diff --git a/examples/widgets/tutorials/notepad/images/exit.png b/examples/widgets/tutorials/notepad/images/exit.png new file mode 100644 index 0000000000..677d4deef2 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/exit.png differ diff --git a/examples/widgets/tutorials/notepad/images/font.png b/examples/widgets/tutorials/notepad/images/font.png new file mode 100644 index 0000000000..925e501c03 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/font.png differ diff --git a/examples/widgets/tutorials/notepad/images/info.png b/examples/widgets/tutorials/notepad/images/info.png new file mode 100644 index 0000000000..9731212c4f Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/info.png differ diff --git a/examples/widgets/tutorials/notepad/images/new.png b/examples/widgets/tutorials/notepad/images/new.png new file mode 100644 index 0000000000..b24edc5d0c Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/new.png differ diff --git a/examples/widgets/tutorials/notepad/images/open.png b/examples/widgets/tutorials/notepad/images/open.png new file mode 100644 index 0000000000..7b052edf5a Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/open.png differ diff --git a/examples/widgets/tutorials/notepad/images/paste.png b/examples/widgets/tutorials/notepad/images/paste.png new file mode 100644 index 0000000000..c50dbd95b2 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/paste.png differ diff --git a/examples/widgets/tutorials/notepad/images/pencil.png b/examples/widgets/tutorials/notepad/images/pencil.png new file mode 100644 index 0000000000..a9c5e5482a Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/pencil.png differ diff --git a/examples/widgets/tutorials/notepad/images/print.png b/examples/widgets/tutorials/notepad/images/print.png new file mode 100644 index 0000000000..0cd3f28bd8 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/print.png differ diff --git a/examples/widgets/tutorials/notepad/images/save.png b/examples/widgets/tutorials/notepad/images/save.png new file mode 100644 index 0000000000..e65a29d5f1 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/save.png differ diff --git a/examples/widgets/tutorials/notepad/images/save_as.png b/examples/widgets/tutorials/notepad/images/save_as.png new file mode 100644 index 0000000000..6040574322 Binary files /dev/null and b/examples/widgets/tutorials/notepad/images/save_as.png differ diff --git a/examples/widgets/tutorials/notepad/main.cpp b/examples/widgets/tutorials/notepad/main.cpp new file mode 100644 index 0000000000..20bcdaa7df --- /dev/null +++ b/examples/widgets/tutorials/notepad/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "notepad.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication EditorApp(argc, argv); + Notepad Editor; + Editor.show(); + + return EditorApp.exec(); +} diff --git a/examples/widgets/tutorials/notepad/notepad.cpp b/examples/widgets/tutorials/notepad/notepad.cpp new file mode 100644 index 0000000000..b4f6cf7f8f --- /dev/null +++ b/examples/widgets/tutorials/notepad/notepad.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "notepad.h" +#include "ui_notepad.h" + +Notepad::Notepad(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::Notepad) +{ + ui->setupUi(this); + this->setCentralWidget(ui->textEdit); +} + +Notepad::~Notepad() +{ + delete ui; +} + +void Notepad::on_actionNew_triggered() +{ + currentFile.clear(); + ui->textEdit->setText(QString()); +} + +void Notepad::on_actionOpen_triggered() +{ + QString fileName = QFileDialog::getOpenFileName(this, "Open the file"); + QFile file(fileName); + currentFile = fileName; + if (!file.open(QIODevice::ReadOnly | QFile::Text)) { + QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString()); + return; + } + setWindowTitle(fileName); + QTextStream in(&file); + QString text = in.readAll(); + ui->textEdit->setText(text); + file.close(); +} + +void Notepad::on_actionSave_triggered() +{ + QString fileName; + // If we don't have a filename from before, get one. + if (currentFile.isEmpty()) { + fileName = QFileDialog::getSaveFileName(this, "Save"); + currentFile = fileName; + } else { + fileName = currentFile; + } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QFile::Text)) { + QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); + return; + } + setWindowTitle(fileName); + QTextStream out(&file); + QString text = ui->textEdit->toPlainText(); + out << text; + file.close(); +} + +void Notepad::on_actionSave_as_triggered() +{ + QString fileName = QFileDialog::getSaveFileName(this, "Save as"); + QFile file(fileName); + + if (!file.open(QFile::WriteOnly | QFile::Text)) { + QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); + return; + } + currentFile = fileName; + setWindowTitle(fileName); + QTextStream out(&file); + QString text = ui->textEdit->toPlainText(); + out << text; + file.close(); +} + +void Notepad::on_actionPrint_triggered() +{ + QPrinter printDev; + QPrintDialog dialog(&printDev, this); + if (dialog.exec() == QDialog::Rejected) + return; + ui->textEdit->print(&printDev); +} + +void Notepad::on_actionExit_triggered() +{ + QCoreApplication::quit(); +} + +void Notepad::on_actionCopy_triggered() +{ + ui->textEdit->copy(); +} + +void Notepad::on_actionCut_triggered() +{ + ui->textEdit->cut(); +} + +void Notepad::on_actionPaste_triggered() +{ + ui->textEdit->paste(); +} + +void Notepad::on_actionUndo_triggered() +{ + ui->textEdit->undo(); +} + +void Notepad::on_actionRedo_triggered() +{ + ui->textEdit->redo(); +} + +void Notepad::on_actionFont_triggered() +{ + bool fontSelected; + QFont font = QFontDialog::getFont(&fontSelected, this); + if (fontSelected) + ui->textEdit->setFont(font); +} diff --git a/examples/widgets/tutorials/notepad/notepad.h b/examples/widgets/tutorials/notepad/notepad.h new file mode 100644 index 0000000000..f688df45ac --- /dev/null +++ b/examples/widgets/tutorials/notepad/notepad.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NOTEPAD_H +#define NOTEPAD_H + +//! [all] +//! [1] +#include +//! [1] + +//! [2] +QT_BEGIN_NAMESPACE +namespace Ui { +class Notepad; +} +QT_END_NAMESPACE +//! [2] + +//! [3] +class Notepad : public QMainWindow +{ + Q_OBJECT +//! [3] + +//! [4] +public: + explicit Notepad(QWidget *parent = 0); +//! [4] +//! [5] + ~Notepad(); +//! [5] + +private slots: + void on_actionNew_triggered(); + + void on_actionOpen_triggered(); + + void on_actionSave_triggered(); + + void on_actionSave_as_triggered(); + + void on_actionPrint_triggered(); + + void on_actionExit_triggered(); + + void on_actionCopy_triggered(); + + void on_actionCut_triggered(); + + void on_actionPaste_triggered(); + + void on_actionUndo_triggered(); + + void on_actionRedo_triggered(); + + void on_actionFont_triggered(); + +//! [6] +private: + Ui::Notepad *ui; + QString currentFile; +//! [6] +}; +//! [all] + +#endif // NOTEPAD_H diff --git a/examples/widgets/tutorials/notepad/notepad.pro b/examples/widgets/tutorials/notepad/notepad.pro new file mode 100644 index 0000000000..7369dbc991 --- /dev/null +++ b/examples/widgets/tutorials/notepad/notepad.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = notepad + +QT += printsupport + +SOURCES += \ + main.cpp\ + notepad.cpp + +HEADERS += notepad.h + +FORMS += notepad.ui + +RESOURCES += \ + notepad.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/notepad +INSTALLS += target + diff --git a/examples/widgets/tutorials/notepad/notepad.qrc b/examples/widgets/tutorials/notepad/notepad.qrc new file mode 100644 index 0000000000..ec11679f13 --- /dev/null +++ b/examples/widgets/tutorials/notepad/notepad.qrc @@ -0,0 +1,19 @@ + + + images/copy.png + images/create.png + images/cut.png + images/edit_redo.png + images/edit_undo.png + images/exit.png + images/font.png + images/info.png + images/new.png + images/open.png + images/paste.png + images/pencil.png + images/print.png + images/save.png + images/save_as.png + + diff --git a/examples/widgets/tutorials/notepad/notepad.ui b/examples/widgets/tutorials/notepad/notepad.ui new file mode 100644 index 0000000000..d197a95fe7 --- /dev/null +++ b/examples/widgets/tutorials/notepad/notepad.ui @@ -0,0 +1,196 @@ + + + Notepad + + + + 0 + 0 + 524 + 300 + + + + Notepad + + + + + + + + + + + + 0 + 0 + 524 + 25 + + + + + File + + + + + + + + + + + + Edit + + + + + + + + + + + + + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + + + + + + :/images/new.png:/images/new.png + + + New + + + + + + :/images/open.png:/images/open.png + + + Open + + + + + + :/images/save.png:/images/save.png + + + Save + + + + + + :/images/save_as.png:/images/save_as.png + + + Save as + + + + + + :/images/print.png:/images/print.png + + + Print + + + + + + :/images/exit.png:/images/exit.png + + + Exit + + + + + + :/images/copy.png:/images/copy.png + + + Copy + + + + + + :/images/cut.png:/images/cut.png + + + Cut + + + + + + :/images/paste.png:/images/paste.png + + + Paste + + + + + + :/images/edit_undo.png:/images/edit_undo.png + + + Undo + + + + + + :/images/edit_redo.png:/images/edit_redo.png + + + Redo + + + + + + :/images/font.png:/images/font.png + + + Font + + + + + + + + + diff --git a/examples/widgets/tutorials/tutorials.pro b/examples/widgets/tutorials/tutorials.pro index 2eb87cdbd5..0aaa119d8f 100644 --- a/examples/widgets/tutorials/tutorials.pro +++ b/examples/widgets/tutorials/tutorials.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS += addressbook widgets modelview gettingStarted +SUBDIRS += addressbook widgets modelview gettingStarted notepad -- cgit v1.2.3 From 7f5a314011de475a5954325a089481fbd5e5fc81 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 12 Dec 2017 15:07:36 +0100 Subject: Doc: complete Easing Curve Example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - updated logo - updated screenshot - add link to easing.qdoc Task-number: QTBUG-60635 Change-Id: I9389dfbbe66cfa5f4e8641bee2f8fd63f5c95f99 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Venugopal Shivashankar Reviewed-by: Topi Reiniö --- doc/src/images/easing-example.png | Bin 23843 -> 12267 bytes .../widgets/animation/easing/images/qt-logo.png | Bin 1495 -> 1165 bytes examples/widgets/doc/src/easing.qdoc | 3 +++ 3 files changed, 3 insertions(+) diff --git a/doc/src/images/easing-example.png b/doc/src/images/easing-example.png index de486670ce..eefae8a6d0 100644 Binary files a/doc/src/images/easing-example.png and b/doc/src/images/easing-example.png differ diff --git a/examples/widgets/animation/easing/images/qt-logo.png b/examples/widgets/animation/easing/images/qt-logo.png index 6b72d5fb72..d10bd0bdf9 100644 Binary files a/examples/widgets/animation/easing/images/qt-logo.png and b/examples/widgets/animation/easing/images/qt-logo.png differ diff --git a/examples/widgets/doc/src/easing.qdoc b/examples/widgets/doc/src/easing.qdoc index 3a9727d393..807dd72e93 100644 --- a/examples/widgets/doc/src/easing.qdoc +++ b/examples/widgets/doc/src/easing.qdoc @@ -34,4 +34,7 @@ \image easing-example.png + See \l QEasingCurve for a detailed description on how to use the class's + functionalities. + */ -- cgit v1.2.3 From e557a3c1d3bc0f77ea669e670029569fd0228598 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 14 Dec 2017 16:23:22 +0100 Subject: Export sanitizer as a global config This is necessary for WebEngine at configure time, to be able to query which of the sanitizers was enabled in order to report unsupported combinations. Task-number: QTBUG-64726 Change-Id: I72f8efe4bed3e14114f885bdae16650f1f23b24b Reviewed-by: Oswald Buddenhagen --- configure.json | 2 +- configure.pri | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/configure.json b/configure.json index c73369e6f6..a6f3ed66a9 100644 --- a/configure.json +++ b/configure.json @@ -867,7 +867,7 @@ "sanitizer": { "label": "Sanitizers", "condition": "features.sanitize_address || features.sanitize_thread || features.sanitize_memory || features.sanitize_undefined", - "output": [ "publicConfig" ] + "output": [ "sanitizer", "publicConfig" ] }, "GNUmake": { "label": "GNU make", diff --git a/configure.pri b/configure.pri index 83c0dee141..021cc1bd1e 100644 --- a/configure.pri +++ b/configure.pri @@ -876,6 +876,19 @@ defineTest(qtConfOutput_shared) { export(CONFIG) } +defineTest(qtConfOutput_sanitizer) { + !$${2}: return() + + # Export this here, so that WebEngine can access it at configure time. + CONFIG += sanitizer + $$qtConfEvaluate("features.sanitize_address"): CONFIG += sanitize_address + $$qtConfEvaluate("features.sanitize_thread"): CONFIG += sanitize_thread + $$qtConfEvaluate("features.sanitize_memory"): CONFIG += sanitize_memory + $$qtConfEvaluate("features.sanitize_undefined"): CONFIG += sanitize_undefined + + export(CONFIG) +} + defineTest(qtConfOutput_architecture) { arch = $$qtConfEvaluate("tests.architecture.arch") buildabi = $$qtConfEvaluate("tests.architecture.buildabi") -- cgit v1.2.3 From bcef582b6f0f851b0d3985decc92eefb820ddf46 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 8 Nov 2017 11:30:01 +1000 Subject: Fix scan reply dbus signature in connman bearer backend Task-number: QTBUG-57844 Change-Id: I1f3035f32d213ec6da95650a946c17c64becf549 Reviewed-by: Sami Nurmenniemi Reviewed-by: Lorn Potter --- src/plugins/bearer/connman/qconnmanservice_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 55eec57270..7c9db4640b 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -506,7 +506,7 @@ void QConnmanTechnologyInterface::scan() void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call) { - QDBusPendingReply props_reply = *call; + QDBusPendingReply<> props_reply = *call; if (props_reply.isError()) { qDebug() << props_reply.error().message(); } -- cgit v1.2.3 From 23c55cd37ce1de489cf7c405a9d21781cbcb1ade Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 14 Dec 2017 05:55:29 +1000 Subject: bearermanagment: fix build for --no-feature-bearermanagement Change-Id: I9e3f44b924e09a8d1a5095dc55d585b3cab33c15 Reviewed-by: Thiago Macieira --- src/network/bearer/qbearerengine.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp index 215cd3fddd..9be49da8a2 100644 --- a/src/network/bearer/qbearerengine.cpp +++ b/src/network/bearer/qbearerengine.cpp @@ -95,6 +95,5 @@ bool QBearerEngine::configurationsInUse() const #include "moc_qbearerengine_p.cpp" -#endif // QT_NO_BEARERMANAGEMENT - QT_END_NAMESPACE +#endif // QT_NO_BEARERMANAGEMENT -- cgit v1.2.3 From d04187b6a17c16cc455a330fd3e3350016dcc889 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 12 Dec 2017 09:23:04 +0100 Subject: Windows QPA: Check validity of device when handling tablet leave Huion GT-191 has been observed to send spurious leave events. Amends 127483b5e30de6c1905ea3280dd45a0b7d6a3813. Task-number: QTBUG-65120 Change-Id: I5dfa003a71be137a7b40cc9c27d7cf2cada6922d Reviewed-by: Shawn Rutledge Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowstabletsupport.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index fba4e8f386..5fdc664603 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -355,6 +355,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L if (!LOWORD(lParam)) { qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice; + if (m_currentDevice < 0 || m_currentDevice >= m_devices.size()) // QTBUG-65120, spurious leave observed + return false; if (totalPacks > 0) { QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime, m_devices.at(m_currentDevice).currentDevice, -- cgit v1.2.3 From 3af9d774316ef0edf65acb478871d89231b930f2 Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Fri, 15 Dec 2017 12:56:47 +0200 Subject: Fix pps and imf support for QNX builds Change from config to feature in the json and pro files. Change-Id: I58ddac3c4ad739253bae010f1d5023fc1d481047 Reviewed-by: Oswald Buddenhagen --- src/corelib/configure.json | 2 +- src/corelib/kernel/kernel.pri | 2 +- src/gui/configure.json | 2 +- src/plugins/platforms/qnx/qnx.pro | 20 +++++++++--------- src/plugins/platforms/qnx/qqnxintegration.cpp | 29 +++++++++++++-------------- src/plugins/platforms/qnx/qqnxintegration.h | 8 ++++---- 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 3db9942123..6002e1d4fc 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -509,7 +509,7 @@ "label": "PPS", "emitIf": "config.qnx", "condition": "libs.pps", - "output": [ "privateConfig" ] + "output": [ "privateFeature" ] }, "qeventtransition": { "label": "QEventTransition class", diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 29bd5bbc6c..9bc6e198f8 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -187,7 +187,7 @@ vxworks { kernel/qfunctions_vxworks.h } -qqnx_pps { +qnx:qtConfig(qqnx_pps) { QMAKE_USE_PRIVATE += pps SOURCES += \ kernel/qppsattribute.cpp \ diff --git a/src/gui/configure.json b/src/gui/configure.json index 23ed9487a8..1252dc507c 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -956,7 +956,7 @@ "label": "IMF", "emitIf": "config.qnx", "condition": "libs.imf", - "output": [ "privateConfig" ] + "output": [ "privateFeature" ] }, "integrityfb": { "label": "INTEGRITY framebuffer", diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 34be6d582e..15d33200e5 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -81,26 +81,26 @@ qtConfig(opengles2) { QMAKE_USE += opengl_es2 egl } -CONFIG(qqnx_pps) { - DEFINES += QQNX_PPS - - SOURCES += qqnxclipboard.cpp \ - qqnxbuttoneventnotifier.cpp \ +qtConfig(qqnx_pps) { + SOURCES += qqnxbuttoneventnotifier.cpp \ qqnxnavigatorpps.cpp \ qqnxnavigatoreventnotifier.cpp \ qqnxvirtualkeyboardpps.cpp - HEADERS += qqnxclipboard.h \ - qqnxbuttoneventnotifier.h \ + HEADERS += qqnxbuttoneventnotifier.h \ qqnxnavigatorpps.h \ qqnxnavigatoreventnotifier.h \ qqnxvirtualkeyboardpps.h QMAKE_USE += pps - !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard - CONFIG(qqnx_imf) { - DEFINES += QQNX_IMF + qtConfig(clipboard) { + SOURCES += qqnxclipboard.cpp + HEADERS += qqnxclipboard.h + LIBS += -lclipboard + } + + qtConfig(qqnx_imf) { HEADERS += qqnxinputcontext_imf.h SOURCES += qqnxinputcontext_imf.cpp } else { diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index eee0581709..072510e052 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -56,17 +56,16 @@ #include "qqnxeglwindow.h" #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) #include "qqnxnavigatorpps.h" #include "qqnxnavigatoreventnotifier.h" #include "qqnxvirtualkeyboardpps.h" #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) # include "qqnxbuttoneventnotifier.h" # include "qqnxclipboard.h" - -# if defined(QQNX_IMF) +# if QT_CONFIG(qqnx_imf) # include "qqnxinputcontext_imf.h" # else # include "qqnxinputcontext_noimf.h" @@ -126,7 +125,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) , m_screenEventThread(0) , m_navigatorEventHandler(new QQnxNavigatorEventHandler()) , m_virtualKeyboard(0) -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) , m_navigatorEventNotifier(0) , m_inputContext(0) , m_buttonsNotifier(new QQnxButtonEventNotifier()) @@ -150,7 +149,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT), "Failed to create screen context"); -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) // Create/start navigator event notifier m_navigatorEventNotifier = new QQnxNavigatorEventNotifier(m_navigatorEventHandler); @@ -168,7 +167,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler); m_screenEventThread->start(); -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) // Create/start the keyboard class. m_virtualKeyboard = new QQnxVirtualKeyboardPps(); @@ -177,7 +176,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) m_navigator = new QQnxNavigatorPps(); #endif @@ -192,16 +191,16 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)), primaryDisplay(), SLOT(keyboardHeightChanged(int))); -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) // Set up the input context m_inputContext = new QQnxInputContext(this, *m_virtualKeyboard); -#if defined(QQNX_IMF) +#if QT_CONFIG(qqnx_imf) m_screenEventHandler->addScreenEventFilter(m_inputContext); #endif #endif } -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) // delay invocation of start() to the time the event loop is up and running // needed to have the QThread internals of the main thread properly initialized QMetaObject::invokeMethod(m_buttonsNotifier, "start", Qt::QueuedConnection); @@ -224,7 +223,7 @@ QQnxIntegration::~QQnxIntegration() #endif // Stop/destroy navigator event notifier -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) delete m_navigatorEventNotifier; #endif delete m_navigatorEventHandler; @@ -248,7 +247,7 @@ QQnxIntegration::~QQnxIntegration() QQnxGLContext::shutdownContext(); #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) // Destroy the hardware button notifier delete m_buttonsNotifier; @@ -318,7 +317,7 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont } #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) QPlatformInputContext *QQnxIntegration::inputContext() const { qIntegrationDebug(); @@ -361,7 +360,7 @@ QPlatformClipboard *QQnxIntegration::clipboard() const { qIntegrationDebug(); -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) if (!m_clipboard) m_clipboard = new QQnxClipboard; #endif diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index b2008baa0c..d1ebb1d4bf 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -41,7 +41,7 @@ #define QQNXINTEGRATION_H #include - +#include #include #include @@ -61,7 +61,7 @@ class QQnxServices; class QSimpleDrag; -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) class QQnxInputContext; class QQnxNavigatorEventNotifier; class QQnxButtonEventNotifier; @@ -96,7 +96,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) QPlatformInputContext *inputContext() const override; #endif @@ -143,7 +143,7 @@ private: QQnxScreenEventThread *m_screenEventThread; QQnxNavigatorEventHandler *m_navigatorEventHandler; QQnxAbstractVirtualKeyboard *m_virtualKeyboard; -#if defined(QQNX_PPS) +#if QT_CONFIG(qqnx_pps) QQnxNavigatorEventNotifier *m_navigatorEventNotifier; QQnxInputContext *m_inputContext; QQnxButtonEventNotifier *m_buttonsNotifier; -- cgit v1.2.3 From ca181d3740c4251ef945625cbb6e235479b56bcd Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 4 Dec 2017 12:11:04 +0100 Subject: Doc: complete Draggable Text example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60635 Change-Id: Ib901c677ad78a663c3f3e0dd689b8d65be10be83 Reviewed-by: Topi Reiniö --- doc/src/images/draggabletext-example.png | Bin 10616 -> 9329 bytes examples/widgets/doc/src/draggabletext.qdoc | 1 + 2 files changed, 1 insertion(+) diff --git a/doc/src/images/draggabletext-example.png b/doc/src/images/draggabletext-example.png index f9b22816e6..8fe5ae4b10 100644 Binary files a/doc/src/images/draggabletext-example.png and b/doc/src/images/draggabletext-example.png differ diff --git a/examples/widgets/doc/src/draggabletext.qdoc b/examples/widgets/doc/src/draggabletext.qdoc index c4a694028b..97b2f036bd 100644 --- a/examples/widgets/doc/src/draggabletext.qdoc +++ b/examples/widgets/doc/src/draggabletext.qdoc @@ -28,6 +28,7 @@ /*! \example draganddrop/draggabletext \title Draggable Text Example + \brief Illustrates how to drag and drop text between widgets \brief The Draggable Text example shows how to drag and drop textual data between widgets in the same application, and between different applications. -- cgit v1.2.3 From 77347a3699f8f236e1d440fb514ff8225ed5971b Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Tue, 19 Dec 2017 11:20:07 +0200 Subject: unify windows mkspecs: delete redundants mingw-w64 toolchain: - remove 'QMAKE_CXXFLAGS_THREAD' variable definition, since 'QMAKE_CFLAGS_THREAD' variable not set for mingw-w64 toolchain. ICC on Windows toolchain: - remove 'QMAKE_LFLAGS', 'QMAKE_LFLAGS_RELEASE', 'QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO' and 'QMAKE_LFLAGS_DEBUG' definitions, since they're properly set in 'msvc-desktop.conf', - remove 'DSP_EXTENSION' variable, which doesn't occur anywhere else within QtBase; its most recent search results relate to Visual Studio 6.0 and Intel Fortran. Change-Id: I2ce5c2c9e9ca2c09c1acfcf8c60381d318e8e380 Reviewed-by: Oswald Buddenhagen --- mkspecs/win32-g++/qmake.conf | 1 - mkspecs/win32-icc/qmake.conf | 6 ------ 2 files changed, 7 deletions(-) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index cf43797b95..39ecf00544 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -30,7 +30,6 @@ QMAKE_CFLAGS_WARN_ON += -Wextra QMAKE_CFLAGS_SSE2 += -mstackrealign QMAKE_CXX = $${CROSS_COMPILE}g++ -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_CXXFLAGS_RTTI_ON = -frtti QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index a25c979d9a..9506097e7f 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -48,16 +48,10 @@ QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG QMAKE_LINK = xilink -QMAKE_LFLAGS = /NOLOGO -QMAKE_LFLAGS_RELEASE = -QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = -QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_LIB = xilib /NOLOGO -DSP_EXTENSION = .dsp - include(../common/angle.conf) load(qt_config) -- cgit v1.2.3 From 17d231039b53c03e67d025f1f72bbd529e98fcbd Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Wed, 13 Dec 2017 21:29:21 +0000 Subject: Don't crash with null receiver/context in new-style connects old style connects have protection against null sender and null receiver, but new style only had against null sender. Change-Id: Ie555ac078412918e60c3b60830fe1f3abfb7f5af Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 2 +- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 3f50716cd7..086b8a51ba 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4796,7 +4796,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type, const int *types, const QMetaObject *senderMetaObject) { - if (!sender || !slotObj || !senderMetaObject) { + if (!sender || !receiver || !slotObj || !senderMetaObject) { qWarning("QObject::connect: invalid null parameter"); if (slotObj) slotObj->destroyIfLastRef(); diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 642d48d721..f1e58921c0 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -150,6 +150,7 @@ private slots: void deleteLaterInAboutToBlockHandler(); void mutableFunctor(); void checkArgumentsForNarrowing(); + void nullReceiver(); }; struct QObjectCreatedOnShutdown @@ -7380,6 +7381,16 @@ void tst_QObject::checkArgumentsForNarrowing() #undef FITS } +void tst_QObject::nullReceiver() +{ + QObject o; + QObject *nullObj = nullptr; // Passing nullptr directly doesn't compile with gcc 4.8 + QVERIFY(!connect(&o, &QObject::destroyed, nullObj, &QObject::deleteLater)); + QVERIFY(!connect(&o, &QObject::destroyed, nullObj, [] {})); + QVERIFY(!connect(&o, &QObject::destroyed, nullObj, Functor_noexcept())); + QVERIFY(!connect(&o, SIGNAL(destroyed()), nullObj, SLOT(deleteLater()))); +} + // Test for QtPrivate::HasQ_OBJECT_Macro Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro::Value); Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro::Value); -- cgit v1.2.3 From d6473eb1865cca088ebc97bafdca17dac75c5a2e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 24 Nov 2017 15:52:09 +0100 Subject: Fix drawing color fonts with shear and perspective transforms Fixes the fallback painting used with complex transforms to be able to handle color bitmap fonts which can't be converted to a path. Change-Id: Id2851607f673b8fc1aea63f92043d0cdebc0fb9d Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpaintengine.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index f42fd4ff87..1aee7d5f74 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -751,11 +751,29 @@ void QPaintEngine::drawPath(const QPainterPath &) void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) { const QTextItemInt &ti = static_cast(textItem); + if (ti.glyphs.numGlyphs == 0) + return; + + if (ti.fontEngine->glyphFormat == QFontEngine::Format_ARGB) { + QVarLengthArray positions; + QVarLengthArray glyphs; + QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - ti.fontEngine->ascent().toReal()); + ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + painter()->save(); + painter()->setRenderHint(QPainter::SmoothPixmapTransform, + bool((painter()->renderHints() & QPainter::TextAntialiasing) + && !(painter()->font().styleStrategy() & QFont::NoAntialias))); + for (int i = 0; i < ti.glyphs.numGlyphs; ++i) { + QImage glyph = ti.fontEngine->bitmapForGlyph(glyphs[i], QFixed(), QTransform()); + painter()->drawImage(positions[i].x.toReal(), positions[i].y.toReal(), glyph); + } + painter()->restore(); + return; + } QPainterPath path; path.setFillRule(Qt::WindingFill); - if (ti.glyphs.numGlyphs) - ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags); + ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags); if (!path.isEmpty()) { painter()->save(); painter()->setRenderHint(QPainter::Antialiasing, -- cgit v1.2.3 From ad2df19c2a65fc993d1071d2ed63e1882b0255a0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Dec 2017 12:05:48 +0100 Subject: Bump version Change-Id: I89c3b608d3a68c2617d0545120abf681d69f1f3d --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 5153f8139f..ed61e3732a 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.10.0 +MODULE_VERSION = 5.10.1 -- cgit v1.2.3 From 33a72ee6f3ed85c3d5f694c2a3ab90b1f50786ea Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 19 Dec 2017 14:30:59 +0100 Subject: winrt: Register ssl socket upgrade callback in Xaml thread Task-number: QTBUG-65354 Change-Id: If628c73b05854c13086708c193995062c8b9f9e4 Reviewed-by: Miguel Costa Reviewed-by: Maurice Kalinowski --- src/network/ssl/qsslsocket_winrt.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index ca65f8a015..762b393738 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -443,8 +444,11 @@ void QSslSocketBackendPrivate::continueHandshake() return; } - hr = op->put_Completed(Callback( - this, &QSslSocketBackendPrivate::onSslUpgrade).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([this, op]() { + HRESULT hr = op->put_Completed(Callback( + this, &QSslSocketBackendPrivate::onSslUpgrade).Get()); + return hr; + }); Q_ASSERT_SUCCEEDED(hr); } -- cgit v1.2.3 From eef2d1af332d4d393734687dcdc80931f3a6dabc Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Wed, 20 Dec 2017 00:48:59 +0200 Subject: unify windows mkspecs: reorder variables and flags Common changes to mingw-w64, ICC on Windows, and MSVC toolchains: - set similar order of variables and its splitting into sections, - set similar order of flags in variables and the way they are set. mingw-w64 toolchain: - move 'gcc-base.conf' include before setting Windows specific flags, similar to include 'msvc-desktop.conf' in ICC on Windows toolchain; this leads to consistency with other toolchains and allows to safely override common GCC variables with Windows specific ones, when needed, - move 'QMAKE_EXT_OBJ' and 'QMAKE_EXT_RES' variables to the linker flags section, according to its purpose. MSVC toolchain: - set flags order in 'CONFIG' variable, similar to mingw-w64 toolchain. Change-Id: I417cc8f7959c669dd504f2c5c11eb879a7989bd4 Reviewed-by: Oswald Buddenhagen --- mkspecs/common/msvc-desktop.conf | 5 ++--- mkspecs/win32-g++/qmake.conf | 11 ++++++----- mkspecs/win32-icc/qmake.conf | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index 5a26add083..496ca1179d 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -15,7 +15,7 @@ MAKEFILE_GENERATOR = MSVC.NET QMAKE_PLATFORM = win32 QMAKE_COMPILER = msvc -CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe +CONFIG += incremental flat debug_and_release debug_and_release_target precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe DEFINES += UNICODE _UNICODE WIN32 QMAKE_COMPILER_DEFINES += _WIN32 contains(QMAKE_TARGET.arch, x86_64) { @@ -35,7 +35,7 @@ QMAKE_CFLAGS = -nologo -Zc:wchar_t QMAKE_CFLAGS_WARN_ON = -W3 QMAKE_CFLAGS_WARN_OFF = -W0 QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE -MD -QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -MD -Zi +QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MD QMAKE_CFLAGS_DEBUG = -Zi -MDd QMAKE_CFLAGS_YACC = QMAKE_CFLAGS_LTCG = -GL @@ -98,7 +98,6 @@ QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib QMAKE_LIBS_OPENGL_ES2 = gdi32.lib user32.lib QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib - QMAKE_LIBS_QT_ENTRY = -lqtmain QMAKE_IDL = midl /NOLOGO diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 39ecf00544..a4955e99f3 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -8,18 +8,17 @@ # load(device_config) +include(../common/gcc-base.conf) include(../common/g++-base.conf) +# modifications to gcc-base.conf and g++-base.conf + MAKEFILE_GENERATOR = MINGW QMAKE_PLATFORM = win32 mingw CONFIG += debug_and_release debug_and_release_target precompile_header DEFINES += UNICODE _UNICODE QMAKE_COMPILER_DEFINES += __GNUC__ WIN32 -QMAKE_EXT_OBJ = .o -QMAKE_EXT_RES = _res.o - - QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_LEX = flex QMAKE_LEXFLAGS = @@ -27,6 +26,7 @@ QMAKE_YACC = bison -y QMAKE_YACCFLAGS = -d QMAKE_CFLAGS += -fno-keep-inline-dllexport QMAKE_CFLAGS_WARN_ON += -Wextra + QMAKE_CFLAGS_SSE2 += -mstackrealign QMAKE_CXX = $${CROSS_COMPILE}g++ @@ -53,6 +53,8 @@ equals(QMAKE_HOST.os, Windows) { QMAKE_LINK_OBJECT_MAX = 10 QMAKE_LINK_OBJECT_SCRIPT = object_script } +QMAKE_EXT_OBJ = .o +QMAKE_EXT_RES = _res.o QMAKE_PREFIX_SHLIB = QMAKE_EXTENSION_SHLIB = dll QMAKE_PREFIX_STATICLIB = lib @@ -78,6 +80,5 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P include(../common/angle.conf) -include(../common/gcc-base.conf) load(qt_config) diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index 9506097e7f..4d18b1cc55 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -17,9 +17,10 @@ QMAKE_CC = icl QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373 QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673 QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673 -QMAKE_CFLAGS_DEBUG = -Zi -MDd -Od +QMAKE_CFLAGS_DEBUG = -Od -Zi -MDd QMAKE_CFLAGS_LTCG = -Qipo QMAKE_CFLAGS_DISABLE_LTCG = -Qno-ipo + QMAKE_CFLAGS_SSE2 = -QxSSE2 QMAKE_CFLAGS_SSE3 = -QxSSE3 QMAKE_CFLAGS_SSSE3 = -QxSSSE3 -- cgit v1.2.3 From 2f96813349681889ad2987173dad18f8f1d3b612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 21 Dec 2017 13:07:14 +0100 Subject: Fix typo in QSslKey Change-Id: I201f4af1dd43a8e74d26652b50f3ad6074952888 Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslkey_qt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp index 3c5dc830d3..fd76d3353a 100644 --- a/src/network/ssl/qsslkey_qt.cpp +++ b/src/network/ssl/qsslkey_qt.cpp @@ -94,7 +94,7 @@ static OidLengthMap createOidMap() oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.8"), 160); // secp160r1 oids.insert(oids.cend(), QByteArrayLiteral("1.3.132.0.9"), 160); // secp160k1 oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.11"), 384); // brainpoolP384r1 - oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.13"), 521); // brainpoolP512r1 + oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.13"), 512); // brainpoolP512r1 oids.insert(oids.cend(), QByteArrayLiteral("1.3.36.3.3.2.8.1.1.7"), 256); // brainpoolP256r1 return oids; } -- cgit v1.2.3 From 83fa66b6d23907ccd443344f9865fcf4ad14e3a9 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 14 Dec 2017 10:32:15 +0100 Subject: Add more code examples to QUrl documentation Code examples make it much easier to learn how an API behaves. One area that the patch tries to address is the distinction between a relative URL and a relative path. Change-Id: Ife52172816b89afb6cd810b07d3573480e2cd747 Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index cf7ed130ba..4587b9fcd6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -90,11 +90,6 @@ fromPercentEncoding() and toPercentEncoding() which deal with percent encoding and decoding of QString objects. - Calling isRelative() will tell whether or not the URL is - relative. A relative URL can be resolved by passing it as argument - to resolved(), which returns an absolute URL. isParentOf() is used - for determining whether one URL is a parent of another. - fromLocalFile() constructs a QUrl by parsing a local file path. toLocalFile() converts a URL to a local file path. @@ -116,6 +111,37 @@ from freedesktop.org, provided that the locale encodes file names using UTF-8 (required by IDN). + \section2 Relative URLs vs Relative Paths + + Calling isRelative() will return whether or not the URL is relative. + A relative URL has no \l {scheme}. For example: + + \code + qDebug() << QUrl("main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme + qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme + \endcode + + Notice that a URL can be absolute while containing a relative path, and + vice versa: + + \code + // Absolute URL, relative path + QUrl url("file:file.txt"); + qDebug() << url.isRelative(); // false: has "file" scheme + qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path + + // Relative URL, absolute path + url = QUrl("/home/user/file.txt"); + qDebug() << url.isRelative(); // true: has no scheme + qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path + \endcode + + A relative URL can be resolved by passing it as an argument to resolved(), + which returns an absolute URL. isParentOf() is used for determining whether + one URL is a parent of another. + \section2 Error checking QUrl is capable of detecting many errors in URLs while parsing it or when @@ -2539,6 +2565,12 @@ void QUrl::setPath(const QString &path, ParsingMode mode) /*! Returns the path of the URL. + \code + qDebug() << QUrl("file:file.txt").path(); // "file.txt" + qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt" + qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123" + \endcode + The \a options argument controls how to format the path component. All values produce an unambiguous result. With QUrl::FullyDecoded, all percent-encoded sequences are decoded; otherwise, the returned value may @@ -2549,6 +2581,31 @@ void QUrl::setPath(const QString &path, ParsingMode mode) sequences are present. It is recommended to use that value when the result will be used in a non-URL context, such as sending to an FTP server. + An example of data loss is when you have non-Unicode percent-encoded sequences + and use FullyDecoded (the default): + + \code + qDebug() << QUrl("/foo%FFbar").path(); + \endcode + + In this example, there will be some level of data loss because the \c %FF cannot + be converted. + + Data loss can also occur when the path contains sub-delimiters (such as \c +): + + \code + qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+" + \endcode + + Other decoding examples: + + \code + const QUrl url("/tmp/Mambo %235%3F.mp3"); + qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3" + \endcode + \sa setPath() */ QString QUrl::path(ComponentFormattingOptions options) const @@ -3257,6 +3314,8 @@ QUrl QUrl::resolved(const QUrl &relative) const equivalent to calling scheme().isEmpty(). Relative references are defined in RFC 3986 section 4.2. + + \sa {Relative URLs vs Relative Paths} */ bool QUrl::isRelative() const { @@ -3796,6 +3855,41 @@ bool QUrl::isDetached() const An empty \a localFile leads to an empty URL (since Qt 5.4). + \code + qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt") + qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt") + qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme + \endcode + + In the first line in snippet above, a file URL is constructed from a + local, relative path. A file URL with a relative path only makes sense + if there is a base URL to resolve it against. For example: + + \code + QUrl url = QUrl::fromLocalFile("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // wrong: prints QUrl("file:file.txt"), as url already has a scheme + qDebug() << baseUrl.resolved(url); + \endcode + + To resolve such a URL, it's necessary to remove the scheme beforehand: + + \code + // correct: prints QUrl("file:///home/user/file.txt") + url.setScheme(QString()); + qDebug() << baseUrl.resolved(url); + \endcode + + For this reason, it is better to use a relative URL (that is, no scheme) + for relative file paths: + + \code + QUrl url = QUrl("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // prints QUrl("file:///home/user/file.txt") + qDebug() << baseUrl.resolved(url); + \endcode + \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators() */ QUrl QUrl::fromLocalFile(const QString &localFile) @@ -3840,6 +3934,12 @@ QUrl QUrl::fromLocalFile(const QString &localFile) returned value in the form found on SMB networks (for example, "//servername/path/to/file.txt"). + \code + qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt" + qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt" + qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme + \endcode + Note: if the path component of this URL contains a non-UTF-8 binary sequence (such as %80), the behaviour of this function is undefined. -- cgit v1.2.3 From ffc8409aa58c04c1dd140001976b55925ac959f6 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Mon, 15 Sep 2014 14:09:22 -0700 Subject: Use AccessCheck for current user effective file permissions On Windows, QFileInfo.isWritable() was returning true in situations where the file would only be writable with elevated privileges. Using AccessCheck instead of GetEffectiveRightsFromAcl to get the correct results. Done-with: Friedemann Kleint Done-with: Edward Welbourne Task-number: QTBUG-30148 Change-Id: I7a3468ac069bf782ca312078e3a84107b6cd468c Reviewed-by: Friedemann Kleint --- src/corelib/io/qfilesystemengine_win.cpp | 64 +++++++++++++++++++---- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 25 ++++++--- 2 files changed, 74 insertions(+), 15 deletions(-) mode change 100644 => 100755 src/corelib/io/qfilesystemengine_win.cpp mode change 100644 => 100755 tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp old mode 100644 new mode 100755 index b01aa55756..c9a56a81cc --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -178,6 +178,7 @@ static TRUSTEE_W currentUserTrusteeW; static TRUSTEE_W worldTrusteeW; static PSID currentUserSID = 0; static PSID worldSID = 0; +static HANDLE currentUserImpersonatedToken = nullptr; /* Deletes the allocated SIDs during global static cleanup @@ -198,6 +199,11 @@ SidCleanup::~SidCleanup() ::FreeSid(worldSID); worldSID = 0; } + + if (currentUserImpersonatedToken) { + ::CloseHandle(currentUserImpersonatedToken); + currentUserImpersonatedToken = nullptr; + } } Q_GLOBAL_STATIC(SidCleanup, initSidCleanup) @@ -254,6 +260,12 @@ static void resolveLibs() ::CloseHandle(token); } + token = nullptr; + if (::OpenProcessToken(hnd, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &token)) { + ::DuplicateToken(token, SecurityImpersonation, ¤tUserImpersonatedToken); + ::CloseHandle(token); + } + typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid"); if (ptrAllocateAndInitializeSid) { @@ -721,15 +733,49 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst ACCESS_MASK access_mask; TRUSTEE_W trustee; if (what & QFileSystemMetaData::UserPermissions) { // user - data.knownFlagsMask |= QFileSystemMetaData::UserPermissions; - if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) - access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - data.entryFlags |= QFileSystemMetaData::UserReadPermission; - if(access_mask & WriteMask) - data.entryFlags|= QFileSystemMetaData::UserWritePermission; - if(access_mask & ExecMask) - data.entryFlags|= QFileSystemMetaData::UserExecutePermission; + // Using AccessCheck because GetEffectiveRightsFromAcl doesn't account for elevation + if (currentUserImpersonatedToken) { + GENERIC_MAPPING mapping = {FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS}; + PRIVILEGE_SET privileges; + DWORD grantedAccess; + BOOL result; + + data.knownFlagsMask |= QFileSystemMetaData::UserPermissions; + DWORD genericAccessRights = GENERIC_READ; + ::MapGenericMask(&genericAccessRights, &mapping); + + DWORD privilegesLength = sizeof(privileges); + if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) { + data.entryFlags |= QFileSystemMetaData::UserReadPermission; + } + + privilegesLength = sizeof(privileges); + genericAccessRights = GENERIC_WRITE; + ::MapGenericMask(&genericAccessRights, &mapping); + if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) { + data.entryFlags |= QFileSystemMetaData::UserWritePermission; + } + + privilegesLength = sizeof(privileges); + genericAccessRights = GENERIC_EXECUTE; + ::MapGenericMask(&genericAccessRights, &mapping); + if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) { + data.entryFlags |= QFileSystemMetaData::UserExecutePermission; + } + } else { // fallback to GetEffectiveRightsFromAcl + data.knownFlagsMask |= QFileSystemMetaData::UserPermissions; + if (ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) + access_mask = ACCESS_MASK(-1); + if (access_mask & ReadMask) + data.entryFlags |= QFileSystemMetaData::UserReadPermission; + if (access_mask & WriteMask) + data.entryFlags|= QFileSystemMetaData::UserWritePermission; + if (access_mask & ExecMask) + data.entryFlags|= QFileSystemMetaData::UserExecutePermission; + } } if (what & QFileSystemMetaData::OwnerPermissions) { // owner data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions; diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp old mode 100644 new mode 100755 index f35dab2cad..efb261ce7e --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -64,6 +64,14 @@ #define Q_NO_SYMLINKS #endif +#if defined(Q_OS_WIN) +QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; +QT_END_NAMESPACE +# ifndef Q_OS_WINRT +bool IsUserAdmin(); +# endif +#endif #if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) inline bool qt_isEvilFsTypeName(const char *name) @@ -1634,6 +1642,15 @@ void tst_QFileInfo::isWritable() QVERIFY2(fi.exists(), msgDoesNotExist(fi.absoluteFilePath()).constData()); QVERIFY(!fi.isWritable()); #endif + +#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT) + QScopedValueRollback ntfsMode(qt_ntfs_permission_lookup); + qt_ntfs_permission_lookup = 1; + QFileInfo fi2(QFile::decodeName(qgetenv("SystemRoot") + "/system.ini")); + QVERIFY(fi2.exists()); + QCOMPARE(fi2.isWritable(), IsUserAdmin()); +#endif + #if defined (Q_OS_QNX) // On QNX /etc is usually on a read-only filesystem QVERIFY(!QFileInfo("/etc/passwd").isWritable()); #elif defined (Q_OS_UNIX) && !defined(Q_OS_VXWORKS) // VxWorks does not have users/groups @@ -1807,7 +1824,7 @@ void tst_QFileInfo::detachingOperations() } #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) -BOOL IsUserAdmin() +bool IsUserAdmin() { BOOL b; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; @@ -1825,13 +1842,9 @@ BOOL IsUserAdmin() FreeSid(AdministratorsGroup); } - return(b); + return b != FALSE; } -QT_BEGIN_NAMESPACE -extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; -QT_END_NAMESPACE - #endif // Q_OS_WIN && !Q_OS_WINRT #ifndef Q_OS_WINRT -- cgit v1.2.3 From 117148c381316c046b99a4ce40ab668fb7c79f11 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 20 Dec 2017 10:34:56 -0800 Subject: QMacStyle: Bring back submenu indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This one fell off the truck while we were removing HITheme calls. We add it back by simply rendering a BLACK RIGHT-POINTING TRIANGLE character. We also fix smaller issues, such as not displaying any shortcut related to a submenu action — this is simply not a thing. The spacing between the menu item's text and the submenu indicator has also been slightly improved. Change-Id: I6c768a5506a5eb9528b0dd76acd52b561266d67b Task-number: QTBUG-64405 Reviewed-by: Jake Petroules --- src/plugins/styles/mac/qmacstyle_mac.mm | 53 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index c6ae7c1b79..386e944e42 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -4187,7 +4187,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter break; } - const int tabwidth = mi->tabWidth; const int maxpmw = mi->maxIconWidth; const bool enabled = mi->state & State_Enabled; @@ -4245,21 +4244,37 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter } QString s = mi->text; - if (!s.isEmpty()) { - int t = s.indexOf(QLatin1Char('\t')); - int text_flags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextHideMnemonic - | Qt::TextSingleLine | Qt::AlignAbsolute; - int yPos = mi->rect.y(); - if (widgetSize == QStyleHelper::SizeMini) - yPos += 1; - p->save(); - if (t >= 0) { - p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font())); - int xp = mi->rect.right() - tabwidth - macRightBorder - macItemHMargin - macItemFrame + 1; - p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags, s.mid(t + 1)); - s = s.left(t); - } + const auto text_flags = Qt::AlignVCenter | Qt::TextHideMnemonic + | Qt::TextSingleLine | Qt::AlignAbsolute; + int yPos = mi->rect.y(); + if (widgetSize == QStyleHelper::SizeMini) + yPos += 1; + + const bool isSubMenu = mi->menuItemType == QStyleOptionMenuItem::SubMenu; + const int tabwidth = isSubMenu ? 9 : mi->tabWidth; + + QString rightMarginText; + if (isSubMenu) + rightMarginText = QStringLiteral("\u25b6\ufe0e"); // U+25B6 U+FE0E: BLACK RIGHT-POINTING TRIANGLE + + // If present, save and remove embedded shorcut from text + const int tabIndex = s.indexOf(QLatin1Char('\t')); + if (tabIndex >= 0) { + if (!isSubMenu) // ... but ignore it if it's a submenu. + rightMarginText = s.mid(tabIndex + 1); + s = s.left(tabIndex); + } + p->save(); + if (!rightMarginText.isEmpty()) { + p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font())); + int xp = mi->rect.right() - tabwidth - macRightBorder + 2; + if (!isSubMenu) + xp -= macItemHMargin + macItemFrame + 3; // Adjust for shortcut + p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags | Qt::AlignRight, rightMarginText); + } + + if (!s.isEmpty()) { const int xm = macItemFrame + maxpmw + macItemHMargin; QFont myFont = mi->font; // myFont may not have any "hard" flags set. We override @@ -4270,9 +4285,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF()); p->setFont(myFont); p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1, - mi->rect.height(), text_flags ^ Qt::AlignRight, s); - p->restore(); + mi->rect.height(), text_flags, s); } + p->restore(); } break; case CE_MenuBarItem: @@ -6364,8 +6379,8 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, } if (mi->text.contains(QLatin1Char('\t'))) w += 12; - if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) - w += 20; + else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) + w += 35; // Not quite exactly as it seems to depend on other factors if (maxpmw) w += maxpmw + 6; // add space for a check. All items have place for a check too. -- cgit v1.2.3 From e3c79b4356ca0d777663e7c4ad673dcb428b76b0 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 20 Dec 2017 16:47:01 -0800 Subject: QMacStyle: Use light color on expanding scrollbar Change-Id: I4e9c870c8acaaa690f530f847c9927d61a508a94 Reviewed-by: Jake Petroules --- src/plugins/styles/mac/qmacstyle_mac.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 386e944e42..ad2ca4a02e 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -5174,11 +5174,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex const auto cw = QMacStylePrivate::CocoaControl(controlType, cocoaSize); NSScroller *scroller = static_cast(d->cocoaControl(cw)); + const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget); + const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; if (isTransient) { // macOS behavior: as soon as one color channel is >= 128, // the background is considered bright, scroller is dark. - const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget); - const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; scroller.knobStyle = hasDarkBg? NSScrollerKnobStyleLight : NSScrollerKnobStyleDark; } else { scroller.knobStyle = NSScrollerKnobStyleDefault; @@ -5228,7 +5228,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex QCFType knobPath = CGPathCreateWithRoundedRect(knobRect, knobRadius, knobRadius, nullptr); CGContextAddPath(cg, knobPath); CGContextSetAlpha(cg, 0.5); - CGContextSetFillColorWithColor(cg, NSColor.blackColor.CGColor); + CGColorRef knobColor = hasDarkBg ? NSColor.whiteColor.CGColor : NSColor.blackColor.CGColor; + CGContextSetFillColorWithColor(cg, knobColor); CGContextFillPath(cg); } else { [scroller drawKnob]; -- cgit v1.2.3 From c5a3022b041f19c3bc2dd2204c9f9b334c7f986f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 20 Dec 2017 17:14:18 -0800 Subject: QMacStyle: Minimize size of scrollbar transparency layer Instead of allocating the full backing store size for the transparency layer, we make sure we only allocate exactly as much as needed by the scrollbar. Change-Id: I55c3172fe3dd2a1f3fd46828463497f9f35cb1ae Reviewed-by: Jake Petroules --- src/plugins/styles/mac/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index ad2ca4a02e..db02ab1fe9 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -5190,7 +5190,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex break; if (isTransient) { - CGContextBeginTransparencyLayer(cg, NULL); + CGContextBeginTransparencyLayerWithRect(cg, scroller.frame, nullptr); CGContextSetAlpha(cg, opacity); } -- cgit v1.2.3 From 44ef95a885f440a33e79ff3f9a79d4bb6d408dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 19 Dec 2017 19:58:29 +0100 Subject: iOS: Don't send all touch events async Commit 77942a1bdf9 introduced the QScopedValueRollback, but without assigning it to a local temporary, so the value was rolled back immediately, resulting in always sending touch events async. Change-Id: Ic7f65c3d38c46813ff06694e883dae3df138b9d4 Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiosscreen.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 521495b42f..5717483a81 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -204,7 +204,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) - (void)sendEvent:(UIEvent *)event { - QScopedValueRollback(self->_sendingEvent, YES); + QScopedValueRollback sendingEvent(self->_sendingEvent, YES); [super sendEvent:event]; } -- cgit v1.2.3 From f9c07da7b6c167820a71d2c840b7be70c393457a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Dec 2017 13:55:32 -0800 Subject: Examples: Update multicast sender and receiver examples for IPv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's the right thing to do, as we're in 2017, not 1997. Also, this takes care to indicate that QAbstractSocket::MulticastTtlOption makes sense mostly for IPv4, even though it's implemented for both families. In IPv4, it's used to indicatae the scope, whereas in IPv6 it's stored in bits 12-15 of the address. Task-number: QTBUG-46046 Change-Id: I9741f017961b410c910dfffd14ffaabe0a2024d8 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- examples/network/multicastreceiver/receiver.cpp | 35 ++++++++++++++++++------- examples/network/multicastreceiver/receiver.h | 6 +++-- examples/network/multicastsender/sender.cpp | 23 ++++++++++++---- examples/network/multicastsender/sender.h | 6 +++-- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/examples/network/multicastreceiver/receiver.cpp b/examples/network/multicastreceiver/receiver.cpp index 8985ad1d82..d793242ad0 100644 --- a/examples/network/multicastreceiver/receiver.cpp +++ b/examples/network/multicastreceiver/receiver.cpp @@ -55,9 +55,10 @@ Receiver::Receiver(QWidget *parent) : QDialog(parent), - groupAddress(QStringLiteral("239.255.43.21")) + groupAddress4(QStringLiteral("239.255.43.21")), + groupAddress6(QStringLiteral("ff12::2115")) { - statusLabel = new QLabel(tr("Listening for multicasted messages")); + statusLabel = new QLabel(tr("Listening for multicast messages on both IPv4 and IPv6")); auto quitButton = new QPushButton(tr("&Quit")); auto buttonLayout = new QHBoxLayout; @@ -72,21 +73,37 @@ Receiver::Receiver(QWidget *parent) setWindowTitle(tr("Multicast Receiver")); - udpSocket.bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); - udpSocket.joinMulticastGroup(groupAddress); + udpSocket4.bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); + udpSocket4.joinMulticastGroup(groupAddress4); - connect(&udpSocket, SIGNAL(readyRead()), + if (!udpSocket6.bind(QHostAddress::AnyIPv6, 45454, QUdpSocket::ShareAddress) || + !udpSocket6.joinMulticastGroup(groupAddress6)) + statusLabel->setText(tr("Listening for multicast messages on IPv4 only")); + + connect(&udpSocket4, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams())); + connect(&udpSocket6, &QUdpSocket::readyRead, this, &Receiver::processPendingDatagrams); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); } void Receiver::processPendingDatagrams() { QByteArray datagram; - while (udpSocket.hasPendingDatagrams()) { - datagram.resize(int(udpSocket.pendingDatagramSize())); - udpSocket.readDatagram(datagram.data(), datagram.size()); - statusLabel->setText(tr("Received datagram: \"%1\"") + + // using QUdpSocket::readDatagram (API since Qt 4) + while (udpSocket4.hasPendingDatagrams()) { + datagram.resize(int(udpSocket4.pendingDatagramSize())); + udpSocket4.readDatagram(datagram.data(), datagram.size()); + statusLabel->setText(tr("Received IPv4 datagram: \"%1\"") .arg(datagram.constData())); } + + // using QUdpSocket::receiveDatagram (API since Qt 5.8) + while (udpSocket6.hasPendingDatagrams()) { + QNetworkDatagram dgram = udpSocket6.receiveDatagram(); + statusLabel->setText(statusLabel->text() + + tr("\nReceived IPv6 datagram from [%2]:%3: \"%1\"") + .arg(dgram.data().constData(), dgram.senderAddress().toString()) + .arg(dgram.senderPort())); + } } diff --git a/examples/network/multicastreceiver/receiver.h b/examples/network/multicastreceiver/receiver.h index 54927fdd63..0325d861df 100644 --- a/examples/network/multicastreceiver/receiver.h +++ b/examples/network/multicastreceiver/receiver.h @@ -71,8 +71,10 @@ private slots: private: QLabel *statusLabel = nullptr; - QUdpSocket udpSocket; - QHostAddress groupAddress; + QUdpSocket udpSocket4; + QUdpSocket udpSocket6; + QHostAddress groupAddress4; + QHostAddress groupAddress6; }; #endif diff --git a/examples/network/multicastsender/sender.cpp b/examples/network/multicastsender/sender.cpp index cb4bf45672..a542a2528f 100644 --- a/examples/network/multicastsender/sender.cpp +++ b/examples/network/multicastsender/sender.cpp @@ -52,11 +52,21 @@ Sender::Sender(QWidget *parent) : QDialog(parent), - groupAddress(QStringLiteral("239.255.43.21")) + groupAddress4(QStringLiteral("239.255.43.21")), + groupAddress6(QStringLiteral("ff12::2115")) { - statusLabel = new QLabel(tr("Ready to multicast datagrams to group %1 on port 45454").arg(groupAddress.toString())); + // force binding to their respective families + udpSocket4.bind(QHostAddress(QHostAddress::AnyIPv4), 0); + udpSocket6.bind(QHostAddress(QHostAddress::AnyIPv6), udpSocket4.localPort()); - auto ttlLabel = new QLabel(tr("TTL for multicast datagrams:")); + QString msg = tr("Ready to multicast datagrams to groups %1 and [%2] on port 45454").arg(groupAddress4.toString()); + if (udpSocket6.state() != QAbstractSocket::BoundState) + msg = tr("IPv6 failed. Ready to multicast datagrams to group %1 on port 45454").arg(groupAddress4.toString()); + else + msg = msg.arg(groupAddress6.toString()); + statusLabel = new QLabel(msg); + + auto ttlLabel = new QLabel(tr("TTL for IPv4 multicast datagrams:")); auto ttlSpinBox = new QSpinBox; ttlSpinBox->setRange(0, 255); @@ -88,7 +98,8 @@ Sender::Sender(QWidget *parent) void Sender::ttlChanged(int newTtl) { - udpSocket.setSocketOption(QAbstractSocket::MulticastTtlOption, newTtl); + // we only set the TTL on the IPv4 socket, as that changes the multicast scope + udpSocket4.setSocketOption(QAbstractSocket::MulticastTtlOption, newTtl); } void Sender::startSending() @@ -101,6 +112,8 @@ void Sender::sendDatagram() { statusLabel->setText(tr("Now sending datagram %1").arg(messageNo)); QByteArray datagram = "Multicast message " + QByteArray::number(messageNo); - udpSocket.writeDatagram(datagram, groupAddress, 45454); + udpSocket4.writeDatagram(datagram, groupAddress4, 45454); + if (udpSocket6.state() == QAbstractSocket::BoundState) + udpSocket6.writeDatagram(datagram, groupAddress6, 45454); ++messageNo; } diff --git a/examples/network/multicastsender/sender.h b/examples/network/multicastsender/sender.h index 5d8769790e..0af6f9aaec 100644 --- a/examples/network/multicastsender/sender.h +++ b/examples/network/multicastsender/sender.h @@ -70,9 +70,11 @@ private slots: private: QLabel *statusLabel = nullptr; QPushButton *startButton = nullptr; - QUdpSocket udpSocket; + QUdpSocket udpSocket4; + QUdpSocket udpSocket6; QTimer timer; - QHostAddress groupAddress; + QHostAddress groupAddress4; + QHostAddress groupAddress6; int messageNo = 1; }; -- cgit v1.2.3 From f95d64d075f8986919db216f7ca44930c37f4ec6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Dec 2017 13:55:50 -0800 Subject: Doc: attempt to fix some qdoc errors for QRandomGenerator This fixes only those that look fixable. There are a number of errors in the online documentation that look like qdoc tool bugs, like missing functions (operator==) and documentation text that does not exist in the source code. This fixes: - QRandomGenerator(System) constructor showing up - Links for C++ reference documentation not showing up as links Change-Id: I9e2892cb6c374e93bcb7fffd14fe21db5a6969d9 Reviewed-by: Martin Smith --- src/corelib/global/qrandom.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 5cb3e75791..0ee6ac9f38 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -847,7 +847,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \endcode This function complies with the requirements for the function - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{std::seed_seq::generate}}, + \l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{\c std::seed_seq::generate}, which requires unsigned 32-bit integer values. Note that if the [begin, end) range refers to an area that can store more @@ -927,7 +927,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \endcode The same may also be obtained by using - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{std::uniform_real_distribution}} + \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{\c std::uniform_real_distribution} with parameters 0 and 1. \sa generate(), generate64(), bounded() @@ -952,7 +952,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel Generates one random 32-bit quantity in the range between 0 (inclusive) and \a highest (exclusive). The same result may also be obtained by using - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{std::uniform_int_distribution}} + \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution} with parameters 0 and \c{highest - 1}. That class can also be used to obtain quantities larger than 32 bits. @@ -990,7 +990,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel Generates one random 32-bit quantity in the range between \a lowest (inclusive) and \a highest (exclusive). The same result may also be obtained by using - \c{\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{std::uniform_int_distribution}} + \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution} with parameters \a lowest and \c{\a highest - 1}. That class can also be used to obtain quantities larger than 32 bits. @@ -1190,7 +1190,9 @@ QRandomGenerator64 QRandomGenerator64::securelySeeded() return result; } -/// \internal +/*! + \internal +*/ inline QRandomGenerator::QRandomGenerator(System) : type(SystemRNG) { -- cgit v1.2.3 From b12db22fcf3ebd3dc5a7143a61745d408ab833aa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 9 Dec 2017 22:54:04 -0800 Subject: Replace a few hardcoded paths with defaults from paths.h This removes at least one special-case we had to have, in Android's lack of /etc/mnttab. Bionic's _PATH_MOUNTED is already /proc/mounts. Change-Id: I9407dcf22de6407c83b5fffd14fedc638586d0f9 Reviewed-by: Edward Welbourne --- src/corelib/global/qlogging.cpp | 8 +++++++- src/corelib/io/qfilesystemengine_unix.cpp | 16 +++++++++++----- src/corelib/io/qprocess.cpp | 6 ++++++ src/corelib/io/qstorageinfo_unix.cpp | 18 ++++++++++-------- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 6602d53b08..7623de8423 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -63,6 +63,9 @@ #if QT_CONFIG(slog2) #include #endif +#if QT_HAS_INCLUDE() +#include +#endif #ifdef Q_OS_ANDROID #include @@ -215,8 +218,11 @@ static bool willLogToConsole() # ifdef Q_OS_WIN return GetConsoleWindow(); # elif defined(Q_OS_UNIX) +# ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +# endif // if /dev/tty exists, we can only open it if we have a controlling TTY - int devtty = qt_safe_open("/dev/tty", O_RDONLY); + int devtty = qt_safe_open(_PATH_TTY, O_RDONLY); if (devtty == -1 && (errno == ENOENT || errno == EPERM || errno == ENXIO)) { // no /dev/tty, fall back to isatty on stderr return isatty(STDERR_FILENO); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index e590e259e7..b974af80dc 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -55,6 +55,13 @@ #include #include +#if QT_HAS_INCLUDE() +# include +#endif +#ifndef _PATH_TMP // from +# define _PATH_TMP "/tmp" +#endif + #if defined(Q_OS_MAC) # include # include @@ -1507,14 +1514,13 @@ QString QFileSystemEngine::tempPath() #else QString temp = QFile::decodeName(qgetenv("TMPDIR")); if (temp.isEmpty()) { + if (false) { #if defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED) - if (NSString *nsPath = NSTemporaryDirectory()) { + } else if (NSString *nsPath = NSTemporaryDirectory()) { temp = QString::fromCFString((CFStringRef)nsPath); - } else { -#else - { #endif - temp = QLatin1String("/tmp"); + } else { + temp = QLatin1String(_PATH_TMP); } } return QDir::cleanPath(temp); diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 7ed319f5f1..64a59bc2c3 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -99,6 +99,10 @@ QT_END_NAMESPACE #include #endif +#if QT_HAS_INCLUDE() +#include +#endif + QT_BEGIN_NAMESPACE /*! @@ -2638,6 +2642,8 @@ QString QProcess::nullDevice() { #ifdef Q_OS_WIN return QStringLiteral("\\\\.\\NUL"); +#elif defined(_PATH_DEVNULL) + return QStringLiteral(_PATH_DEVNULL); #else return QStringLiteral("/dev/null"); #endif diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 1fc32e0f2d..c2d31e7677 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -107,6 +107,13 @@ # endif // QT_LARGEFILE_SUPPORT #endif // Q_OS_BSD4 +#if QT_HAS_INCLUDE() +# include +#endif +#ifndef _PATH_MOUNTED +# define _PATH_MOUNTED "/etc/mnttab" +#endif + QT_BEGIN_NAMESPACE class QStorageIterator @@ -241,11 +248,9 @@ inline QByteArray QStorageIterator::options() const #elif defined(Q_OS_SOLARIS) -static const char pathMounted[] = "/etc/mnttab"; - inline QStorageIterator::QStorageIterator() { - const int fd = qt_safe_open(pathMounted, O_RDONLY); + const int fd = qt_safe_open(_PATH_MOUNTED, O_RDONLY); fp = ::fdopen(fd, "r"); } @@ -282,11 +287,9 @@ inline QByteArray QStorageIterator::device() const #elif defined(Q_OS_ANDROID) -static const QLatin1String pathMounted("/proc/mounts"); - inline QStorageIterator::QStorageIterator() { - file.setFileName(pathMounted); + file.setFileName(_PATH_MOUNTED); file.open(QIODevice::ReadOnly | QIODevice::Text); } @@ -339,14 +342,13 @@ inline QByteArray QStorageIterator::options() const #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD) -static const char pathMounted[] = "/etc/mtab"; static const int bufferSize = 1024; // 2 paths (mount point+device) and metainfo; // should be enough inline QStorageIterator::QStorageIterator() : buffer(QByteArray(bufferSize, 0)) { - fp = ::setmntent(pathMounted, "r"); + fp = ::setmntent(_PATH_MOUNTED, "r"); } inline QStorageIterator::~QStorageIterator() -- cgit v1.2.3 From bbcd4533889b3f3ae45917d638e06bedc9e5c536 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 16:49:40 -0800 Subject: tst_QUdpSocket: stop trying to bind to multicast addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not an official feature of the networking stacks and does not work portably across operating systems. So just stop trying to do that. This was failing reliably (not flaky!) with IPv6 on FreeBSD and Windows. For IPv4, Windows apparently accepts 239.255.0.0/16 but not other addresses, so remove IPv4 too. Change-Id: Ifb5969bf206e4cd7b14efffd14fb682c2839e95d Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- tests/auto/network/socket/qudpsocket/BLACKLIST | 2 -- tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST index 5adb05d3f2..dcb5f87628 100644 --- a/tests/auto/network/socket/qudpsocket/BLACKLIST +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -1,5 +1,3 @@ -[multicast:same bind, group ipv6 address] -* [multicast] osx [writeDatagramToNonExistingPeer] diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 6dff9f3420..9050bbbc93 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1353,10 +1353,8 @@ void tst_QUdpSocket::multicast_data() QTest::addColumn("joinResult"); QTest::newRow("valid bind, group ipv4 address") << anyAddress << true << groupAddress << true; QTest::newRow("valid bind, invalid group ipv4 address") << anyAddress << true << anyAddress << false; - QTest::newRow("same bind, group ipv4 address") << groupAddress << true << groupAddress << true; QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; - QTest::newRow("same bind, group ipv6 address") << group6Address << false << group6Address << false; QTest::newRow("dual bind, group ipv4 address") << dualAddress << true << groupAddress << false; QTest::newRow("dual bind, group ipv6 address") << dualAddress << true << group6Address << true; } -- cgit v1.2.3 From c4f397ee11fc3cea1fc132ebe1db24e3970bb477 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 12:15:37 -0800 Subject: tst_QUdpSocket: Don't use interface-local IPv6 multicast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FreeBSD kernel treats them specially, just like link-local (that's probably why it calls them "interface-local" instead of "node-local"). So instead let's use a random address, which will avoid multiple tst_qudpsocket, when run on the same network at the same time, receiving each other's datagrams. It could happen, considering this test has an 800-second timeout limit. Change-Id: Ifb5969bf206e4cd7b14efffd14fb592a3166547e Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 9050bbbc93..69d549d738 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -124,6 +125,7 @@ private: bool m_skipUnsupportedIPv6Tests; QList allAddresses; + QHostAddress multicastGroup4, multicastGroup6; QUdpSocket *m_asyncSender; QUdpSocket *m_asyncReceiver; }; @@ -208,6 +210,20 @@ void tst_QUdpSocket::initTestCase() allAddresses = QNetworkInterface::allAddresses(); m_skipUnsupportedIPv6Tests = shouldSkipIpv6TestsForBrokenSetsockopt(); + // Create a pair of random multicast groups so we avoid clashing with any + // other tst_qudpsocket running on the same network at the same time. + quint64 r[2] = { + // ff14:: is temporary, not prefix-based, admin-local + qToBigEndian(Q_UINT64_C(0xff14) << 48), + QRandomGenerator64::global()->generate64() + }; + multicastGroup6.setAddress(*reinterpret_cast(&r)); + + // 239.0.0.0/8 is "Organization-Local Scope" + multicastGroup4.setAddress((239U << 24) | (r[1] & 0xffffff)); + + qDebug() << "Will use multicast groups" << multicastGroup4 << multicastGroup6; + if (EmulationDetector::isRunningArmOnX86()) QSKIP("This test is unreliable due to QEMU emulation shortcomings."); } @@ -1232,9 +1248,9 @@ void tst_QUdpSocket::multicastLoopbackOption() void tst_QUdpSocket::multicastJoinBeforeBind_data() { QTest::addColumn("groupAddress"); - QTest::newRow("valid ipv4 group address") << QHostAddress("239.255.118.62"); + QTest::newRow("valid ipv4 group address") << multicastGroup4; QTest::newRow("invalid ipv4 group address") << QHostAddress(QHostAddress::Broadcast); - QTest::newRow("valid ipv6 group address") << QHostAddress("FF01::114"); + QTest::newRow("valid ipv6 group address") << multicastGroup6; QTest::newRow("invalid ipv6 group address") << QHostAddress(QHostAddress::AnyIPv6); } @@ -1254,8 +1270,8 @@ void tst_QUdpSocket::multicastJoinBeforeBind() void tst_QUdpSocket::multicastLeaveAfterClose_data() { QTest::addColumn("groupAddress"); - QTest::newRow("ipv4") << QHostAddress("239.255.118.62"); - QTest::newRow("ipv6") << QHostAddress("FF01::114"); + QTest::newRow("ipv4") << multicastGroup4; + QTest::newRow("ipv6") << multicastGroup6; } void tst_QUdpSocket::multicastLeaveAfterClose() @@ -1342,9 +1358,9 @@ void tst_QUdpSocket::setMulticastInterface() void tst_QUdpSocket::multicast_data() { QHostAddress anyAddress = QHostAddress(QHostAddress::AnyIPv4); - QHostAddress groupAddress = QHostAddress("239.255.118.62"); + QHostAddress groupAddress = multicastGroup4; QHostAddress any6Address = QHostAddress(QHostAddress::AnyIPv6); - QHostAddress group6Address = QHostAddress("FF01::114"); + QHostAddress group6Address = multicastGroup6; QHostAddress dualAddress = QHostAddress(QHostAddress::Any); QTest::addColumn("bindAddress"); -- cgit v1.2.3 From 0c4d31d8c9cdab18743bde17de5ea0bd0daf02e5 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 9 May 2017 12:42:18 +0200 Subject: Improve the findfiles example: use QDirIterator, etc It hasn't been necessary for a long time now to write the recursive file-find function manually. It has just been an obscurely documented feature of QDirIterator for far too long. Demonstrate the new QLocale::formattedDataSize() function. Also sync up the qdoc description of this example with the recent changes. Change-Id: I9c2bb15bb5ec353d38181b160f0be198774cbea2 Reviewed-by: Robin Burchell Reviewed-by: Shawn Rutledge --- examples/widgets/dialogs/findfiles/window.cpp | 57 +++++++++++---------------- examples/widgets/dialogs/findfiles/window.h | 2 +- examples/widgets/doc/src/findfiles.qdoc | 41 ++++++++++--------- 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index f2ce853d99..1b16cdcd35 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -74,6 +74,7 @@ static inline void openFile(const QString &fileName) Window::Window(QWidget *parent) : QWidget(parent) { + setWindowTitle(tr("Find Files")); QPushButton *browseButton = new QPushButton(tr("&Browse..."), this); connect(browseButton, &QAbstractButton::clicked, this, &Window::browse); findButton = new QPushButton(tr("&Find"), this); @@ -92,9 +93,7 @@ Window::Window(QWidget *parent) filesFoundLabel = new QLabel; createFilesTable(); -//! [0] -//! [1] QGridLayout *mainLayout = new QGridLayout(this); mainLayout->addWidget(new QLabel(tr("Named:")), 0, 0); mainLayout->addWidget(fileComboBox, 0, 1, 1, 2); @@ -106,12 +105,13 @@ Window::Window(QWidget *parent) mainLayout->addWidget(filesTable, 3, 0, 1, 3); mainLayout->addWidget(filesFoundLabel, 4, 0, 1, 2); mainLayout->addWidget(findButton, 4, 2); +//! [0] - setWindowTitle(tr("Find Files")); - const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); - resize(screenGeometry.width() / 2, screenGeometry.height() / 3); -} //! [1] + connect(new QShortcut(QKeySequence::Quit, this), &QShortcut::activated, + qApp, &QApplication::quit); +//! [1] +} //! [2] void Window::browse() @@ -133,21 +133,7 @@ static void updateComboBox(QComboBox *comboBox) comboBox->addItem(comboBox->currentText()); } -//! [13] - -static void findRecursion(const QString &path, const QString &pattern, QStringList *result) -{ - QDir currentDir(path); - const QString prefix = path + QLatin1Char('/'); - foreach (const QString &match, currentDir.entryList(QStringList(pattern), QDir::Files | QDir::NoSymLinks)) - result->append(prefix + match); - foreach (const QString &dir, currentDir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot)) - findRecursion(prefix + dir, pattern, result); -} - -//! [13] //! [3] - void Window::find() { filesTable->setRowCount(0); @@ -155,6 +141,7 @@ void Window::find() QString fileName = fileComboBox->currentText(); QString text = textComboBox->currentText(); QString path = QDir::cleanPath(directoryComboBox->currentText()); + currentDir = QDir(path); //! [3] updateComboBox(fileComboBox); @@ -162,12 +149,16 @@ void Window::find() updateComboBox(directoryComboBox); //! [4] - - currentDir = QDir(path); + QStringList filter; + if (!fileName.isEmpty()) + filter << fileName; + QDirIterator it(path, filter, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); QStringList files; - findRecursion(path, fileName.isEmpty() ? QStringLiteral("*") : fileName, &files); + while (it.hasNext()) + files << it.next(); if (!text.isEmpty()) files = findFiles(files, text); + files.sort(); showFiles(files); } //! [4] @@ -225,20 +216,18 @@ QStringList Window::findFiles(const QStringList &files, const QString &text) //! [7] //! [8] -void Window::showFiles(const QStringList &files) +void Window::showFiles(const QStringList &paths) { - for (int i = 0; i < files.size(); ++i) { - const QString &fileName = files.at(i); - const QString toolTip = QDir::toNativeSeparators(fileName); - const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(fileName)); - const qint64 size = QFileInfo(fileName).size(); + for (const QString &filePath : paths) { + const QString toolTip = QDir::toNativeSeparators(filePath); + const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(filePath)); + const qint64 size = QFileInfo(filePath).size(); QTableWidgetItem *fileNameItem = new QTableWidgetItem(relativePath); - fileNameItem->setData(absoluteFileNameRole, QVariant(fileName)); + fileNameItem->setData(absoluteFileNameRole, QVariant(filePath)); fileNameItem->setToolTip(toolTip); fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable); - QTableWidgetItem *sizeItem = new QTableWidgetItem(tr("%1 KB") - .arg(int((size + 1023) / 1024))); - sizeItem->setData(absoluteFileNameRole, QVariant(fileName)); + QTableWidgetItem *sizeItem = new QTableWidgetItem(QLocale().formattedDataSize(size)); + sizeItem->setData(absoluteFileNameRole, QVariant(filePath)); sizeItem->setToolTip(toolTip); sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable); @@ -248,7 +237,7 @@ void Window::showFiles(const QStringList &files) filesTable->setItem(row, 0, fileNameItem); filesTable->setItem(row, 1, sizeItem); } - filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, files.size())); + filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, paths.size())); filesFoundLabel->setWordWrap(true); } //! [8] diff --git a/examples/widgets/dialogs/findfiles/window.h b/examples/widgets/dialogs/findfiles/window.h index fe217381e2..949df704bb 100644 --- a/examples/widgets/dialogs/findfiles/window.h +++ b/examples/widgets/dialogs/findfiles/window.h @@ -79,7 +79,7 @@ private slots: private: QStringList findFiles(const QStringList &files, const QString &text); - void showFiles(const QStringList &files); + void showFiles(const QStringList &paths); QComboBox *createComboBox(const QString &text = QString()); void createFilesTable(); diff --git a/examples/widgets/doc/src/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc index b8363dc698..a2eb326519 100644 --- a/examples/widgets/doc/src/findfiles.qdoc +++ b/examples/widgets/doc/src/findfiles.qdoc @@ -74,19 +74,23 @@ \snippet dialogs/findfiles/window.cpp 0 - We create the application's buttons using the private \c - createButton() function. Then we create the comboboxes associated - with the search specifications, using the private \c - createComboBox() function. We also create the application's labels - before we use the private \c createFilesTable() function to create - the table displaying the search results. + We create the widgets to build up the UI, and we add them to a main layout + using QGridLayout. We have, however, put the \c Find and \c Quit buttons + and a stretchable space in a separate \l QHBoxLayout first, to make the + buttons appear in the \c Window widget's bottom right corner. + + Alternatively, we could have used Qt Designer to construct a UI file, + and \l {uic} to generate this code. \snippet dialogs/findfiles/window.cpp 1 - Then we add all the widgets to a main layout using QGridLayout. We - have, however, put the \c Find and \c Quit buttons and a - stretchable space in a separate QHBoxLayout first, to make the - buttons appear in the \c Window widget's bottom right corner. + We did not create a \l QMenuBar with a \uicontrol Quit menu item; but we + would still like to have a keyboard shortcut for quitting. Since we + construct a \l QShortcut with \l QKeySequence::Quit, and connect it to + \l QApplication::quit(), on most platforms it will be possible to press + Control-Q to quit (or whichever standard Quit key is configured on that platform). + (On \macos, this is redundant, because every application gets a + \uicontrol Quit menu item automatically; but it helps to make the application portable.) \snippet dialogs/findfiles/window.cpp 2 @@ -122,18 +126,16 @@ We use the directory's path to create a QDir; the QDir class provides access to directory structures and their contents. - \snippet dialogs/findfiles/window.cpp 13 - - We recursively create a list of the files (contained in the newl - created QDir) that match the specified file name. + We use QDirIterator to iterate over the files that match the + specified file name and build a QStringList of paths. Then we search through all the files in the list, using the private - \c findFiles() function, eliminating the ones that don't contain - the specified text. And finally, we display the results using the - private \c showFiles() function. + \c findFiles() function, eliminating the ones that don't contain the + specified text. We sort them (because QDirIterator did not). And finally, + we display the results using the private \c showFiles() function. If the user didn't specify any text, there is no reason to search - through the files, and we display the results immediately. + through the files, so we sort and display the results immediately. \image findfiles_progress_dialog.png Screenshot of the Progress Dialog @@ -196,7 +198,8 @@ the \c find() slot. In the \c showFiles() function we run through the provided list of file names, adding each relative file name to the first column in the table widget and retrieving the file's size using - QFileInfo for the second column. For later use, we set + QFileInfo for the second column. We use \l QLocale::formattedDataSize() + to format the file size in a human-readable form. For later use, we set the absolute path as a data on the QTableWidget using the the role absoluteFileNameRole defined to be Qt::UserRole + 1. -- cgit v1.2.3 From 3d7cdb64fca260b303b44263312af3eb65eb175e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 Dec 2017 18:13:46 -0200 Subject: qfloat16: NaN is not infinite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I39332e0a867442d58082fffd1502b7010424f0f8 Reviewed-by: André Hartmann Reviewed-by: Allan Sandfeld Jensen --- src/corelib/global/qfloat16_p.h | 4 ++-- tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qfloat16_p.h b/src/corelib/global/qfloat16_p.h index ae52e64435..f3fc96e119 100644 --- a/src/corelib/global/qfloat16_p.h +++ b/src/corelib/global/qfloat16_p.h @@ -61,9 +61,9 @@ static inline bool qt_is_inf(qfloat16 d) Q_DECL_NOTHROW bool is_inf; uchar *ch = (uchar *)&d; if (QSysInfo::ByteOrder == QSysInfo::BigEndian) - is_inf = (ch[0] & 0x7c) == 0x7c; + is_inf = (ch[0] & 0x7c) == 0x7c && (ch[0] & 0x02) == 0; else - is_inf = (ch[1] & 0x7c) == 0x7c; + is_inf = (ch[1] & 0x7c) == 0x7c && (ch[1] & 0x02) == 0; return is_inf; } diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 9bd87e3f21..6b98e3a823 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -158,12 +158,14 @@ void tst_qfloat16::qNan() qfloat16 nan = qQNaN(); QVERIFY(!(0. > nan)); QVERIFY(!(0. < nan)); + QVERIFY(!qIsInf(nan)); QVERIFY(qIsNaN(nan)); QVERIFY(qIsNaN(nan + 1.f)); QVERIFY(qIsNaN(-nan)); qfloat16 inf = qInf(); QVERIFY(inf > qfloat16(0)); QVERIFY(-inf < qfloat16(0)); + QVERIFY(!qIsNaN(inf)); QVERIFY(qIsInf(inf)); QVERIFY(qIsInf(-inf)); QVERIFY(qIsInf(2.f*inf)); -- cgit v1.2.3 From 597b96b8fa2fc8b9331db8ecc85d742be83fbec5 Mon Sep 17 00:00:00 2001 From: Joni Jantti Date: Fri, 22 Dec 2017 09:39:06 +0200 Subject: Blacklist tst_QDateTime::operator_eqeq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This autotest fails on the new Ubuntu 16.04 template with UTC timezone in the system settings. Task-number: QTBUG-65435 Change-Id: I397f01ab3fed354a4eeec8b05415226a75fce5a1 Reviewed-by: Tony Sarajärvi --- tests/auto/corelib/tools/qdatetime/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/corelib/tools/qdatetime/BLACKLIST diff --git a/tests/auto/corelib/tools/qdatetime/BLACKLIST b/tests/auto/corelib/tools/qdatetime/BLACKLIST new file mode 100644 index 0000000000..e78f5cfd87 --- /dev/null +++ b/tests/auto/corelib/tools/qdatetime/BLACKLIST @@ -0,0 +1,3 @@ +[operator_eqeq] +ubuntu-16.04 +b2qt -- cgit v1.2.3 From 0fd5fe28abd557f96b78c5b52b21efe50ec6763b Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 1 Dec 2017 14:36:48 +0100 Subject: Doc: remove Config Dialog Example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60635 Change-Id: I089f14a92f1b9c53b26200c93cac7ee3c9f26d65 Reviewed-by: Topi Reiniö Reviewed-by: Frederik Gladhorn --- .../widgets/dialogs/configdialog/configdialog.cpp | 124 ---------------- .../widgets/dialogs/configdialog/configdialog.h | 79 ---------- .../widgets/dialogs/configdialog/configdialog.pro | 12 -- .../widgets/dialogs/configdialog/configdialog.qrc | 7 - .../widgets/dialogs/configdialog/images/config.png | Bin 6758 -> 0 bytes .../widgets/dialogs/configdialog/images/query.png | Bin 2116 -> 0 bytes .../widgets/dialogs/configdialog/images/update.png | Bin 7890 -> 0 bytes examples/widgets/dialogs/configdialog/main.cpp | 63 -------- examples/widgets/dialogs/configdialog/pages.cpp | 161 --------------------- examples/widgets/dialogs/configdialog/pages.h | 74 ---------- examples/widgets/dialogs/dialogs.pro | 1 - examples/widgets/doc/src/configdialog.qdoc | 37 ----- 12 files changed, 558 deletions(-) delete mode 100644 examples/widgets/dialogs/configdialog/configdialog.cpp delete mode 100644 examples/widgets/dialogs/configdialog/configdialog.h delete mode 100644 examples/widgets/dialogs/configdialog/configdialog.pro delete mode 100644 examples/widgets/dialogs/configdialog/configdialog.qrc delete mode 100644 examples/widgets/dialogs/configdialog/images/config.png delete mode 100644 examples/widgets/dialogs/configdialog/images/query.png delete mode 100644 examples/widgets/dialogs/configdialog/images/update.png delete mode 100644 examples/widgets/dialogs/configdialog/main.cpp delete mode 100644 examples/widgets/dialogs/configdialog/pages.cpp delete mode 100644 examples/widgets/dialogs/configdialog/pages.h delete mode 100644 examples/widgets/doc/src/configdialog.qdoc diff --git a/examples/widgets/dialogs/configdialog/configdialog.cpp b/examples/widgets/dialogs/configdialog/configdialog.cpp deleted file mode 100644 index 5a0fb1c3bc..0000000000 --- a/examples/widgets/dialogs/configdialog/configdialog.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "configdialog.h" -#include "pages.h" - -ConfigDialog::ConfigDialog() -{ - contentsWidget = new QListWidget; - contentsWidget->setViewMode(QListView::IconMode); - contentsWidget->setIconSize(QSize(96, 84)); - contentsWidget->setMovement(QListView::Static); - contentsWidget->setMaximumWidth(128); - contentsWidget->setSpacing(12); - - pagesWidget = new QStackedWidget; - pagesWidget->addWidget(new ConfigurationPage); - pagesWidget->addWidget(new UpdatePage); - pagesWidget->addWidget(new QueryPage); - - QPushButton *closeButton = new QPushButton(tr("Close")); - - createIcons(); - contentsWidget->setCurrentRow(0); - - connect(closeButton, &QAbstractButton::clicked, this, &QWidget::close); - - QHBoxLayout *horizontalLayout = new QHBoxLayout; - horizontalLayout->addWidget(contentsWidget); - horizontalLayout->addWidget(pagesWidget, 1); - - QHBoxLayout *buttonsLayout = new QHBoxLayout; - buttonsLayout->addStretch(1); - buttonsLayout->addWidget(closeButton); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addLayout(horizontalLayout); - mainLayout->addStretch(1); - mainLayout->addSpacing(12); - mainLayout->addLayout(buttonsLayout); - setLayout(mainLayout); - - setWindowTitle(tr("Config Dialog")); -} - -void ConfigDialog::createIcons() -{ - QListWidgetItem *configButton = new QListWidgetItem(contentsWidget); - configButton->setIcon(QIcon(":/images/config.png")); - configButton->setText(tr("Configuration")); - configButton->setTextAlignment(Qt::AlignHCenter); - configButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - - QListWidgetItem *updateButton = new QListWidgetItem(contentsWidget); - updateButton->setIcon(QIcon(":/images/update.png")); - updateButton->setText(tr("Update")); - updateButton->setTextAlignment(Qt::AlignHCenter); - updateButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - - QListWidgetItem *queryButton = new QListWidgetItem(contentsWidget); - queryButton->setIcon(QIcon(":/images/query.png")); - queryButton->setText(tr("Query")); - queryButton->setTextAlignment(Qt::AlignHCenter); - queryButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - - connect(contentsWidget, &QListWidget::currentItemChanged, this, &ConfigDialog::changePage); -} - -void ConfigDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) -{ - if (!current) - current = previous; - - pagesWidget->setCurrentIndex(contentsWidget->row(current)); -} diff --git a/examples/widgets/dialogs/configdialog/configdialog.h b/examples/widgets/dialogs/configdialog/configdialog.h deleted file mode 100644 index c2edd204e6..0000000000 --- a/examples/widgets/dialogs/configdialog/configdialog.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include - -QT_BEGIN_NAMESPACE -class QListWidget; -class QListWidgetItem; -class QStackedWidget; -QT_END_NAMESPACE - -class ConfigDialog : public QDialog -{ - Q_OBJECT - -public: - ConfigDialog(); - -public slots: - void changePage(QListWidgetItem *current, QListWidgetItem *previous); - -private: - void createIcons(); - - QListWidget *contentsWidget; - QStackedWidget *pagesWidget; -}; - -#endif diff --git a/examples/widgets/dialogs/configdialog/configdialog.pro b/examples/widgets/dialogs/configdialog/configdialog.pro deleted file mode 100644 index 8ba55becad..0000000000 --- a/examples/widgets/dialogs/configdialog/configdialog.pro +++ /dev/null @@ -1,12 +0,0 @@ -QT += widgets - -HEADERS = configdialog.h \ - pages.h -SOURCES = configdialog.cpp \ - main.cpp \ - pages.cpp -RESOURCES += configdialog.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/configdialog -INSTALLS += target diff --git a/examples/widgets/dialogs/configdialog/configdialog.qrc b/examples/widgets/dialogs/configdialog/configdialog.qrc deleted file mode 100644 index 31d0d49666..0000000000 --- a/examples/widgets/dialogs/configdialog/configdialog.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - images/config.png - images/query.png - images/update.png - - diff --git a/examples/widgets/dialogs/configdialog/images/config.png b/examples/widgets/dialogs/configdialog/images/config.png deleted file mode 100644 index 5c14d5f470..0000000000 Binary files a/examples/widgets/dialogs/configdialog/images/config.png and /dev/null differ diff --git a/examples/widgets/dialogs/configdialog/images/query.png b/examples/widgets/dialogs/configdialog/images/query.png deleted file mode 100644 index ea9e291eeb..0000000000 Binary files a/examples/widgets/dialogs/configdialog/images/query.png and /dev/null differ diff --git a/examples/widgets/dialogs/configdialog/images/update.png b/examples/widgets/dialogs/configdialog/images/update.png deleted file mode 100644 index 3cb8ba6c77..0000000000 Binary files a/examples/widgets/dialogs/configdialog/images/update.png and /dev/null differ diff --git a/examples/widgets/dialogs/configdialog/main.cpp b/examples/widgets/dialogs/configdialog/main.cpp deleted file mode 100644 index e73474b866..0000000000 --- a/examples/widgets/dialogs/configdialog/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "configdialog.h" - -int main(int argc, char *argv[]) -{ - Q_INIT_RESOURCE(configdialog); - - QApplication app(argc, argv); - app.setApplicationDisplayName("Qt Example"); - ConfigDialog dialog; - return dialog.exec(); -} diff --git a/examples/widgets/dialogs/configdialog/pages.cpp b/examples/widgets/dialogs/configdialog/pages.cpp deleted file mode 100644 index 0c7762f029..0000000000 --- a/examples/widgets/dialogs/configdialog/pages.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "pages.h" - -ConfigurationPage::ConfigurationPage(QWidget *parent) - : QWidget(parent) -{ - QGroupBox *configGroup = new QGroupBox(tr("Server configuration")); - - QLabel *serverLabel = new QLabel(tr("Server:")); - QComboBox *serverCombo = new QComboBox; - serverCombo->addItem(tr("Qt (Australia)")); - serverCombo->addItem(tr("Qt (Germany)")); - serverCombo->addItem(tr("Qt (Norway)")); - serverCombo->addItem(tr("Qt (People's Republic of China)")); - serverCombo->addItem(tr("Qt (USA)")); - - QHBoxLayout *serverLayout = new QHBoxLayout; - serverLayout->addWidget(serverLabel); - serverLayout->addWidget(serverCombo); - - QVBoxLayout *configLayout = new QVBoxLayout; - configLayout->addLayout(serverLayout); - configGroup->setLayout(configLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(configGroup); - mainLayout->addStretch(1); - setLayout(mainLayout); -} - -UpdatePage::UpdatePage(QWidget *parent) - : QWidget(parent) -{ - QGroupBox *updateGroup = new QGroupBox(tr("Package selection")); - QCheckBox *systemCheckBox = new QCheckBox(tr("Update system")); - QCheckBox *appsCheckBox = new QCheckBox(tr("Update applications")); - QCheckBox *docsCheckBox = new QCheckBox(tr("Update documentation")); - - QGroupBox *packageGroup = new QGroupBox(tr("Existing packages")); - - QListWidget *packageList = new QListWidget; - QListWidgetItem *qtItem = new QListWidgetItem(packageList); - qtItem->setText(tr("Qt")); - QListWidgetItem *qsaItem = new QListWidgetItem(packageList); - qsaItem->setText(tr("QSA")); - QListWidgetItem *teamBuilderItem = new QListWidgetItem(packageList); - teamBuilderItem->setText(tr("Teambuilder")); - - QPushButton *startUpdateButton = new QPushButton(tr("Start update")); - - QVBoxLayout *updateLayout = new QVBoxLayout; - updateLayout->addWidget(systemCheckBox); - updateLayout->addWidget(appsCheckBox); - updateLayout->addWidget(docsCheckBox); - updateGroup->setLayout(updateLayout); - - QVBoxLayout *packageLayout = new QVBoxLayout; - packageLayout->addWidget(packageList); - packageGroup->setLayout(packageLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(updateGroup); - mainLayout->addWidget(packageGroup); - mainLayout->addSpacing(12); - mainLayout->addWidget(startUpdateButton); - mainLayout->addStretch(1); - setLayout(mainLayout); -} - -QueryPage::QueryPage(QWidget *parent) - : QWidget(parent) -{ - QGroupBox *packagesGroup = new QGroupBox(tr("Look for packages")); - - QLabel *nameLabel = new QLabel(tr("Name:")); - QLineEdit *nameEdit = new QLineEdit; - - QLabel *dateLabel = new QLabel(tr("Released after:")); - QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate()); - - QCheckBox *releasesCheckBox = new QCheckBox(tr("Releases")); - QCheckBox *upgradesCheckBox = new QCheckBox(tr("Upgrades")); - - QSpinBox *hitsSpinBox = new QSpinBox; - hitsSpinBox->setPrefix(tr("Return up to ")); - hitsSpinBox->setSuffix(tr(" results")); - hitsSpinBox->setSpecialValueText(tr("Return only the first result")); - hitsSpinBox->setMinimum(1); - hitsSpinBox->setMaximum(100); - hitsSpinBox->setSingleStep(10); - - QPushButton *startQueryButton = new QPushButton(tr("Start query")); - - QGridLayout *packagesLayout = new QGridLayout; - packagesLayout->addWidget(nameLabel, 0, 0); - packagesLayout->addWidget(nameEdit, 0, 1); - packagesLayout->addWidget(dateLabel, 1, 0); - packagesLayout->addWidget(dateEdit, 1, 1); - packagesLayout->addWidget(releasesCheckBox, 2, 0); - packagesLayout->addWidget(upgradesCheckBox, 3, 0); - packagesLayout->addWidget(hitsSpinBox, 4, 0, 1, 2); - packagesGroup->setLayout(packagesLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(packagesGroup); - mainLayout->addSpacing(12); - mainLayout->addWidget(startQueryButton); - mainLayout->addStretch(1); - setLayout(mainLayout); -} diff --git a/examples/widgets/dialogs/configdialog/pages.h b/examples/widgets/dialogs/configdialog/pages.h deleted file mode 100644 index beb7f86ae0..0000000000 --- a/examples/widgets/dialogs/configdialog/pages.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PAGES_H -#define PAGES_H - -#include - -class ConfigurationPage : public QWidget -{ -public: - ConfigurationPage(QWidget *parent = 0); -}; - -class QueryPage : public QWidget -{ -public: - QueryPage(QWidget *parent = 0); -}; - -class UpdatePage : public QWidget -{ -public: - UpdatePage(QWidget *parent = 0); -}; - -#endif diff --git a/examples/widgets/dialogs/dialogs.pro b/examples/widgets/dialogs/dialogs.pro index a29903938e..753308fc55 100644 --- a/examples/widgets/dialogs/dialogs.pro +++ b/examples/widgets/dialogs/dialogs.pro @@ -2,7 +2,6 @@ QT_FOR_CONFIG += widgets TEMPLATE = subdirs SUBDIRS = classwizard \ - configdialog \ extension \ findfiles \ licensewizard \ diff --git a/examples/widgets/doc/src/configdialog.qdoc b/examples/widgets/doc/src/configdialog.qdoc deleted file mode 100644 index 9f2cc21adb..0000000000 --- a/examples/widgets/doc/src/configdialog.qdoc +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example dialogs/configdialog - \title Config Dialog Example - \ingroup examples-dialogs - - \brief The Config Dialog examples shows how a configuration dialog can be created by - using an icon view with a stacked widget. - - \image configdialog-example.png -*/ -- cgit v1.2.3 From e548406d2820b066bdc66c1080976c7710353ae8 Mon Sep 17 00:00:00 2001 From: Joni Jantti Date: Fri, 22 Dec 2017 12:07:13 +0200 Subject: Blacklist tst_QUdpSocket on Ubuntu 16.04 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tst_QUdpSocket::broadcasting and tst_QUdpSocket::pendingDatagramSize fail on the new Ubuntu 16.04 clean template. Task-number: QTBUG-65440 Change-Id: I0e973b9c90b7c5827406bac8138370b61992a115 Reviewed-by: Tony Sarajärvi --- tests/auto/network/socket/qudpsocket/BLACKLIST | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST index 5adb05d3f2..3951be16ab 100644 --- a/tests/auto/network/socket/qudpsocket/BLACKLIST +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -22,7 +22,12 @@ osx osx [broadcasting] osx +ubuntu-16.04 [zeroLengthDatagram] osx [linkLocalIPv6] redhatenterpriselinuxworkstation-6.6 +[pendingDatagramSize] +ubuntu-16.04 +[readyReadForEmptyDatagram] +ubuntu-16.04 -- cgit v1.2.3 From 6f7b64e2a97034f84991e644abd609e73895ffb9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 26 Dec 2017 23:39:33 -0200 Subject: QMap: fix another UB (invalid cast) relating to QMap's end Like in commit 75cdf654bcc192ba73a8834e507583a59140e7e4, we use the pointer value of the QMap header (which is of type QMapNodeBase) as a sentinel. It's never dereferenced. In that commit, the issue was calling end() directly; in here, it happens when iterating forward from any element, which means nextNode() can reach back to the header. However, using static_cast is wrong, so we use reinterpret_cast. Change-Id: I39332e0a867442d58082fffd15040317704a87ce Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 37ed24000d..43acf09ea9 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -115,9 +115,9 @@ struct QMapNode : public QMapNodeBase inline QMapNode *leftNode() const { return static_cast(left); } inline QMapNode *rightNode() const { return static_cast(right); } - inline const QMapNode *nextNode() const { return static_cast(QMapNodeBase::nextNode()); } + inline const QMapNode *nextNode() const { return reinterpret_cast(QMapNodeBase::nextNode()); } inline const QMapNode *previousNode() const { return static_cast(QMapNodeBase::previousNode()); } - inline QMapNode *nextNode() { return static_cast(QMapNodeBase::nextNode()); } + inline QMapNode *nextNode() { return reinterpret_cast(QMapNodeBase::nextNode()); } inline QMapNode *previousNode() { return static_cast(QMapNodeBase::previousNode()); } QMapNode *copy(QMapData *d) const; -- cgit v1.2.3 From 44da5b863597e761df3545dc7ff02a9b53bbb13d Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 27 Dec 2017 12:42:26 -0800 Subject: Allow moc to handle Unicode output filenames on Windows with MSVC The C standard library functions cannot handle UTF-8 filenames. Instead, we need to use the wide-character versions which accept UTF-16 input. Task-number: QTBUG-65492 Change-Id: If4b3b4eeeec4f3bbb428b8f6b0311a65d01463b0 Reviewed-by: Thiago Macieira --- src/tools/moc/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 98cc9652ab..dfcc23f0d6 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -486,8 +486,8 @@ int runMoc(int argc, char **argv) // 3. and output meta object code if (output.size()) { // output file specified -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (fopen_s(&out, QFile::encodeName(output).constData(), "w")) +#if defined(_MSC_VER) + if (_wfopen_s(&out, reinterpret_cast(output.utf16()), L"w") != 0) #else out = fopen(QFile::encodeName(output).constData(), "w"); // create output file if (!out) -- cgit v1.2.3 From 656804b9645a83430dcd0929c49b4065d43d7990 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 21 Dec 2017 10:38:19 -0200 Subject: qrandom.h: actually #undef min and max instead of using parentheses Putting parentheses around the call to (std::numeric_limits::min)() works, but the trick cannot apply to the min() function declaration on the same line. So we really need to #undef. I hope no one after the 1990s still needs these macros. Task-number: QTBUG-65414 Change-Id: I39332e0a867442d58082fffd15024f8edb293311 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll Reviewed-by: Timur Pocheptsov --- src/corelib/global/qrandom.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index cbeab19a7b..46d3e0e152 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -44,6 +44,13 @@ #include // for std::generate #include // for std::mt19937 +#ifdef min +# undef min +#endif +#ifdef max +# undef max +#endif + QT_BEGIN_NAMESPACE class QRandomGenerator @@ -160,8 +167,8 @@ public: void seed(quint32 s = 1) { *this = { s }; } void seed(std::seed_seq &sseq) Q_DECL_NOTHROW { *this = { sseq }; } Q_CORE_EXPORT void discard(unsigned long long z); - static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } - static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } + static Q_DECL_CONSTEXPR result_type min() { return std::numeric_limits::min(); } + static Q_DECL_CONSTEXPR result_type max() { return std::numeric_limits::max(); } static inline Q_DECL_CONST_FUNCTION QRandomGenerator *system(); static inline Q_DECL_CONST_FUNCTION QRandomGenerator *global(); @@ -236,8 +243,8 @@ public: QRandomGenerator::discard(z * 2); } - static Q_DECL_CONSTEXPR result_type min() { return (std::numeric_limits::min)(); } - static Q_DECL_CONSTEXPR result_type max() { return (std::numeric_limits::max)(); } + static Q_DECL_CONSTEXPR result_type min() { return std::numeric_limits::min(); } + static Q_DECL_CONSTEXPR result_type max() { return std::numeric_limits::max(); } static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *system(); static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *global(); static Q_CORE_EXPORT QRandomGenerator64 securelySeeded(); -- cgit v1.2.3 From 198c59dbce63e97ef0fa8f75236ee8b2887997c2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Nov 2017 16:49:00 -0800 Subject: tst_QUdpSocket: always use an interface when binding to IPv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Binding without an interface and expecting the OS to select something is not supported in all OSes. On FreeBSD, I keep getting EADDRNOTAVAIL. So modify our test to only join, leave and send to multicast groups with an interface selection. With this, all tests either pass or are skipped for me on Linux, FreeBSD, and macOS. On Windows, this revealed an inconsistency in behavior, which this commit adds a workaround for. Change-Id: Ifb5969bf206e4cd7b14efffd14fb6815456494d2 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/socket/qnativesocketengine_win.cpp | 26 ++++++++++++++- src/network/socket/qudpsocket.cpp | 10 ++++++ tests/auto/network/socket/qudpsocket/BLACKLIST | 2 -- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 39 +++++++++++++++++++--- 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 747fdeb967..6a091209be 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1319,6 +1319,9 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l setPortAndAddress(header.destinationPort, header.destinationAddress, &aa, &msg.namelen); + uint oldIfIndex = 0; + bool mustSetIpv6MulticastIf = false; + if (msg.namelen == sizeof(aa.a6)) { // sending IPv6 if (header.hopLimit != -1) { @@ -1330,7 +1333,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l cmsgptr = reinterpret_cast(reinterpret_cast(cmsgptr) + WSA_CMSG_SPACE(sizeof(int))); } - if (header.ifindex != 0 || !header.senderAddress.isNull()) { + if (!header.senderAddress.isNull()) { struct in6_pktinfo *data = reinterpret_cast(WSA_CMSG_DATA(cmsgptr)); memset(data, 0, sizeof(*data)); msg.Control.len += WSA_CMSG_SPACE(sizeof(*data)); @@ -1343,6 +1346,21 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l memcpy(&data->ipi6_addr, &tmp, sizeof(tmp)); cmsgptr = reinterpret_cast(reinterpret_cast(cmsgptr) + WSA_CMSG_SPACE(sizeof(*data))); + } else if (header.ifindex != 0) { + // Unlike other operating systems, setting the interface index in the in6_pktinfo + // structure above and leaving the ipi6_addr set to :: will cause the packets to be + // sent with source address ::. So we have to use IPV6_MULTICAST_IF, which MSDN is + // quite clear that "This option does not change the default interface for receiving + // IPv6 multicast traffic." + QT_SOCKOPTLEN_T len = sizeof(oldIfIndex); + if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, + reinterpret_cast(&oldIfIndex), &len) == -1 + || ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, + reinterpret_cast(&header.ifindex), sizeof(header.ifindex)) == -1) { + setError(QAbstractSocket::NetworkError, SendDatagramErrorString); + return -1; + } + mustSetIpv6MulticastIf = true; } } else { // sending IPv4 @@ -1396,6 +1414,12 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l ret = qint64(bytesSent); } + if (mustSetIpv6MulticastIf) { + // undo what we did above + ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, + reinterpret_cast(&oldIfIndex), sizeof(oldIfIndex)); + } + #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data, qt_prettyDebug(data, qMin(len, 16), len).data(), len, diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index 79629a07f2..85c4f4cbfd 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -185,6 +185,10 @@ QUdpSocket::~QUdpSocket() This function returns \c true if successful; otherwise it returns \c false and sets the socket error accordingly. + \note Joining IPv6 multicast groups without an interface selection is not + supported in all operating systems. Consider using the overload where the + interface is specified. + \sa leaveMulticastGroup() */ bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress) @@ -219,6 +223,9 @@ bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress, This function returns \c true if successful; otherwise it returns \c false and sets the socket error accordingly. + \note This function should be called with the same arguments as were passed + to joinMulticastGroup(). + \sa joinMulticastGroup() */ bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress) @@ -233,6 +240,9 @@ bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress) Leaves the multicast group specified by \a groupAddress on the interface \a iface. + \note This function should be called with the same arguments as were passed + to joinMulticastGroup(). + \sa joinMulticastGroup() */ bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress, diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST index dcb5f87628..5b8d4f1e34 100644 --- a/tests/auto/network/socket/qudpsocket/BLACKLIST +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -1,5 +1,3 @@ -[multicast] -osx [writeDatagramToNonExistingPeer] windows osx diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 69d549d738..5fdf014fc6 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -122,6 +122,7 @@ private: #ifdef SHOULD_CHECK_SYSCALL_SUPPORT bool ipv6SetsockoptionMissing(int level, int optname); #endif + QNetworkInterface interfaceForGroup(const QHostAddress &multicastGroup); bool m_skipUnsupportedIPv6Tests; QList allAddresses; @@ -167,6 +168,33 @@ bool tst_QUdpSocket::shouldSkipIpv6TestsForBrokenSetsockopt() return false; } +QNetworkInterface tst_QUdpSocket::interfaceForGroup(const QHostAddress &multicastGroup) +{ + if (multicastGroup.protocol() == QAbstractSocket::IPv4Protocol) + return QNetworkInterface(); + + static QNetworkInterface ipv6if = [=]() { + // find any link local address in the allAddress list + for (const QHostAddress &addr: qAsConst(allAddresses)) { + if (addr.isLoopback()) + continue; + + QString scope = addr.scopeId(); + if (!scope.isEmpty()) { + QNetworkInterface iface = QNetworkInterface::interfaceFromName(scope); + qDebug() << "Will bind IPv6 sockets to" << iface; + return iface; + } + } + + qWarning("interfaceForGroup(%s) could not find any link-local IPv6 address! " + "Make sure this test is behind a check of QtNetworkSettings::hasIPv6().", + qUtf8Printable(multicastGroup.toString())); + return QNetworkInterface(); + }(); + return ipv6if; +} + static QHostAddress makeNonAny(const QHostAddress &address, QHostAddress::SpecialAddress preferForAny = QHostAddress::LocalHost) { if (address == QHostAddress::Any) @@ -1299,7 +1327,7 @@ void tst_QUdpSocket::multicastLeaveAfterClose() bindAddress = QHostAddress::AnyIPv6; QVERIFY2(udpSocket.bind(bindAddress, 0), qPrintable(udpSocket.errorString())); - QVERIFY2(udpSocket.joinMulticastGroup(groupAddress), + QVERIFY2(udpSocket.joinMulticastGroup(groupAddress, interfaceForGroup(groupAddress)), qPrintable(udpSocket.errorString())); udpSocket.close(); QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::leaveMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); @@ -1413,7 +1441,7 @@ void tst_QUdpSocket::multicast() "QAbstractSocket: cannot bind to QHostAddress::Any (or an IPv6 address) and join an IPv4 multicast group;" " bind to QHostAddress::AnyIPv4 instead if you want to do this"); } - QVERIFY2(receiver.joinMulticastGroup(groupAddress) == joinResult, + QVERIFY2(receiver.joinMulticastGroup(groupAddress, interfaceForGroup(groupAddress)) == joinResult, qPrintable(receiver.errorString())); if (!joinResult) return; @@ -1427,7 +1455,9 @@ void tst_QUdpSocket::multicast() QUdpSocket sender; sender.bind(); foreach (const QByteArray &datagram, datagrams) { - QCOMPARE(int(sender.writeDatagram(datagram, groupAddress, receiver.localPort())), + QNetworkDatagram dgram(datagram, groupAddress, receiver.localPort()); + dgram.setInterfaceIndex(interfaceForGroup(groupAddress).index()); + QCOMPARE(int(sender.writeDatagram(dgram)), int(datagram.size())); } @@ -1452,7 +1482,8 @@ void tst_QUdpSocket::multicast() } QCOMPARE(receivedDatagrams, datagrams); - QVERIFY2(receiver.leaveMulticastGroup(groupAddress), qPrintable(receiver.errorString())); + QVERIFY2(receiver.leaveMulticastGroup(groupAddress, interfaceForGroup(groupAddress)), + qPrintable(receiver.errorString())); } void tst_QUdpSocket::echo_data() -- cgit v1.2.3 From dd61a1d98ea9fbffeaf0e2adcd0ddd58105f6a75 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 29 Nov 2017 10:18:01 -0800 Subject: tst_QUdpSocket: add some tests for link-local IPv6 multicasting Unlike higher scopes (like scope 4, admin-local, which the last commit used), scopes 1 and 2 require a scope in order to bind, even if some operating systems are lenient. So test that we are able to bind to them and do bind properly. Change-Id: Ifb5969bf206e4cd7b14efffd14fba153eab965b9 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 5fdf014fc6..4e800dfd63 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -127,6 +127,7 @@ private: bool m_skipUnsupportedIPv6Tests; QList allAddresses; QHostAddress multicastGroup4, multicastGroup6; + QVector linklocalMulticastGroups; QUdpSocket *m_asyncSender; QUdpSocket *m_asyncReceiver; }; @@ -173,6 +174,10 @@ QNetworkInterface tst_QUdpSocket::interfaceForGroup(const QHostAddress &multicas if (multicastGroup.protocol() == QAbstractSocket::IPv4Protocol) return QNetworkInterface(); + QString scope = multicastGroup.scopeId(); + if (!scope.isEmpty()) + return QNetworkInterface::interfaceFromName(scope); + static QNetworkInterface ipv6if = [=]() { // find any link local address in the allAddress list for (const QHostAddress &addr: qAsConst(allAddresses)) { @@ -250,7 +255,19 @@ void tst_QUdpSocket::initTestCase() // 239.0.0.0/8 is "Organization-Local Scope" multicastGroup4.setAddress((239U << 24) | (r[1] & 0xffffff)); - qDebug() << "Will use multicast groups" << multicastGroup4 << multicastGroup6; + // figure out some link-local IPv6 multicast groups + // ff12:: is temporary, not prefix-based, link-local + r[0] = qToBigEndian(Q_UINT64_C(0xff12) << 48); + QHostAddress llbase(*reinterpret_cast(&r)); + for (const QHostAddress &a : qAsConst(allAddresses)) { + QString scope = a.scopeId(); + if (scope.isEmpty()) + continue; + llbase.setScopeId(scope); + linklocalMulticastGroups << llbase; + } + + qDebug() << "Will use multicast groups" << multicastGroup4 << multicastGroup6 << linklocalMulticastGroups; if (EmulationDetector::isRunningArmOnX86()) QSKIP("This test is unreliable due to QEMU emulation shortcomings."); @@ -1279,6 +1296,8 @@ void tst_QUdpSocket::multicastJoinBeforeBind_data() QTest::newRow("valid ipv4 group address") << multicastGroup4; QTest::newRow("invalid ipv4 group address") << QHostAddress(QHostAddress::Broadcast); QTest::newRow("valid ipv6 group address") << multicastGroup6; + for (const QHostAddress &a : qAsConst(linklocalMulticastGroups)) + QTest::addRow("valid ipv6 %s-link group address", a.scopeId().toLatin1().constData()) << a; QTest::newRow("invalid ipv6 group address") << QHostAddress(QHostAddress::AnyIPv6); } @@ -1300,6 +1319,8 @@ void tst_QUdpSocket::multicastLeaveAfterClose_data() QTest::addColumn("groupAddress"); QTest::newRow("ipv4") << multicastGroup4; QTest::newRow("ipv6") << multicastGroup6; + for (const QHostAddress &a : qAsConst(linklocalMulticastGroups)) + QTest::addRow("ipv6-link-%s", a.scopeId().toLatin1().constData()) << a; } void tst_QUdpSocket::multicastLeaveAfterClose() @@ -1398,9 +1419,15 @@ void tst_QUdpSocket::multicast_data() QTest::newRow("valid bind, group ipv4 address") << anyAddress << true << groupAddress << true; QTest::newRow("valid bind, invalid group ipv4 address") << anyAddress << true << anyAddress << false; QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; + for (const QHostAddress &a : qAsConst(linklocalMulticastGroups)) + QTest::addRow("valid bind, %s-link group ipv6 address", a.scopeId().toLatin1().constData()) + << any6Address << true << a << true; QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; QTest::newRow("dual bind, group ipv4 address") << dualAddress << true << groupAddress << false; QTest::newRow("dual bind, group ipv6 address") << dualAddress << true << group6Address << true; + for (const QHostAddress &a : qAsConst(linklocalMulticastGroups)) + QTest::addRow("dual bind, %s-link group ipv6 address", a.scopeId().toLatin1().constData()) + << dualAddress << true << a << true; } void tst_QUdpSocket::multicast() -- cgit v1.2.3 From 52b85212a2ec8ec5bf187f6cd00b669a45bcf0bd Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 7 Dec 2017 16:01:48 +0100 Subject: sqlite: Check that there are values to be set when binding If the values vector is empty then we know already that the paramCount will still be invalid, so we should just accept that and not check the reused named placeholders. Task-number: QTBUG-64923 Change-Id: Ifaa755540c4574f1f76d3f9f129bf0f66b837b70 Reviewed-by: Edward Welbourne --- src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index e9f5ee9508..67dd1a6ee5 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -467,7 +467,7 @@ bool QSQLiteResult::exec() #if (SQLITE_VERSION_NUMBER >= 3003011) // In the case of the reuse of a named placeholder - if (!paramCountIsValid) { + if (paramCount < values.count()) { const auto countIndexes = [](int counter, const QList& indexList) { return counter + indexList.length(); }; -- cgit v1.2.3