From f43e947dc405b6a2324656f631c804db8e8dec3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Thu, 26 Jul 2018 16:03:50 +0200 Subject: [PATCH 01/39] QJsonDocument: Make emptyObject an object A default-constructed QJsonObject has no data payload, it is only a pair of null pointers. So, when it becomes necessary to 'materialize' such an object, a special global emptyObject constant is used as the substitute payload. There is a small problem with this global constant though, namely that it's is_object flag is unset. In other words, the emptyObject is not an object, but an array. Fix by setting the is_object flag on emptyObject. The example code in the bug report QJsonObject parent; QJsonObject child; parent["child"] = child; // 1 child = parent["child"].toObject(); // 2 child["test"] = "test"; // 3 runs into this problem on line 1. Inserting the default-constructed child means inserting a copy of emptyObject. On line 2 a pointer to this copy of emptyObject is retrieved and cast to an object. But it's not an object, it's an array, so things go wrong hereafter. Specifically, on line 3, two inserts are performed, one from operator[] and one from operator=. Each insert increments a compaction counter. The second insert triggers compaction (QJsonObject::insert calls Value::requiredStorage calls Data::compact) and compaction branches based on the is_object flag. Replacing line 3 with child.insert("test", "test"); causes the example to appear to work since compaction is not triggered and the JSON serializer does not look at the is_object flag. Still, any further insert() calls would trigger compaction and memory corruption. Task-number: QTBUG-69626 Change-Id: I8bd5174dce95998bac479c4b4ffea70bca1a4d04 Reviewed-by: Lars Knoll --- src/corelib/serialization/qjson.cpp | 2 +- tests/auto/corelib/serialization/json/tst_qtjson.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index 7912b5040c2..b82923fe0c3 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -46,7 +46,7 @@ namespace QJsonPrivate { static Q_CONSTEXPR Base emptyArray = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } }; -static Q_CONSTEXPR Base emptyObject = { { qle_uint(sizeof(Base)) }, { 0 }, { qle_uint(0) } }; +static Q_CONSTEXPR Base emptyObject = { { qle_uint(sizeof(Base)) }, { qToLittleEndian(1u) }, { qle_uint(0) } }; void Data::compact() { diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 41c8f760dc2..4651258ef35 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -648,6 +648,7 @@ void tst_QtJson::testArrayNestedEmpty() object.insert("inner", inner); QJsonValue val = object.value("inner"); QJsonArray value = object.value("inner").toArray(); + QVERIFY(QJsonDocument(value).isArray()); QCOMPARE(value.size(), 0); QCOMPARE(value, inner); QCOMPARE(value.size(), 0); @@ -666,6 +667,7 @@ void tst_QtJson::testObjectNestedEmpty() object.insert("inner", inner); object.insert("inner2", inner2); QJsonObject value = object.value("inner").toObject(); + QVERIFY(QJsonDocument(value).isObject()); QCOMPARE(value.size(), 0); QCOMPARE(value, inner); QCOMPARE(value.size(), 0); From 2dfa41e0eac65f5772ec61364f9afd0ce49fecc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 30 Jul 2018 17:16:01 +0200 Subject: [PATCH 02/39] Return to eventloop after emitting encrypted When the connection has been encrypted we will, in QHttpNetworkConnectionChannel::_q_encrypted, emit 'reply->encrypted' in which user slots can be called. In the event that the user calls abort it will, however, not abort until the next time it goes back to the event loop (which might not happen until after the request has already been sent). Task-number: QTBUG-65960 Change-Id: I96865f83c47f89deb9f644c86a71948dbb0ec0d0 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- .../access/qhttpnetworkconnectionchannel.cpp | 16 +++++++++- .../access/qhttpnetworkconnectionchannel_p.h | 1 + .../qnetworkreply/tst_qnetworkreply.cpp | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 0ac14c78f69..5726925cb03 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -251,6 +251,20 @@ bool QHttpNetworkConnectionChannel::sendRequest() return protocolHandler->sendRequest(); } +/* + * Invoke "protocolHandler->sendRequest" using a queued connection. + * It's used to return to the event loop before invoking sendRequest when + * there's a very real chance that the request could have been aborted + * (i.e. after having emitted 'encrypted'). + */ +void QHttpNetworkConnectionChannel::sendRequestDelayed() +{ + QMetaObject::invokeMethod(this, [this] { + Q_ASSERT(!protocolHandler.isNull()); + if (reply) + protocolHandler->sendRequest(); + }, Qt::ConnectionType::QueuedConnection); +} void QHttpNetworkConnectionChannel::_q_receiveReply() { @@ -1234,7 +1248,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted() emit reply->encrypted(); } if (reply) - sendRequest(); + sendRequestDelayed(); } } diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index e9cdae56533..270b3eb9ba6 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -174,6 +174,7 @@ public: void abort(); bool sendRequest(); + void sendRequestDelayed(); bool ensureConnection(); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 0ef3dc0b614..9c77e156d70 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -392,6 +392,7 @@ private Q_SLOTS: void ignoreSslErrorsListWithSlot_data(); void ignoreSslErrorsListWithSlot(); void encrypted(); + void abortOnEncrypted(); void sslConfiguration_data(); void sslConfiguration(); #ifdef QT_BUILD_INTERNAL @@ -6244,6 +6245,37 @@ void tst_QNetworkReply::encrypted() reply->deleteLater(); } +void tst_QNetworkReply::abortOnEncrypted() +{ + SslServer server; + server.listen(); + if (!server.isListening()) + QSKIP("Server fails to listen. Skipping since QTcpServer is covered in another test."); + + server.connect(&server, &SslServer::newEncryptedConnection, [&server]() { + connect(server.socket, &QTcpSocket::readyRead, server.socket, []() { + // This slot must not be invoked! + QVERIFY(false); + }); + }); + + QNetworkAccessManager nm; + QNetworkReply *reply = nm.get(QNetworkRequest(QUrl(QString("https://localhost:%1").arg(server.serverPort())))); + reply->ignoreSslErrors(); + + connect(reply, &QNetworkReply::encrypted, [reply, &nm]() { + reply->abort(); + nm.clearConnectionCache(); + }); + + QSignalSpy spyEncrypted(reply, &QNetworkReply::encrypted); + QTRY_COMPARE(spyEncrypted.count(), 1); + + // Wait for the socket to be closed again in order to be sure QTcpSocket::readyRead would have been emitted. + QTRY_VERIFY(server.socket != nullptr); + QTRY_COMPARE(server.socket->state(), QAbstractSocket::UnconnectedState); +} + void tst_QNetworkReply::sslConfiguration() { QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/index.html")); From 9a30a8f4fc19a90835e4d1032f9ab753ff3b2ae6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 30 Jul 2018 17:43:05 +0200 Subject: [PATCH 03/39] Link from QLocale to where date-time formats are explained QLocale has various methods that deal in date-time formats, which may be supplied as strings; but does not document the form of a format string. That's documented in QDate, QTime and QDateTime, so link to them for the details. Task-number: QTBUG-23307 Change-Id: I6347d80a87dc03f6a4065e3d5bf4d535f05af93f Reviewed-by: Thiago Macieira --- src/corelib/tools/qlocale.cpp | 12 ++++++++++++ src/corelib/tools/qlocale.qdoc | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 00a2c05c35a..89896cdc608 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1773,6 +1773,8 @@ QString QLocale::toString(qulonglong i) const Returns a localized string representation of the given \a date in the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QDate::toString() */ QString QLocale::toString(const QDate &date, const QString &format) const @@ -1787,6 +1789,8 @@ QString QLocale::toString(const QDate &date, const QString &format) const Returns a localized string representation of the given \a date in the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QDate::toString() */ QString QLocale::toString(const QDate &date, QStringView format) const { @@ -1839,6 +1843,8 @@ static bool timeFormatContainsAP(QStringView format) Returns a localized string representation of the given \a time according to the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QTime::toString() */ QString QLocale::toString(const QTime &time, const QString &format) const { @@ -1852,6 +1858,8 @@ QString QLocale::toString(const QTime &time, const QString &format) const Returns a localized string representation of the given \a time according to the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QTime::toString() */ QString QLocale::toString(const QTime &time, QStringView format) const { @@ -1865,6 +1873,8 @@ QString QLocale::toString(const QTime &time, QStringView format) const Returns a localized string representation of the given \a dateTime according to the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QDateTime::toString(), QDate::toString(), QTime::toString() */ QString QLocale::toString(const QDateTime &dateTime, const QString &format) const @@ -1879,6 +1889,8 @@ QString QLocale::toString(const QDateTime &dateTime, const QString &format) cons Returns a localized string representation of the given \a dateTime according to the specified \a format. If \a format is an empty string, an empty string is returned. + + \sa QDateTime::toString(), QDate::toString(), QTime::toString() */ QString QLocale::toString(const QDateTime &dateTime, QStringView format) const { diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index ed3eb933134..c23e4e34395 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -939,6 +939,8 @@ locale doesn't support narrow names, so you should avoid using it for date formatting. Also, for the system locale this format is the same as ShortFormat. + + \sa QDateTime::toString(), QDate::toString(), QTime::toString() */ /*! @@ -1103,6 +1105,8 @@ \value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator. \value NativeLanguageName a string that represents the name of the native language. \value NativeCountryName a string that represents the name of the native country. + + \sa FormatType */ /*! From 6a1c26b08a56cd71315fcbbf2743c32072d806d2 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 16 Jul 2018 09:45:48 +0200 Subject: [PATCH 04/39] Doc: Update signals and slots introduction page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use this as context in connect to functors/lambdas. Add description of the use of context in connects. Update the simple example to make it slightly less confusing for (new) readers. Task-number: QTBUG-69483 Change-Id: Ibbbe98c4282cea4ebd860b1d174871559b7f195b Reviewed-by: Topi Reiniö --- .../doc/src/objectmodel/signalsandslots.qdoc | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc index 6d3064d2177..213caa6c59e 100644 --- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc +++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc @@ -246,18 +246,20 @@ If you pass the Qt::UniqueConnection \a type, the connection will only be made if it is not a duplicate. If there is already a duplicate (exact same signal to the exact same slot on the same objects), - the connection will fail and connect will return false + the connection will fail and connect will return \c false. This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple - QObject::connect() function calls, or with \c{uic}'s - \l{Automatic Connections}{automatic connections} feature. + QObject::connect() function calls, or with \l{User Interface Compiler + (uic)}{uic}'s \l{Automatic Connections}{automatic connections} feature. \section1 A Real Example - Here is a simple commented example of a widget. + The following is an example of the header of a simple widget class without + member functions. The purpose is to show how you can utilize signals and + slots in your own applications. \snippet signalsandslots/lcdnumber.h 0 \snippet signalsandslots/lcdnumber.h 1 @@ -281,19 +283,13 @@ \snippet signalsandslots/lcdnumber.h 6 \snippet signalsandslots/lcdnumber.h 7 - - It's not obviously relevant to the moc, but if you inherit - QWidget you almost certainly want to have the \c parent argument - in your constructor and pass it to the base class's constructor. - - Some destructors and member functions are omitted here; the \c - moc ignores member functions. - + \codeline \snippet signalsandslots/lcdnumber.h 8 \snippet signalsandslots/lcdnumber.h 9 - \c LcdNumber emits a signal when it is asked to show an impossible - value. + After the class constructor and \c public members, we declare the class + \c signals. The \c LcdNumber class emits a signal, \c overflow(), when it + is asked to show an impossible value. If you don't care about overflow, or you know that overflow cannot occur, you can ignore the \c overflow() signal, i.e. don't @@ -325,8 +321,8 @@ callbacks, you'd have to find five different names and keep track of the types yourself. - Some irrelevant member functions have been omitted from this - example. + \sa QLCDNumber, QObject::connect(), {Digital Clock Example}, and + {Tetrix Example}. \section1 Signals And Slots With Default Arguments @@ -361,16 +357,24 @@ You can also connect to functors or C++11 lambdas: \code - connect(sender, &QObject::destroyed, [=](){ this->m_objects.remove(sender); }); + connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); }); \endcode + In both these cases, we provide \a this as context in the call to connect(). + The context object provides information about in which thread the receiver + should be executed. This is important, as providing the context ensures + that the receiver is executed in the context thread. + + The lambda will be disconnected when the sender or context is destroyed. + You should take care that any objects used inside the functor are still + alive when the signal is emitted. + The other way to connect a signal to a slot is to use QObject::connect() and the \c{SIGNAL} and \c{SLOT} macros. - The rule about whether to - include arguments or not in the \c{SIGNAL()} and \c{SLOT()} - macros, if the arguments have default values, is that the - signature passed to the \c{SIGNAL()} macro must \e not have fewer - arguments than the signature passed to the \c{SLOT()} macro. + The rule about whether to include arguments or not in the \c{SIGNAL()} and + \c{SLOT()} macros, if the arguments have default values, is that the + signature passed to the \c{SIGNAL()} macro must \e not have fewer arguments + than the signature passed to the \c{SLOT()} macro. All of these would work: \code From 341d967068516ff850227f718eaff46530cd97c2 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 30 Jul 2018 10:44:51 +0200 Subject: [PATCH 05/39] Doc: Fix broken links after page rename The title of the external page 'Creating a Mobile Application' in the Qt Creator docs has changed to include a space between 'Qt' and 'Creator'. This caused the filename to change, thus breaking the incoming links from the Qt for (iOS|Android) Examples pages. Task-number: QTBUG-69678 Change-Id: I7819a9e2b483bc760af5bb636841bccf0c6cb739 Reviewed-by: Nico Vertriest --- doc/global/externalsites/qtcreator.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc index d70f35b04ca..98a5c9f12bc 100644 --- a/doc/global/externalsites/qtcreator.qdoc +++ b/doc/global/externalsites/qtcreator.qdoc @@ -520,7 +520,7 @@ \title Qt Creator: Adding Debuggers */ /*! - \externalpage http://doc.qt.io/qtcreator/qtcreator-accelbubble-example.html + \externalpage http://doc.qt.io/qtcreator/qt-creator-accelbubble-example.html \title Qt Creator: Creating a Mobile Application */ /*! From e386cd03d12e401b9e3945602e9621a86009fa11 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 31 Jul 2018 12:13:25 +0200 Subject: [PATCH 06/39] Doc: Remove reference to QTestEvent QTestEventList refers to QTestEvent, which is an implementation detail that should not appear in documentation. Task-number: QTBUG-68109 Change-Id: Id132889427b757ea17165c8b15ed47bcfb9e1c3f Reviewed-by: Mitch Curtis --- src/testlib/qtestevent.qdoc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/testlib/qtestevent.qdoc b/src/testlib/qtestevent.qdoc index a1180171075..f0d3bff1621 100644 --- a/src/testlib/qtestevent.qdoc +++ b/src/testlib/qtestevent.qdoc @@ -31,12 +31,10 @@ \brief The QTestEventList class provides a list of GUI events. - QTestEventList inherits from QList, and provides - convenience functions for populating the list. - A QTestEventList can be populated with GUI events that can be stored as test data for later usage, or be replayed on any - QWidget. + QWidget. QTestEventList provides convenience functions for populating + the list. Example: \snippet code/doc_src_qtestevent.cpp 0 @@ -174,4 +172,3 @@ \sa QTest::mousePress() */ - From 46fc3d3729df9e81e42f87c46907d6eb81a0c669 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Jul 2018 09:09:03 +0200 Subject: [PATCH 07/39] Windows QPA: Fix override cursor being cleared when crossing window borders Override cursors can be modified externally when for example crossing window borders. Add helper function to enforce the cursor again to QWindowsWindow::applyCursor() which is called for enter events. Task-number: QTBUG-69637 Change-Id: Ibea4da9f2aac81377002b626daae64b1102f6c2b Reviewed-by: Andre de la Rocha Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 16 +++++++++++++--- src/plugins/platforms/windows/qwindowscursor.h | 4 +++- src/plugins/platforms/windows/qwindowswindow.cpp | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index e1a58372018..72155a1d1b4 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -549,6 +549,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) } HCURSOR QWindowsCursor::m_overriddenCursor = nullptr; +HCURSOR QWindowsCursor::m_overrideCursor = nullptr; /*! \brief Return cached pixmap cursor or create new one. @@ -621,11 +622,20 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } } +// QTBUG-69637: Override cursors can get reset externally when moving across +// window borders. Enforce the cursor again (to be called from enter event). +void QWindowsCursor::enforceOverrideCursor() +{ + if (hasOverrideCursor() && m_overrideCursor != GetCursor()) + SetCursor(m_overrideCursor); +} + void QWindowsCursor::setOverrideCursor(const QCursor &cursor) { const CursorHandlePtr wcursor = cursorHandle(cursor); - if (wcursor->handle()) { - const HCURSOR previousCursor = SetCursor(wcursor->handle()); + if (const auto overrideCursor = wcursor->handle()) { + m_overrideCursor = overrideCursor; + const HCURSOR previousCursor = SetCursor(overrideCursor); if (m_overriddenCursor == nullptr) m_overriddenCursor = previousCursor; } else { @@ -638,7 +648,7 @@ void QWindowsCursor::clearOverrideCursor() { if (m_overriddenCursor) { SetCursor(m_overriddenCursor); - m_overriddenCursor = nullptr; + m_overriddenCursor = m_overrideCursor = nullptr; } } diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 53f185358b4..345f47597e0 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -107,7 +107,8 @@ public: void changeCursor(QCursor * widgetCursor, QWindow * widget) override; void setOverrideCursor(const QCursor &cursor) override; void clearOverrideCursor() override; - bool hasOverrideCursor() const { return m_overriddenCursor != nullptr; } + static void enforceOverrideCursor(); + static bool hasOverrideCursor() { return m_overriddenCursor != nullptr; } QPoint pos() const override; void setPos(const QPoint &pos) override; @@ -143,6 +144,7 @@ private: mutable QPixmap m_ignoreDragCursor; static HCURSOR m_overriddenCursor; + static HCURSOR m_overrideCursor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 3909c64c539..aa40d422fbf 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2419,8 +2419,11 @@ static inline bool applyNewCursor(const QWindow *w) void QWindowsWindow::applyCursor() { - if (static_cast(screen()->cursor())->hasOverrideCursor()) + if (QWindowsCursor::hasOverrideCursor()) { + if (isTopLevel()) + QWindowsCursor::enforceOverrideCursor(); return; + } #ifndef QT_NO_CURSOR if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel. if (const QWindow *p = window()->parent()) { From d3cbabcc6dd1c0162e01214b25631332566354bd Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Wed, 1 Aug 2018 07:59:45 +0200 Subject: [PATCH 08/39] QDeadlineTimer: Fix documentation typo Change-Id: If8f7766ca0698a3defdf9c59c44fb02a8a5b3b62 Reviewed-by: Martin Smith --- src/corelib/kernel/qdeadlinetimer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 4b9a946dd84..8a5bd5d6811 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -224,7 +224,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW Constructs a QDeadlineTimer object with a deadline at \a deadline time point, converting from the clock source \c{Clock} to Qt's internal clock - source (see QElapsedTimer::clcokType()). + source (see QElapsedTimer::clockType()). If \a deadline is in the past, this QDeadlineTimer object is set to expired, whereas if \a deadline is equal to \c{Duration::max()}, then this @@ -267,7 +267,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW Sets this QDeadlineTimer to the deadline marked by \a deadline time point, converting from the clock source \c{Clock} to Qt's internal clock - source (see QElapsedTimer::clcokType()). + source (see QElapsedTimer::clockType()). If \a deadline is in the past, this QDeadlineTimer object is set to expired, whereas if \a deadline is equal to \c{Duration::max()}, then this From bd7eb131782286d5b41fb1a5b9de0350b4968e3b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 23 Jul 2018 08:25:56 +0200 Subject: [PATCH 09/39] Fix conditions for dup2 in QProcess::startDetached The channel pipes are only set up if the channel's type is Redirect. Fix the conditions accordingly. This amends commit 7ad55ca6. Change-Id: Ie8a800fbe2bf9f5f6709b14ba03133b80e9b4bef Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_unix.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index a849519635d..713af9bd408 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -949,16 +949,14 @@ bool QProcessPrivate::startDetached(qint64 *pid) qt_safe_close(pidPipe[1]); // copy the stdin socket if asked to (without closing on exec) - if (inputChannelMode != QProcess::ForwardedInputChannel) + if (stdinChannel.type == Channel::Redirect) qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0); // copy the stdout and stderr if asked to - if (processChannelMode != QProcess::ForwardedChannels) { - if (processChannelMode != QProcess::ForwardedOutputChannel) - qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0); - if (processChannelMode != QProcess::ForwardedErrorChannel) - qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0); - } + if (stdoutChannel.type == Channel::Redirect) + qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0); + if (stderrChannel.type == Channel::Redirect) + qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0); if (!encodedWorkingDirectory.isEmpty()) { if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1) From 6284d2cd77971e2b10c6d61572b358cf9b3cf897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 5 Jul 2018 15:52:17 +0200 Subject: [PATCH 10/39] QWidget: Add note about fixPosIncludesFrame not supporting window states Change-Id: Iee841e7e6552e24f2b62b0c2df5df3c432680eef Reviewed-by: Gatis Paeglis --- src/widgets/kernel/qwidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5f1f6d880aa..1e249dc1919 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7165,6 +7165,12 @@ void QWidget::move(const QPoint &p) // move() was invoked with Qt::WA_WState_Created not set (frame geometry // unknown), that is, crect has a position including the frame. // If we can determine the frame strut, fix that and clear the flag. +// FIXME: This does not play well with window states other than +// Qt::WindowNoState, as we depend on calling setGeometry() on the +// platform window after fixing up the position so that the new +// geometry is reflected in the platform window, but when the frame +// comes in after the window has been shown (e.g. maximized), we're +// not in a position to do that kind of fixup. void QWidgetPrivate::fixPosIncludesFrame() { Q_Q(QWidget); From 0dfdf23d05d09cbffcec4021c9cbebfb6eeddfa7 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Wed, 1 Aug 2018 12:18:19 +0200 Subject: [PATCH 11/39] Doc: Synchronize documentation with code snippet * The plugin IID with version number was removed in transition to new plugin system, see efde205586a70320d0525e941e5a1cd9657bdd30. * This change re-adds the version number, so that we deliver on the best practices as mentioned in the documentation for the example. Task-number: QTBUG-59487 Change-Id: I88596e71cf18be88d0b1d28d56b6d3bb72fe756b Reviewed-by: Friedemann Kleint --- examples/widgets/tools/plugandpaint/app/interfaces.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/widgets/tools/plugandpaint/app/interfaces.h b/examples/widgets/tools/plugandpaint/app/interfaces.h index 53f447ce87b..a1e91e13ffc 100644 --- a/examples/widgets/tools/plugandpaint/app/interfaces.h +++ b/examples/widgets/tools/plugandpaint/app/interfaces.h @@ -106,16 +106,16 @@ public: QT_BEGIN_NAMESPACE //! [3] //! [4] -#define BrushInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface" +#define BrushInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface/1.0" Q_DECLARE_INTERFACE(BrushInterface, BrushInterface_iid) //! [3] -#define ShapeInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.ShapeInterface" +#define ShapeInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.ShapeInterface/1.0" Q_DECLARE_INTERFACE(ShapeInterface, ShapeInterface_iid) //! [5] -#define FilterInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" +#define FilterInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface/1.0" Q_DECLARE_INTERFACE(FilterInterface, FilterInterface_iid) //! [4] //! [5] From 6f87926df55edb119e5eeb53c3beac135fdf72e2 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 26 Jul 2018 11:33:33 +0200 Subject: [PATCH 12/39] xcb: partly revert 3bc0f1724ae49c2fd7e6d7bcb650350d20d12246 After trying to fix (work around) system resize/move issues in various ways from within the platform plugin, it has been concluded that it is a bug at widget layer and should be fixed there instead: QTBUG-69716. This patch reverts parts of 3bc0f1724a and disables system move / resize on XCB plugin. Meaning, QSizeGrip will use its own implementation for resizing a window. Task-number: QTBUG-68501 Task-number: QTBUG-69628 Change-Id: Ib4744a93fb3e3c20f690a8f43713103856cb7d1a Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +- src/plugins/platforms/xcb/qxcbconnection.h | 1 - .../platforms/xcb/qxcbconnection_xi2.cpp | 89 +------------------ src/plugins/platforms/xcb/qxcbwindow.cpp | 11 +-- 4 files changed, 3 insertions(+), 101 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index dbc53abeca2..aca2c347ead 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1718,8 +1718,7 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, continue; if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) { xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast(next); - if (id == xiDeviceNextEvent->detail % INT_MAX && - xiDeviceNextEvent->deviceid == xiDeviceEvent->deviceid) + if (id == xiDeviceNextEvent->detail % INT_MAX) return true; } } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 98f08e6b2ce..9966e06c7b3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -582,7 +582,6 @@ private: bool m_xi2Enabled = false; #if QT_CONFIG(xinput2) - QVector m_floatingSlaveDevices; int m_xi2Minor = -1; void initializeXInput2(); void xi2SetupDevice(void *info, bool removeExisting = true); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 9a250b875fc..6a5248b8f1f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -127,7 +127,7 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window) XIEventMask mask; mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; - mask.deviceid = XIAllDevices; + mask.deviceid = XIAllMasterDevices; Display *dpy = static_cast(m_xlib_display); Status result = XISelectEvents(dpy, window, &mask, 1); if (result == Success) @@ -315,7 +315,6 @@ void QXcbConnection::xi2SetupDevices() #endif m_scrollingDevices.clear(); m_touchDevices.clear(); - m_floatingSlaveDevices.clear(); Display *xDisplay = static_cast(m_xlib_display); int deviceCount = 0; @@ -323,10 +322,6 @@ void QXcbConnection::xi2SetupDevices() m_xiMasterPointerIds.clear(); for (int i = 0; i < deviceCount; ++i) { XIDeviceInfo deviceInfo = devices[i]; - if (deviceInfo.use == XIFloatingSlave) { - m_floatingSlaveDevices.append(deviceInfo.deviceid); - continue; - } if (deviceInfo.use == XIMasterPointer) { m_xiMasterPointerIds.append(deviceInfo.deviceid); continue; @@ -555,72 +550,6 @@ static inline qreal fixed1616ToReal(FP1616 val) } #endif // defined(XCB_USE_XINPUT21) || QT_CONFIG(tabletevent) -namespace { - -/*! \internal - - Qt listens for XIAllDevices to avoid losing mouse events. This function - ensures that we don't process the same event twice: from a slave device and - then again from a master device. - - In a normal use case (e.g. mouse press and release inside a window), we will - drop events from master devices as duplicates. Other advantage of processing - events from slave devices is that they don't share button state. All buttons - on a master device share the state. - - Examples of special cases: - - - During system move/resize, window manager (_NET_WM_MOVERESIZE) grabs the - master pointer, in this case we process the matching release from the slave - device. A master device event is not sent by the server, hence no duplicate - event to drop. If we listened for XIAllMasterDevices instead, we would never - see a release event in this case. - - - If we dismiss a context menu by clicking somewhere outside a Qt application, - we will process the mouse press from the master pointer as that is the - device we are grabbing. We are not grabbing slave devices (grabbing on the - slave device is buggy according to 19d289ab1b5bde3e136765e5432b5c7d004df3a4). - And since the event occurs outside our window, the slave device event is - not sent to us by the server, hence no duplicate event to drop. -*/ -bool isDuplicateEvent(xcb_ge_event_t *event) -{ - struct qXIEvent { - bool isValid = false; - uint16_t sourceid; - uint8_t evtype; - uint32_t detail; - int32_t root_x; - int32_t root_y; - }; - static qXIEvent lastSeenEvent; - - bool isDuplicate = false; - auto xiDeviceEvent = reinterpret_cast(event); - if (lastSeenEvent.isValid) { - isDuplicate = lastSeenEvent.sourceid == xiDeviceEvent->sourceid && - lastSeenEvent.evtype == xiDeviceEvent->evtype && - lastSeenEvent.detail == xiDeviceEvent->detail && - lastSeenEvent.root_x == xiDeviceEvent->root_x && - lastSeenEvent.root_y == xiDeviceEvent->root_y; - } else { - lastSeenEvent.isValid = true; - } - lastSeenEvent.sourceid = xiDeviceEvent->sourceid; - lastSeenEvent.evtype = xiDeviceEvent->evtype; - lastSeenEvent.detail = xiDeviceEvent->detail; - lastSeenEvent.root_x = xiDeviceEvent->root_x; - lastSeenEvent.root_y = xiDeviceEvent->root_y; - - if (isDuplicate) - // This sanity check ensures that special cases like QTBUG-59277 keep working. - lastSeenEvent.isValid = false; // An event can be a duplicate only once. - - return isDuplicate; -} - -} // namespace - void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { xi2PrepareXIGenericDeviceEvent(event); @@ -630,14 +559,10 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xXIEnterEvent *xiEnterEvent = 0; QXcbWindowEventListener *eventListener = 0; - bool isTouchEvent = true; switch (xiEvent->evtype) { case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: - isTouchEvent = false; - if (!xi2MouseEventsDisabled() && isDuplicateEvent(event)) - return; #ifdef XCB_USE_XINPUT22 case XI_TouchBegin: case XI_TouchUpdate: @@ -645,18 +570,6 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) #endif { xiDeviceEvent = reinterpret_cast(event); - - if (m_floatingSlaveDevices.contains(xiDeviceEvent->sourceid)) - return; // Not interested in floating slave device events, only in attached slaves. - - bool isSlaveEvent = xiDeviceEvent->deviceid == xiDeviceEvent->sourceid; - if (!xi2MouseEventsDisabled() && isTouchEvent && isSlaveEvent) { - // For touch events we want events only from master devices, at least - // currently there is no apparent reason why we would need to consider - // events from slave devices. - return; - } - eventListener = windowEventListenerFromId(xiDeviceEvent->event); sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master break; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 9b6376f39e1..59b06d543eb 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2632,7 +2632,7 @@ bool QXcbWindow::startSystemMove(const QPoint &pos) bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) { -#if QT_CONFIG(xinput2) + return false; // ### FIXME QTBUG-69716 const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); if (!connection()->wmSupport()->isSupportedByWM(moveResize)) return false; @@ -2651,10 +2651,6 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) } else #endif { // Started by mouse press. - if (!connection()->hasXInput2() || connection()->xi2MouseEventsDisabled()) { - // Without XI2 we can't get button press/move/release events. - return false; - } if (connection()->isUnity()) return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?). @@ -2662,11 +2658,6 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) } return true; -#else - Q_UNUSED(pos); - Q_UNUSED(corner); - return false; -#endif } void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner) { From 843629dd1f4e0521ab9bcc6b3c806a5d90b13613 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 27 Jul 2018 16:55:06 +0200 Subject: [PATCH 13/39] Improve documentation of QString::indexOf that take QRegExp They said "By default, this function is case sensitive" but this makes no sense when you're using a regexp for searching, the regexp is case sensitive or not by itself, QStringList does not influence that. Change-Id: I7446cb52a9f915c6551af6046ce89cbc8bab96ed Reviewed-by: Thiago Macieira --- src/corelib/tools/qstringlist.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index c9db39a29fa..e9b7397a74f 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -611,8 +611,6 @@ static int lastIndexOfMutating(const QStringList *that, QRegExp &rx, int from) the list, searching forward from index position \a from. Returns -1 if no item matched. - By default, this function is case sensitive. - \sa lastIndexOf(), contains(), QRegExp::exactMatch() */ int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from) @@ -630,8 +628,6 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, i the list, searching forward from index position \a from. Returns -1 if no item matched. - By default, this function is case sensitive. - If an item matched, the \a rx regular expression will contain the matched objects (see QRegExp::matchedLength, QRegExp::cap). @@ -650,8 +646,6 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, QRegExp &rx, int fro from is -1 (the default), the search starts at the last item. Returns -1 if no item matched. - By default, this function is case sensitive. - \sa indexOf(), contains(), QRegExp::exactMatch() */ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from) @@ -670,8 +664,6 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &r from is -1 (the default), the search starts at the last item. Returns -1 if no item matched. - By default, this function is case sensitive. - If an item matched, the \a rx regular expression will contain the matched objects (see QRegExp::matchedLength, QRegExp::cap). From 4126de887799c61793bf1f9efc8b7ac7b66c8b32 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 24 Jul 2018 13:23:35 -0700 Subject: [PATCH 14/39] QCocoaMenuLoader - ensure that ensureAppMenuInMenu indeed, ensures The logic seems to be incorrect (or the naming is misleading): it only adds 'appMenu' if it was found in the previous 'mainMenu', failing otherwise. Consider the following example: while (true){ QApplication app(a,b); MainWindow w; w.show(); app.exec(); } It's quite a contrived but apparently allowed API use (OP claims they have to switch languages in their app). The main window and the app are destroyed, so is the menu bar. Then a new main window is created, with a new menu bar. Now the current [NSApp mainMenu] (the one set after we deleted the previous) does not have 'appMenu' anymore (we removed it when initializing the first menu bar). So as a result we have app menu missing and add new menus/items to a wrong menus/at wrong index. Change-Id: I64fce766d6c12ebf7ae12bb94af41c8c1de3d78b Task-number: QTBUG-69496 Reviewed-by: Timur Pocheptsov --- .../platforms/cocoa/qcocoamenuloader.mm | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index cd597da71ca..4432d3e27ae 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -191,26 +191,23 @@ Q_ASSERT(mainMenu); #endif // Grab the app menu out of the current menu. - int numItems = [mainMenu numberOfItems]; - NSMenuItem *oldAppMenuItem = 0; - for (int i = 0; i < numItems; ++i) { - NSMenuItem *item = [mainMenu itemAtIndex:i]; - if ([item submenu] == appMenu) { - oldAppMenuItem = item; - [oldAppMenuItem retain]; - [mainMenu removeItemAtIndex:i]; - break; + auto unparentAppMenu = ^bool (NSMenu *supermenu) { + auto index = [supermenu indexOfItemWithSubmenu:appMenu]; + if (index != -1) { + [supermenu removeItemAtIndex:index]; + return true; } - } + return false; + }; - if (oldAppMenuItem) { - [oldAppMenuItem setSubmenu:nil]; - [oldAppMenuItem release]; - NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" - action:nil keyEquivalent:@""]; - [appMenuItem setSubmenu:appMenu]; - [menu insertItem:appMenuItem atIndex:0]; - } + if (!mainMenu || !unparentAppMenu(mainMenu)) + if (appMenu.supermenu) + unparentAppMenu(appMenu.supermenu); + + NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" + action:nil keyEquivalent:@""]; + [appMenuItem setSubmenu:appMenu]; + [menu insertItem:appMenuItem atIndex:0]; } - (void)removeActionsFromAppMenu From 2de297f1b76b97146a4ef0a74b996c8fa6154ff8 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Wed, 1 Aug 2018 16:49:29 +0200 Subject: [PATCH 15/39] QLabel: Use nullptr in documentation Change-Id: Idc3a5a40e33ddb4257e46d7b6f3279ca14241911 Reviewed-by: Martin Smith --- src/widgets/widgets/qlabel.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 947da273ddc..5d09e14073d 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -189,7 +189,7 @@ QLabelPrivate::~QLabelPrivate() #ifndef QT_NO_PICTURE /*! - Returns the label's picture or 0 if the label doesn't have a + Returns the label's picture or nullptr if the label doesn't have a picture. */ @@ -348,7 +348,7 @@ void QLabel::clear() \property QLabel::pixmap \brief the label's pixmap - If no pixmap has been set this will return 0. + If no pixmap has been set this will return nullptr. Setting the pixmap clears any previous content. The buddy shortcut, if any, is disabled. @@ -1157,7 +1157,7 @@ void QLabelPrivate::updateLabel() Alt+P. To unset a previously set buddy, call this function with \a buddy - set to 0. + set to nullptr. \sa buddy(), setText(), QShortcut, setAlignment() */ @@ -1187,7 +1187,7 @@ void QLabel::setBuddy(QWidget *buddy) /*! - Returns this label's buddy, or 0 if no buddy is currently set. + Returns this label's buddy, or nullptr if no buddy is currently set. \sa setBuddy() */ @@ -1339,7 +1339,7 @@ void QLabelPrivate::clearContents() #if QT_CONFIG(movie) /*! - Returns a pointer to the label's movie, or 0 if no movie has been + Returns a pointer to the label's movie, or nullptr if no movie has been set. \sa setMovie() From c5af04cf8aa7bf2fbeaaf2a40f169fe8c17239f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Thu, 13 Jul 2017 20:02:58 +0200 Subject: [PATCH 16/39] HiDPI: Fix calculating window mask from pixmap on drag and drop Use platform window directly for setting a mask to prevent bitmap scaling if pixmap and window DPR are the same. Amends: 42f788ffe26d67864d569c3a3044619d49fc693a Task-number: QTBUG-61948 Change-Id: I5eec85c01f20bdefff7343e83ff10cbcb2c79508 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qshapedpixmapdndwindow.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index b54c6b67a2a..8509eb0961d 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -39,6 +39,8 @@ #include "qshapedpixmapdndwindow_p.h" +#include "qplatformwindow.h" + #include #include #include @@ -70,7 +72,12 @@ void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) if (!mask.isNull()) { if (!handle()) create(); - setMask(mask); + if (auto platformWindow = handle()) { + const auto pixmapDpr = m_pixmap.devicePixelRatio(); + const auto winDpr = devicePixelRatio(); + const auto maskSize = (QSizeF(m_pixmap.size()) * winDpr / pixmapDpr).toSize(); + platformWindow->setMask(QBitmap(mask.scaled(maskSize))); + } } } } From 780dc2291bc0e114bab8b9ccd8706708f6b47270 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 1 Aug 2018 08:42:45 +0200 Subject: [PATCH 17/39] Fix builds with some MinGW distributions Some distributions do not define MINGW_HAS_SECURE_API globally, resulting in methods like wgetenv_s not being declared in the headers. This is probably to keep compatibility with Windows XP. Anyhow, we don't support Windows XP anymore, so we can safely add the define. Note that this is not necessary for the mingw-builds distro, which is the only one we test and support. Anyhow, I don't see any risk in adding these for other distributions. Diff was provided by Philippe Dunski in the bug report. Task-number: QTBUG-67443 Change-Id: I3a64b11541fe95e527ed44bbf8ad94469d457d3d Reviewed-by: Friedemann Kleint --- mkspecs/common/g++-win32.conf | 2 +- qmake/Makefile.unix.win32 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/g++-win32.conf b/mkspecs/common/g++-win32.conf index 610503379d6..f0df324b644 100644 --- a/mkspecs/common/g++-win32.conf +++ b/mkspecs/common/g++-win32.conf @@ -18,7 +18,7 @@ include(g++-base.conf) MAKEFILE_GENERATOR = MINGW QMAKE_PLATFORM = win32 mingw CONFIG += debug_and_release debug_and_release_target precompile_header -DEFINES += UNICODE _UNICODE WIN32 +DEFINES += UNICODE _UNICODE WIN32 MINGW_HAS_SECURE_API=1 QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 # can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for # x86_64 platform similar to 'msvc-desktop.conf' toolchain, because, unlike for MSVC, diff --git a/qmake/Makefile.unix.win32 b/qmake/Makefile.unix.win32 index bfcad353575..48efd6f0304 100644 --- a/qmake/Makefile.unix.win32 +++ b/qmake/Makefile.unix.win32 @@ -1,5 +1,5 @@ EXEEXT = .exe -EXTRA_CXXFLAGS = -DUNICODE +EXTRA_CXXFLAGS = -DUNICODE -DMINGW_HAS_SECURE_API=1 EXTRA_LFLAGS = -static -s -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32 QTOBJS = \ qfilesystemengine_win.o \ From db738cbaf1ba7a4886f7869db16dbb9107a8e65e Mon Sep 17 00:00:00 2001 From: Ales Erjavec Date: Thu, 12 Jul 2018 10:55:33 +0200 Subject: [PATCH 18/39] QCommonStylePrivate::viewItemSize: Fix text width bounds calculation The width of the icon was subtracted out of the available text area width even when the value of the `decorationPosition` was Top/Bottom. Task-number: QTBUG-69404 Task-number: QTBUG-30116 Change-Id: I501ffc0dab0cff25e525c26adf9bdb060408927b Reviewed-by: Christian Ehrlicher Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qcommonstyle.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 7420bfb3f78..3b9186e61a1 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -879,9 +879,16 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int QRect bounds = option->rect; switch (option->decorationPosition) { case QStyleOptionViewItem::Left: - case QStyleOptionViewItem::Right: - bounds.setWidth(wrapText && bounds.isValid() ? bounds.width() - 2 * textMargin : QFIXED_MAX); + case QStyleOptionViewItem::Right: { + if (wrapText && bounds.isValid()) { + int width = bounds.width() - 2 * textMargin; + if (option->features & QStyleOptionViewItem::HasDecoration) + width -= option->decorationSize.width() + 2 * textMargin; + bounds.setWidth(width); + } else + bounds.setWidth(QFIXED_MAX); break; + } case QStyleOptionViewItem::Top: case QStyleOptionViewItem::Bottom: if (wrapText) @@ -893,12 +900,8 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int break; } - if (wrapText) { - if (option->features & QStyleOptionViewItem::HasCheckIndicator) - bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin); - if (option->features & QStyleOptionViewItem::HasDecoration) - bounds.setWidth(bounds.width() - option->decorationSize.width() - 2 * textMargin); - } + if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator) + bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin); const int lineWidth = bounds.width(); const QSizeF size = viewItemTextLayout(textLayout, lineWidth); From 81910b5f3cfb8c8b0c009913d62dacff4e73bc3b Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 2 Aug 2018 16:18:00 +0200 Subject: [PATCH 19/39] SecureTransport - disable lock on sleep for the custom keychain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It appears that by default our keychain auto-locks when the system sleeps. This makes the keychain totally useless, since its password is a random 256 bytes our user never has a chance to know. Thanks to Mårten for the hint about SecKeychainSetSettings, the way to properly fix it. Task-number: QTBUG-69677 Change-Id: I2603c26b8422a1bcace3336e9b4ebe0381c952d7 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/ssl/qsslsocket_mac.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 046b4322526..aa0e1b0dd11 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -60,6 +60,7 @@ #include #include +#include #include #include @@ -144,6 +145,16 @@ EphemeralSecKeychain::EphemeralSecKeychain() } } + if (keychain) { + SecKeychainSettings settings = {}; + settings.version = SEC_KEYCHAIN_SETTINGS_VERS1; + // Strange, huh? But that's what their docs say to do! With lockOnSleep + // == false, set interval to INT_MAX to never lock ... + settings.lockInterval = INT_MAX; + if (SecKeychainSetSettings(keychain, &settings) != errSecSuccess) + qCWarning(lcSsl) << "SecKeychainSettings: failed to disable lock on sleep"; + } + #ifdef QSSLSOCKET_DEBUG if (keychain) { qCDebug(lcSsl) << "Custom keychain with name" << keychainName << "was created" From c07a73837426bc1463fb64b9ee064583bffa6358 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 31 Jul 2018 13:20:24 +0200 Subject: [PATCH 20/39] Bump version Change-Id: Ib93fe88526ceb4097faee241e35d504042d73032 Reviewed-by: Oswald Buddenhagen --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 8aeb4886b17..afdc0cb413b 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.11.1 +MODULE_VERSION = 5.11.2 From 9d4d05ec536289d8d62cfed60e02f38febfc3052 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 25 Jul 2018 18:21:05 +0200 Subject: [PATCH 21/39] qmake: don't escape colons in dependency paths on windows, after all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amends 7c34e0a7b4. Change-Id: I2ecdf0a450337e667f55af09b3de79fb47e05428 Reviewed-by: Mårten Nordheim Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 580df85c1eb..73e09a1025e 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2829,7 +2829,16 @@ MakefileGenerator::escapeDependencyPath(const QString &path) const QString ret = path; if (!ret.isEmpty()) { // Unix make semantics, to be inherited by unix and mingw generators. +#ifdef Q_OS_UNIX + // When running on Unix, we need to escape colons (which may appear + // anywhere in a path, and would be mis-parsed as dependency separators). static const QRegExp criticalChars(QStringLiteral("([\t :#])")); +#else + // MinGW make has a hack for colons which denote drive letters, and no + // other colons may appear in paths. And escaping colons actually breaks + // the make from the Android SDK. + static const QRegExp criticalChars(QStringLiteral("([\t #])")); +#endif ret.replace(criticalChars, QStringLiteral("\\\\1")); debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } From 8c4207dddf9b2af0767de2ef0a10652612d462a5 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 2 Aug 2018 13:11:20 +0200 Subject: [PATCH 22/39] Fix crash in qppmhandler for certain malformed image files The ppm format specifies that the maximum color value field must be less than 65536. The handler did not enforce this, leading to potentional overflow when the value was used in 16 bits context. Task-number: QTBUG-69449 Change-Id: Iea7a7e0f8953ec1ea8571e215687d12a9d77e11c Reviewed-by: Lars Knoll --- src/gui/image/qppmhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index e9f5a905f0c..53e3fa293d4 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -115,7 +115,7 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int& else mcc = read_pbm_int(device); // get max color component - if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0) + if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff) return false; // weird P.M image return true; From f0ff73f631093b11c77d8d6fb548acfe8eb62583 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 19 Jul 2018 13:05:52 +0200 Subject: [PATCH 23/39] QProcess::startDetached: Fix behavior change on Windows Do not overwrite stdout/stderr by default, but only if requested. This restores the behavior of QProcess::startDetached of Qt 5.9. Task-number: QTBUG-67905 Change-Id: Idccf7b0da7bd80f88a0624286ddf2851bc974fb1 Reviewed-by: Friedemann Kleint --- src/corelib/io/qprocess.cpp | 4 ++ src/corelib/io/qprocess_win.cpp | 14 +++-- tests/auto/corelib/io/qprocess/qprocess.pri | 1 + .../io/qprocess/testForwarding/main.cpp | 57 ++++++++++++++----- .../io/qprocess/testForwardingHelper/main.cpp | 45 +++++++++++++++ .../testForwardingHelper.pro | 4 ++ .../auto/corelib/io/qprocess/tst_qprocess.cpp | 44 ++++++++++---- 7 files changed, 139 insertions(+), 30 deletions(-) create mode 100644 tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp create mode 100644 tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 2ee680a7c68..890867cd518 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2147,6 +2147,10 @@ void QProcess::start(OpenMode mode) \endlist All other properties of the QProcess object are ignored. + \note The called process inherits the console window of the calling + process. To suppress console output, redirect standard/error output to + QProcess::nullDevice(). + \sa start() \sa startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index b1ec2c560c3..8c4e5b41b41 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -874,6 +874,11 @@ static bool startDetachedUacPrompt(const QString &programIn, const QStringList & return true; } +static Q_PIPE pipeOrStdHandle(Q_PIPE pipe, DWORD handleNumber) +{ + return pipe != INVALID_Q_PIPE ? pipe : GetStdHandle(handleNumber); +} + bool QProcessPrivate::startDetached(qint64 *pid) { static const DWORD errorElevationRequired = 740; @@ -906,15 +911,14 @@ bool QProcessPrivate::startDetached(qint64 *pid) 0, 0, 0, STARTF_USESTDHANDLES, 0, 0, 0, - stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] + pipeOrStdHandle(stdinChannel.pipe[0], STD_INPUT_HANDLE), + pipeOrStdHandle(stdoutChannel.pipe[1], STD_OUTPUT_HANDLE), + pipeOrStdHandle(stderrChannel.pipe[1], STD_ERROR_HANDLE) }; - const bool inheritHandles = stdinChannel.type == Channel::Redirect - || stdoutChannel.type == Channel::Redirect - || stderrChannel.type == Channel::Redirect; QProcess::CreateProcessArguments cpargs = { nullptr, reinterpret_cast(const_cast(args.utf16())), - nullptr, nullptr, inheritHandles, dwCreationFlags, envPtr, + nullptr, nullptr, true, dwCreationFlags, envPtr, workingDirectory.isEmpty() ? nullptr : reinterpret_cast(workingDirectory.utf16()), &startupInfo, &pinfo diff --git a/tests/auto/corelib/io/qprocess/qprocess.pri b/tests/auto/corelib/io/qprocess/qprocess.pri index d5a7532ee19..8d17090545d 100644 --- a/tests/auto/corelib/io/qprocess/qprocess.pri +++ b/tests/auto/corelib/io/qprocess/qprocess.pri @@ -11,6 +11,7 @@ SUBPROGRAMS = \ testProcessEOF \ testExitCodes \ testForwarding \ + testForwardingHelper \ testGuiProcess \ testDetached \ fileWriterProcess \ diff --git a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp index b7367ff8c6a..b5d56a11385 100644 --- a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp +++ b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp @@ -27,15 +27,32 @@ ****************************************************************************/ #include +#include #include +#include +#include #include +static bool waitForDoneFileWritten(const QString &filePath, int msecs = 30000) +{ + QDeadlineTimer t(msecs); + do { + QThread::msleep(250); + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + continue; + if (file.readAll() == "That's all folks!") + return true; + } while (!t.hasExpired()); + return false; +} + int main(int argc, char **argv) { QCoreApplication app(argc, argv); - if (argc < 3) + if (argc < 4) return 13; QProcess process; @@ -50,23 +67,37 @@ int main(int argc, char **argv) if (process.inputChannelMode() != inmode) return 11; - process.start("testProcessEcho2/testProcessEcho2"); + if (atoi(argv[3])) { + QTemporaryFile doneFile("testForwarding_XXXXXX.txt"); + if (!doneFile.open()) + return 12; + doneFile.close(); - if (!process.waitForStarted(5000)) - return 2; + process.setProgram("testForwardingHelper/testForwardingHelper"); + process.setArguments(QStringList(doneFile.fileName())); + if (!process.startDetached()) + return 13; + if (!waitForDoneFileWritten(doneFile.fileName())) + return 14; + } else { + process.start("testProcessEcho2/testProcessEcho2"); - if (inmode == QProcess::ManagedInputChannel && process.write("forwarded") != 9) - return 3; + if (!process.waitForStarted(5000)) + return 2; - process.closeWriteChannel(); - if (!process.waitForFinished(5000)) - return 4; + if (inmode == QProcess::ManagedInputChannel && process.write("forwarded") != 9) + return 3; - if ((mode == QProcess::ForwardedOutputChannel || mode == QProcess::ForwardedChannels) + process.closeWriteChannel(); + if (!process.waitForFinished(5000)) + return 4; + + if ((mode == QProcess::ForwardedOutputChannel || mode == QProcess::ForwardedChannels) && !process.readAllStandardOutput().isEmpty()) - return 5; - if ((mode == QProcess::ForwardedErrorChannel || mode == QProcess::ForwardedChannels) + return 5; + if ((mode == QProcess::ForwardedErrorChannel || mode == QProcess::ForwardedChannels) && !process.readAllStandardError().isEmpty()) - return 6; + return 6; + } return 0; } diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp new file mode 100644 index 00000000000..682ca7346b0 --- /dev/null +++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + puts("Usage: testForwardingHelper "); + return 1; + } + fputs("out data", stdout); + fputs("err data", stderr); + fflush(stdout); + fflush(stderr); + std::ofstream out(argv[1]); + out << "That's all folks!"; + return 0; +} diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro new file mode 100644 index 00000000000..e236e05c7d8 --- /dev/null +++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro @@ -0,0 +1,4 @@ +SOURCES = main.cpp +CONFIG -= qt app_bundle +CONFIG += console +DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index e19653abf04..e0aa5771544 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -1047,32 +1047,50 @@ void tst_QProcess::mergedChannels() void tst_QProcess::forwardedChannels_data() { + QTest::addColumn("detach"); QTest::addColumn("mode"); QTest::addColumn("inmode"); QTest::addColumn("outdata"); QTest::addColumn("errdata"); - QTest::newRow("separate") << int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel) - << QByteArray() << QByteArray(); - QTest::newRow("forwarded") << int(QProcess::ForwardedChannels) << int(QProcess::ManagedInputChannel) - << QByteArray("forwarded") << QByteArray("forwarded"); - QTest::newRow("stdout") << int(QProcess::ForwardedOutputChannel) << int(QProcess::ManagedInputChannel) - << QByteArray("forwarded") << QByteArray(); - QTest::newRow("stderr") << int(QProcess::ForwardedErrorChannel) << int(QProcess::ManagedInputChannel) - << QByteArray() << QByteArray("forwarded"); - QTest::newRow("fwdinput") << int(QProcess::ForwardedErrorChannel) << int(QProcess::ForwardedInputChannel) - << QByteArray() << QByteArray("input"); + QTest::newRow("separate") + << false + << int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel) + << QByteArray() << QByteArray(); + QTest::newRow("forwarded") + << false + << int(QProcess::ForwardedChannels) << int(QProcess::ManagedInputChannel) + << QByteArray("forwarded") << QByteArray("forwarded"); + QTest::newRow("stdout") + << false + << int(QProcess::ForwardedOutputChannel) << int(QProcess::ManagedInputChannel) + << QByteArray("forwarded") << QByteArray(); + QTest::newRow("stderr") + << false + << int(QProcess::ForwardedErrorChannel) << int(QProcess::ManagedInputChannel) + << QByteArray() << QByteArray("forwarded"); + QTest::newRow("fwdinput") + << false + << int(QProcess::ForwardedErrorChannel) << int(QProcess::ForwardedInputChannel) + << QByteArray() << QByteArray("input"); + QTest::newRow("detached-default-forwarding") + << true + << int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel) + << QByteArray("out data") << QByteArray("err data"); } void tst_QProcess::forwardedChannels() { + QFETCH(bool, detach); QFETCH(int, mode); QFETCH(int, inmode); QFETCH(QByteArray, outdata); QFETCH(QByteArray, errdata); QProcess process; - process.start("testForwarding/testForwarding", QStringList() << QString::number(mode) << QString::number(inmode)); + process.start("testForwarding/testForwarding", + QStringList() << QString::number(mode) << QString::number(inmode) + << QString::number(bool(detach))); QVERIFY(process.waitForStarted(5000)); QCOMPARE(process.write("input"), 5); process.closeWriteChannel(); @@ -1089,7 +1107,9 @@ void tst_QProcess::forwardedChannels() case 4: err = "did not finish"; break; case 5: err = "unexpected stdout"; break; case 6: err = "unexpected stderr"; break; - case 13: err = "parameter error"; break; + case 12: err = "cannot create temp file"; break; + case 13: err = "startDetached failed"; break; + case 14: err = "waitForDoneFileWritten timed out"; break; default: err = "unknown exit code"; break; } QVERIFY2(!process.exitCode(), err); From 66be5445e64b54bf60069dfee5dd918459e3deed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Aug 2018 12:59:42 +0200 Subject: [PATCH 24/39] Windows: Implement Qt::WindowStaysOnBottomHint Set the Z-order to HWND_BOTTOM in that case. Add a doc note stating that it only works for frameless or full screen windows. Task-number: QTBUG-53717 Change-Id: I7abf219a88aac715c51d27d925504da9e91b56f1 Reviewed-by: Paul Wicking Reviewed-by: Andre de la Rocha Reviewed-by: Oliver Wolff --- src/corelib/global/qnamespace.qdoc | 8 ++++++-- src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 36f2aaee725..8e46f3f0fd0 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2271,13 +2271,17 @@ correctly. \value WindowStaysOnBottomHint Informs the window system that the - window should stay on bottom of all other windows. Note - that on X11 this hint will work only in window managers + window should stay on bottom of all other windows. + + \note On X11, this hint will work only in window managers that support _NET_WM_STATE_BELOW atom. If a window always on the bottom has a parent, the parent will also be left on the bottom. This window hint is currently not implemented for \macos. + \note On Windows, this will work only for frameless or + full-screen windows. + \value WindowTransparentForInput Informs the window system that this window is used only for output (displaying something) and does not take input. Therefore input events should pass through as if it wasn't there. diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index aa40d422fbf..ca87f1b6a43 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2081,6 +2081,8 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow * HWND desktopHWND = GetDesktopWindow(); platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND); } + if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint)) + windowPos->hwndInsertAfter = HWND_BOTTOM; } if (!qWindow->isTopLevel()) // Implement hasHeightForWidth(). return false; From 1c8f9eb79da837db8e37cf6348de459088c3a20e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 2 Aug 2018 18:05:51 +0200 Subject: [PATCH 25/39] Add missing optimization for loading RGB32 to RGBA64 using NEON The rest of the RGB64 routines were optimized, but the loading of RGB32 was not as it was originally not used much, but with ARGB32 using the RGB64 backend, it is essential for decent performance. Task-number: QTBUG-69724 Change-Id: I1c02411ed29d3d993427afde44dfa83689d117e0 Reviewed-by: Lars Knoll --- src/gui/painting/qdrawhelper.cpp | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 34847daf551..9bb1498ff0c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -618,6 +618,53 @@ static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint * *buffer++ = QRgba64::fromArgb32(s); } } +#elif defined(__ARM_NEON__) +template +static inline void qConvertARGB32PMToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count) +{ + if (count <= 0) + return; + + const uint32x4_t amask = vdupq_n_u32(0xff000000); +#if defined(Q_PROCESSOR_ARM_64) + const uint8x16_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15}; +#else + const uint8x8_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7 }; +#endif + int i = 0; + for (; i < count-3; i += 4) { + uint32x4_t vs32 = vld1q_u32(src); + src += 4; + if (maskAlpha) + vs32 = vorrq_u32(vs32, amask); + uint8x16_t vs8 = vreinterpretq_u8_u32(vs32); + if (!RGBA) { +#if defined(Q_PROCESSOR_ARM_64) + vs8 = vqtbl1q_u8(vs8, rgbaMask); +#else + // no vqtbl1q_u8 + const uint8x8_t vlo = vtbl1_u8(vget_low_u8(vs8), rgbaMask); + const uint8x8_t vhi = vtbl1_u8(vget_high_u8(vs8), rgbaMask); + vs8 = vcombine_u8(vlo, vhi); +#endif + } + uint8x16x2_t v = vzipq_u8(vs8, vs8); + + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[0])); + buffer += 2; + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[1])); + buffer += 2; + } + + SIMD_EPILOGUE(i, count, 3) { + uint s = *src++; + if (maskAlpha) + s = s | 0xff000000; + if (RGBA) + s = RGBA2ARGB(s); + *buffer++ = QRgba64::fromArgb32(s); + } +} #endif static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count, @@ -625,6 +672,8 @@ static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uin { #ifdef __SSE2__ qConvertARGB32PMToARGB64PM_sse2(buffer, src, count); +#elif defined(__ARM_NEON__) + qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); #else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(0xff000000 | src[i]); @@ -639,6 +688,10 @@ static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const qConvertARGB32PMToARGB64PM_sse2(buffer, src, count); for (int i = 0; i < count; ++i) buffer[i] = buffer[i].premultiplied(); +#elif defined(__ARM_NEON__) + qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); + for (int i = 0; i < count; ++i) + buffer[i] = buffer[i].premultiplied(); #else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied(); @@ -651,6 +704,8 @@ static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, con { #ifdef __SSE2__ qConvertARGB32PMToARGB64PM_sse2(buffer, src, count); +#elif defined(__ARM_NEON__) + qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); #else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(src[i]); @@ -665,6 +720,10 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, con qConvertARGB32PMToARGB64PM_sse2(buffer, src, count); for (int i = 0; i < count; ++i) buffer[i] = buffer[i].premultiplied(); +#elif defined(__ARM_NEON__) + qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); + for (int i = 0; i < count; ++i) + buffer[i] = buffer[i].premultiplied(); #else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied(); @@ -677,6 +736,8 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, c { #ifdef __SSE2__ qConvertARGB32PMToARGB64PM_sse2(buffer, src, count); +#elif defined(__ARM_NEON__) + qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); #else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])); From d2d59e77d5e16bc79ddfed37f4f29d1dcd9b92a7 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Fri, 3 Aug 2018 10:49:03 +0200 Subject: [PATCH 26/39] Doc: Increase precision in description of convenience typedefs Task-number: QTBUG-53856 Change-Id: I57917bb311d1d93e0903f2b3e021cc4db0f0d05e Reviewed-by: Nico Vertriest --- src/corelib/global/qglobal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f60e47928c9..a6990b88f42 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -589,7 +589,7 @@ Q_STATIC_ASSERT((std::is_same::value)); {long long int } (\c __int64 on Windows). Several convenience type definitions are declared: \l qreal for \c - double, \l uchar for \c unsigned char, \l uint for \c unsigned + double or \c float, \l uchar for \c unsigned char, \l uint for \c unsigned int, \l ulong for \c unsigned long and \l ushort for \c unsigned short. From cdf154e65a3137597f62880361c407e368aae0d6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 2 Aug 2018 16:34:43 +0200 Subject: [PATCH 27/39] Optimize blits of any compatible formats The fast image blending is only used for SourceOver composition, but several of our embedded backends make heavy use of Source composition which doesn't have a short-cut. This patch adds a blitting short cut that works in those cases. Task-number: QTBUG-69724 Change-Id: Icc61a67cc27bc83863153d69cae60dd986d26f69 Reviewed-by: Lars Knoll --- src/gui/painting/qpaintengine_raster.cpp | 119 ++++++++++++++++++++++- src/gui/painting/qpaintengine_raster_p.h | 3 + 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6336b2943e3..cade334ea60 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1056,6 +1056,77 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, alpha); } +void QRasterPaintEnginePrivate::blitImage(const QPointF &pt, + const QImage &img, + const QRect &clip, + const QRect &sr) +{ + if (!clip.isValid()) + return; + + Q_ASSERT(img.depth() >= 8); + + 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(); + int ih = img.height(); + + if (!sr.isEmpty()) { + iw = sr.width(); + ih = sr.height(); + // Adjust the image according to the source offset... + srcBits += ((sr.y() * srcBPL) + sr.x() * srcSize); + } + + // adapt the x parameters + int x = qRound(pt.x()); + int cx1 = clip.x(); + int cx2 = clip.x() + clip.width(); + if (x < cx1) { + int d = cx1 - x; + srcBits += srcSize * d; + iw -= d; + x = cx1; + } + if (x + iw > cx2) { + int d = x + iw - cx2; + iw -= d; + } + if (iw <= 0) + return; + + // adapt the y paremeters... + int cy1 = clip.y(); + int cy2 = clip.y() + clip.height(); + int y = qRound(pt.y()); + if (y < cy1) { + int d = cy1 - y; + srcBits += srcBPL * d; + ih -= d; + y = cy1; + } + if (y + ih > cy2) { + int d = y + ih - cy2; + ih -= d; + } + if (ih <= 0) + return; + + // blit.. + int dstSize = rasterBuffer->bytesPerPixel(); + qsizetype dstBPL = rasterBuffer->bytesPerLine(); + const uint *src = (const uint *) srcBits; + uint *dst = reinterpret_cast(rasterBuffer->buffer() + x * dstSize + y * dstBPL); + + const int len = iw * (qt_depthForFormat(rasterBuffer->format) >> 3); + for (int y = 0; y < ih; ++y) { + memcpy(dst, src, len); + dst = (quint32 *)(((uchar *) dst) + dstBPL); + src = (const quint32 *)(((const uchar *) src) + srcBPL); + } +} + void QRasterPaintEnginePrivate::systemStateChanged() { @@ -2160,7 +2231,15 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img) const QClipData *clip = d->clip(); QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy()); - if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { + if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) { + if (!clip) { + d->blitImage(pt, img, d->deviceRect); + return; + } else if (clip->hasRectClip) { + d->blitImage(pt, img, clip->clipRect); + return; + } + } else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()]; if (func) { if (!clip) { @@ -2445,7 +2524,16 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe fillPath(path, &d->image_filler_xform); s->matrix = m; } else { - if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { + if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) { + QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy()); + if (!clip) { + d->blitImage(pt, img, d->deviceRect, sr.toRect()); + return; + } else if (clip->hasRectClip) { + d->blitImage(pt, img, clip->clipRect, sr.toRect()); + return; + } + } else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()]; if (func) { QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy()); @@ -3665,6 +3753,33 @@ bool QRasterPaintEnginePrivate::canUseFastImageBlending(QPainter::CompositionMod && !image.hasAlphaChannel())); } +bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const +{ + Q_Q(const QRasterPaintEngine); + const QRasterPaintEngineState *s = q->state(); + + if (!s->flags.fast_images || s->intOpacity != 256 || qt_depthForFormat(rasterBuffer->format) < 8) + return false; + + QImage::Format dFormat = rasterBuffer->format; + QImage::Format sFormat = image.format(); + // Formats must match or source format must be a subset of destination format + if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) { + if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32) + || (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888)) + sFormat = dFormat; + else + sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats + } + if (dFormat != sFormat) + return false; + + return s->matrix.type() <= QTransform::TxTranslate + && (mode == QPainter::CompositionMode_Source + || (mode == QPainter::CompositionMode_SourceOver + && !image.hasAlphaChannel())); +} + QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color) { Q_ASSERT(image.depth() == 1); diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 8c6f668d9d3..14eddf07b15 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -291,6 +291,8 @@ public: void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func, const QRect &clip, int alpha, const QRect &sr = QRect()); + void blitImage(const QPointF &pt, const QImage &img, + const QRect &clip, const QRect &sr = QRect()); QTransform brushMatrix() const { Q_Q(const QRasterPaintEngine); @@ -313,6 +315,7 @@ public: void recalculateFastImages(); bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const; + bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const; QPaintDevice *device; QScopedPointer outlineMapper; From 65cd6f2e8271d070cd89da49d0993863e8836558 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 3 Aug 2018 11:31:42 +0200 Subject: [PATCH 28/39] Fix conversion from transparent indexed8 to RGB32 A typo meant the color-table was not fixed. For safety fallback colors are also made opaque. Change-Id: I3e609882177604910c4343c86f00221a89af9078 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage_conversions.cpp | 5 +++-- tests/auto/gui/image/qimage/tst_qimage.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 1b4d3e63ddd..d981c437113 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1194,7 +1194,7 @@ static QVector fix_color_table(const QVector &ctbl, QImage::Format f if (format == QImage::Format_RGB32) { // check if the color table has alpha for (int i = 0; i < colorTable.size(); ++i) - if (qAlpha(colorTable.at(i) != 0xff)) + if (qAlpha(colorTable.at(i)) != 0xff) colorTable[i] = colorTable.at(i) | 0xff000000; } else if (format == QImage::Format_ARGB32_Premultiplied) { // check if the color table has alpha @@ -1796,8 +1796,9 @@ static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt: if (colorTable.size() < 256) { int tableSize = colorTable.size(); colorTable.resize(256); + QRgb fallbackColor = (dest->format == QImage::Format_RGB32) ? 0xff000000 : 0; for (int i=tableSize; i<256; ++i) - colorTable[i] = 0; + colorTable[i] = fallbackColor; } int w = src->width; diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 7ad4a9e9bbd..34b20a5ccaf 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -222,6 +222,8 @@ private slots: void hugeQImage(); + void convertColorTable(); + private: const QString m_prefix; }; @@ -3458,5 +3460,18 @@ void tst_QImage::hugeQImage() #endif } +void tst_QImage::convertColorTable() +{ + QImage image(10, 10, QImage::Format_Indexed8); + image.setColor(0, 0x80ffffff); + image.fill(0); + QImage argb32 = image.convertToFormat(QImage::Format_ARGB32); + QCOMPARE(argb32.pixel(0,0), 0x80ffffff); + QImage argb32pm = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + QCOMPARE(argb32pm.pixel(0,0), 0x80808080); + QImage rgb32 = image.convertToFormat(QImage::Format_RGB32); + QCOMPARE(rgb32.pixel(0,0), 0xffffffff); +} + QTEST_GUILESS_MAIN(tst_QImage) #include "tst_qimage.moc" From ae289884db05cbaac71156983974eebfb9b59730 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Fri, 3 Aug 2018 14:09:52 +0200 Subject: [PATCH 29/39] Doc: Fix wrong link in QFont documentation Task-number: QTBUG-62072 Change-Id: I587534fc5723b3d198fe2065fbcf1bee4871a768 Reviewed-by: Mitch Curtis --- src/gui/text/qfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index c7fff266add..f7462b65c83 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1254,7 +1254,7 @@ QFont::StyleStrategy QFont::styleStrategy() const /*! Returns the StyleHint. - The style hint affects the \l{QFont}{font matching} algorithm. + The style hint affects the \l{#fontmatching}{font matching algorithm}. See \l QFont::StyleHint for the list of available hints. \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint() From 87704611151af78cfef17ae518c40bfb49c7b934 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Fri, 3 Aug 2018 14:01:15 +0200 Subject: [PATCH 30/39] Doc: Update really old screenshot in Sliders Example Task-number: QTBUG-63248 Change-Id: Id756d86539987562b9455881364928ccf7349fbf Reviewed-by: Martin Smith --- doc/src/images/sliders-example.png | Bin 9317 -> 18048 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/images/sliders-example.png b/doc/src/images/sliders-example.png index a67ce1dbdacfa8a265fa3f9744228674d75e946b..d2a9c4804d097a92c98f87ee38e02c13a61027de 100644 GIT binary patch literal 18048 zcmY*>2Rzkn+?9c14iCWYgGZwY*}&gn*x{7m*Fb~{?pGwrKNjVCw�>!aWogpo5HS*4eT<+qEkT!ZpB% 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 literal 9317 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 From 6953e513f9034b98a48d83b67afd671f1ee33aeb Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Fri, 3 Aug 2018 13:47:48 +0200 Subject: [PATCH 31/39] Doc: Clean up Qt::ApplicationAttribute docs * Remove () from links to QGuiApplication link names. The link targets QGuiApplication, and the syntax Q(Gui)Application to suggest both QGuiApplication and QApplication seems unnecessary, as QApplication derives from QGuiApplication anyway. * Move added in version line to the bottom of each entry that contains said line for consistency. * "was added in" > "has been added in" Task-number: QTBUG-56077 Change-Id: Ife93acb7936ff9f0d3af2f2f456ad0db95419797 Reviewed-by: Nico Vertriest --- src/corelib/global/qnamespace.qdoc | 68 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 8e46f3f0fd0..d6191d15855 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -116,8 +116,8 @@ \value AA_DontShowShortcutsInContextMenus Actions with the Shortcut property won't be shown in any shortcut menus unless specifically set by the - QAction::shortcutVisibleInContextMenu property. This value has - been added in Qt 5.10. + QAction::shortcutVisibleInContextMenu property. This value was added + in Qt 5.10. \value AA_NativeWindows Ensures that widgets have native windows. @@ -132,9 +132,8 @@ menu and not taking possession of the native menu bar. Setting this attribute to true will also set the AA_DontUseNativeMenuBar attribute to true. It also disables native event filters. - This attribute has been added in Qt 5.7. It must be set before - \l {QGuiApplication}{Q\(Gui\)Application} is constructed. - + This attribute must be set before QGuiApplication constructed. + This value was added in Qt 5.7. \value AA_DontUseNativeMenuBar All menubars created while this attribute is set to true won't be used as a native menubar (e.g, the menubar at @@ -174,14 +173,14 @@ \value AA_UseDesktopOpenGL Forces the usage of desktop OpenGL (for example, \e opengl32.dll or \e libGL.so) on platforms that use dynamic loading - of the OpenGL implementation. This value has been added in Qt 5.3. - This attribute must be set before \l {QGuiApplication} - {Q\(Gui\)Application} is constructed. + of the OpenGL implementation. This attribute must be set before + QGuiApplication is constructed. + This value was added in Qt 5.3. \value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 or higher on platforms that use dynamic loading of the OpenGL implementation. - This value has been added in Qt 5.3. This attribute must be set - before \l {QGuiApplication}{Q\(Gui\)Application} is constructed. + This attribute must be set before QGuiApplication is constructed. + This value was added in Qt 5.3. \value AA_UseSoftwareOpenGL Forces the usage of a software based OpenGL implementation on platforms that use dynamic loading of the OpenGL @@ -191,29 +190,28 @@ implementation is available. The default name of this library is \c opengl32sw.dll and can be overridden by setting the environment variable \e QT_OPENGL_DLL. See the platform-specific pages, for - instance \l{Qt for Windows}, for more information. This value has - been added in Qt 5.4. This attribute must be set before - \l {QGuiApplication}{Q\(Gui\)Application} is constructed. + instance \l{Qt for Windows}, for more information. This attribute + must be set before QGuiApplication is constructed. + This value was added in Qt 5.4. \value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL contexts used by classes like QOpenGLWidget and QQuickWidget. This allows sharing OpenGL resources, like textures, between QOpenGLWidget - instances that belong to different top-level windows. This value has - been added in Qt 5.4. This attribute must be set before - \l {QGuiApplication}{Q\(Gui\)Application} is constructed. + instances that belong to different top-level windows. This attribute + must be set before QGuiApplication is constructed. + This value was added in Qt 5.4. \value AA_SetPalette Indicates whether a palette was explicitly set on the - \l {QGuiApplication}{Q\(Gui\)Application}. This value has been added - in Qt 5.5. + QGuiApplication. This value was added in Qt 5.5. \value AA_EnableHighDpiScaling Enables high-DPI scaling in Qt on supported platforms (see also \l{High DPI Displays}). Supported platforms are X11, Windows and Android. Enabling makes Qt scale the main (device independent) coordinate system according to display scale factors provided by the operating system. This corresponds to setting the - QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to 1. This value - has been added in Qt 5.6. This attribute must be set before - Q(Gui)Application is constructed. + QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to + 1. This attribute must be set before QGuiApplication is constructed. + This value was added in Qt 5.6. \value AA_DisableHighDpiScaling Disables high-DPI scaling in Qt, exposing window system coordinates. Note that the window system may do its own scaling, @@ -221,24 +219,26 @@ be equal to 1. In addition, scale factors set by QT_SCALE_FACTOR will not be affected. This corresponds to setting the QT_AUTO_SCREEN\unicode{0x200b}_SCALE_FACTOR environment variable to 0. - This value has been added in Qt 5.6. This - attribute must be set before Q(Gui)Application is constructed. + This attribute must be set before QGuiApplication is constructed. + This value was added in Qt 5.6. \value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets disable regular QWidget palette and font propagation. When this flag is enabled, font and palette changes propagate as though the user had manually called the corresponding QWidget methods. See \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance} - for more details. This value has been added in Qt 5.7. + for more details. + This value was added in Qt 5.7. \value AA_DontUseNativeDialogs All dialogs created while this attribute is set to true won't use the native dialogs provided by the platform. - This value has been added in Qt 5.7. + This value was added in Qt 5.7. \value AA_SynthesizeMouseForUnhandledTabletEvents All tablet events that are not accepted by the application will be translated to mouse events instead. This attribute is enabled - by default. This value has been added in Qt 5.7. + by default. + This value was added in Qt 5.7. \value AA_CompressHighFrequencyEvents Enables compression of certain frequent events. On the X11 windowing system, the default value is true, which means that @@ -251,19 +251,21 @@ If your application needs to handle all events with no compression, you can unset this attribute. Notice that input events from tablet devices will not be compressed. See AA_CompressTabletEvents if you want these to be - compressed as well. This value has been added in Qt 5.7. + compressed as well. + This value was added in Qt 5.7. \value AA_CompressTabletEvents Enables compression of input events from tablet devices. Notice that AA_CompressHighFrequencyEvents must be true for events compression to be enabled, and that this flag extends the former to tablet events. Its default - value is false. This value has been added in Qt 5.10. + value is false. + This value was added in Qt 5.10. \value AA_DontCheckOpenGLContextThreadAffinity When making a context current using QOpenGLContext, do not check that the \l{QObject#Thread Affinity}{QObject thread affinity} of the QOpenGLContext object is the same thread calling - \l{QOpenGLContext::makeCurrent}{makeCurrent()}. This value has been - added in Qt 5.8. + \l{QOpenGLContext::makeCurrent}{makeCurrent()}. + This value was added in Qt 5.8. \value AA_DisableShaderDiskCache Disables caching of shader program binaries on disk. By default Qt Quick, QPainter's OpenGL backend, and any @@ -277,7 +279,7 @@ \value AA_DisableWindowContextHelpButton Disables the WindowContextHelpButtonHint by default on Qt::Sheet and Qt::Dialog widgets. This hides the \gui ? button on Windows, which only makes sense if you use \l QWhatsThis functionality. - This value has been added in Qt 5.10. For Qt 6, WindowContextHelpButtonHint + This value was added in Qt 5.10. In Qt 6, WindowContextHelpButtonHint will not be set by default. The following values are deprecated or obsolete: @@ -2651,7 +2653,7 @@ but \b{must} not return an empty string unless the cursor is at the end of the document. \value ImEnterKeyType The Enter key type. \value ImAnchorRectangle The bounding rectangle of the selection anchor. - This value has been added in Qt 5.7. + This value was added in Qt 5.7. \value ImInputItemClipRectangle The actual exposed input item rectangle. Parts of the input item might be clipped. This value will take clipping into consideration and return the actual painted item rectangle. The rectangle is in widget coordinates. @@ -2779,7 +2781,7 @@ \value ItemNeverHasChildren The item never has child items. This is used for optimization purposes only. \value ItemIsUserTristate The user can cycle through three separate states. - This value has been added in Qt 5.5. + This value was added in Qt 5.5. Note that checkable items need to be given both a suitable set of flags and an initial state, indicating whether the item is checked or not. From c6cca0f492717582cb113f3d62e97f554798cf14 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Fri, 3 Aug 2018 14:44:08 +0200 Subject: [PATCH 32/39] Doc: Update out-of-date image in QColorDialog documentation Task-number: QTBUG-58420 Change-Id: Ib5c7a3f681b082182cf6ec9aa62028b7040e81bf Reviewed-by: Martin Smith --- src/widgets/doc/images/fusion-colordialog.png | Bin 21518 -> 27155 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/widgets/doc/images/fusion-colordialog.png b/src/widgets/doc/images/fusion-colordialog.png index 011319e9c892e70a97d27b256a6b1dfbe9012e0a..aacdb7a7272d1557cb51e1a789f2c65ef6841f97 100644 GIT binary patch literal 27155 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 e0;5$Win Date: Wed, 2 May 2018 18:07:05 +0200 Subject: [PATCH 33/39] make it possible to override the basename of module config files using qt$$MODULE isn't enough if the module is composed of submodules which need the final module's headers, because that would require two modules having the same module .pri file. the first thought to fix this was to just use $$lower($$TARGET), but that breaks for testlib (QtTest). while the config file name isn't public api, it's included by a public header, so changing it is risky. so instead stay with the original pattern, but make it explicitly overrideable. the cherry-pick is needed to support QtWebEngine 5.12 with Qt 5.11, a requirement that was raised too late. Change-Id: I758c46ed403620620d577ae16866ce751271b63e Reviewed-by: Michal Klocek Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 95b0e4c956181e535d635b108adc732d8c91a803) Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_module.prf | 5 +++-- mkspecs/features/qt_module_headers.prf | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index f8729de9476..8c7adc45ebb 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -13,8 +13,9 @@ isEmpty(MODULE):MODULE = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0) isEmpty(VERSION): VERSION = $$MODULE_VERSION isEmpty(VERSION): error("Module does not define version.") -exists($$OUT_PWD/qt$${MODULE}-config.pri) { - include($$OUT_PWD/qt$${MODULE}-config.pri) +isEmpty(MODULE_CFG_FILE): MODULE_CFG_FILE = qt$${MODULE}-config +exists($$OUT_PWD/$${MODULE_CFG_FILE}.pri) { + include($$OUT_PWD/$${MODULE_CFG_FILE}.pri) CONFIG += generated_privates } diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index e45ac949667..bbded56b428 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -121,11 +121,12 @@ alien_syncqt: return() MODULE_INC_OUTDIR = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME -exists($$OUT_PWD/qt$${MODULE}-config.h) { +isEmpty(MODULE_CFG_FILE): MODULE_CFG_FILE = qt$${MODULE}-config +exists($$OUT_PWD/$${MODULE_CFG_FILE}.h) { fwd_rel = $$relative_path($$OUT_PWD, $$MODULE_INC_OUTDIR) SYNCQT.INJECTIONS += \ - $$fwd_rel/qt$${MODULE}-config.h:qt$${MODULE}-config.h \ - $$fwd_rel/qt$${MODULE}-config_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/qt$${MODULE}-config_p.h + $$fwd_rel/$${MODULE_CFG_FILE}.h:$${MODULE_CFG_FILE}.h \ + $$fwd_rel/$${MODULE_CFG_FILE}_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/$${MODULE_CFG_FILE}_p.h } for (injection, SYNCQT.INJECTIONS) { From 4c223502787f604fc8e726b0f9006c868810c08d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 30 Jul 2018 10:19:00 -0700 Subject: [PATCH 34/39] Remove the src/sql/README.module file It's stale. Thanks to Olivier B. for pointing out. Change-Id: Ie01831ddac5446fdbdeefffd15463530818cff9e Reviewed-by: Martin Smith Reviewed-by: Oswald Buddenhagen --- src/sql/README.module | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 src/sql/README.module diff --git a/src/sql/README.module b/src/sql/README.module deleted file mode 100644 index 511d90e83fb..00000000000 --- a/src/sql/README.module +++ /dev/null @@ -1,37 +0,0 @@ -Before building the Qt library, the Qt SQL module can be enabled for -specific databases using 'configure'. 'configure' is located at the -top of your QTDIR. - -Specific databases drivers can be enabled using one of the following -options: - - ./configure [-qt-sql-] [-plugin-sql-] - -or disabled using the following option: - - ./configure [-no-sql-] - -Where is the name of the driver, for example 'psql'. This -will configure the Qt library to compile the specified driver into -the Qt lib itself. - -For example, to build the PostgreSQL driver directly into the Qt -library, configure Qt like this: - - ./configure -qt-sql-psql - -In addition, you may need to specify an extra include path, as some -database drivers require headers for the database they are using, -for example: - - ./configure -qt-sql-psql -I/usr/local/include - -If instead you need to build the PostgreSQL driver as a dynamically -loaded plugin, configure Qt like this: - - ./configure -plugin-sql-psql - -To compile drivers as dynamically loaded plugins, see the -QTDIR/plugins/src/sqldrivers directory. Use 'configure -help' -for a complete list of configure options. See the Qt documentation -for a complete list of supported database drivers. From 64a560d977a0a511ef541d6116d82e7b5c911a92 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 3 Aug 2018 17:55:11 -0700 Subject: [PATCH 35/39] QObject: do allow setProperty() to change the type of the property [ChangeLog][QtCore][QObject] Fixed a bug in setProperty() that caused a property change not to take effect if the old value compared equal using QVariant's equality operator, but the values were not strictly equal. Task-number: QTBUG-69744 Change-Id: I00e04a465fcf4fc1a462fffd1547885861a07a64 Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 3 ++- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 566f75a6c3c..c6fe787e03b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3898,7 +3898,8 @@ bool QObject::setProperty(const char *name, const QVariant &value) d->extraData->propertyNames.append(name); d->extraData->propertyValues.append(value); } else { - if (value == d->extraData->propertyValues.at(idx)) + if (value.userType() == d->extraData->propertyValues.at(idx).userType() + && value == d->extraData->propertyValues.at(idx)) return false; d->extraData->propertyValues[idx] = value; } diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index c734cfe4dd9..ec57522f488 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -2976,6 +2976,7 @@ void tst_QObject::dynamicProperties() QVERIFY(obj.dynamicPropertyNames().isEmpty()); + // set a non-dynamic property QVERIFY(obj.setProperty("number", 42)); QVERIFY(obj.changedDynamicProperties.isEmpty()); QCOMPARE(obj.property("number").toInt(), 42); @@ -2983,19 +2984,30 @@ void tst_QObject::dynamicProperties() QVERIFY(!obj.setProperty("number", "invalid string")); QVERIFY(obj.changedDynamicProperties.isEmpty()); + // set a dynamic property QVERIFY(!obj.setProperty("myuserproperty", "Hello")); QCOMPARE(obj.changedDynamicProperties.count(), 1); QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty")); //check if there is no redundant DynamicPropertyChange events QVERIFY(!obj.setProperty("myuserproperty", "Hello")); QCOMPARE(obj.changedDynamicProperties.count(), 1); - obj.changedDynamicProperties.clear(); + QCOMPARE(obj.property("myuserproperty").type(), QVariant::String); QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello")); QCOMPARE(obj.dynamicPropertyNames().count(), 1); QCOMPARE(obj.dynamicPropertyNames().first(), QByteArray("myuserproperty")); + // change type of the dynamic property + obj.changedDynamicProperties.clear(); + QVERIFY(!obj.setProperty("myuserproperty", QByteArray("Hello"))); + QCOMPARE(obj.changedDynamicProperties.count(), 1); + QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty")); + QCOMPARE(obj.property("myuserproperty").type(), QVariant::ByteArray); + QCOMPARE(obj.property("myuserproperty").toString(), QByteArray("Hello")); + + // unset the property + obj.changedDynamicProperties.clear(); QVERIFY(!obj.setProperty("myuserproperty", QVariant())); QCOMPARE(obj.changedDynamicProperties.count(), 1); From 2841e2b61e32f26900bde987d469c8b97ea31999 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 3 Aug 2018 13:25:15 +0200 Subject: [PATCH 36/39] Check for QImage allocation failure in qgifhandler Since image files easily can be (or corrupt files claim to be) huge, it is worth checking for out of memory situations. Change-Id: I635a3ec6852288079fdec4e14cf7e776fe59e9e0 Reviewed-by: Lars Knoll --- src/plugins/imageformats/gif/qgifhandler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp index e0f7f447014..ebe5964664f 100644 --- a/src/plugins/imageformats/gif/qgifhandler.cpp +++ b/src/plugins/imageformats/gif/qgifhandler.cpp @@ -354,7 +354,8 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, (*image) = QImage(swidth, sheight, format); bpl = image->bytesPerLine(); bits = image->bits(); - memset(bits, 0, image->sizeInBytes()); + if (bits) + memset(bits, 0, image->sizeInBytes()); } // Check if the previous attempt to create the image failed. If it @@ -415,6 +416,10 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, backingstore = QImage(qMax(backingstore.width(), w), qMax(backingstore.height(), h), QImage::Format_RGB32); + if (backingstore.isNull()) { + state = Error; + return -1; + } memset(backingstore.bits(), 0, backingstore.sizeInBytes()); } const int dest_bpl = backingstore.bytesPerLine(); From 5d1809be83c667fc72f58b84d95fbe3e37451350 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sun, 5 Aug 2018 14:12:37 +0200 Subject: [PATCH 37/39] QString: Fix documentation for toDouble() and toFloat() The character 'g' is only a valid format when converting numbers to strings, but not other way round. Change-Id: Ie772886e7a45a5067c0a3e4eaa3a6ccef8e69426 Reviewed-by: Martin Smith --- src/corelib/tools/qstring.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index bb5a1cf8528..82a065efc05 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7177,7 +7177,7 @@ ushort QString::toUShort(bool *ok, int base) const \snippet qstring/main.cpp 66 \warning The QString content may only contain valid numerical characters - which includes the plus/minus sign, the characters g and e used in scientific + which includes the plus/minus sign, the character e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error. @@ -7213,7 +7213,7 @@ double QString::toDouble(bool *ok) const to \c false, and success by setting *\a{ok} to \c true. \warning The QString content may only contain valid numerical characters - which includes the plus/minus sign, the characters g and e used in scientific + which includes the plus/minus sign, the character e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error. From a09a28879e76bb011e0eefe0be0219ce396362d9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 2 Aug 2018 16:41:14 +0200 Subject: [PATCH 38/39] qmake: improve the fake project qt creator's clang code model is a bit more picky than the old one, so we need a project that approximately works. while we're at it, inline qmake.pri, add some missing files, and beautify the source lists. Change-Id: I87ca1db2ee3e55ea08e4c23f7913e882ab44fd21 Reviewed-by: Joerg Bornemann --- qmake/qmake.pri | 169 --------------------------------- qmake/qmake.pro | 243 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 229 insertions(+), 183 deletions(-) delete mode 100644 qmake/qmake.pri diff --git a/qmake/qmake.pri b/qmake/qmake.pri deleted file mode 100644 index f6f6a47e950..00000000000 --- a/qmake/qmake.pri +++ /dev/null @@ -1,169 +0,0 @@ - -#qmake code -SOURCES += project.cpp property.cpp main.cpp \ - library/ioutils.cpp library/proitems.cpp library/qmakevfs.cpp library/qmakeglobals.cpp \ - library/qmakeparser.cpp library/qmakeevaluator.cpp library/qmakebuiltins.cpp \ - generators/makefile.cpp \ - generators/unix/unixmake2.cpp generators/unix/unixmake.cpp meta.cpp \ - option.cpp generators/win32/winmakefile.cpp generators/win32/mingw_make.cpp \ - generators/makefiledeps.cpp generators/metamakefile.cpp generators/mac/pbuilder_pbx.cpp \ - generators/xmloutput.cpp \ - generators/win32/msvc_nmake.cpp generators/projectgenerator.cpp \ - generators/win32/msvc_vcproj.cpp \ - generators/win32/msvc_vcxproj.cpp \ - generators/win32/msvc_objectmodel.cpp generators/win32/msbuild_objectmodel.cpp - -HEADERS += project.h property.h \ - library/qmake_global.h library/ioutils.h library/proitems.h library/qmakevfs.h library/qmakeglobals.h \ - library/qmakeparser.h library/qmakeevaluator.h library/qmakeevaluator_p.h \ - generators/makefile.h \ - generators/unix/unixmake.h meta.h option.h cachekeys.h \ - generators/win32/winmakefile.h generators/win32/mingw_make.h generators/projectgenerator.h \ - generators/makefiledeps.h generators/metamakefile.h generators/mac/pbuilder_pbx.h \ - generators/xmloutput.h generators/win32/msvc_nmake.h \ - generators/win32/msvc_vcproj.h \ - generators/win32/msvc_vcxproj.h \ - generators/win32/msvc_objectmodel.h generators/win32/msbuild_objectmodel.h - -bootstrap { #Qt code - SOURCES+= \ - qbitarray.cpp \ - qbuffer.cpp \ - qarraydata.cpp \ - qbytearray.cpp \ - qbytearraymatcher.cpp \ - qcryptographichash.cpp \ - qdatetime.cpp \ - qdir.cpp \ - qdiriterator.cpp \ - qfiledevice.cpp \ - qfile.cpp \ - qabstractfileengine.cpp \ - qfileinfo.cpp \ - qfilesystementry.cpp \ - qfilesystemengine.cpp \ - qfsfileengine.cpp \ - qfsfileengine_iterator.cpp \ - qglobal.cpp \ - qnumeric.cpp \ - qhash.cpp \ - qiodevice.cpp \ - qlist.cpp \ - qlinkedlist.cpp \ - qlocale.cpp \ - qlocale_tools.cpp \ - qmalloc.cpp \ - qmap.cpp \ - qmetatype.cpp \ - qregexp.cpp \ - qtextcodec.cpp \ - qutfcodec.cpp \ - qstring.cpp \ - qstring_compat.cpp \ - qstringlist.cpp \ - qtemporaryfile.cpp \ - qtextstream.cpp \ - quuid.cpp \ - qsettings.cpp \ - qlibraryinfo.cpp \ - qsystemerror.cpp \ - qvariant.cpp \ - qversionnumber.cpp \ - qvsnprintf.cpp \ - qxmlstream.cpp \ - qxmlutils.cpp \ - qlogging.cpp \ - qjson.cpp \ - qjsondocument.cpp \ - qjsonparser.cpp \ - qjsonarray.cpp \ - qjsonobject.cpp \ - qjsonvalue.cpp - - HEADERS+= \ - qbitarray.h \ - qbuffer.h \ - qarraydata.h \ - qbytearray.h \ - qarraydataops.h \ - qarraydatapointer.h \ - qbytearraymatcher.h \ - qchar.h \ - qcryptographichash.h \ - qdatetime.h \ - qdatetime_p.h \ - qdir.h \ - qdir_p.h \ - qdiriterator.h \ - qfile.h \ - qabstractfileengine_p.h \ - qfileinfo.h \ - qglobal.h \ - qnumeric.h \ - qhash.h \ - qiodevice.h \ - qlist.h \ - qlinkedlist.h \ - qlocale.h \ - qlocale_tools_p.h \ - qmalloc.h \ - qmap.h \ - qmetatype.h \ - qregexp.h \ - qtextcodec.h \ - qutfcodec.h \ - qstring.h \ - qstringlist.h \ - qstringmatcher.h \ - qsystemerror_p.h \ - qtemporaryfile.h \ - qtextstream.h \ - quuid.h \ - qvector.h \ - qversionnumber.h \ - qxmlstream.h \ - qxmlutils.h \ - qjson.h \ - qjsondocument.h \ - qjsonparser.h \ - qjsonwriter.h \ - qjsonarray.h \ - qjsonobject.h \ - qjsonvalue.h - - unix { - SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp - mac { - SOURCES += qcore_mac.cpp qsettings_mac.cpp qcore_mac_objc.mm qlocale_mac.mm - LIBS += -framework ApplicationServices -framework CoreServices -framework Foundation - } else { - SOURCES += qlocale_unix.cpp - } - } else:win32 { - SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qsettings_win.cpp \ - qsystemlibrary.cpp qlocale_win.cpp registry.cpp - win32-msvc*:LIBS += ole32.lib advapi32.lib netapi32.lib - mingw:LIBS += -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32 - } - - qnx { - CFLAGS += -fhonor-std - LFLAGS += -lcpp - } - - DEFINES += QT_BOOTSTRAPPED - - INCLUDEPATH += \ - $$QT.core.includes $$QT.core_private.includes \ - $$shadowed(../src/corelib/global) -} else { - CONFIG += qt - QT = core -} -*-g++:profiling { - QMAKE_CFLAGS = -pg - QMAKE_CXXFLAGS = -pg - QMAKE_LFLAGS = -pg -} - -PRECOMPILED_HEADER = qmake_pch.h diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 000aec45fc0..7c3ce3ef898 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -3,12 +3,101 @@ # and the configures. option(host_build) -CONFIG += console bootstrap -CONFIG -= qt +CONFIG += console +CONFIG -= qt app_bundle + DEFINES += \ + PROEVALUATOR_FULL \ + QT_BOOTSTRAPPED \ QT_BUILD_QMAKE \ QT_NO_FOREACH \ - PROEVALUATOR_FULL + $$shell_quote(QT_VERSION_STR=\"$$QT_VERSION\") \ + QT_VERSION_MAJOR=$$QT_MAJOR_VERSION \ + QT_VERSION_MINOR=$$QT_MINOR_VERSION \ + QT_VERSION_PATCH=$$QT_PATCH_VERSION + +win32: DEFINES += \ + UNICODE \ + _ENABLE_EXTENDED_ALIGNED_STORAGE \ + _CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS + +# qmake code + +PRECOMPILED_HEADER = qmake_pch.h + +INCLUDEPATH += \ + . \ + library \ + generators \ + generators/unix \ + generators/win32 \ + generators/mac + +SOURCES += \ + main.cpp \ + meta.cpp \ + option.cpp \ + project.cpp \ + property.cpp \ + library/ioutils.cpp \ + library/proitems.cpp \ + library/qmakebuiltins.cpp \ + library/qmakeevaluator.cpp \ + library/qmakeglobals.cpp \ + library/qmakeparser.cpp \ + library/qmakevfs.cpp \ + generators/makefile.cpp \ + generators/makefiledeps.cpp \ + generators/metamakefile.cpp \ + generators/projectgenerator.cpp \ + generators/xmloutput.cpp \ + generators/mac/pbuilder_pbx.cpp \ + generators/unix/unixmake.cpp \ + generators/unix/unixmake2.cpp \ + generators/win32/mingw_make.cpp \ + generators/win32/msbuild_objectmodel.cpp \ + generators/win32/msvc_nmake.cpp \ + generators/win32/msvc_objectmodel.cpp \ + generators/win32/msvc_vcproj.cpp \ + generators/win32/msvc_vcxproj.cpp \ + generators/win32/winmakefile.cpp + +HEADERS += \ + cachekeys.h \ + meta.h \ + option.h \ + project.h \ + property.h \ + library/ioutils.h \ + library/proitems.h \ + library/qmake_global.h \ + library/qmakeevaluator.h \ + library/qmakeevaluator_p.h \ + library/qmakeglobals.h \ + library/qmakeparser.h \ + library/qmakevfs.h \ + generators/makefile.h \ + generators/makefiledeps.h \ + generators/metamakefile.h \ + generators/projectgenerator.h \ + generators/xmloutput.h \ + generators/mac/pbuilder_pbx.h \ + generators/unix/unixmake.h \ + generators/win32/mingw_make.h \ + generators/win32/msbuild_objectmodel.h \ + generators/win32/msvc_nmake.h \ + generators/win32/msvc_objectmodel.h \ + generators/win32/msvc_vcproj.h \ + generators/win32/msvc_vcxproj.h \ + generators/win32/winmakefile.h + +# qt code + +bp = $$shadowed(..) +INCLUDEPATH += \ + $$bp/include $$bp/include/QtCore \ + $$bp/include/QtCore/$$QT_VERSION $$bp/include/QtCore/$$QT_VERSION/QtCore + $$bp/src/corelib/global VPATH += \ ../src/corelib/global \ @@ -17,17 +106,143 @@ VPATH += \ ../src/corelib/codecs \ ../src/corelib/plugin \ ../src/corelib/io \ - ../src/corelib/serialization \ - ../tools/shared/windows + ../src/corelib/serialization -INCLUDEPATH += . \ - library \ - generators \ - generators/unix \ - generators/win32 \ - generators/mac \ - ../tools/shared +SOURCES += \ + qabstractfileengine.cpp \ + qarraydata.cpp \ + qbitarray.cpp \ + qbuffer.cpp \ + qbytearray.cpp \ + qbytearraymatcher.cpp \ + qcryptographichash.cpp \ + qdatetime.cpp \ + qdir.cpp \ + qdiriterator.cpp \ + qfile.cpp \ + qfiledevice.cpp \ + qfileinfo.cpp \ + qfilesystemengine.cpp \ + qfilesystementry.cpp \ + qfsfileengine.cpp \ + qfsfileengine_iterator.cpp \ + qglobal.cpp \ + qhash.cpp \ + qiodevice.cpp \ + qjson.cpp \ + qjsonarray.cpp \ + qjsondocument.cpp \ + qjsonobject.cpp \ + qjsonparser.cpp \ + qjsonvalue.cpp \ + qlibraryinfo.cpp \ + qlinkedlist.cpp \ + qlist.cpp \ + qlocale.cpp \ + qlocale_tools.cpp \ + qlogging.cpp \ + qmalloc.cpp \ + qmap.cpp \ + qmetatype.cpp \ + qnumeric.cpp \ + qregexp.cpp \ + qsettings.cpp \ + qstring.cpp \ + qstring_compat.cpp \ + qstringlist.cpp \ + qsystemerror.cpp \ + qtemporaryfile.cpp \ + qtextcodec.cpp \ + qtextstream.cpp \ + qutfcodec.cpp \ + quuid.cpp \ + qvariant.cpp \ + qversionnumber.cpp \ + qvsnprintf.cpp \ + qxmlstream.cpp \ + qxmlutils.cpp -include(qmake.pri) +HEADERS += \ + qabstractfileengine_p.h \ + qarraydata.h \ + qarraydataops.h \ + qarraydatapointer.h \ + qbitarray.h \ + qbuffer.h \ + qbytearray.h \ + qbytearraymatcher.h \ + qchar.h \ + qcryptographichash.h \ + qdatetime.h \ + qdatetime_p.h \ + qdir.h \ + qdir_p.h \ + qdiriterator.h \ + qfile.h \ + qfileinfo.h \ + qglobal.h \ + qhash.h \ + qiodevice.h \ + qjson.h \ + qjsonarray.h \ + qjsondocument.h \ + qjsonobject.h \ + qjsonparser.h \ + qjsonvalue.h \ + qjsonwriter.h \ + qlinkedlist.h \ + qlist.h \ + qlocale.h \ + qlocale_tools_p.h \ + qmalloc.h \ + qmap.h \ + qmetatype.h \ + qnumeric.h \ + qregexp.h \ + qstring.h \ + qstringlist.h \ + qstringmatcher.h \ + qsystemerror_p.h \ + qtemporaryfile.h \ + qtextcodec.h \ + qtextstream.h \ + qutfcodec.h \ + quuid.h \ + qvector.h \ + qversionnumber.h \ + qxmlstream.h \ + qxmlutils.h -load(qt_app) +unix { + SOURCES += \ + qcore_unix.cpp \ + qfilesystemengine_unix.cpp \ + qfilesystemiterator_unix.cpp \ + qfsfileengine_unix.cpp \ + qlocale_unix.cpp + macos { + SOURCES += \ + qcore_foundation.mm \ + qcore_mac.cpp \ + qoperatingsystemversion_darwin.mm \ + qsettings_mac.cpp + LIBS += \ + -framework ApplicationServices \ + -framework CoreServices \ + -framework Foundation + QMAKE_CXXFLAGS += -fconstant-cfstrings + } +} else { + SOURCES += \ + qfilesystemengine_win.cpp \ + qfilesystemiterator_win.cpp \ + qfsfileengine_win.cpp \ + qlocale_win.cpp \ + qoperatingsystemversion_win.cpp \ + qsettings_win.cpp \ + qsystemlibrary.cpp \ + registry.cpp + LIBS += -lole32 -ladvapi32 -lkernel32 -lnetapi32 + mingw: LIBS += -luuid + clang: QMAKE_CXXFLAGS += -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value +} From f271dd8f960ad9f61697dfa57b26c4071441cadc Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Mon, 6 Aug 2018 15:27:21 +0200 Subject: [PATCH 39/39] Windows QPA: Fix UIA-to-MSAA accessibility bridge According to MS sample code, MSAA requests should be replied with UI Automation providers to enable the use the UIA-to-MSAA bridge, in order to support MSAA-only clients. Also changing the mapping of QAccessible::Client from UIA_CustomControlTypeId to UIA_GroupControlTypeId, as it seems more appropriate and avoids an incorrect mapping to a push button type in the UIA-to-MSAA conversion. Change-Id: I5149d250da2d1bd7b14b44ca46e856a81c9be045 Reviewed-by: Friedemann Kleint --- .../uiautomation/qwindowsuiaaccessibility.cpp | 23 ++++++++----------- .../windows/uiautomation/qwindowsuiautils.cpp | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp index 907883bf5b9..0f0f42fafee 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp @@ -68,21 +68,18 @@ QWindowsUiaAccessibility::~QWindowsUiaAccessibility() // Handles UI Automation window messages. bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) { - if (lParam == LPARAM(UiaRootObjectId)) { + // Start handling accessibility internally + QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); - // Start handling accessibility internally - QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); + // Ignoring all requests while starting up / shutting down + if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) + return false; - // Ignoring all requests while starting up / shutting down - if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) - return false; - - if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { - if (QAccessibleInterface *accessible = window->accessibleRoot()) { - QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible); - *lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider); - return true; - } + if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { + if (QAccessibleInterface *accessible = window->accessibleRoot()) { + QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible); + *lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider); + return true; } } return false; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp index 89e5075dcb0..f777a59ce93 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -149,7 +149,7 @@ long roleToControlTypeId(QAccessible::Role role) {QAccessible::Caret, UIA_CustomControlTypeId}, {QAccessible::AlertMessage, UIA_CustomControlTypeId}, {QAccessible::Window, UIA_WindowControlTypeId}, - {QAccessible::Client, UIA_CustomControlTypeId}, + {QAccessible::Client, UIA_GroupControlTypeId}, {QAccessible::PopupMenu, UIA_MenuControlTypeId}, {QAccessible::MenuItem, UIA_MenuItemControlTypeId}, {QAccessible::ToolTip, UIA_ToolTipControlTypeId},