From 97891aa19765591ed9c85952e8eac53459167315 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 7 Jun 2019 16:27:44 +0200 Subject: Fix Vulkan yes OpenGL no builds The format conversion relies on the QOpenGLTexture header that has its body ifdefed out with -no-opengl. However, Qt, in a very forward looking manner, allows having Vulkan support even when OpenGL is disabled. Assuming that the format conversion will not be used in -no-opengl builds, put the entire function inside a #if QT_CONFIG(opengl). Change-Id: I772e12129729d69b81159669d239ea3945a42e5a Reviewed-by: Johan Helsing --- src/platformsupport/vkconvenience/qvkconvenience.cpp | 2 ++ src/platformsupport/vkconvenience/qvkconvenience_p.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/platformsupport/vkconvenience/qvkconvenience.cpp b/src/platformsupport/vkconvenience/qvkconvenience.cpp index 462cdc9e0d..acde1d1bda 100644 --- a/src/platformsupport/vkconvenience/qvkconvenience.cpp +++ b/src/platformsupport/vkconvenience/qvkconvenience.cpp @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE \ingroup qpa */ +#if QT_CONFIG(opengl) VkFormat QVkConvenience::vkFormatFromGlFormat(uint glFormat) { using GlFormat = QOpenGLTexture::TextureFormat; @@ -211,5 +212,6 @@ VkFormat QVkConvenience::vkFormatFromGlFormat(uint glFormat) default: return VK_FORMAT_UNDEFINED; } } +#endif QT_END_NAMESPACE diff --git a/src/platformsupport/vkconvenience/qvkconvenience_p.h b/src/platformsupport/vkconvenience/qvkconvenience_p.h index 1dd1dfc4a7..580271b593 100644 --- a/src/platformsupport/vkconvenience/qvkconvenience_p.h +++ b/src/platformsupport/vkconvenience/qvkconvenience_p.h @@ -59,7 +59,9 @@ QT_BEGIN_NAMESPACE class QVkConvenience { public: +#if QT_CONFIG(opengl) static VkFormat vkFormatFromGlFormat(uint glFormat); +#endif }; QT_END_NAMESPACE -- cgit v1.2.3 From 45373c19243aea335897ba0f371a1dd53ae8f079 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 10 Jun 2019 00:10:53 +0200 Subject: Deprecate QLatin1Literal It's an undocumented typedef for QLatin1String. [ChangeLog][QtCore][QLatin1Literal] The undocumented QLatin1Literal type alias for QLatin1String is now deprecated. Use QLatin1String instead. Change-Id: I05eba8b857454e59b9b9d7b07c42fe6fc9c77fec Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index da8260a999..a885ad1412 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -214,7 +214,9 @@ private: Q_DECLARE_TYPEINFO(QLatin1String, Q_MOVABLE_TYPE); // Qt 4.x compatibility -typedef QLatin1String QLatin1Literal; +#if QT_DEPRECATED_SINCE(5, 14) +QT_DEPRECATED_X("Use QLatin1String") typedef QLatin1String QLatin1Literal; +#endif // // QLatin1String inline implementations -- cgit v1.2.3 From 6fbf50248db858cf47dddd8b917685f757b83a97 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 May 2019 11:43:29 +0200 Subject: Brush up tst_QUrl Fix clang-tidy warnings: - Use range-based for and streamline some code - Use nullptr Change-Id: Iad43490d0e968baa76d54d3bf81558a48b19cdbd Reviewed-by: Kari Oikarinen --- tests/auto/corelib/io/qurl/tst_qurl.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index daaa5516cd..3123c42326 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2192,10 +2192,12 @@ void tst_QUrl::schemeValidator_data() QTest::newRow("percent-encoded") << "%68%74%%74%70://example.com" << false << "%68%74%%74%70"; static const char controls[] = "!\"$&'()*,;<=>[\\]^_`{|}~"; - for (size_t i = 0; i < sizeof(controls) - 1; ++i) - QTest::newRow(("with-" + QByteArray(1, controls[i])).constData()) - << QString("pre%1post://example.com/").arg(QLatin1Char(controls[i])) - << false << QString("pre%1post").arg(QLatin1Char(controls[i])); + for (char control : controls) { + const QString scheme = QLatin1String("pre") + QLatin1Char(control) + QLatin1String("post"); + QTest::newRow((QByteArrayLiteral("with-") + control).constData()) + << (scheme + QLatin1String("://example.com/")) + << false << scheme; + } } void tst_QUrl::schemeValidator() @@ -4074,13 +4076,12 @@ public: QVector m_urls; }; -static const UrlStorage * s_urlStorage = 0; +static const UrlStorage * s_urlStorage = nullptr; void tst_QUrl::testThreadingHelper() { const UrlStorage* storage = s_urlStorage; - for (int i = 0 ; i < storage->m_urls.size(); ++i ) { - const QUrl& u = storage->m_urls.at(i); + for (const auto &u : storage->m_urls) { // QVERIFY/QCOMPARE trigger race conditions in helgrind if (!u.isValid()) qFatal("invalid url"); -- cgit v1.2.3 From 972a0402be4d7aed0ebbd0ff56b5018cda01599d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 12:38:45 +0100 Subject: Use insert instead of insertMulti when operating on a QMultiHash Change-Id: I96ebf6954d0a137f9f6f9632cdad6e18750519fe Reviewed-by: Mikhail Svetkin Reviewed-by: Marc Mutz --- src/gui/text/qtextdocumentlayout.cpp | 2 +- src/widgets/widgets/qwidgettextcontrol.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index e5cfa7f46e..638dd5a5a8 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1614,7 +1614,7 @@ QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom for (int i = 0; i < children.count(); ++i) { QTextFrame *frame = children.at(i); QTextTableCell cell = table->cellAt(frame->firstPosition()); - td->childFrameMap.insertMulti(cell.row() + cell.column() * rows, frame); + td->childFrameMap.insert(cell.row() + cell.column() * rows, frame); } } diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index af3b03cd9e..081acb0998 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2479,7 +2479,7 @@ void QWidgetTextControl::setExtraSelections(const QList hash; for (int i = 0; i < d->extraSelections.count(); ++i) { const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i); - hash.insertMulti(esel.cursor.anchor(), i); + hash.insert(esel.cursor.anchor(), i); } for (int i = 0; i < selections.count(); ++i) { -- cgit v1.2.3 From ba4fdd99fff80790f764ab1ac8addd699e3101e7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 29 Apr 2019 09:56:49 +0200 Subject: CMake: Ignore CMAKE_CXX_STANDARD_LIBRARIES in .prl files Do not call find_library() on libs that are part of CMAKE_CXX_STANDARD_LIBRARIES: At CMake call time they might not be found. Fixes: QTBUG-73475 Change-Id: I350b3280744883e82d83c46e70f6a7cfc8aeed2e Reviewed-by: Andy Shaw Reviewed-by: Alexandru Croitor --- mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index aca8703238..1c4994c30f 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -59,6 +59,7 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura file(STRINGS \"${prl_file_location}\" _prl_strings REGEX \"QMAKE_PRL_LIBS[ \\t]*=\") string(REGEX REPLACE \"QMAKE_PRL_LIBS[ \\t]*=[ \\t]*([^\\n]*)\" \"\\\\1\" _static_depends ${_prl_strings}) string(REGEX REPLACE \"[ \\t]+\" \";\" _static_depends ${_static_depends}) + string(REGEX REPLACE \"[ \\t]+\" \";\" _standard_libraries ${CMAKE_CXX_STANDARD_LIBRARIES}) set(_search_paths) string(REPLACE \"\\$\\$[QT_INSTALL_LIBS]\" \"${_qt5_install_libs}\" _static_depends \"${_static_depends}\") foreach(_flag ${_static_depends}) @@ -66,7 +67,15 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura if(_flag MATCHES \"^-l(.*)$\") # Handle normal libraries passed as -lfoo set(_lib \"${CMAKE_MATCH_1}\") - if(_lib MATCHES \"^pthread$\") + foreach(_standard_library ${_standard_libraries}) + if(_standard_library MATCHES \"^${_lib}(\\.lib)?$\") + set(_lib_is_default_linked TRUE) + break() + endif() + endforeach() + if (_lib_is_default_linked) + unset(_lib_is_default_linked) + elseif(_lib MATCHES \"^pthread$\") find_package(Threads REQUIRED) list(APPEND _lib_deps Threads::Threads) else() -- cgit v1.2.3 From 22c1e10e1955c63e3b1761e05ce06164c0464073 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 30 Apr 2019 12:01:23 +0200 Subject: Fix emar invocation on Windows On Windows we hit the command line length limit when building the wasm port of Qt. We must not pass the list of object files directly to emar, but write a response file which is then passed via the @ parameter. Fixes: QTBUG-75257 Change-Id: Id518fd81325716b8efaba29f495568a9a3e34be4 Reviewed-by: Kai Koehne Reviewed-by: Edward Welbourne Reviewed-by: Lorn Potter --- mkspecs/wasm-emscripten/qmake.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index c80f2bfb92..ca8c477c80 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -94,6 +94,12 @@ QMAKE_PREFIX_STATICLIB = lib QMAKE_EXTENSION_STATICLIB = a # llvm bitcode QMAKE_AR = emar cqs +equals(QMAKE_HOST.os, Windows) { + QMAKE_AR_CMD = \ + "$(file >$(OBJECTS_DIR)/$(TARGET).rsp, $(OBJECTS))$$escape_expand(\\n\\t)" \ + "$(AR) $(DESTDIR)$(TARGET) @$(OBJECTS_DIR)/$(TARGET).rsp" +} + QMAKE_DISTCLEAN += *.html *.js *.wasm load(qt_config) -- cgit v1.2.3 From 050e7bafad3b723fe5be6e981a32e708dbdc5150 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 6 May 2019 13:37:56 +1000 Subject: wasm: add fixedPitch font Also define our default font so as to return something we actually have Task-number: QTBUG-75587 Change-Id: I26e3c62921d369c3017af9796c0a20f7ac06d07c Reviewed-by: Shawn Rutledge --- src/3rdparty/wasm/DejaVuSansMono.ttf | Bin 0 -> 237788 bytes src/3rdparty/wasm/qt_attribution.json | 2 +- .../fontdatabases/freetype/qfreetypefontdatabase.cpp | 1 - src/plugins/platforms/wasm/qwasmfontdatabase.cpp | 8 ++++++-- src/plugins/platforms/wasm/qwasmfontdatabase.h | 1 + src/plugins/platforms/wasm/qwasmtheme.cpp | 15 +++++++++++++++ src/plugins/platforms/wasm/qwasmtheme.h | 3 +++ src/plugins/platforms/wasm/wasm.pro | 3 ++- 8 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/3rdparty/wasm/DejaVuSansMono.ttf diff --git a/src/3rdparty/wasm/DejaVuSansMono.ttf b/src/3rdparty/wasm/DejaVuSansMono.ttf new file mode 100644 index 0000000000..029fcac35f Binary files /dev/null and b/src/3rdparty/wasm/DejaVuSansMono.ttf differ diff --git a/src/3rdparty/wasm/qt_attribution.json b/src/3rdparty/wasm/qt_attribution.json index d569fdc167..75c5c6c49f 100644 --- a/src/3rdparty/wasm/qt_attribution.json +++ b/src/3rdparty/wasm/qt_attribution.json @@ -20,7 +20,7 @@ "Name": "DejaVu Fonts", "QDocModule": "qtgui", "QtUsage": "Used for WebAssembly platform.", - "Files": "DejaVuSans.ttf", + "Files": "DejaVuSans.ttf, DejaVuSansMono.ttf", "Description": "The DejaVu fonts are a font family based on the Vera Fonts.", "Homepage": "https://dejavu-fonts.github.io/", diff --git a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp index 4baba64de3..adc2f6c1fe 100644 --- a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp @@ -142,7 +142,6 @@ QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const Q weight = QFont::Bold; bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH); - QSupportedWritingSystems writingSystems; // detect symbol fonts for (int i = 0; i < face->num_charmaps; ++i) { diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp index 0c72dfddc4..dc6bb5847e 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp @@ -38,9 +38,9 @@ void QWasmFontDatabase::populateFontDatabase() // Load font file from resources. Currently // all fonts needs to be bundled with the nexe // as Qt resources. - QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/Vera.ttf") + QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/DejaVuSansMono.ttf") + << QStringLiteral(":/fonts/Vera.ttf") << QStringLiteral(":/fonts/DejaVuSans.ttf"); - foreach (const QString &fontFileName, fontFileNames) { QFile theFont(fontFileName); if (!theFont.open(QIODevice::ReadOnly)) @@ -82,5 +82,9 @@ void QWasmFontDatabase::releaseHandle(void *handle) QFreeTypeFontDatabase::releaseHandle(handle); } +QFont QWasmFontDatabase::defaultFont() const +{ + return QFont(QLatin1String("Bitstream Vera Sans")); +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.h b/src/plugins/platforms/wasm/qwasmfontdatabase.h index 891f12859e..cbd187a022 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.h +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.h @@ -44,6 +44,7 @@ public: QChar::Script script) const override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; void releaseHandle(void *handle) override; + QFont defaultFont() const override; }; QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/wasm/qwasmtheme.cpp b/src/plugins/platforms/wasm/qwasmtheme.cpp index a7f2db3bd3..978d60d686 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.cpp +++ b/src/plugins/platforms/wasm/qwasmtheme.cpp @@ -29,15 +29,22 @@ #include "qwasmtheme.h" #include +#include QT_BEGIN_NAMESPACE QWasmTheme::QWasmTheme() { + QFontDatabase fdb; + for (auto family : fdb.families()) + if (fdb.isFixedPitch(family)) + fixedFont = new QFont(family); } QWasmTheme::~QWasmTheme() { + if (fixedFont) + delete fixedFont; } QVariant QWasmTheme::themeHint(ThemeHint hint) const @@ -47,4 +54,12 @@ QVariant QWasmTheme::themeHint(ThemeHint hint) const return QPlatformTheme::themeHint(hint); } +const QFont *QWasmTheme::font(Font type) const +{ + if (type == QPlatformTheme::FixedFont) { + return fixedFont; + } + return nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmtheme.h b/src/plugins/platforms/wasm/qwasmtheme.h index e4cc06e049..7123a1f3d4 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.h +++ b/src/plugins/platforms/wasm/qwasmtheme.h @@ -31,6 +31,7 @@ #define QWASMTHEME_H #include +#include QT_BEGIN_NAMESPACE @@ -49,6 +50,8 @@ public: ~QWasmTheme(); QVariant themeHint(ThemeHint hint) const override; + const QFont *font(Font type) const override; + QFont *fixedFont = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index 9b98445c68..e8728d9dba 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -39,7 +39,8 @@ HEADERS = \ wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ - ../../../3rdparty/wasm/DejaVuSans.ttf + ../../../3rdparty/wasm/DejaVuSans.ttf \ + ../../../3rdparty/wasm/DejaVuSansMono.ttf wasmfonts.prefix = /fonts wasmfonts.base = ../../../3rdparty/wasm RESOURCES += wasmfonts -- cgit v1.2.3 From ac68ef1efc27669e9c8fc255298345d72d198d68 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 3 May 2019 13:45:53 +0200 Subject: Don't duplicate font family names in the fallback list Fixes: QTBUG-75333 Change-Id: Iaaf4b13d50c6b9b52e629b81d5e9cbc552a0202c Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qfontdatabase.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index fa9573441a..6dad5196e8 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -707,7 +707,8 @@ static QStringList familyList(const QFontDef &req) if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\'')))) str = str.mid(1, str.length() - 2); - family_list << str.toString(); + if (!family_list.contains(str)) + family_list << str.toString(); } } // append the substitute list for each family in family_list -- cgit v1.2.3 From 0e2c013a4523915a0af37fe1f338a4f66b07f91d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 7 May 2019 10:56:08 +0200 Subject: doc: Add dontdocument.qdoc files Each module that has publically declared classes or structs that are not meant to be documented is given a dontdocument.qdoc file to tell qdoc that these classes are not meant to be documentented. Then qdoc will not print warnings about missing \class comments for these classes and structs. Change-Id: I9195f0b546032e1c7642c9da34d85a0a4a9bfb08 Reviewed-by: Paul Wicking --- src/corelib/doc/src/dontdocument.qdoc | 41 +++++++++++++++++ src/dbus/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/gui/doc/src/dontdocument.qdoc | 66 +++++++++++++++++++++++++++ src/network/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/platformheaders/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/printsupport/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/sql/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/testlib/doc/src/dontdocument.qdoc | 32 +++++++++++++ src/widgets/doc/src/dontdocument.qdoc | 30 ++++++++++++ src/xml/doc/src/dontdocument.qdoc | 30 ++++++++++++ 10 files changed, 349 insertions(+) create mode 100644 src/corelib/doc/src/dontdocument.qdoc create mode 100644 src/dbus/doc/src/dontdocument.qdoc create mode 100644 src/gui/doc/src/dontdocument.qdoc create mode 100644 src/network/doc/src/dontdocument.qdoc create mode 100644 src/platformheaders/doc/src/dontdocument.qdoc create mode 100644 src/printsupport/doc/src/dontdocument.qdoc create mode 100644 src/sql/doc/src/dontdocument.qdoc create mode 100644 src/testlib/doc/src/dontdocument.qdoc create mode 100644 src/widgets/doc/src/dontdocument.qdoc create mode 100644 src/xml/doc/src/dontdocument.qdoc diff --git a/src/corelib/doc/src/dontdocument.qdoc b/src/corelib/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..19ca7db299 --- /dev/null +++ b/src/corelib/doc/src/dontdocument.qdoc @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QMacAutoReleasePool QIncompatibleFlag QGenericAtomicOps QAtomicTraits + QAtomicOps QBasicAtomicInteger QBasicAtomicPointer QBasicMutex QInternal + QArgument QReturnArgument QArrayData QTypedArrayData QStaticByteArrayData + QByteRef QStaticStringData QListSpecialMethods QListData QScopedPointerDeleter + QScopedPointerArrayDeleter QScopedPointerPodDeleter QScopedPointerObjectDeleteLater + QMetaTypeId2 QObjectData QObjectUserData QMapNodeBase QMapNode QMapDataBase + QMapData QHashData QHashNode QArrayDataPointer QTextStreamManipulator + QContiguousCacheData QContiguousCacheTypedData QNoDebug QUrlTwoFlags + QCborValueRef qfloat16 QDeferredDeleteEvent QSpecialInteger QLittleEndianStorageType + QBigEndianStorageType QFactoryInterface QFutureWatcherBase QJsonValuePtr + QJsonValueRefPtr QLinkedListNode QAbstractConcatenable QStringBuilderCommon + QTextCodec::ConverterState QThreadStorageData) +*/ diff --git a/src/dbus/doc/src/dontdocument.qdoc b/src/dbus/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..bbb8acb53c --- /dev/null +++ b/src/dbus/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo QMetaTypeId QDBusAbstractInterfaceBase QDBusPendingReplyData QMetaTypeId2) +*/ diff --git a/src/gui/doc/src/dontdocument.qdoc b/src/gui/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..b360acefc1 --- /dev/null +++ b/src/gui/doc/src/dontdocument.qdoc @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo QScreenOrientationChangeEvent QApplicationStateChangeEvent + QImageTextKeyLang QMetaTypeId QAbstractUndoItem + QOpenGLVersionStatus + QOpenGLVersionFunctionsBackend + QOpenGLVersionFunctionsStorage + QOpenGLFunctions_1_0_CoreBackend + QOpenGLFunctions_1_1_CoreBackend + QOpenGLFunctions_1_2_CoreBackend + QOpenGLFunctions_1_3_CoreBackend + QOpenGLFunctions_1_4_CoreBackend + QOpenGLFunctions_1_5_CoreBackend + QOpenGLFunctions_2_0_CoreBackend + QOpenGLFunctions_2_1_CoreBackend + QOpenGLFunctions_3_0_CoreBackend + QOpenGLFunctions_3_1_CoreBackend + QOpenGLFunctions_3_2_CoreBackend + QOpenGLFunctions_3_3_CoreBackend + QOpenGLFunctions_4_0_CoreBackend + QOpenGLFunctions_4_1_CoreBackend + QOpenGLFunctions_4_2_CoreBackend + QOpenGLFunctions_4_3_CoreBackend + QOpenGLFunctions_4_4_CoreBackend + QOpenGLFunctions_4_5_CoreBackend + QOpenGLFunctions_1_0_DeprecatedBackend + QOpenGLFunctions_1_1_DeprecatedBackend + QOpenGLFunctions_1_2_DeprecatedBackend + QOpenGLFunctions_1_3_DeprecatedBackend + QOpenGLFunctions_1_4_DeprecatedBackend + QOpenGLFunctions_2_0_DeprecatedBackend + QOpenGLFunctions_3_0_DeprecatedBackend + QOpenGLFunctions_3_3_DeprecatedBackend + QOpenGLFunctions_4_5_DeprecatedBackend + QTextFrameLayoutData QPlatformDropQtResponse QPlatformDragQtResponse + QPlatformOffscreenSurface QColorDialogOptions QFontDialogOptions + QFileDialogOptions QMessageDialogOptions QMessageDialogOptions::CustomButton + QPlatformSessionManager QPlatformIntegrationPlugin QPlatformMenuItem + QPlatformMenu QPlatformMenuBar QPlatformTextureList) +*/ diff --git a/src/network/doc/src/dontdocument.qdoc b/src/network/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..fe2e54b34c --- /dev/null +++ b/src/network/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo QMetaTypeId QIPv6Address) +*/ diff --git a/src/platformheaders/doc/src/dontdocument.qdoc b/src/platformheaders/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..dc02c6473e --- /dev/null +++ b/src/platformheaders/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QMetaTypeId) +*/ diff --git a/src/printsupport/doc/src/dontdocument.qdoc b/src/printsupport/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..74552b4e99 --- /dev/null +++ b/src/printsupport/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QMetaTypeId QPlatformPrintDevice QPlatformPrinterSupportPlugin) +*/ diff --git a/src/sql/doc/src/dontdocument.qdoc b/src/sql/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..0193ace4b4 --- /dev/null +++ b/src/sql/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo) +*/ diff --git a/src/testlib/doc/src/dontdocument.qdoc b/src/testlib/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..59270c7a4f --- /dev/null +++ b/src/testlib/doc/src/dontdocument.qdoc @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTestEventLoop QTestData QEventSizeOfChecker QSpontaneKeyEvent + QTestEvent QTestKeyEvent QTestKeyClicksEvent QTestMouseEvent + QTestDelayEvent QMetaTypeId) +*/ diff --git a/src/widgets/doc/src/dontdocument.qdoc b/src/widgets/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..9de8b5e62d --- /dev/null +++ b/src/widgets/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo QMetaTypeId) +*/ diff --git a/src/xml/doc/src/dontdocument.qdoc b/src/xml/doc/src/dontdocument.qdoc new file mode 100644 index 0000000000..0193ace4b4 --- /dev/null +++ b/src/xml/doc/src/dontdocument.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \dontdocument (QTypeInfo) +*/ -- cgit v1.2.3 From 9c196b40d10f992b5ecc71f2e0093cff2308ed88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 7 May 2019 23:26:28 +0200 Subject: wasm: remove qDebug Change-Id: Ic9812421b2a79a33bb138f448fe132dab141b724 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 6a02a457a0..7126c00354 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -337,8 +337,6 @@ QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen) void QWasmEventTranslator::initEventHandlers() { - qDebug() << "QWasmEventTranslator::initEventHandlers"; - QByteArray _canvasId = screen()->canvasId().toUtf8(); const char *canvasId = _canvasId.constData(); -- cgit v1.2.3 From c996d131266bd0f470cc1a14141a61e1d48a2b77 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 1 May 2019 18:03:16 +0300 Subject: Android: Fix x86_64 linking x86_64 libs are located in ANDROID_PLATFORM_ROOT_PATH/usr/lib64 not in ANDROID_PLATFORM_ROOT_PATH/usr/lib . Fixes: QTBUG-47672 Change-Id: Ia1f74f7c2a30b276b95fd0e7dcf8370d739e3c41 Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 43763e279644cdd2a52d770b9aeda4d485caaa76) Reviewed-by: Jani Heikkinen --- mkspecs/common/android-base-tail.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf index f403ef9330..edc255d08e 100644 --- a/mkspecs/common/android-base-tail.conf +++ b/mkspecs/common/android-base-tail.conf @@ -69,6 +69,7 @@ QMAKE_LIBDIR_OPENGL = QMAKE_LINK_SHLIB = $$QMAKE_LINK QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64 QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -- cgit v1.2.3 From 0b693175e4e70cead730a245cffa66304998196a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sun, 7 Apr 2019 12:32:51 +0200 Subject: wasm: make idealThreadCount() work on all threads navigator.hardwareConcurrency can be accessed from the main thread only. Read and cache the value on QCoreApplication initialization. Change-Id: I731f7f356ce106c7107977783d4b763326af06b6 Reviewed-by: Lorn Potter --- src/corelib/kernel/qcoreapplication.cpp | 5 +++++ src/corelib/thread/qthread_p.h | 3 +++ src/corelib/thread/qthread_unix.cpp | 10 +++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 69b2a9bf41..5c0bf93acc 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -119,6 +119,7 @@ #ifdef Q_OS_WASM #include +#include #endif #ifdef QT_BOOTSTRAPPED @@ -800,6 +801,10 @@ void QCoreApplicationPrivate::init() Module.print(err); }); ); + +#if QT_CONFIG(thread) + QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as(); +#endif #endif // Store app name/version (so they're still available after QCoreApplication is destroyed) diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 7d9442ab79..57e6c995c5 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -195,6 +195,9 @@ public: int waiters; bool terminationEnabled, terminatePending; #endif // Q_OS_WIN +#ifdef Q_OS_WASM + static int idealThreadCount; +#endif QThreadData *data; static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index a13f8ca215..ea78b0a147 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -100,10 +100,6 @@ #include #endif -#if defined(Q_OS_WASM) -#include -#endif - QT_BEGIN_NAMESPACE #if QT_CONFIG(thread) @@ -454,6 +450,10 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW # define _SC_NPROCESSORS_ONLN 84 #endif +#ifdef Q_OS_WASM +int QThreadPrivate::idealThreadCount = 1; +#endif + int QThread::idealThreadCount() Q_DECL_NOTHROW { int cores = 1; @@ -503,7 +503,7 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW cores = 1; # endif #elif defined(Q_OS_WASM) - cores = emscripten::val::global("navigator")["hardwareConcurrency"].as(); + cores = QThreadPrivate::idealThreadCount; #else // the rest: Linux, Solaris, AIX, Tru64 cores = (int)sysconf(_SC_NPROCESSORS_ONLN); -- cgit v1.2.3 From fc3e8514144535db22c431251bc0feea99cf72e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 11 Apr 2019 11:44:36 +0200 Subject: macOS: disable threaded OpenGL (unconditionally) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can’t determine when the app will use layer-backed views without having access to the QWindow and NSView instance, so make the conservative choice of always returning false for ThreadedOpenGL. Task-number: QTBUG-74820 Change-Id: If2779b17eead78ce1929ccebc3bd8fc0eb00c4b5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index fb3d05d3e4..855b42657d 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -347,11 +347,13 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons switch (cap) { #ifndef QT_NO_OPENGL case ThreadedOpenGL: - // AppKit expects rendering to happen on the main thread, and we can - // easily end up in situations where rendering on secondary threads - // will result in visual artifacts, bugs, or even deadlocks, when - // building with SDK 10.14 or higher which enbles view layer-backing. - return QMacVersion::buildSDK() < QOperatingSystemVersion(QOperatingSystemVersion::MacOSMojave); + // Qt's threaded OpenGL implementation does not work well for layer-backed + // views, where we can easily end up in situations where rendering on secondary + // threads will result in visual artifacts, bugs, or even deadlocks. It is + // not possible to determine here if the the app will be using layer-backed + // views (it can opt-in using SDK 10.14+ on macOS 10.4+, or by setting + // NSWindow flags such as NSWindowStyleMaskFullSizeContentView). + return false; case OpenGL: case BufferQueueingOpenGL: #endif -- cgit v1.2.3 From a5725561da44215e43b808732ad22fdca4d91454 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Sat, 13 Apr 2019 18:08:33 +0300 Subject: Fetch stylus button remapping from WinTab driver The user can remap the stylus buttons using tablet driver settings. This information is available to the application via CSR_SYSBTNMAP WinTab feature. We should fetch this information every time the stylus gets into proximity, because the user can change these settings on the fly. Change-Id: Idc839905c3485179d782814f78fa862fd4a99127 Reviewed-by: Andre de la Rocha Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowstabletsupport.cpp | 72 +++++++++++++++++++++- .../platforms/windows/qwindowstabletsupport.h | 2 + 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index fa209f09c4..44b94d044d 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -435,6 +435,27 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L m_currentDevice = m_devices.size(); m_devices.push_back(tabletInit(uniqueId, cursorType)); } + + /** + * We should check button map for changes on every proximity event, not + * only during initialization phase. + * + * WARNING: in 2016 there were some Wacom table drivers, which could mess up + * button mapping if the remapped button was pressed, while the + * application **didn't have input focus**. This bug is somehow + * related to the fact that Wacom drivers allow user to configure + * per-application button-mappings. If the bug shows up again, + * just move this button-map fetching into initialization block. + * + * See https://bugs.kde.org/show_bug.cgi?id=359561 + */ + BYTE logicalButtons[32]; + memset(logicalButtons, 0, 32); + m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_SYSBTNMAP, &logicalButtons); + m_devices[m_currentDevice].buttonsMap[0x1] = logicalButtons[0]; + m_devices[m_currentDevice].buttonsMap[0x2] = logicalButtons[1]; + m_devices[m_currentDevice].buttonsMap[0x4] = logicalButtons[2]; + m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor); m_state = PenProximity; qCDebug(lcQpaTablet) << "enter proximity for device #" @@ -446,6 +467,52 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L return true; } +Qt::MouseButton buttonValueToEnum(DWORD button, + const QWindowsTabletDeviceData &tdd) { + + enum : unsigned { + leftButtonValue = 0x1, + middleButtonValue = 0x2, + rightButtonValue = 0x4, + doubleClickButtonValue = 0x7 + }; + + button = tdd.buttonsMap.value(button); + + return button == leftButtonValue ? Qt::LeftButton : + button == rightButtonValue ? Qt::RightButton : + button == doubleClickButtonValue ? Qt::MiddleButton : + button == middleButtonValue ? Qt::MiddleButton : + button ? Qt::LeftButton /* fallback item */ : + Qt::NoButton; +} + +Qt::MouseButtons convertTabletButtons(DWORD btnNew, + const QWindowsTabletDeviceData &tdd) { + + Qt::MouseButtons buttons = Qt::NoButton; + for (unsigned int i = 0; i < 3; i++) { + unsigned int btn = 0x1 << i; + + if (btn & btnNew) { + Qt::MouseButton convertedButton = + buttonValueToEnum(btn, tdd); + + buttons |= convertedButton; + + /** + * If a button that is present in hardware input is + * mapped to a Qt::NoButton, it means that it is going + * to be eaten by the driver, for example by its + * "Pan/Scroll" feature. Therefore we shouldn't handle + * any of the events associated to it. We'll just return + * Qt::NoButtons here. + */ + } + } + return buttons; +} + bool QWindowsTabletSupport::translateTabletPacketEvent() { static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue. @@ -552,9 +619,12 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation; } + Qt::MouseButtons buttons = + convertTabletButtons(packet.pkButtons, m_devices.at(m_currentDevice)); + QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF, currentDevice, currentPointer, - static_cast(packet.pkButtons), + buttons, pressureNew, tiltX, tiltY, tangentialPressure, rotation, z, uniqueId, diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index d91701d6a5..8f97982308 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -45,6 +45,7 @@ #include #include +#include #include @@ -100,6 +101,7 @@ struct QWindowsTabletDeviceData qint64 uniqueId = 0; int currentDevice = 0; int currentPointerType = 0; + QHash buttonsMap; }; #ifndef QT_NO_DEBUG_STREAM -- cgit v1.2.3 From 69f6cab0af78285472deb8d91c862c600685e618 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 28 Apr 2019 12:52:19 +0200 Subject: Doc: replace even more null/0/nullptr with \nullptr macro Try to replace all wordings like '.. to 0' with '.. to \nullptr'. Also checked for 'null pointer' and similar. Change-Id: I73341f59ba51e0798e816a8b1a532c7c7374b74a Reviewed-by: Edward Welbourne --- src/corelib/animation/qvariantanimation.cpp | 4 +- src/corelib/codecs/qtextcodec.cpp | 2 +- src/corelib/io/qsettings.cpp | 2 +- src/corelib/kernel/qcoreapplication.cpp | 2 +- src/corelib/kernel/qobject.cpp | 4 +- src/corelib/kernel/qpointer.cpp | 8 +-- src/corelib/kernel/qvariant.cpp | 6 +- src/corelib/serialization/qdatastream.cpp | 3 +- src/corelib/statemachine/qstate.cpp | 2 +- src/corelib/tools/qbytearray.cpp | 4 +- src/corelib/tools/qlocale.cpp | 12 ++-- src/corelib/tools/qscopedpointer.cpp | 37 +++++------ src/corelib/tools/qshareddata.cpp | 12 ++-- src/corelib/tools/qsharedpointer.cpp | 79 ++++++++++------------- src/corelib/tools/qstring.cpp | 25 ++++--- src/corelib/tools/qstring.h | 2 +- src/gui/accessible/qaccessible.cpp | 2 +- src/gui/image/qicon.cpp | 2 +- src/gui/image/qpicture.cpp | 4 +- src/gui/itemmodels/qstandarditemmodel.cpp | 2 +- src/gui/kernel/qopenglcontext.cpp | 4 +- src/gui/kernel/qwindow.cpp | 2 +- src/gui/text/qtextobject.cpp | 4 +- src/gui/vulkan/qvulkaninstance.cpp | 2 +- src/network/socket/qlocalserver.cpp | 2 +- src/network/socket/qtcpserver.cpp | 2 +- src/network/ssl/qsslcertificate.cpp | 2 +- src/network/ssl/qsslkey_p.cpp | 4 +- src/opengl/qgl.cpp | 2 +- src/widgets/dialogs/qfilesystemmodel.cpp | 4 +- src/widgets/itemviews/qlistwidget.cpp | 4 +- src/widgets/itemviews/qtablewidget.cpp | 4 +- src/widgets/itemviews/qtreewidget.cpp | 4 +- src/widgets/itemviews/qtreewidgetitemiterator.cpp | 8 +-- src/widgets/kernel/qapplication.cpp | 4 +- src/widgets/kernel/qlayout.cpp | 8 +-- src/widgets/util/qundoview.cpp | 2 +- src/widgets/widgets/qmainwindow.cpp | 6 +- src/widgets/widgets/qmdiarea.cpp | 6 +- src/widgets/widgets/qmenubar.cpp | 4 +- src/xml/dom/qdom.cpp | 2 +- src/xml/sax/qxml.cpp | 2 +- 42 files changed, 138 insertions(+), 158 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index e935ac711e..ac81f89ed4 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -399,7 +399,7 @@ static QBasicMutex registeredInterpolatorsMutex; Registers a custom interpolator \a func for the template type \c{T}. The interpolator has to be registered before the animation is constructed. - To unregister (and use the default interpolator) set \a func to 0. + To unregister (and use the default interpolator) set \a func to \nullptr. */ /*! @@ -416,7 +416,7 @@ static QBasicMutex registeredInterpolatorsMutex; * \internal * Registers a custom interpolator \a func for the specific \a interpolationType. * The interpolator has to be registered before the animation is constructed. - * To unregister (and use the default interpolator) set \a func to 0. + * To unregister (and use the default interpolator) set \a func to \nullptr. */ void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator func, int interpolationType) { diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index ffd8a2ce93..b7bb3196af 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -678,7 +678,7 @@ QList QTextCodec::availableMibs() \nonreentrant Set the codec to \a c; this will be returned by - codecForLocale(). If \a c is a null pointer, the codec is reset to + codecForLocale(). If \a c is \nullptr, the codec is reset to the default. This might be needed for some applications that want to use their diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index f14229896f..9234a23f3a 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2919,7 +2919,7 @@ void QSettings::setIniCodec(const char *codecName) \since 4.5 Returns the codec that is used for accessing INI files. By default, - no codec is used, so a null pointer is returned. + no codec is used, so \nullptr is returned. */ QTextCodec *QSettings::iniCodec() const diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 69b2a9bf41..9a3d5c6ef4 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -699,7 +699,7 @@ void QCoreApplicationPrivate::initLocale() Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance. - If no instance has been allocated, \c null is returned. + If no instance has been allocated, \nullptr is returned. */ /*! diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e6b313863f..94b7ccd761 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -797,7 +797,7 @@ static bool check_parent_thread(QObject *parent, The destructor of a parent object destroys all child objects. - Setting \a parent to 0 constructs an object with no parent. If the + Setting \a parent to \nullptr constructs an object with no parent. If the object is a widget, it will become a top-level window. \sa parent(), findChild(), findChildren() @@ -3382,7 +3382,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index, /*! \internal - Helper function to remove the connection from the senders list and setting the receivers to 0 + Helper function to remove the connection from the senders list and set the receivers to \nullptr */ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c, const QObject *receiver, int method_index, void **slot, diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index c3dee7989e..068314633b 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -45,7 +45,7 @@ \ingroup objectmodel A guarded pointer, QPointer, behaves like a normal C++ - pointer \c{T *}, except that it is automatically set to 0 when the + pointer \c{T *}, except that it is automatically cleared when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). \c T must be a subclass of QObject. @@ -79,7 +79,7 @@ \snippet pointer/pointer.cpp 2 If the QLabel is deleted in the meantime, the \c label variable - will hold 0 instead of an invalid address, and the last line will + will hold \nullptr instead of an invalid address, and the last line will never be executed. The functions and operators available with a QPointer are the @@ -93,7 +93,7 @@ For creating guarded pointers, you can construct or assign to them from a T* or from another guarded pointer of the same type. You can compare them with each other using operator==() and - operator!=(), or test for 0 with isNull(). You can dereference + operator!=(), or test for \nullptr with isNull(). You can dereference them using either the \c *x or the \c x->member notation. A guarded pointer will automatically cast to a \c T *, so you can @@ -113,7 +113,7 @@ /*! \fn template QPointer::QPointer() - Constructs a 0 guarded pointer. + Constructs a guarded pointer with value \nullptr. \sa isNull() */ diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 18c7f7648d..3b7be3d12f 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2408,7 +2408,7 @@ void QVariant::clear() Converts the int representation of the storage type, \a typeId, to its string representation. - Returns a null pointer if the type is QMetaType::UnknownType or doesn't exist. + Returns \nullptr if the type is QMetaType::UnknownType or doesn't exist. */ const char *QVariant::typeToName(int typeId) { @@ -4144,7 +4144,7 @@ void* QVariant::data() /*! Returns \c true if this is a null variant, false otherwise. A variant is considered null if it contains no initialized value, or the contained value - is a null pointer or is an instance of a built-in type that has an isNull + is \nullptr or is an instance of a built-in type that has an isNull method, in which case the result would be the same as calling isNull on the wrapped object. @@ -4224,7 +4224,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) If the QVariant contains a pointer to a type derived from QObject then \c{T} may be any QObject type. If the pointer stored in the QVariant can be - qobject_cast to T, then that result is returned. Otherwise a null pointer is + qobject_cast to T, then that result is returned. Otherwise \nullptr is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro. diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index ead6ed5083..02c1d1c573 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -1028,8 +1028,7 @@ QDataStream &QDataStream::operator>>(char *&s) \c{delete []} operator. The \a l parameter is set to the length of the buffer. If the - string read is empty, \a l is set to 0 and \a s is set to - a null pointer. + string read is empty, \a l is set to 0 and \a s is set to \nullptr. The serialization format is a quint32 length specifier first, then \a l bytes of data. diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index ae13d4e4cf..62dd4f0284 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -285,7 +285,7 @@ QAbstractState *QState::errorState() const /*! Sets this state's error state to be the given \a state. If the error state - is not set, or if it is set to 0, the state will inherit its parent's error + is not set, or if it is set to \nullptr, the state will inherit its parent's error state recursively. If no error state is set for the state itself or any of its ancestors, an error will cause the machine to stop executing and an error will be printed to the console. diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 0f27071176..6cc41a8956 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1038,8 +1038,8 @@ QByteArray qUncompress(const uchar* data, int nbytes) \snippet code/src_corelib_tools_qbytearray.cpp 5 All functions except isNull() treat null byte arrays the same as - empty byte arrays. For example, data() returns a pointer to a - '\\0' character for a null byte array (\e not a null pointer), + empty byte arrays. For example, data() returns a valid pointer + (\e not nullptr) to a '\\0' character for a byte array and QByteArray() compares equal to QByteArray(""). We recommend that you always use isEmpty() and avoid isNull(). diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index e55331a5f9..152c2edb50 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1337,7 +1337,7 @@ uint QLocale::toUInt(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1359,7 +1359,7 @@ long QLocale::toLong(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1546,7 +1546,7 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1568,7 +1568,7 @@ long QLocale::toLong(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1764,7 +1764,7 @@ uint QLocale::toUInt(QStringView s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1786,7 +1786,7 @@ long QLocale::toLong(QStringView s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 769a18f9e0..eb08bdba62 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -157,7 +157,7 @@ QT_BEGIN_NAMESPACE Provides access to the scoped pointer's object. - If the contained pointer is \c null, behavior is undefined. + If the contained pointer is \nullptr, behavior is undefined. \sa isNull() */ @@ -166,7 +166,7 @@ QT_BEGIN_NAMESPACE Provides access to the scoped pointer's object. - If the contained pointer is \c null, behavior is undefined. + If the contained pointer is \nullptr, behavior is undefined. \sa isNull() */ @@ -174,8 +174,8 @@ QT_BEGIN_NAMESPACE /*! \fn template QScopedPointer::operator bool() const - Returns \c true if this object is not \c null. This function is suitable - for use in \tt if-constructs, like: + Returns \c true if the contained pointer is not \nullptr. + This function is suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qscopedpointer.cpp 3 @@ -185,18 +185,14 @@ QT_BEGIN_NAMESPACE /*! \fn template bool operator==(const QScopedPointer &lhs, const QScopedPointer &rhs) - Equality operator. Returns \c true if the scoped pointers - \a lhs and \a rhs are pointing to the same object. - Otherwise returns \c false. + Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer. */ /*! \fn template bool operator!=(const QScopedPointer &lhs, const QScopedPointer &rhs) - Inequality operator. Returns \c true if the scoped pointers - \a lhs and \a rhs are \e not pointing to the same object. - Otherwise returns \c false. + Returns \c true if \a lhs and \a rhs refer to distinct pointers. */ /*! @@ -204,7 +200,7 @@ QT_BEGIN_NAMESPACE \relates QScopedPointer \since 5.8 - Returns \c true if the scoped pointer \a lhs is a null pointer. + Returns \c true if \a lhs refers to \nullptr. \sa QScopedPointer::isNull() */ @@ -214,7 +210,7 @@ QT_BEGIN_NAMESPACE \relates QScopedPointer \since 5.8 - Returns \c true if the scoped pointer \a rhs is a null pointer. + Returns \c true if \a rhs refers to \nullptr. \sa QScopedPointer::isNull() */ @@ -224,8 +220,7 @@ QT_BEGIN_NAMESPACE \relates QScopedPointer \since 5.8 - Returns \c true if the scoped pointer \a lhs is a valid (i.e. a non-null) - pointer. + Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer. \sa QScopedPointer::isNull() */ @@ -235,8 +230,7 @@ QT_BEGIN_NAMESPACE \relates QScopedPointer \since 5.8 - Returns \c true if the scoped pointer \a rhs is a valid (i.e. a non-null) - pointer. + Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer. \sa QScopedPointer::isNull() */ @@ -244,7 +238,7 @@ QT_BEGIN_NAMESPACE /*! \fn template bool QScopedPointer::isNull() const - Returns \c true if this object is holding a pointer that is \c null. + Returns \c true if this object refers to \nullptr. */ /*! @@ -262,15 +256,14 @@ QT_BEGIN_NAMESPACE \fn template T *QScopedPointer::take() Returns the value of the pointer referenced by this object. The pointer of this - QScopedPointer object will be reset to \c null. + QScopedPointer object will be reset to \nullptr. Callers of this function take ownership of the pointer. */ /*! \fn template bool QScopedPointer::operator!() const - Returns \c true if the pointer referenced by this object is \c null, otherwise - returns \c false. + Returns \c true if this object refers to \nullptr. \sa isNull() */ @@ -325,7 +318,7 @@ QT_BEGIN_NAMESPACE Provides access to entry \a i of the scoped pointer's array of objects. - If the contained pointer is \c null, behavior is undefined. + If the contained pointer is \nullptr, behavior is undefined. \sa isNull() */ @@ -336,7 +329,7 @@ QT_BEGIN_NAMESPACE Provides access to entry \a i of the scoped pointer's array of objects. - If the contained pointer is \c null, behavior is undefined. + If the contained pointer is \nullptr behavior is undefined. \sa isNull() */ diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index dcfda40eda..2748f9d95f 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -321,7 +321,7 @@ QT_BEGIN_NAMESPACE */ /*! \fn template QSharedDataPointer::QSharedDataPointer() - Constructs a QSharedDataPointer initialized with a null \e{d pointer}. + Constructs a QSharedDataPointer initialized with \nullptr as \e{d pointer}. */ /*! @@ -494,8 +494,8 @@ QT_BEGIN_NAMESPACE */ /*! \fn template QExplicitlySharedDataPointer::QExplicitlySharedDataPointer() - Constructs a QExplicitlySharedDataPointer initialized with a null - \e{d pointer}. + Constructs a QExplicitlySharedDataPointer initialized with \nullptr + as \e{d pointer}. */ /*! \fn template QExplicitlySharedDataPointer::~QExplicitlySharedDataPointer() @@ -573,8 +573,8 @@ QT_BEGIN_NAMESPACE */ /*! \fn template void QExplicitlySharedDataPointer::reset() - Resets \e this to be null. i.e., this function sets the - \e{d pointer} of \e this to 0, but first it decrements + Resets \e this to be null - i.e., this function sets the + \e{d pointer} of \e this to \nullptr, but first it decrements the reference count of the shared data object and deletes the shared data object if the reference count became 0. */ @@ -582,7 +582,7 @@ QT_BEGIN_NAMESPACE /*! \fn template T *QExplicitlySharedDataPointer::take() \since 5.12 - Returns a pointer to the shared object, and resets \e this to be null. + Returns a pointer to the shared object, and resets \e this to be \nullptr. That is, this function sets the \e{d pointer} of \e this to \nullptr. */ diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 9e9466f6b1..8c0f8379fb 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -401,7 +401,8 @@ /*! \fn template QSharedPointer::QSharedPointer() - Creates a QSharedPointer that points to null (0). + Creates a QSharedPointer that is null (the object is holding + a reference to \nullptr). */ /*! @@ -547,6 +548,7 @@ Provides access to the shared pointer's members. + If the contained pointer is \nullptr, behavior is undefined. \sa isNull() */ @@ -555,21 +557,21 @@ Provides access to the shared pointer's members. + If the contained pointer is \nullptr, behavior is undefined. \sa isNull() */ /*! \fn template bool QSharedPointer::isNull() const - Returns \c true if this object is holding a reference to a null - pointer. + Returns \c true if this object refers to \nullptr. */ /*! \fn template QSharedPointer::operator bool() const - Returns \c true if this object is not null. This function is suitable - for use in \tt if-constructs, like: + Returns \c true if the contained pointer is not \nullptr. + This function is suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 4 @@ -579,8 +581,8 @@ /*! \fn template bool QSharedPointer::operator !() const - Returns \c true if this object is \nullptr. This function is - suitable for use in \tt if-constructs, like: + Returns \c true if this object refers to \nullptr. + This function is suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 5 @@ -803,11 +805,10 @@ /*! \fn template bool QWeakPointer::isNull() const - Returns \c true if this object is holding a reference to a null - pointer. + Returns \c true if this object refers to \nullptr. Note that, due to the nature of weak references, the pointer that - QWeakPointer references can become null at any moment, so + QWeakPointer references can become \nullptr at any moment, so the value returned from this function can change from false to true from one call to the next. */ @@ -815,13 +816,13 @@ /*! \fn template QWeakPointer::operator bool() const - Returns \c true if this object is not null. This function is suitable - for use in \tt if-constructs, like: + Returns \c true if the contained pointer is not \nullptr. + This function is suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 8 Note that, due to the nature of weak references, the pointer that - QWeakPointer references can become null at any moment, so + QWeakPointer references can become \nullptr at any moment, so the value returned from this function can change from true to false from one call to the next. @@ -831,13 +832,13 @@ /*! \fn template bool QWeakPointer::operator !() const - Returns \c true if this object is \nullptr. This function is - suitable for use in \tt if-constructs, like: + Returns \c true if this object refers to \nullptr. + This function is suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 9 Note that, due to the nature of weak references, the pointer that - QWeakPointer references can become null at any moment, so + QWeakPointer references can become \nullptr at any moment, so the value returned from this function can change from false to true from one call to the next. @@ -918,7 +919,7 @@ If \c this (that is, the subclass instance invoking this method) is being managed by a QSharedPointer, returns a shared pointer instance pointing to - \c this; otherwise returns a QSharedPointer holding a null pointer. + \c this; otherwise returns a null QSharedPointer. */ /*! @@ -933,8 +934,7 @@ \fn template template bool operator==(const QSharedPointer &ptr1, const QSharedPointer &ptr2) \relates QSharedPointer - Returns \c true if the pointer referenced by \a ptr1 is the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -947,8 +947,7 @@ \fn template template bool operator!=(const QSharedPointer &ptr1, const QSharedPointer &ptr2) \relates QSharedPointer - Returns \c true if the pointer referenced by \a ptr1 is not the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -961,8 +960,7 @@ \fn template template bool operator==(const QSharedPointer &ptr1, const X *ptr2) \relates QSharedPointer - Returns \c true if the pointer referenced by \a ptr1 is the - same pointer as \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer. If \a ptr2's type is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -975,8 +973,7 @@ \fn template template bool operator!=(const QSharedPointer &ptr1, const X *ptr2) \relates QSharedPointer - Returns \c true if the pointer referenced by \a ptr1 is not the - same pointer as \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers. If \a ptr2's type is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -1017,8 +1014,7 @@ \fn template template bool operator==(const QSharedPointer &ptr1, const QWeakPointer &ptr2) \relates QWeakPointer - Returns \c true if the pointer referenced by \a ptr1 is the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -1031,8 +1027,7 @@ \fn template template bool operator!=(const QSharedPointer &ptr1, const QWeakPointer &ptr2) \relates QWeakPointer - Returns \c true if the pointer referenced by \a ptr1 is not the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -1045,8 +1040,7 @@ \fn template template bool operator==(const QWeakPointer &ptr1, const QSharedPointer &ptr2) \relates QWeakPointer - Returns \c true if the pointer referenced by \a ptr1 is the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast @@ -1060,7 +1054,7 @@ \relates QSharedPointer \since 5.8 - Returns \c true if the pointer referenced by \a lhs is a null pointer. + Returns \c true if \a lhs refers to \nullptr. \sa QSharedPointer::isNull() */ @@ -1070,7 +1064,7 @@ \relates QSharedPointer \since 5.8 - Returns \c true if the pointer referenced by \a rhs is a null pointer. + Returns \c true if \a rhs refers to \nullptr. \sa QSharedPointer::isNull() */ @@ -1080,8 +1074,7 @@ \relates QSharedPointer \since 5.8 - Returns \c true if the pointer referenced by \a lhs is a valid (i.e. - non-null) pointer. + Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer. \sa QSharedPointer::isNull() */ @@ -1091,8 +1084,7 @@ \relates QSharedPointer \since 5.8 - Returns \c true if the pointer referenced by \a rhs is a valid (i.e. - non-null) pointer. + Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer. \sa QSharedPointer::isNull() */ @@ -1102,7 +1094,7 @@ \relates QWeakPointer \since 5.8 - Returns \c true if the pointer referenced by \a lhs is a null pointer. + Returns \c true if \a lhs refers to \nullptr. \sa QWeakPointer::isNull() */ @@ -1112,7 +1104,7 @@ \relates QWeakPointer \since 5.8 - Returns \c true if the pointer referenced by \a rhs is a null pointer. + Returns \c true if \a rhs refers to \nullptr. \sa QWeakPointer::isNull() */ @@ -1122,8 +1114,7 @@ \relates QWeakPointer \since 5.8 - Returns \c true if the pointer referenced by \a lhs is a valid (i.e. - non-null) pointer. + Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer. \sa QWeakPointer::isNull() */ @@ -1133,8 +1124,7 @@ \relates QWeakPointer \since 5.8 - Returns \c true if the pointer referenced by \a rhs is a valid (i.e. - non-null) pointer. + Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer. \sa QWeakPointer::isNull() */ @@ -1143,8 +1133,7 @@ \fn template template bool operator!=(const QWeakPointer &ptr1, const QSharedPointer &ptr2) \relates QWeakPointer - Returns \c true if the pointer referenced by \a ptr1 is not the - same pointer as that referenced by \a ptr2. + Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers. If \a ptr2's template parameter is different from \a ptr1's, QSharedPointer will attempt to perform an automatic \tt static_cast diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index a123aa8e75..ee9d486eb8 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1685,10 +1685,9 @@ const QString::Null QString::null = { }; \snippet qstring/main.cpp 8 All functions except isNull() treat null strings the same as empty - strings. For example, toUtf8().constData() returns a pointer to a - '\\0' character for a null string (\e not a null pointer), and - QString() compares equal to QString(""). We recommend that you - always use the isEmpty() function and avoid isNull(). + strings. For example, toUtf8().constData() returns a valid pointer + (\e not nullptr) to a '\\0' character for a null string. We + recommend that you always use the isEmpty() function and avoid isNull(). \section1 Argument Formats @@ -4553,7 +4552,7 @@ int QString::indexOf(const QRegularExpression& re, int from) const expression \a re in the string, searching forward from index position \a from. Returns -1 if \a re didn't match anywhere. - If the match is successful and \a rmatch is not a null pointer, it also + If the match is successful and \a rmatch is not \nullptr, it also writes the results of the match into the QRegularExpressionMatch object pointed to by \a rmatch. @@ -4604,7 +4603,7 @@ int QString::lastIndexOf(const QRegularExpression &re, int from) const expression \a re in the string, which starts before the index position \a from. Returns -1 if \a re didn't match anywhere. - If the match is successful and \a rmatch is not a null pointer, it also + If the match is successful and \a rmatch is not \nullptr, it also writes the results of the match into the QRegularExpressionMatch object pointed to by \a rmatch. @@ -4655,14 +4654,14 @@ bool QString::contains(const QRegularExpression &re) const Returns \c true if the regular expression \a re matches somewhere in this string; otherwise returns \c false. - If the match is successful and \a match is not a null pointer, it also + If the match is successful and \a rmatch is not \nullptr, it also writes the results of the match into the QRegularExpressionMatch object - pointed to by \a match. + pointed to by \a rmatch. \sa QRegularExpression::match() */ -bool QString::contains(const QRegularExpression &re, QRegularExpressionMatch *match) const +bool QString::contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch) const { if (!re.isValid()) { qWarning("QString::contains: invalid QRegularExpression object"); @@ -4670,8 +4669,8 @@ bool QString::contains(const QRegularExpression &re, QRegularExpressionMatch *ma } QRegularExpressionMatch m = re.match(*this); bool hasMatch = m.hasMatch(); - if (hasMatch && match) - *match = qMove(m); + if (hasMatch && rmatch) + *rmatch = qMove(m); return hasMatch; } @@ -10333,8 +10332,8 @@ ownership of it, no memory is freed when instances are destroyed. /*! \fn bool QStringRef::isNull() const - Returns \c true if string() returns a null pointer or a pointer to a - null string; otherwise returns \c true. + Returns \c true if this string reference does not reference a string or if + the string it references is null (i.e. QString::isNull() is true). \sa size() */ diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index da76601e88..b138c3f140 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -359,7 +359,7 @@ public: int lastIndexOf(const QRegularExpression &re, int from = -1) const; int lastIndexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads bool contains(const QRegularExpression &re) const; - bool contains(const QRegularExpression &re, QRegularExpressionMatch *match) const; // ### Qt 6: merge overloads + bool contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads int count(const QRegularExpression &re) const; #endif diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 46dec7f28d..6b825fa001 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -526,7 +526,7 @@ static void qAccessibleCleanup() to it. If the key and the QObject does not have a corresponding - QAccessibleInterface, a null-pointer will be returned. + QAccessibleInterface, \nullptr will be returned. Installed factories are called by queryAccessibilityInterface() until one provides an interface. diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index c3c4b24678..80fa65daac 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -1523,7 +1523,7 @@ QDebug operator<<(QDebug dbg, const QIcon &i) foo@3x.png, then foo@2x, then fall back to foo.png if not found. \a sourceDevicePixelRatio will be set to the value of N if the argument is - a non-null pointer + not \nullptr */ QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 56b82abcfa..bba36b09cd 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -1485,8 +1485,8 @@ static QPictureHandler *get_picture_handler(const char *format) \a format is used to select a handler to write a QPicture; \a header is used to select a handler to read an picture file. - If \a readPicture is a null pointer, the QPictureIO will not be able - to read pictures in \a format. If \a writePicture is a null pointer, + If \a readPicture is \nullptr, the QPictureIO will not be able + to read pictures in \a format. If \a writePicture is \nullptr, the QPictureIO will not be able to write pictures in \a format. If both are null, the QPictureIO object is valid but useless. diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 3e3c7a6211..2390c62b9f 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -1846,7 +1846,7 @@ bool QStandardItem::hasChildren() const item) takes ownership of \a item. If necessary, the row count and column count are increased to fit the item. - \note Passing a null pointer as \a item removes the item. + \note Passing \nullptr as \a item removes the item. \sa child() */ diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index bf3403f2e4..5bc6e27eb2 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -787,7 +787,7 @@ QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const to the non-template function. Note that requests for function objects of other versions or profiles can fail and - in doing so will return a null pointer. Situations in which creation of the functions + in doing so will return \nullptr. Situations in which creation of the functions object can fail are if the request cannot be satisfied due to asking for functions that are not in the version or profile of this context. For example: @@ -1330,7 +1330,7 @@ bool QOpenGLContext::supportsThreadedOpenGL() \since 5.5 Returns the application-wide shared OpenGL context, if present. - Otherwise, returns a null pointer. + Otherwise, returns \nullptr. This is useful if you need to upload OpenGL objects (buffers, textures, etc.) before creating or showing a QOpenGLWidget or QQuickWidget. diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 590e2a85bb..476a7f2ffb 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2862,7 +2862,7 @@ void QWindow::setVulkanInstance(QVulkanInstance *instance) } /*! - \return the associated Vulkan instance or \c null if there is none. + \return the associated Vulkan instance if any was set, otherwise \nullptr. */ QVulkanInstance *QWindow::vulkanInstance() const { diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 18c5a4f3dd..547b21c02e 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1316,8 +1316,8 @@ QTextList *QTextBlock::textList() const /*! \since 4.1 - Returns a pointer to a QTextBlockUserData object if previously set with - setUserData() or a null pointer. + Returns a pointer to a QTextBlockUserData object, + if one has been set with setUserData(), or \nullptr. */ QTextBlockUserData *QTextBlock::userData() const { diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp index 9895fec2ca..2941bfd01f 100644 --- a/src/gui/vulkan/qvulkaninstance.cpp +++ b/src/gui/vulkan/qvulkaninstance.cpp @@ -614,7 +614,7 @@ VkResult QVulkanInstance::errorCode() const } /*! - \return the VkInstance handle this QVulkanInstance wraps, or \c null if + \return the VkInstance handle this QVulkanInstance wraps, or \nullptr if create() has not yet been successfully called and no existing instance has been provided via setVkInstance(). */ diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index c5bd599a51..3e36a7b229 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -408,7 +408,7 @@ int QLocalServer::maxPendingConnections() const still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory. - 0 is returned if this function is called when there are no pending + \nullptr is returned if this function is called when there are no pending connections. \sa hasPendingConnections(), newConnection(), incomingConnection() diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 56c700ca8f..98e58192a2 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -548,7 +548,7 @@ bool QTcpServer::hasPendingConnections() const destroyed. It is still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory. - 0 is returned if this function is called when there are no pending + \nullptr is returned if this function is called when there are no pending connections. \note The returned QTcpSocket object cannot be used from another diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 0156b5bf96..4820953468 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -417,7 +417,7 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons /*! \fn Qt::HANDLE QSslCertificate::handle() const Returns a pointer to the native certificate handle, if there is - one, or a null pointer otherwise. + one, else \nullptr. You can use this handle, together with the native API, to access extended information about the certificate. diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp index b29b38beab..5c90719fcd 100644 --- a/src/network/ssl/qsslkey_p.cpp +++ b/src/network/ssl/qsslkey_p.cpp @@ -490,8 +490,8 @@ QByteArray QSslKey::toPem(const QByteArray &passPhrase) const } /*! - Returns a pointer to the native key handle, if it is available; - otherwise a null pointer is returned. + Returns a pointer to the native key handle, if there is + one, else \nullptr. You can use this handle together with the native API to access extended information about the key. diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 8ef53afaea..799e984a68 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4023,7 +4023,7 @@ QGLWidget::~QGLWidget() \fn QFunctionPointer QGLContext::getProcAddress(const QString &proc) const Returns a function pointer to the GL extension function passed in - \a proc. 0 is returned if a pointer to the function could not be + \a proc. \nullptr is returned if a pointer to the function could not be obtained. */ QFunctionPointer QGLContext::getProcAddress(const QString &procName) const diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index d29f74e93d..e486037e08 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -1197,8 +1197,8 @@ QStringList QFileSystemModel::mimeTypes() const \a indexes. The format used to describe the items corresponding to the indexes is obtained from the mimeTypes() function. - If the list of indexes is empty, 0 is returned rather than a serialized - empty list. + If the list of indexes is empty, \nullptr is returned rather than a + serialized empty list. */ QMimeData *QFileSystemModel::mimeData(const QModelIndexList &indexes) const { diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index e46d25bef1..37bb370e73 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1902,8 +1902,8 @@ QStringList QListWidget::mimeTypes() const \a items. The format used to describe the items is obtained from the mimeTypes() function. - If the list of items is empty, 0 is returned instead of a serialized empty - list. + If the list of items is empty, \nullptr is returned instead of a + serialized empty list. */ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) QMimeData *QListWidget::mimeData(const QList &items) const diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index ec4897a7ae..0fb9e28385 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -2633,8 +2633,8 @@ QStringList QTableWidget::mimeTypes() const \a items. The format used to describe the items is obtained from the mimeTypes() function. - If the list of items is empty, 0 is returned rather than a serialized - empty list. + If the list of items is empty, \nullptr is returned rather than a + serialized empty list. */ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) QMimeData *QTableWidget::mimeData(const QList &items) const diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 29cc199526..d2dc91b18c 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -3395,8 +3395,8 @@ QStringList QTreeWidget::mimeTypes() const \a items. The format used to describe the items is obtained from the mimeTypes() function. - If the list of items is empty, 0 is returned rather than a serialized - empty list. + If the list of items is empty, \nullptr is returned rather than a + serialized empty list. */ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) QMimeData *QTreeWidget::mimeData(const QList &items) const diff --git a/src/widgets/itemviews/qtreewidgetitemiterator.cpp b/src/widgets/itemviews/qtreewidgetitemiterator.cpp index 1c1f60bc37..14c19fcb9c 100644 --- a/src/widgets/itemviews/qtreewidgetitemiterator.cpp +++ b/src/widgets/itemviews/qtreewidgetitemiterator.cpp @@ -170,7 +170,7 @@ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator=(const QTreeWidgetIte /*! The prefix ++ operator (++it) advances the iterator to the next matching item and returns a reference to the resulting iterator. - Sets the current pointer to 0 if the current item is the last matching item. + Sets the current pointer to \nullptr if the current item is the last matching item. */ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator++() @@ -185,7 +185,7 @@ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator++() /*! The prefix -- operator (--it) advances the iterator to the previous matching item and returns a reference to the resulting iterator. - Sets the current pointer to 0 if the current item is the first matching item. + Sets the current pointer to \nullptr if the current item is the first matching item. */ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator--() @@ -395,7 +395,7 @@ void QTreeWidgetItemIteratorPrivate::ensureValidIterator(const QTreeWidgetItem * iterator goes backward.) If the current item is beyond the last item, the current item pointer is - set to 0. Returns the resulting iterator. + set to \nullptr. Returns the resulting iterator. */ /*! @@ -411,7 +411,7 @@ void QTreeWidgetItemIteratorPrivate::ensureValidIterator(const QTreeWidgetItem * iterator goes forward.) If the current item is ahead of the last item, the current item pointer is - set to 0. Returns the resulting iterator. + set to \nullptr. Returns the resulting iterator. */ /*! diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b4a091765b..8f339a23f6 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1904,8 +1904,8 @@ void QApplication::aboutQt() This signal is emitted when the widget that has keyboard focus changed from \a old to \a now, i.e., because the user pressed the tab-key, clicked into - a widget or changed the active window. Both \a old and \a now can be the - null-pointer. + a widget or changed the active window. Both \a old and \a now can be \nullptr. + The signal is emitted after both widget have been notified about the change through QFocusEvent. diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index e3f6a56875..53c4de49c6 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -109,7 +109,7 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) /*! Constructs a new top-level QLayout, with parent \a parent. - \a parent may not be a \nullptr. + \a parent may not be \nullptr. The layout is set directly as the top-level layout for \a parent. There can be only one top-level layout for a @@ -419,9 +419,9 @@ void QLayout::setContentsMargins(const QMargins &margins) /*! \since 4.3 - Extracts the left, top, right, and bottom margins used around the - layout, and assigns them to *\a left, *\a top, *\a right, and *\a - bottom (unless they are null pointers). + For each of \a left, \a top, \a right and \a bottom that is not + \nullptr, stores the size of the margin named in the location the + pointer refers to. By default, QLayout uses the values provided by the style. On most platforms, the margin is 11 pixels in all directions. diff --git a/src/widgets/util/qundoview.cpp b/src/widgets/util/qundoview.cpp index c862cbcea5..f59d87fb9d 100644 --- a/src/widgets/util/qundoview.cpp +++ b/src/widgets/util/qundoview.cpp @@ -361,7 +361,7 @@ QUndoStack *QUndoView::stack() const Sets the stack displayed by this view to \a stack. If \a stack is 0, the view will be empty. - If the view was previously looking at a QUndoGroup, the group is set to 0. + If the view was previously looking at a QUndoGroup, the group is set to \nullptr. \sa stack(), setGroup() */ diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index fae3aebba4..9c4c46f2d6 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -596,7 +596,7 @@ QStatusBar *QMainWindow::statusBar() const /*! Sets the status bar for the main window to \a statusbar. - Setting the status bar to 0 will remove it from the main window. + Setting the status bar to \nullptr will remove it from the main window. Note that QMainWindow takes ownership of the \a statusbar pointer and deletes it at the appropriate time. @@ -1464,8 +1464,8 @@ void QMainWindow::contextMenuEvent(QContextMenuEvent *event) #if QT_CONFIG(menu) /*! Returns a popup menu containing checkable entries for the toolbars and - dock widgets present in the main window. If there are no toolbars and - dock widgets present, this function returns a null pointer. + dock widgets present in the main window. If there are no toolbars and + dock widgets present, this function returns \nullptr. By default, this function is called by the main window when the user activates a context menu, typically by right-clicking on a toolbar or a dock diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index feea7cd050..8b201dcf9d 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -1998,9 +1998,9 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla Removes \a widget from the MDI area. The \a widget must be either a QMdiSubWindow or a widget that is the internal widget of a subwindow. Note \a widget is never actually deleted by QMdiArea. - If a QMdiSubWindow is passed in its parent is set to 0 and it is - removed, but if an internal widget is passed in the child widget - is set to 0 but the QMdiSubWindow is not removed. + If a QMdiSubWindow is passed in, its parent is set to \nullptr and it is + removed; but if an internal widget is passed in, the child widget + is set to \nullptr and the QMdiSubWindow is \e not removed. \sa addSubWindow() */ diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index e7984078de..a53d7841f4 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -897,8 +897,8 @@ QAction *QMenuBar::insertMenu(QAction *before, QMenu *menu) } /*! - Returns the QAction that is currently highlighted. A null pointer - will be returned if no action is currently selected. + Returns the QAction that is currently highlighted, if any, + else \nullptr. */ QAction *QMenuBar::activeAction() const { diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index cffc1974af..0516d426e5 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -1951,7 +1951,7 @@ void QDomNodePrivate::setLocation(int lineNumber, int columnNumber) which return a QDomNode, e.g. firstChild(). You can make an independent (deep) copy of the node with cloneNode(). - A QDomNode can be null, much like a null pointer. Creating a copy + A QDomNode can be null, much like \nullptr. Creating a copy of a null node results in another null node. It is not possible to modify a null node, but it is possible to assign another, possibly non-null node to it. In this case, the copy of the null node diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 0e3a87e883..b2fff5b61f 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -2371,7 +2371,7 @@ bool QXmlDefaultHandler::unparsedEntityDecl(const QString&, const QString&, /*! \reimp - Sets \a ret to 0, so that the reader uses the system identifier + Sets \a ret to \nullptr, so that the reader uses the system identifier provided in the XML document. */ bool QXmlDefaultHandler::resolveEntity(const QString&, const QString&, -- cgit v1.2.3 From 2a79af6b5c67eba6f967c7443bf73bbe11206a62 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 8 May 2019 10:22:26 +0200 Subject: Doc: Document the c++2a CONFIG value Change-Id: Ia4d84ac141b6fb27b244dfb8272b8039e337a9e4 Reviewed-by: Allan Sandfeld Jensen --- qmake/doc/src/qmake-manual.qdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 3119a440d4..e669ca77a7 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -974,6 +974,9 @@ the compiler does not support C++17, or can't select the C++ standard. By default, support is disabled. \row \li c++17 \li Same as c++1z. + \row \li c++2a \li C++2a support is enabled. This option has no effect if + the compiler does not support C++2a, or can't select the C++ standard. + By default, support is disabled. \row \li strict_c++ \li Disables support for C++ compiler extensions. By default, they are enabled. \row \li depend_includepath \li Appending the value of INCLUDEPATH to -- cgit v1.2.3 From 3d8ed3ba969ba958401dbf5e6760cf0788f1888e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 12 Apr 2019 15:59:03 +0200 Subject: Fix: style sheet styling of background of triangular QTabWidget tabs The triangular tab shape is not reproducible with setting style border options, so it should be painted with the usual code path, also when a custom background has been set. Fixes: QTBUG-72096 Change-Id: I7bc1c0579386b8ea7266ce6456534c2519d9addf Reviewed-by: Christian Ehrlicher --- src/widgets/styles/qstylesheetstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index fc4efa18fb..2118bad9d6 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4165,12 +4165,12 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction); - if (ce == CE_TabBarTabShape && subRule.hasDrawable()) { + if (ce == CE_TabBarTabShape && subRule.hasDrawable() && tab->shape < QTabBar::TriangularNorth) { subRule.drawRule(p, r); return; } QStyleOptionTab tabCopy(*tab); - subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Window); + subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Base); QFont oldFont = p->font(); if (subRule.hasFont) p->setFont(subRule.font); -- cgit v1.2.3 From 9dbbccf7a2515c81842e80fb4d6bb3c3d82802b3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 9 May 2019 11:58:23 +0200 Subject: Fix emar invocation on Windows for MinGW If qmake is called without sh.exe in PATH, the relative paths in OBJECTS will contain backslashes as separator. Anyhow, emar needs forward slashes. Use GNU make's subst command to fix this. This amends 22c1e10e1955c63. Task-number: QTBUG-75257 Change-Id: Iacc6fe69cf470f35c6ddd829be7a80944346452d Reviewed-by: Joerg Bornemann --- mkspecs/wasm-emscripten/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index ca8c477c80..c6c3af3622 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -96,7 +96,7 @@ QMAKE_EXTENSION_STATICLIB = a # llvm bitcode QMAKE_AR = emar cqs equals(QMAKE_HOST.os, Windows) { QMAKE_AR_CMD = \ - "$(file >$(OBJECTS_DIR)/$(TARGET).rsp, $(OBJECTS))$$escape_expand(\\n\\t)" \ + "$(file >$(OBJECTS_DIR)/$(TARGET).rsp, $(subst \\,/,$(OBJECTS)))$$escape_expand(\\n\\t)" \ "$(AR) $(DESTDIR)$(TARGET) @$(OBJECTS_DIR)/$(TARGET).rsp" } -- cgit v1.2.3 From bac2b0ef369503a9f00c503c1d8c5b12a496c3eb Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 9 May 2019 10:42:03 +0200 Subject: qmake: Escape trailing backslash for OBJECTS_DIR for MinGW qmake automatically appends a dir_sep to a few directory paths (see MakefileGenerator::initOutPaths), and various .pri and .prf files rely on that. Anyhow, for non-MSys MinGW on Windows this creates a problem, because mingw32-make will interpret the backslash in OBJECTS_DIR = some_path\ to escape the following newline. We have been working around this problem in various ways: - winmakefile.cpp just removes the trailing \ for OBJECTS_DIR, at the cost of not being compatible with logic in .prf/.pri files that rely on the separator. - winmakefile.cpp adds a '#avoid trailing-slash linebreak' comment for DESTDIR. Anyhow, this does not seem to work for mingw32-make: If you reference $(DESTDIR), the variable will contain trailing spaces. - unixmakefile2.cpp duplicates a trailing \ for DESTDIR. The last approach is now taken also for OBJECTS_DIR. Task-number: QTBUG-75257 Change-Id: Ie8171a990a9ce1cfbf1b94037252ef2392313338 Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake2.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 7d8c70ec3b..b9de61fbc7 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -169,6 +169,16 @@ static QString rfc1034Identifier(const QString &str) return s; } +static QString escapeDir(const QString &dir) +{ + // When building on non-MSys MinGW, the path ends with a backslash, which + // GNU make will interpret that as a line continuation. Doubling the backslash + // avoids the problem, at the cost of the variable containing *both* backslashes. + if (dir.endsWith('\\')) + return dir + '\\'; + return dir; +} + void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { @@ -231,7 +241,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "####### Output directory\n\n"; // This is used in commands by some .prf files. if (! project->values("OBJECTS_DIR").isEmpty()) - t << "OBJECTS_DIR = " << fileVar("OBJECTS_DIR") << endl; + t << "OBJECTS_DIR = " << escapeDir(fileVar("OBJECTS_DIR")) << endl; else t << "OBJECTS_DIR = ./\n"; t << endl; @@ -277,13 +287,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " " << fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << endl; t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl; - QString destd = fileVar("DESTDIR"); - // When building on non-MSys MinGW, the path ends with a backslash, which - // GNU make will interpret that as a line continuation. Doubling the backslash - // avoids the problem, at the cost of the variable containing *both* backslashes. - if (destd.endsWith('\\')) - destd += '\\'; - t << "DESTDIR = " << destd << endl; + t << "DESTDIR = " << escapeDir(fileVar("DESTDIR")) << endl; t << "TARGET = " << fileVar("TARGET") << endl; if(project->isActiveConfig("plugin")) { t << "TARGETD = " << fileVar("TARGET") << endl; -- cgit v1.2.3 From 22c3c55de44b9b900b5e4d7040a9c3f906d0bfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 26 Apr 2019 15:33:49 +0200 Subject: wasm: install one browser window resize handler Install one browser window resize handler instead of per-canvas resize handlers, which avoids having to uninstall on QScreen destruction. Task-number: QTBUG-75463 Change-Id: I8345262a906ed735f8e9e146f1e963f515cf0d25 Reviewed-by: Lorn Potter --- .../platforms/wasm/qwasmeventtranslator.cpp | 18 ------------------ src/plugins/platforms/wasm/qwasmeventtranslator.h | 2 -- src/plugins/platforms/wasm/qwasmintegration.cpp | 22 ++++++++++++++++++++++ src/plugins/platforms/wasm/qwasmintegration.h | 1 + 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 7126c00354..f586c5378e 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -375,9 +375,6 @@ void QWasmEventTranslator::initEventHandlers() emscripten_set_touchend_callback(canvasId, (void *)this, 1, &touchCallback); emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback); emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback); - - emscripten_set_resize_callback(nullptr, (void *)this, 1, uiEvent_cb); // Note: handles browser window resize - } template @@ -909,19 +906,4 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa return accepted; } -int QWasmEventTranslator::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData) -{ - Q_UNUSED(e) - QWasmEventTranslator *eventTranslator = static_cast(userData); - - if (eventType == EMSCRIPTEN_EVENT_RESIZE) { - // This resize event is called when the HTML window is resized. Depending - // on the page layout the the canvas might also have been resized, so we - // update the Qt screen size (and canvas render size). - eventTranslator->screen()->updateQScreenAndCanvasRenderSize(); - } - - return 0; -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index d6043072ba..1655b7226a 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -57,8 +57,6 @@ public: static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData); - static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData); - void processEvents(); void initEventHandlers(); int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent); diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index e601d553f2..703b0fde0b 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -115,6 +115,21 @@ QWasmIntegration::QWasmIntegration() } emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload")); + + // install browser window resize handler + auto onWindowResize = [](int eventType, const EmscriptenUiEvent *e, void *userData) -> int { + Q_UNUSED(eventType); + Q_UNUSED(e); + Q_UNUSED(userData); + + // This resize event is called when the HTML window is resized. Depending + // on the page layout the the canvas(es) might also have been resized, so we + // update the Qt screen sizes (and canvas render sizes). + if (QWasmIntegration *integration = QWasmIntegration::get()) + integration->resizeAllScreens(); + return 0; + }; + emscripten_set_resize_callback(nullptr, nullptr, 1, onWindowResize); } QWasmIntegration::~QWasmIntegration() @@ -245,4 +260,11 @@ void QWasmIntegration::resizeScreen(const QString &canvasId) m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize(); } +void QWasmIntegration::resizeAllScreens() +{ + qDebug() << "resizeAllScreens"; + for (QWasmScreen *screen : m_screens) + screen->updateQScreenAndCanvasRenderSize(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index 11d8d0f7f5..d5011db067 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -81,6 +81,7 @@ public: void addScreen(const QString &canvasId); void removeScreen(const QString &canvasId); void resizeScreen(const QString &canvasId); + void resizeAllScreens(); private: mutable QWasmFontDatabase *m_fontDb; -- cgit v1.2.3 From 6d7c7a5ddafc8005969d4d99dc0c92b49ac4bcb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 27 Apr 2019 00:27:19 +0200 Subject: wasm: prevent crash on null backingstore pointer We can get draw calls in between creating the platform window and the platform backing store. Task-number: QTBUG-75463 Change-Id: If0b67d40fac84e466f204ec23a267aa4c6121cbd Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcompositor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index e6a69c4814..b3234197d0 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -251,6 +251,8 @@ void QWasmCompositor::blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window) { QWasmBackingStore *backingStore = window->backingStore(); + if (!backingStore) + return; QOpenGLTexture const *texture = backingStore->getUpdatedTexture(); -- cgit v1.2.3 From 00de44701d1496377632681c5228af4abfea0033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 27 Apr 2019 00:30:20 +0200 Subject: wasm: use correct coordinates when blitting The target position is the position on the canvas, not the global position on the page. Task-number: QTBUG-75463 Change-Id: I4ea2c9afacd2065fa975f6fa2e6a93d98f637854 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcompositor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index b3234197d0..9d99c21195 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -255,8 +255,9 @@ void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScr return; QOpenGLTexture const *texture = backingStore->getUpdatedTexture(); - - blit(blitter, screen, texture, window->geometry()); + QPoint windowCanvasPosition = window->geometry().topLeft() - screen->geometry().topLeft(); + QRect windowCanvasGeometry = QRect(windowCanvasPosition, window->geometry().size()); + blit(blitter, screen, texture, windowCanvasGeometry); } QPalette QWasmCompositor::makeWindowPalette() -- cgit v1.2.3 From 4e0f26289244d587714abf8adda932cce5697925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 01:11:25 +0200 Subject: wasm: add QWasmOffscreenSurface This no-op implementation is sufficient to support OpenGL cleanup use cases, where the OpenGL context needs to be made current at times where we don't have a window available. A specific requirement on WebAssembly is that the context is tied to one specific screen; which is an extra requirement on QWasmOffscreenSurface, compared to the other platforms. Task-number: QTBUG-75463 Change-Id: Ie3658cb235bf342be66f19dfe981e3a56a90e1b6 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmintegration.cpp | 6 +++ src/plugins/platforms/wasm/qwasmintegration.h | 1 + .../platforms/wasm/qwasmoffscreensurface.cpp | 41 ++++++++++++++++++ src/plugins/platforms/wasm/qwasmoffscreensurface.h | 49 ++++++++++++++++++++++ src/plugins/platforms/wasm/wasm.pro | 6 ++- 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/wasm/qwasmoffscreensurface.cpp create mode 100644 src/plugins/platforms/wasm/qwasmoffscreensurface.h diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 703b0fde0b..0d22d31c25 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -35,6 +35,7 @@ #include "qwasmtheme.h" #include "qwasmclipboard.h" #include "qwasmservices.h" +#include "qwasmoffscreensurface.h" #include "qwasmwindow.h" #ifndef QT_NO_OPENGL @@ -188,6 +189,11 @@ QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLCon } #endif +QPlatformOffscreenSurface *QWasmIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ + return new QWasmOffscrenSurface(surface); +} + QPlatformFontDatabase *QWasmIntegration::fontDatabase() const { if (m_fontDb == nullptr) diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index d5011db067..dc1cc72382 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -65,6 +65,7 @@ public: #ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; QPlatformFontDatabase *fontDatabase() const override; QAbstractEventDispatcher *createEventDispatcher() const override; QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; diff --git a/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp b/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp new file mode 100644 index 0000000000..a205e5ddea --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmoffscreensurface.h" + +QWasmOffscrenSurface::QWasmOffscrenSurface(QOffscreenSurface *offscreenSurface) + :QPlatformOffscreenSurface(offscreenSurface) +{ + +} + +QWasmOffscrenSurface::~QWasmOffscrenSurface() +{ + +} diff --git a/src/plugins/platforms/wasm/qwasmoffscreensurface.h b/src/plugins/platforms/wasm/qwasmoffscreensurface.h new file mode 100644 index 0000000000..9d3e805be0 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmoffscreensurface.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASMOFFSCREENSURFACE_H +#define QWASMOFFSCREENSURFACE_H + +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenSurface; +class QWasmOffscrenSurface : public QPlatformOffscreenSurface +{ +public: + explicit QWasmOffscrenSurface(QOffscreenSurface *offscreenSurface); + ~QWasmOffscrenSurface(); +private: + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index e8728d9dba..c28df8f893 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -20,7 +20,8 @@ SOURCES = \ qwasmopenglcontext.cpp \ qwasmtheme.cpp \ qwasmclipboard.cpp \ - qwasmservices.cpp + qwasmservices.cpp \ + qwasmoffscreensurface.cpp HEADERS = \ qwasmintegration.h \ @@ -35,7 +36,8 @@ HEADERS = \ qwasmopenglcontext.h \ qwasmtheme.h \ qwasmclipboard.h \ - qwasmservices.h + qwasmservices.h \ + qwasmoffscreensurface.h wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ -- cgit v1.2.3 From c8c4819b7b2f20c2972c31c49547ce5b59fe1240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 00:35:42 +0200 Subject: wasm: controlled screen destruction Freeing OpenGL resources requires a current context, which (on wasm) requires a screen. Add a destroy() functions to QWasmScreen, QWasmCompositor, QWasmWindow, and QWasmBackingStore which facilitates OpenGL cleanup before we start deleting screen objects. Task-number: QTBUG-75463 Change-Id: I9954b536416b9147965c74459ccad838d1578778 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmbackingstore.cpp | 6 +++++ src/plugins/platforms/wasm/qwasmbackingstore.h | 1 + src/plugins/platforms/wasm/qwasmcompositor.cpp | 29 ++++++++++++++++++++++-- src/plugins/platforms/wasm/qwasmcompositor.h | 1 + src/plugins/platforms/wasm/qwasmintegration.cpp | 4 +++- src/plugins/platforms/wasm/qwasmscreen.cpp | 5 ++++ src/plugins/platforms/wasm/qwasmscreen.h | 1 + src/plugins/platforms/wasm/qwasmwindow.cpp | 6 +++++ src/plugins/platforms/wasm/qwasmwindow.h | 1 + 9 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp index 5b40c44807..e8eda2605f 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp +++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp @@ -55,6 +55,12 @@ QWasmBackingStore::~QWasmBackingStore() { } +void QWasmBackingStore::destroy() +{ + if (m_texture->isCreated()) + m_texture->destroy(); +} + QPaintDevice *QWasmBackingStore::paintDevice() { return &m_image; diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.h b/src/plugins/platforms/wasm/qwasmbackingstore.h index 6ffa262e3d..4bca83c457 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.h +++ b/src/plugins/platforms/wasm/qwasmbackingstore.h @@ -44,6 +44,7 @@ class QWasmBackingStore : public QPlatformBackingStore public: QWasmBackingStore(QWasmCompositor *compositor, QWindow *window); ~QWasmBackingStore(); + void destroy(); QPaintDevice *paintDevice() override; diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 9d99c21195..6d211667be 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,28 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen) QWasmCompositor::~QWasmCompositor() { delete m_frameBuffer; + destroy(); +} + +void QWasmCompositor::destroy() +{ + // Destroy OpenGL resources. This is done here in a separate function + // which can be called while screen() still returns a valid screen + // (which it might not, during destruction). A valid QScreen is + // a requirement for QOffscreenSurface on Wasm since the native + // context is tied to a single canvas. + if (m_context) { + QOffscreenSurface offScreenSurface(screen()->screen()); + offScreenSurface.setFormat(m_context->format()); + offScreenSurface.create(); + m_context->makeCurrent(&offScreenSurface); + for (QWasmWindow *window : m_windowStack) + window->destroy(); + m_blitter.reset(nullptr); + m_context.reset(nullptr); + } + + m_isEnabled = false; // prevent frame() from creating a new m_context } void QWasmCompositor::setEnabled(bool enabled) @@ -653,7 +676,7 @@ void QWasmCompositor::frame() m_needComposit = false; - if (m_windowStack.empty() || !screen()) + if (!m_isEnabled || m_windowStack.empty() || !screen()) return; QWasmWindow *someWindow = nullptr; @@ -676,7 +699,9 @@ void QWasmCompositor::frame() m_context->create(); } - m_context->makeCurrent(someWindow->window()); + bool ok = m_context->makeCurrent(someWindow->window()); + if (!ok) + return; if (!m_blitter->isCreated()) m_blitter->create(); diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 3104573073..98f4a79b27 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -64,6 +64,7 @@ class QWasmCompositor : public QObject public: QWasmCompositor(QWasmScreen *screen); ~QWasmCompositor(); + void destroy(); enum QWasmSubControl { SC_None = 0x00000000, diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 0d22d31c25..93d3b5f76d 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -258,7 +258,9 @@ void QWasmIntegration::addScreen(const QString &canvasId) void QWasmIntegration::removeScreen(const QString &canvasId) { - QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId)); + QWasmScreen *exScreen = m_screens.take(canvasId); + exScreen->destroy(); // clean up before deleting the screen + QWindowSystemInterface::handleScreenRemoved(exScreen); } void QWasmIntegration::resizeScreen(const QString &canvasId) diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index a26cafa900..74d47555fc 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -57,7 +57,12 @@ QWasmScreen::QWasmScreen(const QString &canvasId) QWasmScreen::~QWasmScreen() { + destroy(); +} +void QWasmScreen::destroy() +{ + m_compositor->destroy(); } QWasmScreen *QWasmScreen::get(QPlatformScreen *screen) diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h index 82d2a83edb..4ad4ffa9ad 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.h +++ b/src/plugins/platforms/wasm/qwasmscreen.h @@ -52,6 +52,7 @@ class QWasmScreen : public QObject, public QPlatformScreen public: QWasmScreen(const QString &canvasId); ~QWasmScreen(); + void destroy(); static QWasmScreen *get(QPlatformScreen *screen); static QWasmScreen *get(QScreen *screen); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 39797cb09d..594db65cfd 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -65,6 +65,12 @@ QWasmWindow::~QWasmWindow() m_compositor->removeWindow(this); } +void QWasmWindow::destroy() +{ + if (m_backingStore) + m_backingStore->destroy(); +} + void QWasmWindow::initialize() { QRect rect = windowGeometry(); diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index cbbce99aeb..a098172649 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -58,6 +58,7 @@ public: QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore); ~QWasmWindow(); + void destroy(); void initialize() override; -- cgit v1.2.3 From 77216c5c5295a38cc432135e31529335c18c5a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 01:19:14 +0200 Subject: wasm: rewrite/simplify OpenglContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don’t need the contextLost callback since we can poll for the “lost” status in isValid() Recreating the native context is not very helpful, since it destroys all current context state. Remove this logic. Support makeCurrent() on different surfaces, as long as they refer to the same screen. Create the native context (and record which screen) on the first call to makeCurrent() Task-number: QTBUG-75463 Change-Id: I6eb830df14578ffdbed5b0505fe860ce433e4f9b Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmopenglcontext.cpp | 59 +++++++++++------------ src/plugins/platforms/wasm/qwasmopenglcontext.h | 6 +-- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp index ae43e2ebf0..0eaffdb77e 100644 --- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp +++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp @@ -41,40 +41,31 @@ QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format) QWasmOpenGLContext::~QWasmOpenGLContext() { - if (m_context) + if (m_context) { emscripten_webgl_destroy_context(m_context); + m_context = 0; + } } -void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surface) +bool QWasmOpenGLContext::maybeCreateEmscriptenContext(QPlatformSurface *surface) { - // Native emscripten contexts are tied to a single surface. Recreate - // the context if the surface is changed. - if (surface != m_surface) { - m_surface = surface; - - // Destroy existing context - if (m_context) - emscripten_webgl_destroy_context(m_context); - - // Create new context - const QString canvasId = QWasmScreen::get(surface->screen())->canvasId(); - m_context = createEmscriptenContext(canvasId, m_requestedFormat); - - // Register context-lost callback. - auto callback = [](int eventType, const void *reserved, void *userData) -> EM_BOOL - { - Q_UNUSED(eventType); - Q_UNUSED(reserved); - // The application may get contex-lost if e.g. moved to the background. Set - // m_contextLost which will make isValid() return false. Application code will - // then detect this and recrate the the context, resulting in a new QWasmOpenGLContext - // instance. - reinterpret_cast(userData)->m_contextLost = true; - return true; - }; - bool capture = true; - emscripten_set_webglcontextlost_callback(canvasId.toLocal8Bit().constData(), this, capture, callback); - } + // Native emscripten/WebGL contexts are tied to a single screen/canvas. The first + // call to this function creates a native canvas for the given screen, subsequent + // calls verify that the surface is on/off the same screen. + QPlatformScreen *screen = surface->screen(); + if (m_context && !screen) + return false; // Alternative: return true to support makeCurrent on QOffScreenSurface with + // no screen. However, Qt likes to substitute QGuiApplication::primaryScreen() + // for null screens, which foils this plan. + if (!screen) + return false; + if (m_context) + return m_screen == screen; + + QString canvasId = QWasmScreen::get(screen)->canvasId(); + m_context = createEmscriptenContext(canvasId, m_requestedFormat); + m_screen = screen; + return true; } EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const QString &canvasId, QSurfaceFormat format) @@ -113,7 +104,9 @@ GLuint QWasmOpenGLContext::defaultFramebufferObject(QPlatformSurface *surface) c bool QWasmOpenGLContext::makeCurrent(QPlatformSurface *surface) { - maybeRecreateEmscriptenContext(surface); + bool ok = maybeCreateEmscriptenContext(surface); + if (!ok) + return false; return emscripten_webgl_make_context_current(m_context) == EMSCRIPTEN_RESULT_SUCCESS; } @@ -136,7 +129,9 @@ bool QWasmOpenGLContext::isSharing() const bool QWasmOpenGLContext::isValid() const { - return (m_contextLost == false); + // Note: we get isValid() calls before we see the surface and can + // create a native context, so no context is also a valid state. + return !m_context || !emscripten_is_webgl_context_lost(m_context); } QFunctionPointer QWasmOpenGLContext::getProcAddress(const char *procName) diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.h b/src/plugins/platforms/wasm/qwasmopenglcontext.h index 126b596a7e..d27007e8ea 100644 --- a/src/plugins/platforms/wasm/qwasmopenglcontext.h +++ b/src/plugins/platforms/wasm/qwasmopenglcontext.h @@ -34,6 +34,7 @@ QT_BEGIN_NAMESPACE +class QPlatformScreen; class QWasmOpenGLContext : public QPlatformOpenGLContext { public: @@ -50,12 +51,11 @@ public: QFunctionPointer getProcAddress(const char *procName) override; private: - void maybeRecreateEmscriptenContext(QPlatformSurface *surface); + bool maybeCreateEmscriptenContext(QPlatformSurface *surface); static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE createEmscriptenContext(const QString &canvasId, QSurfaceFormat format); - bool m_contextLost = false; QSurfaceFormat m_requestedFormat; - QPlatformSurface *m_surface = nullptr; + QPlatformScreen *m_screen = nullptr; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE m_context = 0; }; -- cgit v1.2.3 From 1c7b5c20a5f1c2fabf9df7ee636014f5ba0ab114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 09:52:55 +0200 Subject: QOpenGLWindow: set QOffScreenSurface screen Required by QWasmOpenGLContext. Task-number: QTBUG-75463 Change-Id: Ie3cb80b50d7c909e6f46a6dec19644bf27cd41e7 Reviewed-by: Lorn Potter --- src/gui/kernel/qopenglwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index 8b052d92ae..022a47c919 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -440,7 +440,7 @@ void QOpenGLWindow::makeCurrent() d->context->makeCurrent(this); } else { if (!d->offscreenSurface) { - d->offscreenSurface.reset(new QOffscreenSurface); + d->offscreenSurface.reset(new QOffscreenSurface(screen())); d->offscreenSurface->setFormat(d->context->format()); d->offscreenSurface->create(); } -- cgit v1.2.3 From 3803b41eaecb6c1686aba88b4226486507aca094 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 14 May 2019 14:02:32 +0200 Subject: Revert "macOS: disable threaded OpenGL (unconditionally)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fc3e8514144535db22c431251bc0feea99cf72e2. The patch introduces a crash in Qt Quick in the test tst_QQuickWindow::multipleWindows() on macOS 10.12. Reverting this will cause dead locks on older macOS versions for users who opt in to using layer backed mode, so we should bring this back as soon as a fix can be found for the crash. But in order to proceed with qt5.git integration, we revert it for now. Task-number: QTBUG-75782 Change-Id: I57f6b2918c3fc4b4e58a8c39b24a19e2d796a4f4 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 855b42657d..fb3d05d3e4 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -347,13 +347,11 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons switch (cap) { #ifndef QT_NO_OPENGL case ThreadedOpenGL: - // Qt's threaded OpenGL implementation does not work well for layer-backed - // views, where we can easily end up in situations where rendering on secondary - // threads will result in visual artifacts, bugs, or even deadlocks. It is - // not possible to determine here if the the app will be using layer-backed - // views (it can opt-in using SDK 10.14+ on macOS 10.4+, or by setting - // NSWindow flags such as NSWindowStyleMaskFullSizeContentView). - return false; + // AppKit expects rendering to happen on the main thread, and we can + // easily end up in situations where rendering on secondary threads + // will result in visual artifacts, bugs, or even deadlocks, when + // building with SDK 10.14 or higher which enbles view layer-backing. + return QMacVersion::buildSDK() < QOperatingSystemVersion(QOperatingSystemVersion::MacOSMojave); case OpenGL: case BufferQueueingOpenGL: #endif -- cgit v1.2.3 From 8bcc6f111b1c8f0e5c9c9da18313a16559de63a5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 14 Mar 2019 20:12:08 +0100 Subject: QComboBox: add QT_DEPRECATED_X() for deprecated functions QT_DEPRECATED_X() was not added with d6d33f0b80dd85043c71f71a3ed5485d6014e6c4 for the deprecated QComboBox functions - Add them now. Change-Id: I8d4ea08766ae6ff052dfccac6c3f35ecf34affb7 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qcombobox.cpp | 2 +- src/widgets/widgets/qcombobox.h | 5 ++++- tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 9a403e8eef..a93c72a933 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1509,7 +1509,7 @@ int QComboBox::maxCount() const /*! \obsolete - Use setCompleter() instead. + Use completer() instead. */ bool QComboBox::autoCompletion() const { diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 64fbebb3c5..33686e547d 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -96,10 +96,13 @@ public: #if QT_CONFIG(completer) #if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use completer() instead.") bool autoCompletion() const; + QT_DEPRECATED_X("Use setCompleter() instead.") void setAutoCompletion(bool enable); - + QT_DEPRECATED_X("Use completer()->caseSensitivity() instead.") Qt::CaseSensitivity autoCompletionCaseSensitivity() const; + QT_DEPRECATED_X("Use completer()->setCaseSensitivity() instead.") void setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity); #endif #endif diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 5b4761ba87..a576770811 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -852,8 +852,8 @@ void tst_QComboBox::autoCompletionCaseSensitivity() // case insensitive testWidget->clearEditText(); QSignalSpy spyReturn(testWidget, SIGNAL(activated(int))); - testWidget->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); - QCOMPARE(testWidget->autoCompletionCaseSensitivity(), Qt::CaseInsensitive); + testWidget->completer()->setCaseSensitivity(Qt::CaseInsensitive); + QCOMPARE(testWidget->completer()->caseSensitivity(), Qt::CaseInsensitive); QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); qApp->processEvents(); @@ -886,8 +886,8 @@ void tst_QComboBox::autoCompletionCaseSensitivity() // case sensitive testWidget->clearEditText(); - testWidget->setAutoCompletionCaseSensitivity(Qt::CaseSensitive); - QCOMPARE(testWidget->autoCompletionCaseSensitivity(), Qt::CaseSensitive); + testWidget->completer()->setCaseSensitivity(Qt::CaseSensitive); + QCOMPARE(testWidget->completer()->caseSensitivity(), Qt::CaseSensitive); QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); qApp->processEvents(); QCOMPARE(testWidget->currentText(), QString("aww")); -- cgit v1.2.3 From 3976df280521cad0bb3e782369494ad4ef906fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Mar 2019 15:38:41 +0100 Subject: macOS: Track screens via Quartz Display Services instead of NSScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using NSScreen as the basis for tracking screens is not recommended, as the list of screens can be added, removed, or dynamically reconfigured at any time, and the NSScreen instance, or index in the NSScreen.screens array may not be stable. Quartz Display Services on the other hand tracks displays via a unique display ID, which typically remains constant until the machine is restarted. The lower level API also gives us earlier callbacks about screen changes than the corresponding NSApplicationDidChangeScreenParametersNotification does. By reacting to screen changes _before_ AppKit does, we can remove workarounds for receiving window move and screen change notifications before the screen was actually visibly reconfigured. The new approach also handles changes to the primary screen, which can happen if the user moves the menu bar in the macOS display arrangement pane. The device pixel ratio of the screen has been made into a cached property, like all the other properties of QCocoaScreen. This is more consistent, and allows us to qDebug the screen even when it has been removed and we no longer have access to resolve the properties from the associated Quarts display. Change-Id: I2d86c7629ed3bf5fb8c77f174712633752ae4079 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 12 -- src/plugins/platforms/cocoa/qcocoahelpers.h | 12 ++ src/plugins/platforms/cocoa/qcocoahelpers.mm | 2 +- src/plugins/platforms/cocoa/qcocoaintegration.h | 7 - src/plugins/platforms/cocoa/qcocoaintegration.mm | 91 +-------- src/plugins/platforms/cocoa/qcocoascreen.h | 31 ++- src/plugins/platforms/cocoa/qcocoascreen.mm | 220 +++++++++++++++------ .../platforms/cocoa/qcocoasystemtrayicon.mm | 6 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 +- 9 files changed, 204 insertions(+), 185 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index e786ecb5a5..a98fcfae92 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -273,18 +273,6 @@ void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const // ---------------------------------------------------------------------------- -// https://stackoverflow.com/a/52722575/2761869 -template -struct backwards_t { - R r; - constexpr auto begin() const { using std::rbegin; return rbegin(r); } - constexpr auto begin() { using std::rbegin; return rbegin(r); } - constexpr auto end() const { using std::rend; return rend(r); } - constexpr auto end() { using std::rend; return rend(r); } -}; -template -constexpr backwards_t backwards(R&& r) { return {std::forward(r)}; } - QCALayerBackingStore::QCALayerBackingStore(QWindow *window) : QPlatformBackingStore(window) { diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 69aa7937b6..69a1854598 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -176,6 +176,18 @@ T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &pro return fallback; } +// https://stackoverflow.com/a/52722575/2761869 +template +struct backwards_t { + R r; + constexpr auto begin() const { using std::rbegin; return rbegin(r); } + constexpr auto begin() { using std::rbegin; return rbegin(r); } + constexpr auto end() const { using std::rend; return rend(r); } + constexpr auto end() { using std::rend; return rend(r); } +}; +template +constexpr backwards_t backwards(R&& r) { return {std::forward(r)}; } + // ------------------------------------------------------------------------- #if !defined(Q_PROCESSOR_X86_64) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 9c705616ba..1b184cd60f 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window"); Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing"); Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg); -Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen"); +Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen", QtCriticalMsg); // // Conversion Functions diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 04cb4e1226..bfc3bfe9de 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -61,8 +61,6 @@ QT_BEGIN_NAMESPACE -class QCocoaScreen; - class QCocoaIntegration : public QObject, public QPlatformIntegration { Q_OBJECT @@ -113,9 +111,6 @@ public: Qt::KeyboardModifiers queryKeyboardModifiers() const override; QList possibleKeys(const QKeyEvent *event) const override; - void updateScreens(); - QCocoaScreen *screenForNSScreen(NSScreen *nsScreen); - void setToolbar(QWindow *window, NSToolbar *toolbar); NSToolbar *toolbar(QWindow *window) const; void clearToolbars(); @@ -143,8 +138,6 @@ private: QScopedPointer mAccessibility; #endif QScopedPointer mPlatformTheme; - QList mScreens; - QMacScopedObserver m_screensObserver; #ifndef QT_NO_CLIPBOARD QCocoaClipboard *mCocoaClipboard; #endif diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index fb3d05d3e4..1d35d9f440 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -207,9 +207,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) // which will resolve to an actual value and result in screen invalidation. cocoaApplication.presentationOptions = NSApplicationPresentationDefault; - m_screensObserver = QMacScopedObserver([NSApplication sharedApplication], - NSApplicationDidChangeScreenParametersNotification, [&]() { updateScreens(); }); - updateScreens(); + QCocoaScreen::initializeScreens(); QMacInternalPasteboardMime::initializeMimeTypes(); QCocoaMimeTypes::initializeMimeTypes(); @@ -242,10 +240,7 @@ QCocoaIntegration::~QCocoaIntegration() QMacInternalPasteboardMime::destroyMimeTypes(); #endif - // Delete screens in reverse order to avoid crash in case of multiple screens - while (!mScreens.isEmpty()) { - QWindowSystemInterface::handleScreenRemoved(mScreens.takeLast()); - } + QCocoaScreen::cleanupScreens(); clearToolbars(); } @@ -260,88 +255,6 @@ QCocoaIntegration::Options QCocoaIntegration::options() const return mOptions; } -/*! - \brief Synchronizes the screen list, adds new screens, removes deleted ones -*/ -void QCocoaIntegration::updateScreens() -{ - NSArray *scrs = [NSScreen screens]; - NSMutableArray *screens = [NSMutableArray arrayWithArray:scrs]; - if ([screens count] == 0) - if ([NSScreen mainScreen]) - [screens addObject:[NSScreen mainScreen]]; - if ([screens count] == 0) - return; - QSet remainingScreens = QSet::fromList(mScreens); - QList siblings; - uint screenCount = [screens count]; - for (uint i = 0; i < screenCount; i++) { - NSScreen* scr = [screens objectAtIndex:i]; - CGDirectDisplayID dpy = scr.qt_displayId; - // If this screen is a mirror and is not the primary one of the mirror set, ignore it. - // Exception: The NSScreen API has been observed to a return a screen list with one - // mirrored, non-primary screen when Qt is running as a startup item. Always use the - // screen if there's only one screen in the list. - if (screenCount > 1 && CGDisplayIsInMirrorSet(dpy)) { - CGDirectDisplayID primary = CGDisplayMirrorsDisplay(dpy); - if (primary != kCGNullDirectDisplay && primary != dpy) - continue; - } - QCocoaScreen* screen = nullptr; - foreach (QCocoaScreen* existingScr, mScreens) { - // NSScreen documentation says do not cache the array returned from [NSScreen screens]. - // However in practice, we can identify a screen by its pointer: if resolution changes, - // the NSScreen object will be the same instance, just with different values. - if (existingScr->nativeScreen() == scr) { - screen = existingScr; - break; - } - } - if (screen) { - remainingScreens.remove(screen); - screen->updateProperties(); - } else { - screen = new QCocoaScreen(i); - mScreens.append(screen); - qCDebug(lcQpaScreen) << "Adding" << screen; - QWindowSystemInterface::handleScreenAdded(screen); - } - siblings << screen; - } - - // Set virtual siblings list. All screens in mScreens are siblings, because we ignored the - // mirrors. Note that some of the screens we update the siblings list for here may be deleted - // below, but update anyway to keep the to-be-deleted screens out of the siblings list. - foreach (QCocoaScreen* screen, mScreens) - screen->setVirtualSiblings(siblings); - - // Now the leftovers in remainingScreens are no longer current, so we can delete them. - foreach (QCocoaScreen* screen, remainingScreens) { - mScreens.removeOne(screen); - // Prevent stale references to NSScreen during destroy - screen->m_screenIndex = -1; - qCDebug(lcQpaScreen) << "Removing" << screen; - QWindowSystemInterface::handleScreenRemoved(screen); - } -} - -QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen) -{ - NSUInteger index = [[NSScreen screens] indexOfObject:nsScreen]; - if (index == NSNotFound) - return nullptr; - - if (index >= unsigned(mScreens.count())) - updateScreens(); - - for (QCocoaScreen *screen : mScreens) { - if (screen->nativeScreen() == nsScreen) - return screen; - } - - return nullptr; -} - bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index 9ded98df32..491af2fe9c 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -48,10 +48,14 @@ QT_BEGIN_NAMESPACE +class QCocoaIntegration; + class QCocoaScreen : public QPlatformScreen { public: - QCocoaScreen(int screenIndex); + static void initializeScreens(); + static void cleanupScreens(); + ~QCocoaScreen(); // ---------------------------------------------------- @@ -61,19 +65,18 @@ public: QRect availableGeometry() const override { return m_availableGeometry; } int depth() const override { return m_depth; } QImage::Format format() const override { return m_format; } - qreal devicePixelRatio() const override; + qreal devicePixelRatio() const override { return m_devicePixelRatio; } QSizeF physicalSize() const override { return m_physicalSize; } QDpi logicalDpi() const override { return m_logicalDpi; } qreal refreshRate() const override { return m_refreshRate; } QString name() const override { return m_name; } QPlatformCursor *cursor() const override { return m_cursor; } QWindow *topLevelAt(const QPoint &point) const override; - QList virtualSiblings() const override { return m_siblings; } + QList virtualSiblings() const override; QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override; // ---------------------------------------------------- - // Additional methods - void setVirtualSiblings(const QList &siblings) { m_siblings = siblings; } + NSScreen *nativeScreen() const; void updateProperties(); @@ -82,14 +85,21 @@ public: bool isRunningDisplayLink() const; static QCocoaScreen *primaryScreen(); + static QCocoaScreen *get(NSScreen *nsScreen); + static QCocoaScreen *get(CGDirectDisplayID displayId); static CGPoint mapToNative(const QPointF &pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); static CGRect mapToNative(const QRectF &rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); static QPointF mapFromNative(CGPoint pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); static QRectF mapFromNative(CGRect rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); -public: - int m_screenIndex; +private: + QCocoaScreen(CGDirectDisplayID displayId); + static void add(CGDirectDisplayID displayId); + void remove(); + + CGDirectDisplayID m_displayId = 0; + QRect m_geometry; QRect m_availableGeometry; QDpi m_logicalDpi; @@ -99,11 +109,13 @@ public: QImage::Format m_format; QSizeF m_physicalSize; QCocoaCursor *m_cursor; - QList m_siblings; + qreal m_devicePixelRatio; CVDisplayLinkRef m_displayLink = nullptr; dispatch_source_t m_displayLinkSource = nullptr; QAtomicInt m_pendingUpdates; + + friend QDebug operator<<(QDebug debug, const QCocoaScreen *screen); }; #ifndef QT_NO_DEBUG_STREAM @@ -116,5 +128,4 @@ QT_END_NAMESPACE @property(readonly) CGDirectDisplayID qt_displayId; @end -#endif - +#endif // QCOCOASCREEN_H diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 6a5b0e6e3e..392099d083 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -41,6 +41,7 @@ #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include "qcocoaintegration.h" #include #include @@ -53,34 +54,104 @@ QT_BEGIN_NAMESPACE -class QCoreTextFontEngine; -class QFontEngineFT; +void QCocoaScreen::initializeScreens() +{ + uint32_t displayCount = 0; + if (CGGetActiveDisplayList(0, nullptr, &displayCount) != kCGErrorSuccess) + qFatal("Failed to get number of active displays"); + + CGDirectDisplayID activeDisplays[displayCount]; + if (CGGetActiveDisplayList(displayCount, &activeDisplays[0], &displayCount) != kCGErrorSuccess) + qFatal("Failed to get active displays"); + + for (CGDirectDisplayID displayId : activeDisplays) + QCocoaScreen::add(displayId); + + CGDisplayRegisterReconfigurationCallback([](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) { + if (flags & kCGDisplayBeginConfigurationFlag) + return; // Wait for changes to apply + + Q_UNUSED(userInfo); + + QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId); + + if ((flags & kCGDisplayAddFlag) || !cocoaScreen) { + if (!CGDisplayIsActive(displayId)) { + qCDebug(lcQpaScreen) << "Not adding inactive display" << displayId; + return; // Will be added when activated + } + QCocoaScreen::add(displayId); + } else if ((flags & kCGDisplayRemoveFlag) || !CGDisplayIsActive(displayId)) { + cocoaScreen->remove(); + } else { + // Detect changes to the primary screen immediately, instead of + // waiting for a display reconfigure with kCGDisplaySetMainFlag. + // This ensures that any property updates to the other screens + // will be in reference to the correct primary screen. + QCocoaScreen *mainDisplay = QCocoaScreen::get(CGMainDisplayID()); + if (QGuiApplication::primaryScreen()->handle() != mainDisplay) { + mainDisplay->updateProperties(); + qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay; + QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay); + } -QCocoaScreen::QCocoaScreen(int screenIndex) - : QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0) + if (cocoaScreen == mainDisplay) + return; // Already reconfigured + + cocoaScreen->updateProperties(); + qCInfo(lcQpaScreen) << "Reconfigured" << cocoaScreen; + } + }, nullptr); +} + +void QCocoaScreen::add(CGDirectDisplayID displayId) +{ + QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId); + qCInfo(lcQpaScreen) << "Adding" << cocoaScreen; + QWindowSystemInterface::handleScreenAdded(cocoaScreen, CGDisplayIsMain(displayId)); +} + +QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId) + : QPlatformScreen(), m_displayId(displayId) { updateProperties(); m_cursor = new QCocoaCursor; } -QCocoaScreen::~QCocoaScreen() +void QCocoaScreen::cleanupScreens() { - delete m_cursor; + // Remove screens in reverse order to avoid crash in case of multiple screens + for (QScreen *screen : backwards(QGuiApplication::screens())) + static_cast(screen->handle())->remove(); +} - CVDisplayLinkRelease(m_displayLink); - if (m_displayLinkSource) - dispatch_release(m_displayLinkSource); +void QCocoaScreen::remove() +{ + m_displayId = 0; // Prevent stale references during removal + + // This may result in the application responding to QGuiApplication::screenRemoved + // by moving the window to another screen, either by setGeometry, or by setScreen. + // If the window isn't moved by the application, Qt will as a fallback move it to + // the primary screen via setScreen. Due to the way setScreen works, this won't + // actually recreate the window on the new screen, it will just assign the new + // QScreen to the window. The associated NSWindow will have an NSScreen determined + // by AppKit. AppKit will then move the window to another screen by changing the + // geometry, and we will get a callback in QCocoaWindow::windowDidMove and then + // QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have + // already changed its screen, but that's only true if comparing the Qt screens, + // not when comparing the NSScreens. + QWindowSystemInterface::handleScreenRemoved(this); } -NSScreen *QCocoaScreen::nativeScreen() const +QCocoaScreen::~QCocoaScreen() { - NSArray *screens = [NSScreen screens]; + Q_ASSERT_X(!screen(), "QCocoaScreen", "QScreen should be deleted first"); - // Stale reference, screen configuration has changed - if (m_screenIndex < 0 || (NSUInteger)m_screenIndex >= [screens count]) - return nil; + delete m_cursor; - return [screens objectAtIndex:m_screenIndex]; + CVDisplayLinkRelease(m_displayLink); + if (m_displayLinkSource) + dispatch_release(m_displayLinkSource); } static QString displayName(CGDirectDisplayID displayID) @@ -117,35 +188,37 @@ static QString displayName(CGDirectDisplayID displayID) void QCocoaScreen::updateProperties() { - NSScreen *nsScreen = nativeScreen(); - if (!nsScreen) - return; + Q_ASSERT(m_displayId); const QRect previousGeometry = m_geometry; const QRect previousAvailableGeometry = m_availableGeometry; const QDpi previousLogicalDpi = m_logicalDpi; const qreal previousRefreshRate = m_refreshRate; + // Some properties are only available via NSScreen + NSScreen *nsScreen = nativeScreen(); + Q_ASSERT(nsScreen); + // The reference screen for the geometry is always the primary screen - QRectF primaryScreenGeometry = QRectF::fromCGRect([[NSScreen screens] firstObject].frame); + QRectF primaryScreenGeometry = QRectF::fromCGRect(CGDisplayBounds(CGMainDisplayID())); m_geometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.frame), primaryScreenGeometry).toRect(); m_availableGeometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.visibleFrame), primaryScreenGeometry).toRect(); + m_devicePixelRatio = nsScreen.backingScaleFactor; + m_format = QImage::Format_RGB32; - m_depth = NSBitsPerPixelFromDepth([nsScreen depth]); + m_depth = NSBitsPerPixelFromDepth(nsScreen.depth); - CGDirectDisplayID dpy = nsScreen.qt_displayId; - CGSize size = CGDisplayScreenSize(dpy); + CGSize size = CGDisplayScreenSize(m_displayId); m_physicalSize = QSizeF(size.width, size.height); m_logicalDpi.first = 72; m_logicalDpi.second = 72; - CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(dpy); + + QCFType displayMode = CGDisplayCopyDisplayMode(m_displayId); float refresh = CGDisplayModeGetRefreshRate(displayMode); - CGDisplayModeRelease(displayMode); - if (refresh > 0) - m_refreshRate = refresh; + m_refreshRate = refresh > 0 ? refresh : 60.0; - m_name = displayName(dpy); + m_name = displayName(m_displayId); const bool didChangeGeometry = m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry; @@ -155,24 +228,6 @@ void QCocoaScreen::updateProperties() QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second); if (m_refreshRate != previousRefreshRate) QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate); - - qCDebug(lcQpaScreen) << "Updated properties for" << this; - - if (didChangeGeometry) { - // When a screen changes its geometry, AppKit will send us a NSWindowDidMoveNotification - // for each window, resulting in calls to handleGeometryChange(), but this happens before - // the NSApplicationDidChangeScreenParametersNotification, so when we map the new geometry - // (which is correct at that point) to the screen using QCocoaScreen::mapFromNative(), we - // end up using the stale screen geometry, and the new window geometry we report is wrong. - // To make sure we finally report the correct window geometry, we need to do another pass - // of geometry reporting, now that the screen properties have been updates. FIXME: Ideally - // this would be solved by not caching the screen properties in QCocoaScreen, but that - // requires more research. - for (QWindow *window : windows()) { - if (QCocoaWindow *cocoaWindow = static_cast(window->handle())) - cocoaWindow->handleGeometryChange(); - } - } } // ----------------------- Display link ----------------------- @@ -181,8 +236,10 @@ Q_LOGGING_CATEGORY(lcQpaScreenUpdates, "qt.qpa.screen.updates", QtCriticalMsg); void QCocoaScreen::requestUpdate() { + Q_ASSERT(m_displayId); + if (!m_displayLink) { - CVDisplayLinkCreateWithCGDisplay(nativeScreen().qt_displayId, &m_displayLink); + CVDisplayLinkCreateWithCGDisplay(m_displayId, &m_displayLink); CVDisplayLinkSetOutputCallback(m_displayLink, [](CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* displayLinkContext) -> int { // FIXME: It would be nice if update requests would include timing info @@ -269,6 +326,9 @@ struct DeferredDebugHelper void QCocoaScreen::deliverUpdateRequests() { + if (!m_displayId) + return; // Screen removed + QMacAutoReleasePool pool; // The CVDisplayLink callback is a notification that it's a good time to produce a new frame. @@ -283,7 +343,7 @@ void QCocoaScreen::deliverUpdateRequests() const int pendingUpdates = ++m_pendingUpdates; DeferredDebugHelper screenUpdates(lcQpaScreenUpdates()); - qDeferredDebug(screenUpdates) << "display link callback for screen " << m_screenIndex; + qDeferredDebug(screenUpdates) << "display link callback for screen " << m_displayId; if (const int framesAheadOfDelivery = pendingUpdates - 1) { // If we have more than one update pending it means that a previous display link callback @@ -370,13 +430,6 @@ bool QCocoaScreen::isRunningDisplayLink() const // ----------------------------------------------------------- -qreal QCocoaScreen::devicePixelRatio() const -{ - QMacAutoReleasePool pool; - NSScreen *nsScreen = nativeScreen(); - return qreal(nsScreen ? [nsScreen backingScaleFactor] : 1.0); -} - QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const { QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint(); @@ -430,7 +483,7 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) { // Determine the grab rect. FIXME: The rect should be bounded by the view's // geometry, but note that for the pixeltool use case that window will be the - // desktop widgets's view, which currently gets resized to fit one screen + // desktop widget's view, which currently gets resized to fit one screen // only, since its NSWindow has the NSWindowStyleMaskTitled flag set. Q_UNUSED(view); QRect grabRect = QRect(x, y, width, height); @@ -482,7 +535,7 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) for (uint i = 0; i < displayCount; ++i) dpr = qMax(dpr, images.at(i).devicePixelRatio()); - // Alocate target pixmap and draw each screen's content + // Allocate target pixmap and draw each screen's content qCDebug(lcQpaScreen) << "Create grap pixmap" << grabRect.size() << "at devicePixelRatio" << dpr; QPixmap windowPixmap(grabRect.size() * dpr); windowPixmap.setDevicePixelRatio(dpr); @@ -499,7 +552,57 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) */ QCocoaScreen *QCocoaScreen::primaryScreen() { - return static_cast(QGuiApplication::primaryScreen()->handle()); + auto screen = static_cast(QGuiApplication::primaryScreen()->handle()); + Q_ASSERT_X(screen == get(CGMainDisplayID()), "QCocoaScreen", + "The application's primary screen should always be in sync with the main display"); + return screen; +} + +QList QCocoaScreen::virtualSiblings() const +{ + QList siblings; + + // Screens on macOS are always part of the same virtual desktop + for (QScreen *screen : QGuiApplication::screens()) + siblings << screen->handle(); + + return siblings; +} + +QCocoaScreen *QCocoaScreen::get(NSScreen *nsScreen) +{ + return get(nsScreen.qt_displayId); +} + +QCocoaScreen *QCocoaScreen::get(CGDirectDisplayID displayId) +{ + for (QScreen *screen : QGuiApplication::screens()) { + QCocoaScreen *cocoaScreen = static_cast(screen->handle()); + if (cocoaScreen->m_displayId == displayId) + return cocoaScreen; + } + + return nullptr; +} + +NSScreen *QCocoaScreen::nativeScreen() const +{ + if (!m_displayId) + return nil; // The display has been disconnected + + // A single display may have different displayIds depending on + // which GPU is in use or which physical port the display is + // connected to. By comparing UUIDs instead of display IDs we + // ensure that we always pick up the appropriate NSScreen. + QCFType uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId); + + for (NSScreen *screen in [NSScreen screens]) { + if (CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId) == uuid) + return screen; + } + + qCWarning(lcQpaScreen) << "Could not find NSScreen for display ID" << m_displayId; + return nil; } CGPoint QCocoaScreen::mapToNative(const QPointF &pos, QCocoaScreen *screen) @@ -533,11 +636,10 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen) debug.nospace(); debug << "QCocoaScreen(" << (const void *)screen; if (screen) { - debug << ", index=" << screen->m_screenIndex; - debug << ", native=" << screen->nativeScreen(); debug << ", geometry=" << screen->geometry(); debug << ", dpr=" << screen->devicePixelRatio(); debug << ", name=" << screen->name(); + debug << ", native=" << screen->nativeScreen(); } debug << ')'; return debug; diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 4982f5ee05..de5cf85854 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -383,9 +383,9 @@ QT_END_NAMESPACE } - (QRectF)geometry { - if (NSWindow *window = [[item view] window]) { - if (QCocoaScreen *screen = QCocoaIntegration::instance()->screenForNSScreen([window screen])) - return screen->mapFromNative([window frame]); + if (NSWindow *window = item.view.window) { + if (QCocoaScreen *screen = QCocoaScreen::get(window.screen)) + return screen->mapFromNative(window.frame); } return QRectF(); } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 0d7eab9a94..c09ff12c2b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1209,17 +1209,17 @@ void QCocoaWindow::windowDidChangeScreen() return; // Note: When a window is resized to 0x0 Cocoa will report the window's screen as nil - auto *currentScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen); + auto *currentScreen = QCocoaScreen::get(m_view.window.screen); auto *previousScreen = static_cast(screen()); Q_ASSERT_X(!m_view.window.screen || currentScreen, "QCocoaWindow", "Failed to get QCocoaScreen for NSScreen"); // Note: The previous screen may be the same as the current screen, either because - // the screen was just reconfigured, which still results in AppKit sending an - // NSWindowDidChangeScreenNotification, because the previous screen was removed, + // a) the screen was just reconfigured, which still results in AppKit sending an + // NSWindowDidChangeScreenNotification, b) because the previous screen was removed, // and we ended up calling QWindow::setScreen to move the window, which doesn't - // actually move the window to the new screen, or because we've delivered the + // actually move the window to the new screen, or c) because we've delivered the // screen change to the top level window, which will make all the child windows // of that window report the new screen when requested via QWindow::screen(). // We still need to deliver the screen change in all these cases, as the -- cgit v1.2.3 From 98cb9275d064d8b996dcd78324c4249f69a981a9 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 5 Dec 2018 13:18:50 +0100 Subject: doc: clang reported two fake declarations to be the same These declarations are provided for qdoc, but clang says they are the same: template QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); template QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); clang accepts this one, but is it ok for the documentation? template QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection); Change-Id: I9d63b1bccfa8d73dbc17ab70c4415eb7891fbbe2 Reviewed-by: Martin Smith --- src/corelib/kernel/qtimer.cpp | 2 +- src/corelib/kernel/qtimer.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 13f027074a..9d3bd5fdbf 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -599,7 +599,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! - \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload callOnTimeout() diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 66f317c567..336b814b27 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -100,8 +100,8 @@ public: QMetaObject::Connection callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); template QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); - template - QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template + QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection); #else // singleShot to a QObject slot template -- cgit v1.2.3 From 56acf089c7759ce21a5bc3ce32616df5b01e78ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 30 Apr 2019 09:17:54 +0200 Subject: wasm: support setting the font DPI from JS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have not really been able to determine what the default DPI should be, so make it configurable with API on qtloader.js: qtLoader.setFontDpi(72); Also lowers the default DPI to the standard value of 96 (down from Qt default 100). Task-number: QTBUG-75510 Change-Id: Ica1164c8d80bb06519233adebf2c9e400c0991ce Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/wasm/qtloader.js | 14 ++++++++++++++ src/plugins/platforms/wasm/qwasmintegration.cpp | 17 +++++++++++++++++ src/plugins/platforms/wasm/qwasmintegration.h | 2 ++ src/plugins/platforms/wasm/qwasmscreen.cpp | 12 ++++++++++++ src/plugins/platforms/wasm/qwasmscreen.h | 1 + 5 files changed, 46 insertions(+) diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js index 4752a1dcee..ef4a6ec2b9 100644 --- a/src/plugins/platforms/wasm/qtloader.js +++ b/src/plugins/platforms/wasm/qtloader.js @@ -124,6 +124,8 @@ // Remove canvas at run-time. Removes the corresponding QScreen. // resizeCanvasElement // Signals to the application that a canvas has been resized. +// setFontDpi +// Sets the logical font dpi for the application. var Module = {} @@ -237,6 +239,8 @@ function QtLoader(config) publicAPI.addCanvasElement = addCanvasElement; publicAPI.removeCanvasElement = removeCanvasElement; publicAPI.resizeCanvasElement = resizeCanvasElement; + publicAPI.setFontDpi = setFontDpi; + publicAPI.fontDpi = fontDpi; restartCount = 0; @@ -557,6 +561,16 @@ function QtLoader(config) Module.qtResizeCanvasElement(element); } + function setFontDpi(dpi) { + Module.qtFontDpi = dpi; + if (publicAPI.status == "Running") + Module.qtSetFontDpi(dpi); + } + + function fontDpi() { + return Module.qtFontDpi; + } + setStatus("Created"); return publicAPI; diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index e601d553f2..150783e193 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -50,6 +50,7 @@ #include #include +#include // this is where EGL headers are pulled in, make sure it is last #include "qwasmscreen.h" @@ -80,12 +81,18 @@ static void resizeCanvasElement(emscripten::val canvas) QWasmIntegration::get()->resizeScreen(canvasId); } +static void qtUpdateDpi() +{ + QWasmIntegration::get()->updateDpi(); +} + EMSCRIPTEN_BINDINGS(qtQWasmIntegraton) { function("qtBrowserBeforeUnload", &browserBeforeUnload); function("qtAddCanvasElement", &addCanvasElement); function("qtRemoveCanvasElement", &removeCanvasElement); function("qtResizeCanvasElement", &resizeCanvasElement); + function("qtUpdateDpi", &qtUpdateDpi); } QWasmIntegration *QWasmIntegration::s_instance; @@ -245,4 +252,14 @@ void QWasmIntegration::resizeScreen(const QString &canvasId) m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize(); } +void QWasmIntegration::updateDpi() +{ + emscripten::val dpi = emscripten::val::module_property("qtFontDpi"); + if (dpi.isUndefined()) + return; + qreal dpiValue = dpi.as(); + for (QWasmScreen *screen : m_screens) + QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), dpiValue, dpiValue); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index 11d8d0f7f5..6bd2f857db 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -81,6 +81,7 @@ public: void addScreen(const QString &canvasId); void removeScreen(const QString &canvasId); void resizeScreen(const QString &canvasId); + void updateDpi(); private: mutable QWasmFontDatabase *m_fontDb; @@ -89,6 +90,7 @@ private: QHash m_screens; mutable QWasmClipboard *m_clipboard; + qreal m_fontDpi = -1; static QWasmIntegration *s_instance; }; diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index a26cafa900..af50ce7440 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -31,6 +31,7 @@ #include "qwasmwindow.h" #include "qwasmeventtranslator.h" #include "qwasmcompositor.h" +#include "qwasmintegration.h" #include #include @@ -100,6 +101,17 @@ QImage::Format QWasmScreen::format() const return m_format; } +QDpi QWasmScreen::logicalDpi() const +{ + emscripten::val dpi = emscripten::val::module_property("qtFontDpi"); + if (!dpi.isUndefined()) { + qreal dpiValue = dpi.as(); + return QDpi(dpiValue, dpiValue); + } + const qreal defaultDpi = 96; + return QDpi(defaultDpi, defaultDpi); +} + qreal QWasmScreen::devicePixelRatio() const { // FIXME: The effective device pixel ratio may be different from the diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h index 82d2a83edb..8d0d15f245 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.h +++ b/src/plugins/platforms/wasm/qwasmscreen.h @@ -63,6 +63,7 @@ public: QRect geometry() const override; int depth() const override; QImage::Format format() const override; + QDpi logicalDpi() const override; qreal devicePixelRatio() const override; QString name() const override; QPlatformCursor *cursor() const override; -- cgit v1.2.3 From 871b65ab1023d7a9c5e1582816bd038c93f3a86c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 8 May 2019 11:32:48 +0200 Subject: Add the c++latest CONFIG value to select the latest C++ standard [ChangeLog][qmake] The CONFIG value c++latest was added to select the latest C++ standard the currently used toolchain supports. Task-number: QTBUG-75653 Change-Id: I22ddc9d293109d99e652b7ccb19d7226fca4716d Reviewed-by: Thiago Macieira --- mkspecs/features/default_post.prf | 1 + qmake/doc/src/qmake-manual.qdoc | 3 +++ 2 files changed, 4 insertions(+) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 9df99b8648..0e41b825ec 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -120,6 +120,7 @@ breakpad { } c++17: CONFIG += c++1z +c++latest: CONFIG *= c++2a c++1z c++14 c++11 !c++11:!c++14:!c++1z:!c++2a { # Qt requires C++11 since 5.7, check if we need to force a compiler option diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 27f45089d1..48ca96ae92 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -977,6 +977,9 @@ \row \li c++2a \li C++2a support is enabled. This option has no effect if the compiler does not support C++2a, or can't select the C++ standard. By default, support is disabled. + \row \li c++latest \li Support for the latest C++ language standard is + enabled that is supported by the compiler. By default, this option is + disabled. \row \li strict_c++ \li Disables support for C++ compiler extensions. By default, they are enabled. \row \li depend_includepath \li Appending the value of INCLUDEPATH to -- cgit v1.2.3 From 1e5deb06416b6efc33a2009d9678fd8f743c5ce7 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Thu, 2 May 2019 18:02:45 +0200 Subject: Add 'well-formated' JSON string values Add support for surrogate code points U+D800 through U+DFFF, represent them with JSON escape sequences. https://github.com/tc39/proposal-well-formed-stringify Change-Id: I84fea53a8ef400beebefdba10ea82dc510fe7dda Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjsonwriter.cpp | 12 ++++++---- .../auto/corelib/serialization/json/tst_qtjson.cpp | 27 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/corelib/serialization/qjsonwriter.cpp b/src/corelib/serialization/qjsonwriter.cpp index 12ce20ef09..5b246837d2 100644 --- a/src/corelib/serialization/qjsonwriter.cpp +++ b/src/corelib/serialization/qjsonwriter.cpp @@ -58,7 +58,6 @@ static inline uchar hexdig(uint u) static QByteArray escapedString(const QString &s) { - const uchar replacement = '?'; QByteArray ba(s.length(), Qt::Uninitialized); uchar *cursor = reinterpret_cast(const_cast(ba.constData())); @@ -111,9 +110,14 @@ static QByteArray escapedString(const QString &s) } else { *cursor++ = (uchar)u; } - } else { - if (QUtf8Functions::toUtf8(u, cursor, src, end) < 0) - *cursor++ = replacement; + } else if (QUtf8Functions::toUtf8(u, cursor, src, end) < 0) { + // failed to get valid utf8 use JSON escape sequence + *cursor++ = '\\'; + *cursor++ = 'u'; + *cursor++ = hexdig(u>>12 & 0x0f); + *cursor++ = hexdig(u>>8 & 0x0f); + *cursor++ = hexdig(u>>4 & 0x0f); + *cursor++ = hexdig(u & 0x0f); } } diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 083e78375a..8907704a33 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -163,7 +163,8 @@ private Q_SLOTS: void streamSerializationQJsonValue(); void streamSerializationQJsonValueEmpty(); void streamVariantSerialization(); - + void escapeSurrogateCodePoints_data(); + void escapeSurrogateCodePoints(); private: QString testDataDir; }; @@ -3093,6 +3094,9 @@ void tst_QtJson::streamSerializationQJsonValue_data() QTest::newRow("string") << QJsonValue{QStringLiteral("bum")}; QTest::newRow("array") << QJsonValue{QJsonArray{12,1,5,6,7}}; QTest::newRow("object") << QJsonValue{QJsonObject{{"foo", 665}, {"bar", 666}}}; + // test json escape sequence + QTest::newRow("array with 0xD800") << QJsonValue(QJsonArray{QString(0xD800)}); + QTest::newRow("array with 0xDF06,0xD834") << QJsonValue(QJsonArray{QString(0xDF06).append(0xD834)}); } void tst_QtJson::streamSerializationQJsonValue() @@ -3181,5 +3185,26 @@ void tst_QtJson::streamVariantSerialization() } } +void tst_QtJson::escapeSurrogateCodePoints_data() +{ + QTest::addColumn("str"); + QTest::addColumn("escStr"); + QTest::newRow("0xD800") << QString(0xD800) << QByteArray("\\ud800"); + QTest::newRow("0xDF06,0xD834") << QString(0xDF06).append(0xD834) << QByteArray("\\udf06\\ud834"); +} + +void tst_QtJson::escapeSurrogateCodePoints() +{ + QFETCH(QString, str); + QFETCH(QByteArray, escStr); + QJsonArray array; + array.append(str); + QByteArray buffer; + QDataStream save(&buffer, QIODevice::WriteOnly); + save << array; + // verify the buffer has escaped values + QVERIFY(buffer.contains(escStr)); +} + QTEST_MAIN(tst_QtJson) #include "tst_qtjson.moc" -- cgit v1.2.3 From 895db969a5b21c88f7b488c9e466d8332f5d392e Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Thu, 16 May 2019 00:15:40 +0200 Subject: doc: improve QStandardItemModel code snippet The snippet currently uses hard coded values for looping which is not good practice. This patch fixes this using rowCount and columnCount. Change-Id: Ie532649353f757843426a18e9a50b86a2278f7a5 Reviewed-by: Paul Wicking --- src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp index 4266da0a11..a7e22e549d 100644 --- a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp +++ b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp @@ -50,8 +50,8 @@ //! [0] QStandardItemModel model(4, 4); -for (int row = 0; row < 4; ++row) { - for (int column = 0; column < 4; ++column) { +for (int row = 0; row < model.rowCount(); ++row) { + for (int column = 0; column < model.columnCount(); ++column) { QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column)); model.setItem(row, column, item); } -- cgit v1.2.3 From 704b6bac13cc35322f3febbec47503c8ddb09b47 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Fri, 12 Apr 2019 16:07:59 +0200 Subject: doc: Explain how qmake finds for files included in your source code Task-number: QTBUG-26651 Change-Id: Icc09e3272fcec8af0c33d79655159d13183c66ce Reviewed-by: Joerg Bornemann --- qmake/doc/src/qmake-manual.qdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 48ca96ae92..b271abcee3 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1154,8 +1154,9 @@ \target DEPENDPATH \section1 DEPENDPATH - Specifies a list of all directories to look in to resolve dependencies. This - variable is used when crawling through \c included files. + Specifies a list of directories for qmake to scan, to resolve dependencies. + This variable is used when qmake crawls through the header files that you + \c{#include} in your source code. \target DESTDIR \section1 DESTDIR -- cgit v1.2.3 From 4504d9ca31986b6e939b1a434b724404b72102f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 15 May 2019 16:05:04 +0200 Subject: macOS: Remove broken UTF-16 handling in QMacPasteboard::retrieveData The logic seems to be to prefer public.utf16-plain-text over the UTI reported by the mime converter's flavorFor, but this doesn't make sense for two reasons: 1. If the converter reports a UTI from flavorFor, we should respect that as the preferred UTI. QMacPasteboardMimeUnicodeText already reports public.utf16-plain-text as expected. 2. We don't know if the converter supports the public.utf16-plain-text UTI, which is the case for QMacPasteboardMimeTraditionalMacPlainText for example. The result is that we fail to retrieve any data. The reason we haven't been seeing this issue is that the code path above using qt_mac_get_pasteboardString will in most cases succeed and return early. Change-Id: I0b7e0d09a97389a229e7a945f17fef74ad5c2fc0 Reviewed-by: Volker Hilsheimer Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qmacclipboard.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index ba6cfca219..554fd7c4c1 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -500,8 +500,6 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const if (!str.isEmpty()) return str; } - if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text"))) - c_flavor = QLatin1String("public.utf16-plain-text"); QVariant ret; QList retList; -- cgit v1.2.3 From e6036cfc5ae1b0ab30ef3e23f0bb3362db32f1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 15 May 2019 16:30:16 +0200 Subject: macOS: Better document plain-text code-path in QMacPasteboard::retrieveData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to PasteboardCopyItemFlavorData converting newlines to '\r' for some UTIs we have traditionally had to shortcut these UTIs via NSStringPboardType instead of the mime converters such as QMacPasteboardMimeUnicodeText. Let's explain this a bit better for future generations. Note that public.utf8-plain-text doesn't seem to have this problem anymore, but it's left in for now to not cause any regressions due to behavior change. Change-Id: I7dce80828865c6323ed308780b8ca07b7a3e7c17 Reviewed-by: Volker Hilsheimer Reviewed-by: Morten Johan Sørvig Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qmacclipboard.mm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 554fd7c4c1..358a6b49fd 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -489,13 +489,12 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const QMacInternalPasteboardMime *c = mimes.at(mime); QString c_flavor = c->flavorFor(format); if (!c_flavor.isEmpty()) { - // Handle text/plain a little differently. Try handling Unicode first. - bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") - || c_flavor == QLatin1String("public.utf8-plain-text")); - if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { - // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped - // correctly (as '\n') in this data. The 'public.utf16-plain-text' type - // usually maps newlines to '\r' instead. + // Converting via PasteboardCopyItemFlavorData below will for some UITs result + // in newlines mapping to '\r' instead of '\n'. To work around this we shortcut + // the conversion via NSPasteboard's NSStringPboardType if possible. + if (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") + || c_flavor == QLatin1String("public.utf8-plain-text") + || c_flavor == QLatin1String("public.utf16-plain-text")) { QString str = qt_mac_get_pasteboardString(paste); if (!str.isEmpty()) return str; -- cgit v1.2.3 From bba44746f9f2cfca785a309deb056033ae0bea6e Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 15 May 2019 14:15:37 +0200 Subject: Disable debug plugin check for MinGW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MinGW doesn't have a debug and a release version of the CRT like Visual C++ does. Disabling the check would allow distribution only of a Release build of Qt. Change-Id: Iecfa753217af96ca74091cd1d47400632629abdb Reviewed-by: Jörg Bornemann --- src/corelib/plugin/qlibrary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 0e32776c71..3aadd1a73b 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE # define QLIBRARY_AS_DEBUG true #endif -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) || defined(Q_CC_MINGW) // We don't use separate debug and release libs on UNIX, so we want // to allow loading plugins, regardless of how they were built. # define QT_NO_DEBUG_PLUGIN_CHECK -- cgit v1.2.3 From bd55a9d91227d1ac38f51b21ca23dec7fa5e82af Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 11 Mar 2015 14:38:59 +0100 Subject: Fix canonicalFilePath() for files with trailing slashes Such files do not exist (as per QFileInfo::exists), but on some platforms that rely on realpath(), QFileInfo::canonicalFilePath did not return the empty string. Use the same logic on macOS as we already did on Android, and include a test case. Remove the unnecessary dynamic memory allocation and use a stack-allocated array instead, unless we use modern POSIX in which case realpath() will alloc the memory for the result for us. Change-Id: Ide987c68ebf00cbb7b1a66c2e9245a12c7807128 Fixes: QTBUG-44242 Reviewed-by: Lars Knoll --- src/corelib/io/qfilesystemengine_unix.cpp | 50 ++++++++--------------- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 2 + 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5bab897d43..b78e037865 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -695,52 +695,36 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, Q_UNUSED(data); return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); #else - char *ret = 0; -# if defined(Q_OS_DARWIN) - ret = (char*)malloc(PATH_MAX + 1); - if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } -# elif defined(Q_OS_ANDROID) - // On some Android versions, realpath() will return a path even if it does not exist - // To work around this, we check existence in advance. + char stack_result[PATH_MAX+1]; + char *resolved_name = nullptr; +# if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID) + // On some Android and macOS versions, realpath() will return a path even if + // it does not exist. To work around this, we check existence in advance. if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute)) fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); if (!data.exists()) { - ret = 0; errno = ENOENT; } else { - ret = (char*)malloc(PATH_MAX + 1); - if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } + resolved_name = stack_result; } - + if (resolved_name && realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr) + resolved_name = nullptr; # else -# if _POSIX_VERSION >= 200801L - ret = realpath(entry.nativeFilePath().constData(), (char*)0); +# if _POSIX_VERSION >= 200801L // ask realpath to allocate memory + resolved_name = realpath(entry.nativeFilePath().constData(), nullptr); # else - ret = (char*)malloc(PATH_MAX + 1); - if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } + resolved_name = stack_result; + if (realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr) + resolved_name = nullptr; # endif # endif - if (ret) { + if (resolved_name) { data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; data.entryFlags |= QFileSystemMetaData::ExistsAttribute; - QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret)); - free(ret); + QString canonicalPath = QDir::cleanPath(QFile::decodeName(resolved_name)); + if (resolved_name != stack_result) + free(resolved_name); return QFileSystemEntry(canonicalPath); } else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index a92b4bd1cb..646fb2078a 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -655,6 +655,8 @@ void tst_QFileInfo::canonicalFilePath() QVERIFY(tempFile.open(QFile::WriteOnly)); QFileInfo fi(tempFile.fileName()); QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName); + fi = QFileInfo(tempFile.fileName() + QString::fromLatin1("/")); + QCOMPARE(fi.canonicalFilePath(), QString::fromLatin1("")); tempFile.remove(); // This used to crash on Mac, verify that it doesn't anymore. -- cgit v1.2.3 From 2a2f04205ccedf83b32cd91f08f40972e5430468 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Mon, 20 May 2019 10:28:12 +0200 Subject: WASM: Make wasm_shell.html compatible with CMake configure_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CMake configure_file command is commonly used copy & modify template files during the build process. One limitation, thought, is that configure_file expect the variables to be replaced to be encoded using either a @APPNAME@ or ${APPNAME} convention. This commit therefore changes "APPNAME" to "@APPNAME@" in wasm_shell.html to make the HTML template file compatible with CMake configure_file. With this commit, it becomes possible to write the following CMake function that mimics what QMake is already doing: function(copy_html_js_launch_files target) set(APPNAME ${target}) configure_file("${_qt5Core_install_prefix}/plugins/platforms/wasm_shell.html" "${target}.html") configure_file("${_qt5Core_install_prefix}/plugins/platforms/qtloader.js" qtloader.js COPYONLY) endfunction() Change-Id: Ic38abdc498ba03b8d21f1b9b70aa1d480ae7f362 Reference: https://cmake.org/cmake/help/latest/command/configure_file.html Reviewed-by: Morten Johan Sørvig --- mkspecs/features/wasm/wasm.prf | 2 +- src/plugins/platforms/wasm/wasm_shell.html | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf index de726c674c..54d351bfd5 100644 --- a/mkspecs/features/wasm/wasm.prf +++ b/mkspecs/features/wasm/wasm.prf @@ -67,7 +67,7 @@ contains(TEMPLATE, .*app) { # replacing the app name placeholder with the actual app name. apphtml.name = application main html file apphtml.output = $$DESTDIR/$$TARGET_HTML - apphtml.commands = sed -e s/APPNAME/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML + apphtml.commands = sed -e s/@APPNAME@/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML apphtml.input = $$WASM_PLUGIN_PATH/wasm_shell.html apphtml.depends = $$apphtml.input QMAKE_EXTRA_COMPILERS += apphtml diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html index f7c856d63d..a118c217f3 100644 --- a/src/plugins/platforms/wasm/wasm_shell.html +++ b/src/plugins/platforms/wasm/wasm_shell.html @@ -3,7 +3,7 @@ - APPNAME + @APPNAME@