diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0 new file mode 100644 index 0000000000..f8e2330311 --- /dev/null +++ b/dist/changes-5.15.0 @@ -0,0 +1,444 @@ +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Calling QList::insert() or removeAt() with an out of bounds index is + deprecated and will no longer be supported in Qt 6. + +**************************************************************************** +* Potentially Binary-Incompatible Changes * +**************************************************************************** + + - QHash: + QHash's iterator category was changed from bidirectional iterator to + forward iterator. This may cause trouble if a library uses the + iterator category to alter functionality through tag dispatching. This + only applies when compiling the library or application with + QT_DISABLE_DEPRECATED_BEFORE=0x050F00 and the other with a lower value. + +**************************************************************************** +* Deprecation Notice * +**************************************************************************** + + - The binary JSON representation is deprecated. The CBOR format should be + used instead. + + - [QTBUG-80308] QUrl::topLevelDomain() was deprecated in 5.15 and will be + removed in 6.0 + + - QtNetwork: + * QNetworkConfigurationManager, QNetworkConfiguration and QNetworkSession + are deprecated, to be removed in Qt 6. + + - [REVERTED] [QTBUG-80369] QAbstractSocket::error() (the getter) is + deprecated; superseded by socketError(). + - [REVERTED] [QTBUG-80369] QLocalSocket::error() (the getter) is + deprecated; superseded by socketError(). + - [QTBUG-80369] QSslSocket::sslErrors() (the getter) was deprecated and + superseded by sslHandshakeErrors() + - [REVERTED] [QTBUG-80369] QNetworkReply::error() (the getter) was + deprecated; superseded by networkError(). + - [QTBUG-81630][QTBUG-80312] QLinkedList is deprecated and will be moved + to Qt5Compat in Qt 6. It is recommended to use std::list instead. + - QLocalSocket::error() (the signal) is deprecated; superseded by + errorOccurred() + - QAbstractSocket::error() (the signal) is deprecated; superseded by + errorOccurred() + - QNetworkReply::error() (the signal) is deprecated; superseded by + errorOccurred() + +See also the various sections below, which include many more deprecations. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - QCalendar::monthsInYear(QCalendar::Unspecified) now returns + maximumMonthsInYear(). QCalendar::daysInYear() now makes clear that its + handling of unspecified year is undefined. + + - Containers: + * Added operator-> to the key-value iterator for QHash/QMap. + + - QAbstractItemModel: + * [QTBUG-72587] The match() method now supports the new + Qt::RegularExpression match flag value. This will allow users to use + either a string or a fully configured QRegularExpression when doing + searches. In the second case, the case sensitivity flag will be + ignored if passed. + + - QByteArray: + * resize() will no longer shrink the capacity. That means resize(0) now + reliably preserves capacity(). + * Added the new fromBase64Encoding function. + * Added new flags to make fromBase64 / fromBase64Encoding strictly + validate their input, instead of skipping over invalid characters. + + - QCborArray: + * Fixed an infinite loop when operator[] was called with an index larger + than the array's size plus 1. + + - QCborMap: + * [QTBUG-83366] Fixed some issues relating to assigning elements from a + map to itself. + + - QCborValue: + * fromCbor() now limits decoding to at most 1024 nested maps, arrays, + and tags to prevent stack overflows. This should be sufficient for + most uses of CBOR. An API to limit further or to relax the limit will + be provided in 5.15. Meanwhile, if decoding more is required, + QCborStreamReader can be used (note that each level of map and array + allocates memory). + + - QDate: + * QDate::toString(Qt::DateFormat, QCalendar) no longer takes calendar + into account for Qt::TextDate. There was no matching support in + QDateTime and the locale-independent formats are intended to be + standard, rather than customized to the user. + + - QDateTime: + * Added some missing QCalendar variants of QDateTime::toString(). + Included docs for QCalendar variants in both QDate and QDateTime. + + - QFile: + * Introduce QFile::moveToTrash to allow applications to move files to + the trash. + + - QFileInfo: + * [QTBUG-75869] Add QFileInfo::isJunction so that applications can + recognize NTFS file system entries as junctions + + - QHash: + * Reverse iteration over QHash is now deprecated. + * insertMulti(), unite() and values(const Key &key) are now deprecated. + Please use QMultiHash instead. + + - QJsonObject: + * Fixed a regression from 5.13 that incorrect results when assigning + elements from an object to itself. + + - QLatin1String: + * Added compare(). + + - QLibrary and QPluginLoader: + * [QTBUG-39642] Fixed a deadlock that would happen if the plugin or + library being loaded has load-time initialization code (C++ global + variables) that recursed back into the same QLibrary or QPluginLoader + object. + + - QLocale: + * Deprecated toTime() variants taking a calendar. The calendar is + ignored in time parsing. + * Data used for currency formats in several locales and list patterns in + some locales have changed due to now parsing the CLDR data more + faithfully. + * [QTBUG-79902] Currency formats are now based on CLDR's accounting + formats, where they were previously mostly based (more or less by + accident) on standard formats. In particular, this now means negative + currency formats are specified, where available, where they (mostly) + were not previously. + + - QMap: + * [QTBUG-35544] insertMulti(), unite(), values(Key), uniqueKeys(), + count(Key) is now deprecated. Please use QMultiMap instead. + + - QObject: + * [QTBUG-76375] A logging category + qt.core.qmetaobject.connectslotsbyname was added, which will report + on the connections made by QMetaObject::connectSlotsByName(). + + - QProcess: + * Overloads of start/execute/startDatached that parse a single command + string into program and arguments have been marked as deprecated. A + static helper splitCommand has been added to construct a QStringList + from a command string. + + - QRandomGenerator: + * The system() random generator will now use the RDSEED instruction on + x86 processors whenever available as the first source of random data. + It will fall back to RDRAND and then to the system functions, in that + order. + + - QRegularExpression: + * The escape(), wildcardToRegularExpression() and anchoredPattern() + functions now have overloads taking a QStringView parameter. + + - QResource: + * Added uncompressedSize() and uncompressedData(), which will perform + any required decompression on the data, prior to returning (unlike + data() and size()). + + - QSet: + * Reverse iteration over QSet is now deprecated. + + - QStandardPaths: + * When used in a low-integrity process on Windows, + QStandardPaths::writableLocation returns respective low-integrity + paths. + + - QString: + * Added QString::isValidUtf16. + + - QStringView: + * Added QStringView::isValidUtf16. + * Added compare() overloads taking QLatin1String, QChar. + * Conversion from std::basic_string can now be constexpr (when + std::basic_string is). + + - QTimeZone: + * The constructor can now handle general UTC-offset zone names. The + reported id() of such a zone shall be in canonical form, so might not + match the ID passed to the constructor. + + - QXmlStream: + * QXmlStreamReader does now by default limit the expansion of entities + to 4096 characters. Documents where a single entity expands to more + characters than the limit are not considered well formed. The limit is + there to avoid DoS attacks through recursively expanding entities when + loading untrusted content. The limit can be changed through the + QXmlStreamReader::setEntityExpansionLimit() method. + + - moc: + * Moc now correctly sets a non-null QMetaObject::superClass for + Q_GADGETs that inherit from a template which inherits another + Q_GADGET. + * [QTBUG-74521][QTBUG-76598] moc can now output a ".d" dep file that can + be consumed by other build systems. + +**************************************************************************** +* QtGui * +**************************************************************************** + + - Extended QVulkanWindow to allow user to specify additional queues to be + created. + - Added API for starting interactive window resize and move operations + handled by the system. + + - QClipboard: + * Support lazily-provided copying of data to the clipboard on macOS + + - QCursor: + * [QTBUG-48701] QCursor::bitmap() and QCursor::mask() can now return + by-value instead of by-pointer. + + - QFont: + * Deprecated QFont::ForceIntegerMetrics and QFont::OpenGLCompatible, + with the intention of removing them in Qt 6.0.0. + + - QMarkdownWriter: + * [QTBUG-80603] Code blocks are no longer word-wrapped; the beginning + fence of a code block no longer has a space before the language string; + and the ending fence is no longer skipped in some cases where it was. + + - QPdfWriter: + * New API to provide external document XMP metadata and attach files to + PDF. + + - QTabletEvent: + * QTabletEvent::device() is deprecated, because the plan is to return + an object pointer in Qt 6 rather than an enum. The enum is now provided + by deviceType(). + * hiResGlobalX() and hiResGlobalY() are deprecated, because globalPosF() + has the same resolution. But globalPosF() (and several others) will + probably be renamed in Qt 6. The replacements are not in place yet. + * [QTBUG-77826] Local coordinates are now correct when the event is + delivered to a nested window on X11. + + - Text: + * Fixed a problem where pixel sizes would be truncated before calculating + glyph positions. + * Fixed an issue with QFont::PreferNoShaping where boxes would appear in + place of unprintable characters. + * Fixed a problem where certain bold fonts would be synthetically + emboldened by Qt when using the Freetype font engine. + + - Application palettes are now resolved against the platform's theme + palette, the same way widget palettes are resolved against their parents, + and the application palette. This means the application palette reflected + through QGuiApplication::palette() may not be exactly the same palette as + set via QGuiApplication::setPalette(). + +**************************************************************************** +* QtWidgets * +**************************************************************************** + + - Added QStyleOptionTabV4 as a subclass of QStyleOptionTab so that the + tab's index information can be obtained. + + - ItemViews: + * [QTBUG-76423] The convenience views QList/Table/TreeWidgetItem now + treat a default constructed QBrush or QSize as an empty QVariant which + allows resetting of the values set to it's default values. + + - QApplication: + * The globalStrut property has been deprecated and will be removed from + Qt 6. + + - QButtonGroup: + * Added signals idClicked/Pressed/Released/Toggled that replace the + deprecated signal overloads. + + - QComboBox: + * QComboBox got a new property 'placeholderText' + * Support checkable items in styles that use a popup for the dropdown. + * the SizeAdjustPolicy value AdjustToMinimumContentLength is deprecated, + use AdjustToContents or AdjustToContentsOnFirstShow instead. + + - QGraphicsView: + * Fixed a bug where hover events would not be delivered if the item was + added while blocked by a modal panel. + + - QLabel: + * [QTBUG-48701] QLabel::pixmap() and QLabel::picture() can now return + by-value instead of by-pointer. + + - QLineEdit: + * Inputmask X character now requires non-blank input. + + - QMenu: + * a popup menu hides when a QWidgetAction added to it fires the + triggered signal. + + - QShortcut: + * QShortcut ctor has now pointer to member function overloads + + - QStyle: + * You can now set the CSS property 'icon' on a QPushButton to override + which icon to draw. + + - QSystemTrayIcon: + * On macOS, clicking on the message will remove the notification. + + - QTabWidget/QTabBar: + * Tabs can now be hidden with setTabVisible + + - QWidget: + * Fonts and palette settings are inherited by children from their + parents even if the children have application-wide platform theme + overrides. + + - QWizard: + * visitedPages has been deprecated, use visitedIds instead. + +**************************************************************************** +* QtNetwork * +**************************************************************************** + + - A new signal introduced to report when a valid session ticket is received + (TLS 1.3) + + - SSL: + * Removed OpenSSL 1.0.x support, now 1.1.x is required + * The minimum required version of OpenSSL is now 1.1.1. + + - QSslCertificate: + * [QTBUG-72587] Add overload of fromPath that does not make use of + QRegExp and deprecate the QRegExp variant. + +**************************************************************************** +* QtSql * +**************************************************************************** + + - QMYSQL: + * Removed support for MySql < 5.0 since 5.0 was released 14 years ago. + * The QMYSQL plugin can now be build with the MariaDB C connector libs + on Windows. + + - QSqlDriver: + * The one-arg version of QSqlDriver::notifcation() is now deprecated. + +**************************************************************************** +* QTestLib * +**************************************************************************** + + - The formerly named 'xunitxml' test reporter has been renamed to what it + actually is: a JUnit test reporter, and is now triggered by passing -o + junitxml to the test binary. + +**************************************************************************** +* QtXml * +**************************************************************************** + + - [QTBUG-76177] SAX classes are now deprecated. Use QXmlStreamReader, + QXmlStreamWriter in QtCore instead. + +**************************************************************************** +* Configure * +**************************************************************************** + + - Add switch "-coverage source-based" to enable clang's "source-based" code + coverage feature. This can be used for code coverage analysis. + + - X11: + * [QTBUG-67277][QTBUG-30939] The minimal required version of libxcb now + is 1.11. + * [QTBUG-67277][QTBUG-30939] Removed -qt-xcb, -system-xcb, -xkb, + -xcb-xinput switches. + +**************************************************************************** +* cmake * +**************************************************************************** + + - Fixed an issue where some Qt location and declarative plugins whose name + did not end with "Plugin" where not imported by the corresponding Qt + component package. + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - libjpeg-turbo was updated to version 2.0.4 + + - X11: + * [QTBUG-67277][QTBUG-30939] Removed all bundled XCB libs, with the + exception of xcb-xinput, which is not available on systems with libxcb + 1.11. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + - Linux: + * Enable accessibility on Linux when Orca is started by hand + * [QTBUG-78754] Vulkan is now supported by eglfs (eglfs_viv backend) on + i.MX8 devices with the Vivante graphics stack. This is done via + VK_KHR_display so no windowing system is required. + + - X11: + * [QTBUG-67277][QTBUG-30939] XKB and XInput2 now are mandatory + dependencies for XCB plugin. XCB-XKB is a part of libxcb 1.11 + releases. XCB-XInput is not part of libxcb 1.11 releases, but Qt + builders can use the -bundled-xcb-xinput switch. + + - Android: + * [REVERTED] Qt::MaximizeUsingFullscreenGeometryHint window flag is + now supported, and will make the window fullscreen, but keep the + system UI on-screen, with a translucent background color. + * [QTBUG-82120] Use native file dialog by default for open and save + operations. + + - Windows: + * Fixed a bug where some fonts would not be accessible by + referencing their typographic name. + * Fixed a 2 pixel offset on glyphs when using color fonts or any + hinting preference other than the default (full) hinting. + + - WebAssembly: + * Updated emscripten to version 1.39.8 diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp index c343ee81b9..0d56858514 100644 --- a/examples/network/torrent/mainwindow.cpp +++ b/examples/network/torrent/mainwindow.cpp @@ -407,7 +407,7 @@ bool MainWindow::addTorrent(const QString &fileName, const QString &destinationF QString baseFileName = QFileInfo(fileName).fileName(); if (baseFileName.toLower().endsWith(".torrent")) - baseFileName.remove(baseFileName.size() - 8); + baseFileName.chop(8); item->setText(0, baseFileName); item->setToolTip(0, tr("Torrent: %1
Destination: %2") diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index fc46bcb74b..6fe0059bf7 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -279,11 +279,22 @@ contains(all_qt_module_deps, qml): \ for (QMLPATH, QMLPATHS): \ IMPORTPATHS += -importPath $$system_quote($$QMLPATH) - # add qrc files, too - !isEmpty(RESOURCES) { - IMPORTPATHS += -qrcFiles - for (RESOURCE, RESOURCES): \ - IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_) + # add resources to qmlimportscanner + for (RESOURCE, RESOURCES) { + defined($${RESOURCE}.files, var) { + # in case of a "struct", add the struct's files + base = $$RESOURCE.base + for (f, $$RESOURCE.files): SCANNERRESOURCES += "$$base/$$f" + } else { + # if the resource is a file, just add it + SCANNERRESOURCES += $$RESOURCE + } + } + + !isEmpty(SCANNERRESOURCES) { + IMPORTPATHS += -qrcFiles + for (RESOURCE, SCANNERRESOURCES) + IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_) } diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index 72b47bce27..15b373ba40 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -74,6 +74,7 @@ sourcefiles += \ extras = \ $$_PRO_FILE_PWD_/README \ $$_PRO_FILE_PWD_/README.TXT \ + $$_PRO_FILE_PWD_/qmldir \ $$files($$_PRO_FILE_PWD_/*.pri) \ $$replace(_PRO_FILE_, \\.pro$, .qmlproject) \ $$replace(_PRO_FILE_, \\.pro$, .json) \ @@ -140,6 +141,9 @@ equals(TEMPLATE, app)|equals(TEMPLATE, lib) { SOURCES = OBJECTIVE_SOURCES = INSTALLS -= target + QMAKE_SUBSTITUTES = + QMAKE_EXTRA_COMPILERS = + COPIES = } else { CONFIG += relative_qt_rpath # Examples built as part of Qt should be relocatable } diff --git a/mkspecs/features/uikit/default_post.prf b/mkspecs/features/uikit/default_post.prf index c1b6f38a6c..088b39ff3f 100644 --- a/mkspecs/features/uikit/default_post.prf +++ b/mkspecs/features/uikit/default_post.prf @@ -43,7 +43,7 @@ macx-xcode { warning("You need to update Xcode to version 6 or newer to fully support iPhone6/6+") } else { # Set up default LaunchScreen to support iPhone6/6+ - qmake_launch_screen = LaunchScreen.xib + qmake_launch_screen = LaunchScreen.storyboard qmake_copy_launch_screen.input = $$QMAKESPEC/$$qmake_launch_screen qmake_copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$qmake_launch_screen QMAKE_SUBSTITUTES += qmake_copy_launch_screen diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 22bda003fb..279971bd65 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -36,8 +36,9 @@ VCLIBS = $${VCLIBS}.Debug else: \ VCLIBS = $${VCLIBS} - # VS 2017 still uses vclibs 140 + # VS 2017 and 2019 still use vclibs 140 contains(MSVC_VER, "15.0"): VCLIBS = $$replace(VCLIBS, 150, 140) + contains(MSVC_VER, "16.0"): VCLIBS = $$replace(VCLIBS, 160, 140) VCLIBS = "$${VCLIBS}\" MinVersion=\"14.0.0.0\" Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" WINRT_MANIFEST.dependencies += $$VCLIBS } @@ -68,12 +69,10 @@ isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en - *-msvc2015|*-msvc2017 { - isEmpty(WINRT_MANIFEST.minVersion): \ - WINRT_MANIFEST.minVersion = $$WINDOWS_TARGET_PLATFORM_VERSION - isEmpty(WINRT_MANIFEST.maxVersionTested): \ - WINRT_MANIFEST.maxVersionTested = $$WINDOWS_TARGET_PLATFORM_MIN_VERSION - } + isEmpty(WINRT_MANIFEST.minVersion): \ + WINRT_MANIFEST.minVersion = $$WINDOWS_TARGET_PLATFORM_VERSION + isEmpty(WINRT_MANIFEST.maxVersionTested): \ + WINRT_MANIFEST.maxVersionTested = $$WINDOWS_TARGET_PLATFORM_MIN_VERSION INDENT = "$$escape_expand(\\r\\n) " diff --git a/mkspecs/macx-ios-clang/LaunchScreen.storyboard b/mkspecs/macx-ios-clang/LaunchScreen.storyboard new file mode 100644 index 0000000000..7d8d9a3405 --- /dev/null +++ b/mkspecs/macx-ios-clang/LaunchScreen.storyboard @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mkspecs/macx-ios-clang/LaunchScreen.xib b/mkspecs/macx-ios-clang/LaunchScreen.xib deleted file mode 100644 index d28c06b375..0000000000 --- a/mkspecs/macx-ios-clang/LaunchScreen.xib +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index c45a09ad99..a3729b4ef9 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1561,8 +1561,6 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) if (newSize > MaxByteArraySize) return -1; - // since usedData <= data.size(), this can't overflow - usedData += increment; data.resize(newSize); return offset; }; @@ -1635,7 +1633,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) } // update size - if (e.flags & Element::HasByteData) { + if (r.status == QCborStreamReader::EndOfString && e.flags & Element::HasByteData) { auto b = new (dataPtr() + e.value) ByteData; b->len = data.size() - e.value - int(sizeof(*b)); usedData += b->len; diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 850e878571..36429662fc 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -577,7 +577,7 @@ void QJsonObject::removeImpl(T key) if (!keyExists) return; - removeAt(index); + removeAt(index / 2); } #if QT_STRINGVIEW_LEVEL < 2 @@ -629,7 +629,7 @@ QJsonValue QJsonObject::takeImpl(T key) return QJsonValue(QJsonValue::Undefined); const QJsonValue v = QJsonPrivate::Value::fromTrustedCbor(o->extractAt(index + 1)); - removeAt(index); + removeAt(index / 2); return v; } @@ -1486,8 +1486,8 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) void QJsonObject::removeAt(int index) { detach2(); - o->removeAt(index + 1); - o->removeAt(index); + o->removeAt(2 * index + 1); + o->removeAt(2 * index); } uint qHash(const QJsonObject &object, uint seed) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 210a8afc53..54a2f9cdd2 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -1803,57 +1803,39 @@ const QString::Null QString::null = { }; /*! \typedef QString::const_iterator - This typedef provides an STL-style const iterator for QString. - \sa QString::iterator */ /*! \typedef QString::iterator - The QString::iterator typedef provides an STL-style non-const - iterator for QString. - \sa QString::const_iterator */ /*! \typedef QString::const_reverse_iterator \since 5.6 - This typedef provides an STL-style const reverse iterator for QString. - \sa QString::reverse_iterator, QString::const_iterator */ /*! \typedef QString::reverse_iterator \since 5.6 - This typedef provides an STL-style non-const reverse iterator for QString. - \sa QString::const_reverse_iterator, QString::iterator */ /*! \typedef QString::size_type - - The QString::size_type typedef provides an STL-style type for sizes (int). */ /*! \typedef QString::difference_type - - The QString::size_type typedef provides an STL-style type for difference between pointers. */ /*! \typedef QString::const_reference - - This typedef provides an STL-style const reference for a QString element (QChar). */ /*! \typedef QString::reference - - This typedef provides an STL-style - reference for a QString element (QChar). */ /*! @@ -1871,8 +1853,6 @@ const QString::Null QString::null = { }; /*! \typedef QString::value_type - - This typedef provides an STL-style value type for QString. */ /*! \fn QString::iterator QString::begin() @@ -9537,8 +9517,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::iterator \since 5.10 - This typedef provides an STL-style const iterator for QLatin1String. - QLatin1String does not support mutable iterators, so this is the same as const_iterator. @@ -9549,8 +9527,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::const_iterator \since 5.10 - This typedef provides an STL-style const iterator for QLatin1String. - \sa iterator, const_reverse_iterator */ @@ -9558,8 +9534,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::reverse_iterator \since 5.10 - This typedef provides an STL-style const reverse iterator for QLatin1String. - QLatin1String does not support mutable reverse iterators, so this is the same as const_reverse_iterator. @@ -9570,8 +9544,6 @@ QString &QString::setRawData(const QChar *unicode, int size) \typedef QLatin1String::const_reverse_iterator \since 5.10 - This typedef provides an STL-style const reverse iterator for QLatin1String. - \sa reverse_iterator, const_iterator */ @@ -10472,8 +10444,6 @@ QDataStream &operator>>(QDataStream &in, QString &str) \typedef QStringRef::const_iterator \since 5.4 - This typedef provides an STL-style const iterator for QStringRef. - \sa QStringRef::const_reverse_iterator */ @@ -10481,8 +10451,6 @@ QDataStream &operator>>(QDataStream &in, QString &str) \typedef QStringRef::const_reverse_iterator \since 5.7 - This typedef provides an STL-style const reverse iterator for QStringRef. - \sa QStringRef::const_iterator */ diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 34d2b8d8c7..506ebc797f 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -2016,6 +2016,21 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt } } +static void copy_8bit_pixels(QImageData *dest, const QImageData *src) +{ + if (src->bytes_per_line == dest->bytes_per_line) { + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + } else { + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + memcpy(ddata, sdata, src->width); + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; + } + } +} + static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_Indexed8); @@ -2031,11 +2046,15 @@ static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, } if (simpleCase) - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); else { - qsizetype size = src->bytes_per_line * src->height; - for (qsizetype i = 0; i < size; ++i) { - dest->data[i] = translate[src->data[i]]; + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + for (int x = 0; x < src->width; ++x) + ddata[x] = translate[sdata[x]]; + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; } } } @@ -2055,11 +2074,15 @@ static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *s } if (simpleCase) - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); else { - qsizetype size = src->bytes_per_line * src->height; - for (qsizetype i = 0; i < size; ++i) { - dest->data[i] = translate[src->data[i]]; + const uchar *sdata = src->data; + uchar *ddata = dest->data; + for (int y = 0; y < src->height; ++y) { + for (int x = 0; x < src->width; ++x) + ddata[x] = translate[sdata[x]]; + sdata += src->bytes_per_line; + ddata += dest->bytes_per_line; } } } @@ -2107,7 +2130,7 @@ static void convert_Alpha8_to_Indexed8(QImageData *dest, const QImageData *src, Q_ASSERT(src->format == QImage::Format_Alpha8); Q_ASSERT(dest->format == QImage::Format_Indexed8); - memcpy(dest->data, src->data, src->bytes_per_line * src->height); + copy_8bit_pixels(dest, src); dest->colortable = defaultColorTables->alpha; } @@ -2117,8 +2140,7 @@ static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *s Q_ASSERT(src->format == QImage::Format_Grayscale8); Q_ASSERT(dest->format == QImage::Format_Indexed8); - memcpy(dest->data, src->data, src->bytes_per_line * src->height); - + copy_8bit_pixels(dest, src); dest->colortable = defaultColorTables->gray; } diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 466e70db30..68f2d0392f 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -951,6 +951,7 @@ QWheelEvent::~QWheelEvent() /*! \fn QPoint QWheelEvent::position() const + \since 5.14 Returns the position of the mouse cursor relative to the widget that received the event. diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 94ba004c93..7fb075d19e 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -162,12 +162,12 @@ QT_END_NAMESPACE if (icon.isNull()) return nil; - auto nsImage = [[NSImage alloc] initWithSize:NSZeroSize]; - auto availableSizes = icon.availableSizes(); if (availableSizes.isEmpty() && size > 0) availableSizes << QSize(size, size); + auto nsImage = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease]; + for (QSize size : qAsConst(availableSizes)) { QImage image = icon.pixmap(size).toImage(); if (image.isNull()) @@ -182,12 +182,15 @@ QT_END_NAMESPACE [nsImage addRepresentation:[imageRep autorelease]]; } + if (!nsImage.representations.count) + return nil; + [nsImage setTemplate:icon.isMask()]; if (size) nsImage.size = CGSizeMake(size, size); - return [nsImage autorelease]; + return nsImage; } @end diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 8f0d7d9d38..1b681a2a9f 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -420,7 +420,9 @@ QFontEngineData::~QFontEngineData() be removed with removeSubstitutions(). Use substitute() to retrieve a family's first substitute, or the family name itself if it has no substitutes. Use substitutes() to retrieve a list of a family's - substitutes (which may be empty). + substitutes (which may be empty). After substituting a font, you must + trigger the updating of the font by destroying and re-creating all + QFont objects. Every QFont has a key() which you can use, for example, as the key in a cache or dictionary. If you want to store a user's font @@ -1864,6 +1866,9 @@ QStringList QFont::substitutes(const QString &familyName) Inserts \a substituteName into the substitution table for the family \a familyName. + After substituting a font, trigger the updating of the font by destroying + and re-creating all QFont objects. + \sa insertSubstitutions(), removeSubstitutions(), substitutions(), substitute(), substitutes() */ void QFont::insertSubstitution(const QString &familyName, @@ -1882,6 +1887,10 @@ void QFont::insertSubstitution(const QString &familyName, Inserts the list of families \a substituteNames into the substitution list for \a familyName. + After substituting a font, trigger the updating of the font by destroying + and re-creating all QFont objects. + + \sa insertSubstitution(), removeSubstitutions(), substitutions(), substitute() */ void QFont::insertSubstitutions(const QString &familyName, diff --git a/src/network/ssl/qasn1element.cpp b/src/network/ssl/qasn1element.cpp index 6558643386..5634332a67 100644 --- a/src/network/ssl/qasn1element.cpp +++ b/src/network/ssl/qasn1element.cpp @@ -45,6 +45,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -120,7 +121,7 @@ bool QAsn1Element::read(QDataStream &stream) return false; // length - qint64 length = 0; + quint64 length = 0; quint8 first; stream >> first; if (first & 0x80) { @@ -139,11 +140,13 @@ bool QAsn1Element::read(QDataStream &stream) length = (first & 0x7f); } + if (length > quint64(std::numeric_limits::max())) + return false; // value QByteArray tmpValue; tmpValue.resize(length); int count = stream.readRawData(tmpValue.data(), tmpValue.size()); - if (count != length) + if (count != int(length)) return false; mType = tmpType; diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index a2280a7d10..74fb691dde 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -278,8 +278,6 @@ /*! \typedef QDtls::GeneratorParameters - - This is a synonym for QDtlsClientVerifier::GeneratorParameters. */ /*! diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 245db429c5..9b57b89529 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -472,7 +472,9 @@ QList *QCocoaIntegration::popupWindowStack() void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const { - NSApp.applicationIconImage = [NSImage imageFromQIcon:icon]; + // Fall back to a size that looks good on the highest resolution screen available + auto fallbackSize = NSApp.dockTile.size.width * qGuiApp->devicePixelRatio(); + NSApp.applicationIconImage = [NSImage imageFromQIcon:icon withSize:fallbackSize]; } void QCocoaIntegration::beep() const diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index e4dd4cf6c6..6a3172fb19 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -614,7 +614,11 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) QRect windowRect; for (uint i = 0; i < displayCount; ++i) { QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(displays[i])).toRect(); - windowRect = windowRect.united(displayBounds); + // Only include the screen if it is positioned past the x/y position + if ((displayBounds.x() >= x || displayBounds.right() > x) && + (displayBounds.y() >= y || displayBounds.bottom() > y)) { + windowRect = windowRect.united(displayBounds); + } } if (grabRect.width() < 0) grabRect.setWidth(windowRect.width()); @@ -631,6 +635,11 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) auto display = displays[i]; QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(display)).toRect(); QRect grabBounds = displayBounds.intersected(grabRect); + if (grabBounds.isNull()) { + destinations.append(QRect()); + images.append(QImage()); + continue; + } QRect displayLocalGrabBounds = QRect(QPoint(grabBounds.topLeft() - displayBounds.topLeft()), grabBounds.size()); QImage displayImage = qt_mac_toQImage(QCFType(CGDisplayCreateImageForRect(display, displayLocalGrabBounds.toCGRect()))); displayImage.setDevicePixelRatio(displayImage.size().width() / displayLocalGrabBounds.size().width()); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 2cbdb3c873..24e98f5bac 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -376,8 +376,18 @@ void QCocoaWindow::setVisible(bool visible) } else if (window()->modality() == Qt::ApplicationModal) { // Show the window as application modal eventDispatcher()->beginModalSession(window()); - } else if (m_view.window.canBecomeKeyWindow && !eventDispatcher()->hasModalSession()) { - [m_view.window makeKeyAndOrderFront:nil]; + } else if (m_view.window.canBecomeKeyWindow) { + bool shouldBecomeKeyNow = !NSApp.modalWindow || m_view.window.worksWhenModal; + + // Panels with becomesKeyOnlyIfNeeded set should not activate until a view + // with needsPanelToBecomeKey, for example a line edit, is clicked. + if ([m_view.window isKindOfClass:[NSPanel class]]) + shouldBecomeKeyNow &= !(static_cast(m_view.window).becomesKeyOnlyIfNeeded); + + if (shouldBecomeKeyNow) + [m_view.window makeKeyAndOrderFront:nil]; + else + [m_view.window orderFront:nil]; } else { [m_view.window orderFront:nil]; } @@ -894,10 +904,13 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon) QMacAutoReleasePool pool; - if (icon.isNull()) + if (icon.isNull()) { iconButton.image = [NSWorkspace.sharedWorkspace iconForFile:m_view.window.representedFilename]; - else - iconButton.image = [NSImage imageFromQIcon:icon]; + } else { + // Fall back to a size that looks good on the highest resolution screen available + auto fallbackSize = iconButton.frame.size.height * qGuiApp->devicePixelRatio(); + iconButton.image = [NSImage imageFromQIcon:icon withSize:fallbackSize]; + } } void QCocoaWindow::setAlertState(bool enabled) diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm index 9c45d8c7fc..5e218157c2 100644 --- a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm +++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm @@ -100,6 +100,18 @@ void QCocoaWindowManager::modalSessionChanged() } } } + + // Our worksWhenModal implementation is declarative and will normally be picked + // up by AppKit when needed, but to make sure AppKit also reflects the state + // in the window tag, so that the window can be ordered front by clicking it, + // we need to explicitly call setWorksWhenModal. + for (id window in NSApp.windows) { + if ([window isKindOfClass:[QNSPanel class]]) { + auto *panel = static_cast(window); + // Call setter to tell AppKit that our state has changed + [panel setWorksWhenModal:panel.worksWhenModal]; + } + } } static void initializeWindowManager() { Q_UNUSED(QCocoaWindowManager::instance()); } diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 6b4e110af2..311c291252 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -158,8 +158,79 @@ static bool isMouseEvent(NSEvent *ev) #define QNSWINDOW_PROTOCOL_IMPLMENTATION 1 #include "qnswindow.mm" #undef QNSWINDOW_PROTOCOL_IMPLMENTATION + +- (BOOL)worksWhenModal +{ + if (!m_platformWindow) + return NO; + + // Conceptually there are two sets of windows we need consider: + // + // - windows 'lower' in the modal session stack + // - windows 'within' the current modal session + // + // The first set of windows should always be blocked by the current + // modal session, regardless of window type. The latter set may contain + // windows with a transient parent, which from Qt's point of view makes + // them 'child' windows, so we treat them as operable within the current + // modal session. + + if (!NSApp.modalWindow) + return NO; + + // If the current modal window (top level modal session) is not a Qt window we + // have no way of knowing if this window is transient child of the modal window. + if (![NSApp.modalWindow conformsToProtocol:@protocol(QNSWindowProtocol)]) + return NO; + + if (auto *modalWindow = static_cast(NSApp.modalWindow).platformWindow) { + if (modalWindow->window()->isAncestorOf(m_platformWindow->window(), QWindow::IncludeTransients)) + return YES; + } + + return NO; +} @end +#if !defined(QT_APPLE_NO_PRIVATE_APIS) +// When creating an NSWindow the worksWhenModal function is queried, +// and the resulting state is used to set the corresponding window tag, +// which the window server uses to determine whether or not the window +// should be allowed to activate via mouse clicks in the title-bar. +// Unfortunately, prior to macOS 10.15, this window tag was never +// updated after the initial assignment in [NSWindow _commonAwake], +// which meant that windows that dynamically change their worksWhenModal +// state will behave as if they were never allowed to work when modal. +// We work around this by manually updating the window tag when needed. + +typedef uint32_t CGSConnectionID; +typedef uint32_t CGSWindowID; + +extern "C" { +CGSConnectionID CGSMainConnectionID() __attribute__((weak_import)); +OSStatus CGSSetWindowTags(const CGSConnectionID, const CGSWindowID, int *, int) __attribute__((weak_import)); +OSStatus CGSClearWindowTags(const CGSConnectionID, const CGSWindowID, int *, int) __attribute__((weak_import)); +} + +@interface QNSPanel (WorksWhenModalWindowTagWorkaround) @end +@implementation QNSPanel (WorksWhenModalWindowTagWorkaround) +- (void)setWorksWhenModal:(BOOL)worksWhenModal +{ + [super setWorksWhenModal:worksWhenModal]; + + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSCatalina) { + if (CGSMainConnectionID && CGSSetWindowTags && CGSClearWindowTags) { + static int kWorksWhenModalWindowTag = 0x40; + auto *function = worksWhenModal ? CGSSetWindowTags : CGSClearWindowTags; + function(CGSMainConnectionID(), self.windowNumber, &kWorksWhenModalWindowTag, 64); + } else { + qWarning() << "Missing APIs for window tag handling, can not update worksWhenModal state"; + } + } +} +@end +#endif // QT_APPLE_NO_PRIVATE_APIS + #else // QNSWINDOW_PROTOCOL_IMPLMENTATION // The following content is mixed in to the QNSWindow and QNSPanel classes via includes @@ -237,17 +308,6 @@ static bool isMouseEvent(NSEvent *ev) return canBecomeMain; } -- (BOOL)worksWhenModal -{ - if (m_platformWindow && [self isKindOfClass:[QNSPanel class]]) { - Qt::WindowType type = m_platformWindow->window()->type(); - if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) - return YES; - } - - return [super worksWhenModal]; -} - - (BOOL)isOpaque { return m_platformWindow ? m_platformWindow->isOpaque() : [super isOpaque]; diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp index eda0f430a1..cfa999a6f4 100644 --- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp +++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp @@ -84,7 +84,7 @@ class TestQString : public QObject void wrapInFunction() { //! [1] -QVERIFY2(qIsNaN(0.0 / 0.0), "Ill-defined division produced unambiguous result."); +QVERIFY2(QFileInfo("file.txt").exists(), "file.txt does not exist."); //! [1] //! [2] diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index bace311924..b406333fef 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1370,6 +1370,9 @@ QStringList qt_make_filter_list(const QString &filter) \snippet code/src_gui_dialogs_qfiledialog.cpp 6 + \note This is not supported on Android's native file dialog. Use + \l{setMimeTypeFilters()} instead. + \sa setMimeTypeFilters(), setNameFilters() */ void QFileDialog::setNameFilter(const QString &filter) @@ -1441,6 +1444,9 @@ QStringList qt_strip_filters(const QStringList &filters) filters for each file type. For example, JPEG images have three possible extensions; if your application can open such files, selecting the \c image/jpeg mime type as a filter will allow you to open all of them. + + \note This is not supported on Android's native file dialog. Use + \l{setMimeTypeFilters()} instead. */ void QFileDialog::setNameFilters(const QStringList &filters) { diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 7da20772f8..e5d909b9a7 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -927,9 +927,16 @@ void tst_QtJson::testObjectIteration() QCOMPARE(object, object2); QJsonObject::iterator it = object2.find(QString::number(5)); + QJsonValue val = *it; object2.erase(it); QCOMPARE(object.size(), 10); QCOMPARE(object2.size(), 9); + + for (QJsonObject::const_iterator it = object2.constBegin(); it != object2.constEnd(); ++it) { + QJsonValue value = it.value(); + QVERIFY(it.value() != val); + QCOMPARE((double)it.key().toInt(), value.toDouble()); + } } {