summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtBaseGlobalTargets.cmake15
-rw-r--r--cmake/QtBuildHelpers.cmake1
-rw-r--r--cmake/QtBuildOptionsHelpers.cmake17
-rw-r--r--cmake/QtBuildRepoHelpers.cmake1
-rw-r--r--coin/instructions/prepare_building_env.yaml3
-rw-r--r--src/corelib/Qt6WasmMacros.cmake9
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp966
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp3
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp17
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp25
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp194
-rw-r--r--src/corelib/doc/src/cpp20-overview.qdoc10
-rw-r--r--src/corelib/global/qassert.cpp8
-rw-r--r--src/corelib/global/qforeach.qdoc2
-rw-r--r--src/corelib/io/qdebug.cpp18
-rw-r--r--src/corelib/itemmodels/qrangemodel.cpp103
-rw-r--r--src/corelib/itemmodels/qrangemodel.h20
-rw-r--r--src/corelib/itemmodels/qrangemodel_impl.h39
-rw-r--r--src/corelib/kernel/qsystemerror.cpp4
-rw-r--r--src/corelib/platform/windows/qcomobject_p.h18
-rw-r--r--src/corelib/serialization/qtextstream.cpp51
-rw-r--r--src/corelib/serialization/qtextstream_p.h14
-rw-r--r--src/corelib/tools/qduplicatetracker_p.h6
-rw-r--r--src/dbus/dbus_minimal_p.h1
-rw-r--r--src/dbus/qdbus_symbols_p.h1
-rw-r--r--src/dbus/qdbusabstractadaptor.cpp1
-rw-r--r--src/dbus/qdbusabstractadaptor.h1
-rw-r--r--src/dbus/qdbusabstractadaptor_p.h1
-rw-r--r--src/dbus/qdbusabstractinterface.cpp1
-rw-r--r--src/dbus/qdbusabstractinterface.h1
-rw-r--r--src/dbus/qdbusabstractinterface_p.h1
-rw-r--r--src/dbus/qdbusargument.h44
-rw-r--r--src/dbus/qdbusargument_p.h1
-rw-r--r--src/dbus/qdbusconnection.cpp1
-rw-r--r--src/dbus/qdbusconnection.h1
-rw-r--r--src/dbus/qdbusconnection_p.h1
-rw-r--r--src/dbus/qdbusconnectioninterface.cpp1
-rw-r--r--src/dbus/qdbusconnectioninterface.h1
-rw-r--r--src/dbus/qdbusconnectionmanager.cpp5
-rw-r--r--src/dbus/qdbusconnectionmanager_p.h1
-rw-r--r--src/dbus/qdbuscontext.cpp1
-rw-r--r--src/dbus/qdbuscontext.h1
-rw-r--r--src/dbus/qdbuscontext_p.h1
-rw-r--r--src/dbus/qdbuserror.cpp1
-rw-r--r--src/dbus/qdbuserror.h1
-rw-r--r--src/dbus/qdbusextratypes.cpp1
-rw-r--r--src/dbus/qdbusextratypes.h1
-rw-r--r--src/dbus/qdbusintegrator.cpp1
-rw-r--r--src/dbus/qdbusintegrator_p.h1
-rw-r--r--src/dbus/qdbusinterface.cpp1
-rw-r--r--src/dbus/qdbusinterface.h1
-rw-r--r--src/dbus/qdbusinterface_p.h1
-rw-r--r--src/dbus/qdbusinternalfilters.cpp1
-rw-r--r--src/dbus/qdbusintrospection.cpp1
-rw-r--r--src/dbus/qdbusintrospection_p.h1
-rw-r--r--src/dbus/qdbusmessage.cpp1
-rw-r--r--src/dbus/qdbusmessage.h1
-rw-r--r--src/dbus/qdbusmessage_p.h1
-rw-r--r--src/dbus/qdbusmetaobject.cpp1
-rw-r--r--src/dbus/qdbusmetaobject_p.h1
-rw-r--r--src/dbus/qdbusmetatype.cpp1
-rw-r--r--src/dbus/qdbusmetatype.h1
-rw-r--r--src/dbus/qdbusmetatype_p.h1
-rw-r--r--src/dbus/qdbusmisc.cpp1
-rw-r--r--src/dbus/qdbuspendingcall.cpp3
-rw-r--r--src/dbus/qdbuspendingcall.h1
-rw-r--r--src/dbus/qdbuspendingcall_p.h1
-rw-r--r--src/dbus/qdbuspendingreply.cpp1
-rw-r--r--src/dbus/qdbuspendingreply.h1
-rw-r--r--src/dbus/qdbusreply.cpp1
-rw-r--r--src/dbus/qdbusreply.h1
-rw-r--r--src/dbus/qdbusserver.cpp1
-rw-r--r--src/dbus/qdbusserver.h1
-rw-r--r--src/dbus/qdbusservicewatcher.cpp1
-rw-r--r--src/dbus/qdbusservicewatcher.h1
-rw-r--r--src/dbus/qdbusthreaddebug_p.h1
-rw-r--r--src/dbus/qdbusunixfiledescriptor.cpp1
-rw-r--r--src/dbus/qdbusunixfiledescriptor.h1
-rw-r--r--src/dbus/qdbusutil.cpp1
-rw-r--r--src/dbus/qdbusutil_p.h1
-rw-r--r--src/dbus/qdbusvirtualobject.cpp1
-rw-r--r--src/dbus/qdbusvirtualobject.h1
-rw-r--r--src/dbus/qdbusxmlgenerator.cpp1
-rw-r--r--src/dbus/qdbusxmlparser.cpp1
-rw-r--r--src/dbus/qdbusxmlparser_p.h1
-rw-r--r--src/dbus/qtdbusglobal.h1
-rw-r--r--src/dbus/qtdbusglobal_p.h1
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp4
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp2
-rw-r--r--src/gui/math3d/qmatrix4x4.h4
-rw-r--r--src/gui/painting/qpainterpath.cpp24
-rw-r--r--src/gui/painting/qpainterpath.h5
-rw-r--r--src/gui/painting/qpainterpath_p.h1
-rw-r--r--src/network/access/qhttp2connection.cpp13
-rw-r--r--src/network/kernel/qnetworkproxy_android.cpp3
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.cpp2
-rw-r--r--src/plugins/platforms/android/extract.cpp1
-rw-r--r--src/plugins/platforms/wasm/qtloader.js3
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp110
-rw-r--r--src/plugins/platforms/wasm/qwasminputcontext.cpp309
-rw-r--r--src/plugins/platforms/wasm/qwasminputcontext.h23
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp181
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.h25
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp3
-rw-r--r--src/testlib/3rdparty/catch2/qt_attribution.json1
-rw-r--r--src/tools/CMakeLists.txt4
-rw-r--r--src/tools/configure.cmake6
-rw-r--r--src/tools/wasmdeployqt/CMakeLists.txt19
-rw-r--r--src/tools/wasmdeployqt/common.h26
-rw-r--r--src/tools/wasmdeployqt/jsontools.cpp101
-rw-r--r--src/tools/wasmdeployqt/jsontools.h19
-rw-r--r--src/tools/wasmdeployqt/main.cpp417
-rw-r--r--src/tools/wasmdeployqt/wasmbinary.cpp91
-rw-r--r--src/tools/wasmdeployqt/wasmbinary.h24
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp49
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp65
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp16
-rw-r--r--tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp5
-rw-r--r--tests/auto/dbus/qdbusconnection/CMakeLists.txt12
-rw-r--r--tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp56
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp30
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h2
-rw-r--r--tests/benchmarks/corelib/CMakeLists.txt1
-rw-r--r--tests/benchmarks/corelib/platform/CMakeLists.txt6
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt24
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java56
-rw-r--r--tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp144
-rw-r--r--tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp2
-rw-r--r--util/wasm/preload/generate_default_preloads.sh.in19
-rwxr-xr-xutil/wasm/preload/preload_qml_imports.py98
-rwxr-xr-xutil/wasm/preload/preload_qt_plugins.py57
131 files changed, 2473 insertions, 1247 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 405b5e22635..601592277fe 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -437,21 +437,6 @@ elseif(WASM)
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py"
DESTINATION "${INSTALL_LIBEXECDIR}")
-
- if(QT_FEATURE_shared)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qml_imports.py"
- "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py" COPYONLY)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qt_plugins.py"
- "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py" COPYONLY)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/generate_default_preloads.sh.in"
- "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in" COPYONLY)
- qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py"
- DESTINATION "${INSTALL_LIBEXECDIR}")
- qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py"
- DESTINATION "${INSTALL_LIBEXECDIR}")
- qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in"
- DESTINATION "${INSTALL_LIBEXECDIR}")
- endif()
endif()
# Install CI support files to libexec.
diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake
index 1fb5c6350e1..df0aa33cda2 100644
--- a/cmake/QtBuildHelpers.cmake
+++ b/cmake/QtBuildHelpers.cmake
@@ -487,7 +487,6 @@ macro(qt_internal_setup_build_and_global_variables)
qt_set_language_standards()
qt_internal_set_use_ccache()
- qt_internal_set_unity_build()
qt_internal_set_allow_symlink_in_paths()
qt_internal_set_skip_setup_deployment()
qt_internal_set_qt_allow_download()
diff --git a/cmake/QtBuildOptionsHelpers.cmake b/cmake/QtBuildOptionsHelpers.cmake
index ccd054183d4..ae8cf51e016 100644
--- a/cmake/QtBuildOptionsHelpers.cmake
+++ b/cmake/QtBuildOptionsHelpers.cmake
@@ -444,10 +444,19 @@ endmacro()
macro(qt_internal_set_unity_build)
option(QT_UNITY_BUILD "Enable unity (jumbo) build")
set(QT_UNITY_BUILD_BATCH_SIZE "32" CACHE STRING "Unity build batch size")
- if(QT_UNITY_BUILD)
- set(CMAKE_UNITY_BUILD ON)
- set(CMAKE_UNITY_BUILD_BATCH_SIZE "${QT_UNITY_BUILD_BATCH_SIZE}")
- endif()
+
+ include(CMakeDependentOption)
+ string(TOLOWER "${PROJECT_NAME}" project_name_lower)
+ cmake_dependent_option(
+ "QT_UNITY_BUILD_PROJECT_${project_name_lower}"
+ "Enable unity builds for project ${PROJECT_NAME}"
+ TRUE
+ QT_UNITY_BUILD
+ FALSE
+ )
+
+ set(CMAKE_UNITY_BUILD "${QT_UNITY_BUILD_PROJECT_${project_name_lower}}")
+ set(CMAKE_UNITY_BUILD_BATCH_SIZE "${QT_UNITY_BUILD_BATCH_SIZE}")
endmacro()
macro(qt_internal_set_allow_symlink_in_paths)
diff --git a/cmake/QtBuildRepoHelpers.cmake b/cmake/QtBuildRepoHelpers.cmake
index 86107179475..70a066f11b2 100644
--- a/cmake/QtBuildRepoHelpers.cmake
+++ b/cmake/QtBuildRepoHelpers.cmake
@@ -355,6 +355,7 @@ macro(qt_build_repo_begin)
endif()
_qt_internal_sbom_auto_begin_qt_repo_project()
+ qt_internal_set_unity_build()
endmacro()
# Runs delayed actions on some of the Qt targets.
diff --git a/coin/instructions/prepare_building_env.yaml b/coin/instructions/prepare_building_env.yaml
index 0330369662d..ac2ad89027b 100644
--- a/coin/instructions/prepare_building_env.yaml
+++ b/coin/instructions/prepare_building_env.yaml
@@ -679,6 +679,9 @@ instructions:
- type: AppendToEnvironmentVariable
variableName: COMMON_NON_QTBASE_TARGET_CMAKE_ARGS
variableValue: " -DQT_USE_VCPKG=ON -DVCPKG_INSTALLED_DIR={{.Env.VCPKG_INSTALLED_DIR}} -DVCPKG_HOST_TRIPLET={{.Env.VCPKG_HOST_TRIPLET}} -DVCPKG_TARGET_TRIPLET={{.Env.VCPKG_TARGET_TRIPLET}}"
+ - type: AppendToEnvironmentVariable
+ variableName: COMMON_TARGET_TEST_CMAKE_ARGS
+ variableValue: " -DQT_USE_VCPKG=ON -DVCPKG_INSTALLED_DIR={{.Env.VCPKG_INSTALLED_DIR}} -DVCPKG_HOST_TRIPLET={{.Env.VCPKG_HOST_TRIPLET}} -DVCPKG_TARGET_TRIPLET={{.Env.VCPKG_TARGET_TRIPLET}}"
enable_if:
condition: runtime
env_var: USE_VCPKG
diff --git a/src/corelib/Qt6WasmMacros.cmake b/src/corelib/Qt6WasmMacros.cmake
index e185ef67490..eae356679bd 100644
--- a/src/corelib/Qt6WasmMacros.cmake
+++ b/src/corelib/Qt6WasmMacros.cmake
@@ -91,15 +91,6 @@ function(_qt_internal_wasm_add_target_helpers target)
${_target_directory}/qtloader.js COPYONLY)
configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtlogo.svg"
${_target_directory}/qtlogo.svg COPYONLY)
- if(QT_FEATURE_shared)
- set(TARGET_DIR "${_target_directory}")
- set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- set(QT_HOST_DIR "${QT_HOST_PATH}")
- set(QT_WASM_DIR "${WASM_BUILD_DIR}")
- set(QT_INSTALL_DIR "${QT6_INSTALL_PREFIX}")
- configure_file("${WASM_BUILD_DIR}/libexec/generate_default_preloads.sh.in"
- "${_target_directory}/generate_default_preloads_for_${target}.sh" @ONLY)
- endif()
endif()
endif()
endif()
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index a981163a6e7..61621f54911 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -1,14 +1,21 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-//! [0]
-label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
-label->setAlignment({ });
-//! [0]
-
+#if __has_include(<QLabel>)
+#include <QLabel>
+void label_example()
+{
+ QLabel *label = new QLabel;
+ //! [0]
+ label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ label->setAlignment({ });
+ //! [0]
+}
+#endif
+#include <QMetaProperty>
//! [1]
-class MyClass
+class MyClass_1
{
public:
enum Option {
@@ -18,182 +25,226 @@ public:
SqueezeBlank = 0x4
};
Q_DECLARE_FLAGS(Options, Option)
- ...
+ //...
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::Options)
+Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass_1::Options)
//! [1]
+#if 0
//! [meta-object flags]
Q_FLAG(Options)
//! [meta-object flags]
+#endif
-//! [2]
-typedef QFlags<Enum> Flags;
-//! [2]
+struct DummyDriver {
+ bool isOpen() const { return true; }
+ bool isOpenError() const { return false; }
+};
-//! [4]
-if (!driver()->isOpen() || driver()->isOpenError()) {
- qWarning("QSqlQuery::exec: database not open");
- return false;
+DummyDriver* driver() {
+ static DummyDriver d;
+ return &d;
}
-//! [4]
-
-
-//! [5]
-qint64 value = Q_INT64_C(932838457459459);
-//! [5]
-
-
-//! [6]
-quint64 value = Q_UINT64_C(932838457459459);
-//! [6]
-
-//! [8]
-qint64 value = Q_INT64_C(932838457459459);
-//! [8]
+bool examples()
+{
+ enum Enum {};
+ //! [2]
+ typedef QFlags<Enum> Flags;
+ //! [2]
-//! [9]
-quint64 value = Q_UINT64_C(932838457459459);
-//! [9]
+ //! [4]
+ if (!driver()->isOpen() || driver()->isOpenError()) {
+ qWarning("QSqlQuery::exec: database not open");
+ return false;
+ }
+ //! [4]
+ {
+ //! [5]
+ qint64 value = Q_INT64_C(932838457459459);
+ //! [5]
+ }
-//! [10]
-int absoluteValue;
-int myValue = -4;
+ {
+ //! [6]
+ quint64 value = Q_UINT64_C(932838457459459);
+ //! [6]
+ }
-absoluteValue = qAbs(myValue);
-// absoluteValue == 4
-//! [10]
+ {
+ //! [8]
+ qint64 value = Q_INT64_C(932838457459459);
+ //! [8]
+ }
+ {
+ //! [9]
+ quint64 value = Q_UINT64_C(932838457459459);
+ //! [9]
+ }
-//! [11A]
-double valueA = 2.3;
-double valueB = 2.7;
+ {
+ //! [10]
+ int absoluteValue;
+ int myValue = -4;
-int roundedValueA = qRound(valueA);
-// roundedValueA = 2
-int roundedValueB = qRound(valueB);
-// roundedValueB = 3
-//! [11A]
+ absoluteValue = qAbs(myValue);
+ // absoluteValue == 4
+ //! [10]
+ }
-//! [11B]
-float valueA = 2.3;
-float valueB = 2.7;
+ {
+ //! [11A]
+ double valueA = 2.3;
+ double valueB = 2.7;
-int roundedValueA = qRound(valueA);
-// roundedValueA = 2
-int roundedValueB = qRound(valueB);
-// roundedValueB = 3
-//! [11B]
+ int roundedValueA = qRound(valueA);
+ // roundedValueA = 2
+ int roundedValueB = qRound(valueB);
+ // roundedValueB = 3
+ //! [11A]
+ }
+ {
+ //! [11B]
+ float valueA = 2.3f;
+ float valueB = 2.7f;
-//! [12A]
-double valueA = 42949672960.3;
-double valueB = 42949672960.7;
+ int roundedValueA = qRound(valueA);
+ // roundedValueA = 2
+ int roundedValueB = qRound(valueB);
+ // roundedValueB = 3
+ //! [11B]
+ }
-qint64 roundedValueA = qRound64(valueA);
-// roundedValueA = 42949672960
-qint64 roundedValueB = qRound64(valueB);
-// roundedValueB = 42949672961
-//! [12A]
+ {
+ //! [12A]
+ double valueA = 42949672960.3;
+ double valueB = 42949672960.7;
-//! [12B]
-float valueA = 42949672960.3;
-float valueB = 42949672960.7;
+ qint64 roundedValueA = qRound64(valueA);
+ // roundedValueA = 42949672960
+ qint64 roundedValueB = qRound64(valueB);
+ // roundedValueB = 42949672961
+ //! [12A]
+ }
-qint64 roundedValueA = qRound64(valueA);
-// roundedValueA = 42949672960
-qint64 roundedValueB = qRound64(valueB);
-// roundedValueB = 42949672961
-//! [12B]
+ {
+ //! [12B]
+ float valueA = 42949672960.3f;
+ float valueB = 42949672960.7f;
+ qint64 roundedValueA = qRound64(valueA);
+ // roundedValueA = 42949672960
+ qint64 roundedValueB = qRound64(valueB);
+ // roundedValueB = 42949672961
+ //! [12B]
+ }
-//! [13]
-int myValue = 6;
-int yourValue = 4;
+ {
+ //! [13]
+ int myValue = 6;
+ int yourValue = 4;
-int minValue = qMin(myValue, yourValue);
-// minValue == yourValue
-//! [13]
+ int minValue = qMin(myValue, yourValue);
+ // minValue == yourValue
+ //! [13]
+ }
+ {
+ //! [14]
+ int myValue = 6;
+ int yourValue = 4;
-//! [14]
-int myValue = 6;
-int yourValue = 4;
+ int maxValue = qMax(myValue, yourValue);
+ // maxValue == myValue
+ //! [14]
+ }
-int maxValue = qMax(myValue, yourValue);
-// maxValue == myValue
-//! [14]
+ {
+ //! [15]
+ int myValue = 10;
+ int minValue = 2;
+ int maxValue = 6;
+ int boundedValue = qBound(minValue, myValue, maxValue);
+ // boundedValue == 6
+ //! [15]
+ }
-//! [15]
-int myValue = 10;
-int minValue = 2;
-int maxValue = 6;
+ return true;
+}
-int boundedValue = qBound(minValue, myValue, maxValue);
-// boundedValue == 6
-//! [15]
+#if __has_include(<QStyle>)
+#include <QStyle>
+QStyle *style()
+{
+ static QStyle *s = nullptr;
+ return s;
+}
-//! [16]
-#if QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)
- QIcon icon = style()->standardIcon(QStyle::SP_TrashIcon);
-#else
- QPixmap pixmap = style()->standardPixmap(QStyle::SP_TrashIcon);
- QIcon icon(pixmap);
+void snippet_16()
+{
+ //! [16]
+ #if QT_VERSION >= QT_VERSION_CHECK(4, 1, 0)
+ QIcon icon = style()->standardIcon(QStyle::SP_TrashIcon);
+ #else
+ QPixmap pixmap = style()->standardPixmap(QStyle::SP_TrashIcon);
+ QIcon icon(pixmap);
+ #endif
+ //! [16]
+}
#endif
-//! [16]
-
-//! [17]
+//! [17&19_include_open]
// File: div.cpp
#include <QtGlobal>
int divide(int a, int b)
{
- Q_ASSERT(b != 0);
- return a / b;
-}
-//! [17]
-
+//! [17&19_include_open]
-//! [18]
-ASSERT: "b != 0" in file div.cpp, line 7
-//! [18]
+ //! [17assert]
+ Q_ASSERT(b != 0);
+ //! [17assert]
+ //! [19assert]
+ Q_ASSERT_X(b != 0, "divide", "division by zero");
+ //! [19assert]
-//! [19]
-// File: div.cpp
-
-#include <QtGlobal>
-
-int divide(int a, int b)
-{
- Q_ASSERT_X(b != 0, "divide", "division by zero");
- return a / b;
+ //! [17&19_return_close]
+ return a / b;
}
-//! [19]
+//! [17&19_return_close]
+#if 0
+//! [18]
+ASSERT: "b != 0" in file div.cpp, line 7
+//! [18]
//! [20]
ASSERT failure in divide: "division by zero", file div.cpp, line 7
//! [20]
+#endif
+#include <QtAssert>
-//! [21]
-int *a;
-
-Q_CHECK_PTR(a = new int[80]); // WRONG!
+void pointer_example()
+{
+ //! [21]
+ int *a;
-a = new (nothrow) int[80]; // Right
-Q_CHECK_PTR(a);
-//! [21]
+ Q_CHECK_PTR(a = new int[80]); // WRONG!
+ a = new (std::nothrow) int[80]; // Right
+ Q_CHECK_PTR(a);
+ //! [21]
+}
//! [22]
template<typename TInputType>
@@ -208,7 +259,7 @@ const TInputType &myMin(const TInputType &value1, const TInputType &value2)
}
//! [22]
-
+# if __has_include(<QWidget>)
//! [23]
#include <QApplication>
#include <stdio.h>
@@ -224,36 +275,44 @@ void logToFile(QtMsgType type, const QMessageLogContext &context, const QString
fflush(f);
if (originalHandler)
- *originalHandler(type, context, msg);
+ originalHandler(type, context, msg);
}
int main(int argc, char **argv)
{
originalHandler = qInstallMessageHandler(logToFile);
QApplication app(argc, argv);
- ...
+ // ...
return app.exec();
}
//! [23]
+#endif
+#include <QBrush>
-//! [24]
-qDebug("Items in list: %d", myList.size());
-//! [24]
+void debug_info_example()
+{
+ QList<int> myList;
+ QBrush myQBrush(Qt::red);
+ int i = 0;
+ //! [24]
+ qDebug("Items in list: %d", myList.size());
+ //! [24]
-//! [25]
-qDebug() << "Brush:" << myQBrush << "Other value:" << i;
-//! [25]
+ //! [25]
+ qDebug() << "Brush:" << myQBrush << "Other value:" << i;
+ //! [25]
-//! [qInfo_printf]
-qInfo("Items in list: %d", myList.size());
-//! [qInfo_printf]
+ //! [qInfo_printf]
+ qInfo("Items in list: %d", myList.size());
+ //! [qInfo_printf]
-//! [qInfo_stream]
-qInfo() << "Brush:" << myQBrush << "Other value:" << i;
-//! [qInfo_stream]
+ //! [qInfo_stream]
+ qInfo() << "Brush:" << myQBrush << "Other value:" << i;
+ //! [qInfo_stream]
+}
//! [26]
void f(int c)
@@ -263,12 +322,16 @@ void f(int c)
}
//! [26]
+void warning_example()
+{
+ QBrush myQBrush(Qt::red);
+ int i = 0;
+ //! [27]
+ qWarning() << "Brush:" << myQBrush << "Other value:" << i;
+ //! [27]
+}
-//! [27]
-qWarning() << "Brush:" << myQBrush << "Other value:" << i;
-//! [27]
-
-
+#include <QFile>
//! [28]
void load(const QString &fileName)
{
@@ -278,14 +341,17 @@ void load(const QString &fileName)
}
//! [28]
-
-//! [29]
-qCritical() << "Brush:" << myQBrush << "Other value:" << i;
-//! [29]
-
+void critical_example()
+{
+ QBrush myQBrush(Qt::red);
+ int i = 0;
+ //! [29]
+ qCritical() << "Brush:" << myQBrush << "Other value:" << i;
+ //! [29]
+}
//! [30]
-int divide(int a, int b)
+int divide_by_zero(int a, int b)
{
if (b == 0) // program error
qFatal("divide: cannot divide by zero");
@@ -293,91 +359,150 @@ int divide(int a, int b)
}
//! [30]
-
-//! [31]
-forever {
- ...
+void forever_example()
+{
+ //! [31]
+ forever {
+ // ...
+ }
+ //! [31]
}
-//! [31]
-
+# if 0
//! [32]
CONFIG += no_keywords
//! [32]
+#endif
+namespace snippet_34
+{
+ class FriendlyConversation
+ {
+ public:
+ QString greeting(int type);
+ };
-//! [33]
-CONFIG += no_keywords
-//! [33]
+ QString tr(const char *)
+ {
+ return "";
+ }
+ //! [34]
+ QString FriendlyConversation::greeting(int type)
+ {
+ static const char *greeting_strings[] = {
+ QT_TR_NOOP("Hello"),
+ QT_TR_NOOP("Goodbye")
+ };
+ return tr(greeting_strings[type]);
+ }
+ //! [34]
+}
-//! [34]
-QString FriendlyConversation::greeting(int type)
+#if __has_include(<QApplication>)
+namespace snippet_35
{
- static const char *greeting_strings[] = {
- QT_TR_NOOP("Hello"),
- QT_TR_NOOP("Goodbye")
+ class FriendlyConversation
+ {
+ public:
+ QString greeting(int type);
};
- return tr(greeting_strings[type]);
-}
-//! [34]
+ QString tr(const char *)
+ {
+ return "";
+ }
-//! [35]
-static const char *greeting_strings[] = {
- QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
- QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
-};
-QString FriendlyConversation::greeting(int type)
-{
- return tr(greeting_strings[type]);
+ //! [35]
+ static const char *greeting_strings[] = {
+ QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
+ QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
+ };
+
+ QString FriendlyConversation::greeting(int type)
+ {
+ return tr(greeting_strings[type]);
+ }
+
+ QString global_greeting(int type)
+ {
+ return qApp->translate("FriendlyConversation",
+ greeting_strings[type]);
+ }
+ //! [35]
}
-QString global_greeting(int type)
+namespace snippet_36
{
- return qApp->translate("FriendlyConversation",
- greeting_strings[type]);
-}
-//! [35]
+ class FriendlyConversation
+ {
+ public:
+ QString greeting(int type);
+ };
+ QString tr(const char *text, const char *comment)
+ {
+ return "";
+ }
-//! [36]
-static { const char *source; const char *comment; } greeting_strings[] =
-{
- QT_TRANSLATE_NOOP3("FriendlyConversation", "Hello",
- "A really friendly hello"),
- QT_TRANSLATE_NOOP3("FriendlyConversation", "Goodbye",
- "A really friendly goodbye")
-};
+ //! [36]
-QString FriendlyConversation::greeting(int type)
-{
- return tr(greeting_strings[type].source,
- greeting_strings[type].comment);
+ static struct { const char *source; const char *comment; } greeting_strings[] =
+ {
+ QT_TRANSLATE_NOOP3("FriendlyConversation", "Hello",
+ "A really friendly hello"),
+ QT_TRANSLATE_NOOP3("FriendlyConversation", "Goodbye",
+ "A really friendly goodbye")
+ };
+
+ QString FriendlyConversation::greeting(int type)
+ {
+ return tr(greeting_strings[type].source,
+ greeting_strings[type].comment);
+ }
+
+ QString global_greeting(int type)
+ {
+ return qApp->translate("FriendlyConversation",
+ greeting_strings[type].source,
+ greeting_strings[type].comment);
+ }
+ //! [36]
}
+#endif // __has_include(<QApplication>)
-QString global_greeting(int type)
+namespace snippet_qttrnnoop
{
- return qApp->translate("FriendlyConversation",
- greeting_strings[type].source,
- greeting_strings[type].comment);
-}
-//! [36]
+ class StatusClass
+ {
+ public:
+ static QString status(int type, int count);
+ static const char * const status_strings[];
+ };
+ QString tr(const char *, const char *, int)
+ {
+ return "";
+ }
+ //! [qttrnnoop]
+ const char * const StatusClass::status_strings[] = {
+ QT_TR_N_NOOP("There are %n new message(s)"),
+ QT_TR_N_NOOP("There are %n total message(s)")
+ };
-//! [qttrnnoop]
-static const char * const StatusClass::status_strings[] = {
- QT_TR_N_NOOP("There are %n new message(s)"),
- QT_TR_N_NOOP("There are %n total message(s)")
-};
+ QString StatusClass::status(int type, int count)
+ {
+ return tr(status_strings[type], nullptr, count);
+ }
+ //! [qttrnnoop]
+}
-QString StatusClass::status(int type, int count)
+QString translate(const char *, const char *, const char *, int)
{
- return tr(status_strings[type], nullptr, count);
+ return "";
}
-//! [qttrnnoop]
//! [qttranslatennoop]
static const char * const greeting_strings[] = {
@@ -391,88 +516,125 @@ QString global_greeting(int type, int msgcnt)
}
//! [qttranslatennoop]
-//! [qttranslatennoop3]
-static { const char * const source; const char * const comment; } status_strings[] = {
- QT_TRANSLATE_N_NOOP3("Message Status", "Hello, you have %n message(s)",
- "A login message status"),
- QT_TRANSLATE_N_NOOP3("Message status", "You have %n new message(s)",
- "A new message query status")
-};
-
-QString FriendlyConversation::greeting(int type, int count)
+#if __has_include(<QApplication>)
+namespace snippet_qttranslatennoop3
{
- return tr(status_strings[type].source,
- status_strings[type].comment, count);
-}
+ class FriendlyConversation
+ {
+ public:
+ QString greeting(int type, int count);
+ };
-QString global_greeting(int type, int count)
-{
- return qApp->translate("Message Status",
- status_strings[type].source,
- status_strings[type].comment,
- count);
-}
-//! [qttranslatennoop3]
+ QString tr(const char *text, const char *comment, int n)
+ {
+ return "";
+ }
+ //! [qttranslatennoop3]
+ static struct { const char * const source; const char * const comment; } status_strings[] = {
+ QT_TRANSLATE_N_NOOP3("Message Status", "Hello, you have %n message(s)",
+ "A login message status"),
+ QT_TRANSLATE_N_NOOP3("Message status", "You have %n new message(s)",
+ "A new message query status")
+ };
-//! [qttrid]
+ QString FriendlyConversation::greeting(int type, int count)
+ {
+ return tr(status_strings[type].source,
+ status_strings[type].comment, count);
+ }
+
+ QString global_greeting(int type, int count)
+ {
+ return qApp->translate("Message Status",
+ status_strings[type].source,
+ status_strings[type].comment,
+ count);
+ }
+ //! [qttranslatennoop3]
+}
+#endif // __has_include(<QApplication>)
+
+void qttrid_example()
+{
+ int n = 0;
+ //! [qttrid]
//% "%n fooish bar(s) found.\n"
//% "Do you want to continue?"
QString text = qtTrId("qtn_foo_bar", n);
-//! [qttrid]
+ //! [qttrid]
+}
+#if __has_include(<QWidget>)
+namespace qttrid_noop
+{
+ class TheClass : public QWidget
+ {
+ public:
+ TheClass(QWidget *parent = nullptr) : QWidget(parent) {
+ addLabels();
+ }
+ void addLabels();
+ };
-//! [qttrid_noop]
-static const char * const ids[] = {
- //% "This is the first text."
- QT_TRID_NOOP("qtn_1st_text"),
- //% "This is the second text."
- QT_TRID_NOOP("qtn_2nd_text"),
- 0
-};
+ //! [qttrid_noop]
+ static const char * const ids[] = {
+ //% "This is the first text."
+ QT_TRID_NOOP("qtn_1st_text"),
+ //% "This is the second text."
+ QT_TRID_NOOP("qtn_2nd_text"),
+ 0
+ };
-void TheClass::addLabels()
-{
- for (int i = 0; ids[i]; ++i)
- new QLabel(qtTrId(ids[i]), this);
+ void TheClass::addLabels()
+ {
+ for (int i = 0; ids[i]; ++i)
+ new QLabel(qtTrId(ids[i]), this);
+ }
+ //! [qttrid_noop]
}
-//! [qttrid_noop]
-
-//! [qttrid_n_noop]
-static const char * const ids[] = {
- //% "%n foo(s) found."
- QT_TRID_N_NOOP("qtn_foo"),
- //% "%n bar(s) found."
- QT_TRID_N_NOOP("qtn_bar"),
- 0
-};
+#endif
-QString result(int type, int n)
+namespace qttrid_n_noop
{
- return qtTrId(ids[type], n);
+ //! [qttrid_n_noop]
+ static const char * const ids[] = {
+ //% "%n foo(s) found."
+ QT_TRID_N_NOOP("qtn_foo"),
+ //% "%n bar(s) found."
+ QT_TRID_N_NOOP("qtn_bar"),
+ 0
+ };
+
+ QString result(int type, int n)
+ {
+ return qtTrId(ids[type], n);
+ }
+ //! [qttrid_n_noop]
}
-//! [qttrid_n_noop]
-//! [38]
-struct Point2D
+namespace for_struct
{
- int x;
- int y;
-};
-
-Q_DECLARE_TYPEINFO(Point2D, Q_PRIMITIVE_TYPE);
-//! [38]
+ //! [38]
+ struct Point2D
+ {
+ int x;
+ int y;
+ };
+ Q_DECLARE_TYPEINFO(Point2D, Q_PRIMITIVE_TYPE);
+ //! [38]
+}
//! [39]
class Point2D
{
public:
Point2D() { data = new int[2]; }
- Point2D(const Point2D &other) { ... }
+ Point2D(const Point2D &other) { /*...*/ }
~Point2D() { delete[] data; }
- Point2D &operator=(const Point2D &other) { ... }
+ Point2D &operator=(const Point2D &other) { /*...*/ }
int x() const { return data[0]; }
int y() const { return data[1]; }
@@ -487,13 +649,13 @@ Q_DECLARE_TYPEINFO(Point2D, Q_RELOCATABLE_TYPE);
//! [40]
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-...
+//...
#endif
-or
+//or
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-...
+//...
#endif
//! [40]
@@ -502,7 +664,7 @@ or
//! [41]
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-...
+//...
#endif
//! [41]
@@ -510,7 +672,7 @@ or
//! [42]
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-...
+//...
#endif
//! [42]
@@ -523,14 +685,17 @@ namespace QT_NAMESPACE {
}
//! [end namespace macro]
-//! [43]
-class MyClass : public QObject
+namespace snippet_43
{
-private:
- Q_DISABLE_COPY(MyClass)
-};
+ //! [43]
+ class MyClass : public QObject
+ {
+ private:
+ Q_DISABLE_COPY(MyClass)
+ };
-//! [43]
+ //! [43]
+}
//! [44]
class MyClass : public QObject
@@ -541,25 +706,33 @@ private:
};
//! [44]
-//! [45]
-QWidget w = QWidget();
-//! [45]
+#if __has_include(<QWidget>)
+void qwidget_example()
+{
+ //! [45]
+ QWidget w = QWidget();
+ //! [45]
+}
+#endif
-//! [46]
-// Instead of comparing with 0.0
-qFuzzyCompare(0.0, 1.0e-200); // This will return false
-// Compare adding 1 to both values will fix the problem
-qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true
-//! [46]
+void qfuzzycompare_example()
+{
+ //! [46]
+ // Instead of comparing with 0.0
+ qFuzzyCompare(0.0, 1.0e-200); // This will return false
+ // Compare adding 1 to both values will fix the problem
+ qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true
+ //! [46]
+}
//! [49]
void myMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
//! [49]
//! [50]
-class B {...};
-class C {...};
-class D {...};
+class B {/*...*/};
+class C {/*...*/};
+class D {/*...*/};
struct A : public B {
C c;
D d;
@@ -570,33 +743,45 @@ struct A : public B {
template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
//! [51]
-//! [52]
+namespace snippet_52
+{
+ //! [52]
struct Foo {
void overloadedFunction();
void overloadedFunction(int, const QString &);
};
- ... qOverload<>(&Foo::overloadedFunction)
- ... qOverload<int, const QString &>(&Foo::overloadedFunction)
-//! [52]
+ auto ptr_1 = qOverload<>(&Foo::overloadedFunction);
+ auto ptr_2 = qOverload<int, const QString &>(&Foo::overloadedFunction);
+ //! [52]
+}
+
//! [54]
struct Foo {
void overloadedFunction(int, const QString &);
void overloadedFunction(int, const QString &) const;
};
- ... qConstOverload<int, const QString &>(&Foo::overloadedFunction)
- ... qNonConstOverload<int, const QString &>(&Foo::overloadedFunction)
+ auto ptr_1 = qConstOverload<int, const QString &>(&Foo::overloadedFunction);
+ auto ptr_2 = qNonConstOverload<int, const QString &>(&Foo::overloadedFunction);
//! [54]
-//! [qlikely]
- // the condition inside the "if" will be successful most of the times
- for (int i = 1; i <= 365; i++) {
- if (Q_LIKELY(isWorkingDay(i))) {
- ...
+bool isWorkingDay(int day)
+{
+ return false;
+}
+
+void qlikely_example()
+{
+ //! [qlikely]
+ // the condition inside the "if" will be successful most of the times
+ for (int i = 1; i <= 365; i++) {
+ if (Q_LIKELY(isWorkingDay(i))) {
+ //...
+ }
+ //...
}
- ...
- }
-//! [qlikely]
+ //! [qlikely]
+}
//! [qunlikely]
bool readConfiguration(const QFile &file)
@@ -607,7 +792,7 @@ bool readConfiguration(const QFile &file)
return false;
}
- ...
+ //...
return true;
}
//! [qunlikely]
@@ -621,20 +806,29 @@ bool readConfiguration(const QFile &file)
};
//! [qunreachable-enum]
-//! [qunreachable-switch]
- switch (shape) {
- case Rectangle:
- return rectangle();
- case Triangle:
- return triangle();
- case Circle:
- return circle();
- case NumShapes:
- Q_UNREACHABLE();
- break;
- }
-//! [qunreachable-switch]
+int rectangle() { return 0; }
+int triangle() { return 1; }
+int circle() { return 2; }
+
+int qunreachable_example(Shapes shape)
+{
+ //! [qunreachable-switch]
+ switch (shape) {
+ case Rectangle:
+ return rectangle();
+ case Triangle:
+ return triangle();
+ case Circle:
+ return circle();
+ case NumShapes:
+ Q_UNREACHABLE();
+ break;
+ }
+ //! [qunreachable-switch]
+ return -1;
+}
+# if __has_include(<QWidget>)
//! [qt-version-check]
#include <QtGlobal>
@@ -644,68 +838,94 @@ bool readConfiguration(const QFile &file)
#include <QtGui>
#endif
//! [qt-version-check]
+#endif
+
+void qgetenv_examples()
+{
+ const char *varName = "MY_ENV_VAR";
+ bool *ok = nullptr;
+
+ //! [is-empty]
+ bool is_empty = qgetenv(varName).isEmpty();
+ //! [is-empty]
+
+ //! [to-int]
+ int to_int = qgetenv(varName).toInt(ok, 0);
+ //! [to-int]
-//! [is-empty]
- qgetenv(varName).isEmpty()
-//! [is-empty]
-
-//! [to-int]
- qgetenv(varName).toInt(ok, 0)
-//! [to-int]
-
-//! [int-value_or]
- qEnvironmentVariableIntegerValue(varName).value_or(0)
-//! [int-value_or]
-
-//! [int-eq0]
- qEnvironmentVariableIntegerValue(varName) == 0
-//! [int-eq0]
-
-//! [is-null]
- !qgetenv(varName).isNull()
-//! [is-null]
-
-//! [as-const-0]
- QString s = ...;
- for (QChar ch : s) // detaches 's' (performs a deep-copy if 's' was shared)
- process(ch);
- for (QChar ch : qAsConst(s)) // ok, no detach attempt
- process(ch);
-//! [as-const-0]
-
-//! [as-const-1]
- const QString s = ...;
- for (QChar ch : s) // ok, no detach attempt on const objects
- process(ch);
-//! [as-const-1]
-
-//! [as-const-2]
- for (QChar ch : funcReturningQString())
- process(ch); // OK, the returned object is kept alive for the loop's duration
-//! [as-const-2]
-
-//! [as-const-3]
- for (QChar ch : qAsConst(funcReturningQString()))
- process(ch); // ERROR: ch is copied from deleted memory
-//! [as-const-3]
-
-//! [as-const-4]
- for (QChar ch : qAsConst(funcReturningQString()))
- process(ch); // ERROR: ch is copied from deleted memory
-//! [as-const-4]
-
-//! [qdecloverride]
- // generate error if this doesn't actually override anything:
- virtual void MyWidget::paintEvent(QPaintEvent*) override;
-//! [qdecloverride]
-
-//! [qdeclfinal-1]
- // more-derived classes no longer permitted to override this:
- virtual void MyWidget::paintEvent(QPaintEvent*) final;
-//! [qdeclfinal-1]
+ //! [int-value_or]
+ auto value = qEnvironmentVariableIntegerValue(varName).value_or(0);
+ //! [int-value_or]
+
+ //! [int-eq0]
+ bool equals_zero = qEnvironmentVariableIntegerValue(varName) == 0;
+ //! [int-eq0]
+
+ //! [is-null]
+ bool is_not_null = !qgetenv(varName).isNull();
+ //! [is-null]
+}
+
+QString funcReturningQString()
+{
+ return "Hello, World!";
+}
+void process(const QChar &ch) { }
+
+void qchar_examples()
+{
+ {
+ //! [as-const-0]
+ QString s = "...";
+ for (QChar ch : s) // detaches 's' (performs a deep-copy if 's' was shared)
+ process(ch);
+ for (QChar ch : qAsConst(s)) // ok, no detach attempt
+ process(ch);
+ //! [as-const-0]
+ }
+
+ //! [as-const-1]
+ const QString s = "...";
+ for (QChar ch : s) // ok, no detach attempt on const objects
+ process(ch);
+ //! [as-const-1]
+
+ //! [as-const-2]
+ for (QChar ch : funcReturningQString())
+ process(ch); // OK, the returned object is kept alive for the loop's duration
+ //! [as-const-2]
+
+#if MAKE_ERRORS
+ //! [as-const-3]
+ for (QChar ch : qAsConst(funcReturningQString()))
+ process(ch); // ERROR: ch is copied from deleted memory
+ //! [as-const-3]
+
+ //! [as-const-4]
+ for (QChar ch : qAsConst(funcReturningQString()))
+ process(ch); // ERROR: ch is copied from deleted memory
+ //! [as-const-4]
+#endif
+}
+
+class ExampleClass
+{
+protected:
+#if MAKE_ERRORS
+ //! [qdecloverride]
+ // generate error if this doesn't actually override anything:
+ virtual void override_func() override;
+ //! [qdecloverride]
+#endif
+
+ //! [qdeclfinal-1]
+ // more-derived classes no longer permitted to override this:
+ virtual void final_func() final;
+ //! [qdeclfinal-1]
+};
//! [qdeclfinal-2]
- class QRect final { // cannot be derived from
+ class SomeClass final { // cannot be derived from
// ...
};
//! [qdeclfinal-2]
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp
index 4a31a2e6617..d035606629c 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
+#if MESSAGE
//! [0]
QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz ttt} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"
//! [0]
+#endif
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp
index d88675d8f15..94ee3abf4fa 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp
@@ -1,9 +1,14 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-//! [0]
- if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not
- // significant
- // precise enough
- }
-//! [0]
+#include <QtNumeric>
+
+void example(float a, float b)
+{
+ //! [0]
+ if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not
+ // significant
+ // precise enough
+ }
+ //! [0]
+}
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp
index d86d40bc981..ab49a634527 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp
@@ -1,14 +1,19 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-//! [0]
- QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)
-//! [0]
+#include <QOperatingSystemVersion>
-//! [1]
- auto current = QOperatingSystemVersion::current();
- if (current >= QOperatingSystemVersion::OSXYosemite ||
- current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
- // returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0
- }
-//! [1]
+void example()
+{
+ //! [0]
+ bool ios_higher_then_9 = QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9);
+ //! [0]
+
+ //! [1]
+ auto current = QOperatingSystemVersion::current();
+ if (current >= QOperatingSystemVersion::OSXYosemite ||
+ current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
+ // returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0
+ }
+ //! [1]
+}
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp
index 8be3f91120f..c3112d11768 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp
@@ -2,83 +2,117 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-//! [0]
- quint32 value = QRandomGenerator::global()->generate();
-//! [0]
-
-//! [1]
- QRandomGenerator prng1(1234), prng2(1234);
- Q_ASSERT(prng1.generate() == prng2.generate());
- Q_ASSERT(prng1.generate64() == prng2.generate64());
-//! [1]
-
-//! [2]
- int x = QRandomGenerator::global()->generate();
- int y = QRandomGenerator::global()->generate();
- int w = QRandomGenerator::global()->bounded(16384);
- int h = QRandomGenerator::global()->bounded(16384);
-//! [2]
-
-//! [3]
- std::uniform_real_distribution dist(1, 2.5);
- return dist(*QRandomGenerator::global());
-//! [3]
-
-//! [4]
- std::seed_seq sseq(seedBuffer, seedBuffer + len);
- QRandomGenerator generator(sseq);
-//! [4]
-
-//! [5]
- std::seed_seq sseq(begin, end);
- QRandomGenerator generator(sseq);
-//! [5]
-
-//! [6]
- while (z--)
- generator.generate();
-//! [6]
-
-//! [7]
- std::generate(begin, end, [this]() { return generate(); });
-//! [7]
-
-//! [8]
- std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); });
-//! [8]
-
-//! [9]
- QList<quint32> list;
- list.resize(16);
- QRandomGenerator::global()->fillRange(list.data(), list.size());
-//! [9]
-
-//! [10]
- quint32 array[2];
- QRandomGenerator::global()->fillRange(array);
-//! [10]
-
-//! [11]
- QRandomGenerator64 rd;
- return std::generate_canonical<qreal, std::numeric_limits<qreal>::digits>(rd);
-//! [11]
-
-//! [12]
- return generateDouble() * highest;
-//! [12]
-
-//! [13]
- quint32 v = QRandomGenerator::global()->bounded(256);
-//! [13]
-
-//! [14]
- quint32 v = QRandomGenerator::global()->bounded(1000, 2000);
-//! [14]
-
-//! [15]
- return QColor::fromRgb(QRandomGenerator::global()->generate());
-//! [15]
-
-//! [16]
- qint64 value = QRandomGenerator64::global()->generate() & std::numeric_limits<qint64>::max();
-//! [16]
+#include <QRandomGenerator>
+#include <QList>
+
+double snippets_1_2_3()
+{
+ //! [0]
+ quint32 value = QRandomGenerator::global()->generate();
+ //! [0]
+
+ //! [1]
+ QRandomGenerator prng1(1234), prng2(1234);
+ Q_ASSERT(prng1.generate() == prng2.generate());
+ Q_ASSERT(prng1.generate64() == prng2.generate64());
+ //! [1]
+
+ //! [2]
+ int x = QRandomGenerator::global()->generate();
+ int y = QRandomGenerator::global()->generate();
+ int w = QRandomGenerator::global()->bounded(16384);
+ int h = QRandomGenerator::global()->bounded(16384);
+ //! [2]
+
+ //! [3]
+ std::uniform_real_distribution<> dist(1, 2.5);
+ return dist(*QRandomGenerator::global());
+ //! [3]
+}
+class Generator : public QRandomGenerator
+{
+ public:
+ qreal snippets_4_to_11(int z, quint32 *begin, quint32 *end, const quint32 *seedBuffer, size_t len);
+};
+
+qreal Generator::snippets_4_to_11(int z, quint32 *begin, quint32 *end, const quint32 *seedBuffer, size_t len)
+{
+ {
+ //! [4]
+ std::seed_seq sseq(seedBuffer, seedBuffer + len);
+ QRandomGenerator generator(sseq);
+ //! [4]
+ }
+
+ //! [5]
+ std::seed_seq sseq(begin, end);
+ QRandomGenerator generator(sseq);
+ //! [5]
+
+ //! [6]
+ while (z--)
+ generator.generate();
+ //! [6]
+
+ //! [7]
+ std::generate(begin, end, [this]() { return generate(); });
+ //! [7]
+
+ //! [8]
+ std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); });
+ //! [8]
+
+ //! [9]
+ QList<quint32> list;
+ list.resize(16);
+ QRandomGenerator::global()->fillRange(list.data(), list.size());
+ //! [9]
+
+ //! [10]
+ quint32 array[2];
+ QRandomGenerator::global()->fillRange(array);
+ //! [10]
+
+ //! [11]
+ QRandomGenerator64 rd;
+ return std::generate_canonical<qreal, std::numeric_limits<qreal>::digits>(rd);
+ //! [11]
+}
+
+double generateDouble()
+{
+ return 0.0;
+}
+
+double generateDoubleWithHighest(double highest)
+{
+ //! [12]
+ return generateDouble() * highest;
+ //! [12]
+}
+
+#include <QColor>
+
+QColor snippets_13_to_15()
+{
+ {
+ //! [13]
+ quint32 v = QRandomGenerator::global()->bounded(256);
+ //! [13]
+ }
+
+ //! [14]
+ quint32 v = QRandomGenerator::global()->bounded(1000, 2000);
+ //! [14]
+
+ //! [15]
+ return QColor::fromRgb(QRandomGenerator::global()->generate());
+ //! [15]
+}
+
+void snippet_16()
+{
+ //! [16]
+ qint64 value = QRandomGenerator64::global()->generate() & std::numeric_limits<qint64>::max();
+ //! [16]
+}
diff --git a/src/corelib/doc/src/cpp20-overview.qdoc b/src/corelib/doc/src/cpp20-overview.qdoc
index ed48e10f94a..1231394c161 100644
--- a/src/corelib/doc/src/cpp20-overview.qdoc
+++ b/src/corelib/doc/src/cpp20-overview.qdoc
@@ -12,6 +12,16 @@
This page gives a brief overview of C++20 features available in Qt.
+ \section1 WebEngine and Module-Specific Requirements
+
+ While Qt 6 only requires a C++17-compatible compiler in general,
+ the \l{Qt WebEngine} module requires a C++20-compatible compiler
+ due to its dependencies (such as Chromium).
+
+ If you are building Qt WebEngine, ensure that your compiler fully supports C++20.
+
+ See \l{qtwebengine-platform-notes.html}{Qt WebEngine Platform Notes} for detailed requirements.
+
\section1 Support for \c{std::chrono}
Various classes related to date and time have support for \l
diff --git a/src/corelib/global/qassert.cpp b/src/corelib/global/qassert.cpp
index 208619fd5cc..4da8a0cb037 100644
--- a/src/corelib/global/qassert.cpp
+++ b/src/corelib/global/qassert.cpp
@@ -63,7 +63,9 @@ Q_NORETURN void qAbort()
Example:
- \snippet code/src_corelib_global_qglobal.cpp 17
+ \snippet code/src_corelib_global_qglobal.cpp 17&19_include_open
+ \snippet code/src_corelib_global_qglobal.cpp 17assert
+ \snippet code/src_corelib_global_qglobal.cpp 17&19_return_close
If \c b is zero, the Q_ASSERT statement will output the following
message using the qFatal() function:
@@ -86,7 +88,9 @@ Q_NORETURN void qAbort()
Example:
- \snippet code/src_corelib_global_qglobal.cpp 19
+ \snippet code/src_corelib_global_qglobal.cpp 17&19_include_open
+ \snippet code/src_corelib_global_qglobal.cpp 19assert
+ \snippet code/src_corelib_global_qglobal.cpp 17&19_return_close
If \c b is zero, the Q_ASSERT_X statement will output the following
message using the qFatal() function:
diff --git a/src/corelib/global/qforeach.qdoc b/src/corelib/global/qforeach.qdoc
index e6abf0e29c8..bec01152c04 100644
--- a/src/corelib/global/qforeach.qdoc
+++ b/src/corelib/global/qforeach.qdoc
@@ -50,7 +50,7 @@
If you're worried about namespace pollution, you can disable this
macro by adding the following line to your \c .pro file:
- \snippet code/src_corelib_global_qglobal.cpp 33
+ \snippet code/src_corelib_global_qglobal.cpp 32
\note Since Qt 5.7, the use of this macro is discouraged.
Use C++11 range-based \c for, possibly with \c {std::as_const()},
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 645f27798c4..5d6b5e06be6 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -200,7 +200,7 @@ template <typename Char>
static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true)
{
QChar quote(u'"');
- d->write(&quote, 1);
+ d->write(quote);
bool lastWasHexEscape = false;
const Char *end = begin + length;
@@ -227,8 +227,7 @@ static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, si
continue;
}
} else if (isPrintable(*p) && *p != '\\' && *p != '"') {
- QChar c = QLatin1Char(*p);
- d->write(&c, 1);
+ d->write(char16_t{uchar(*p)});
continue;
}
@@ -302,7 +301,7 @@ static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, si
d->write(reinterpret_cast<QChar *>(buf), buflen);
}
- d->write(&quote, 1);
+ d->write(quote);
}
/*!
@@ -332,9 +331,14 @@ void QDebug::putByteArray(const char *begin, size_t length, Latin1Content conten
if (stream->noQuotes) {
// no quotes, write the string directly too (no pretty-printing)
// this respects the QTextStream state, though
- QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, qsizetype(length))
- : QString::fromUtf8(begin, qsizetype(length));
- stream->ts.d_ptr->putString(string);
+ switch (content) {
+ case Latin1Content::ContainsLatin1:
+ stream->ts.d_ptr->putString(QLatin1StringView{begin, qsizetype(length)});
+ break;
+ case Latin1Content::ContainsBinary:
+ stream->ts.d_ptr->putString(QUtf8StringView{begin, qsizetype(length)});
+ break;
+ }
} else {
// we'll reset the QTextStream formatting mechanisms, so save the state
QDebugStateSaver saver(*this);
diff --git a/src/corelib/itemmodels/qrangemodel.cpp b/src/corelib/itemmodels/qrangemodel.cpp
index 51043eb0e24..8ced35a4ae0 100644
--- a/src/corelib/itemmodels/qrangemodel.cpp
+++ b/src/corelib/itemmodels/qrangemodel.cpp
@@ -5,8 +5,48 @@
#include "qrangemodel.h"
#include <QtCore/qsize.h>
+#include <QtCore/private/qabstractitemmodel_p.h>
+
QT_BEGIN_NAMESPACE
+class QRangeModelPrivate : QAbstractItemModelPrivate
+{
+ Q_DECLARE_PUBLIC(QRangeModel)
+
+ struct Deleter { void operator()(QRangeModelImplBase *that) { that->destroy(); } };
+
+public:
+ explicit QRangeModelPrivate(std::unique_ptr<QRangeModelImplBase, Deleter> impl)
+ : impl(std::move(impl))
+ {}
+
+ template <typename Ret, typename ...Args>
+ Ret call(QRangeModelImplBase::ConstOp op, const Args &...args) const
+ {
+ Ret ret = {};
+ const auto tuple = std::tie(args...);
+ impl->callConst_fn(op, impl.get(), &ret, &tuple);
+ return ret;
+ }
+
+ template <typename Ret, typename ...Args>
+ Ret call(QRangeModelImplBase::Op op, const Args &...args)
+ {
+ Ret ret = {};
+ const auto tuple = std::tie(args...);
+ impl->call_fn(op, impl.get(), &ret, &tuple);
+ return ret;
+ }
+
+private:
+ std::unique_ptr<QRangeModelImplBase, Deleter> impl;
+};
+
+QRangeModel::QRangeModel(QRangeModelImplBase *impl, QObject *parent)
+ : QAbstractItemModel(*new QRangeModelPrivate({impl, {}}), parent)
+{
+}
+
/*!
\class QRangeModel
\inmodule QtCore
@@ -503,7 +543,8 @@ QRangeModel::~QRangeModel() = default;
*/
QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent) const
{
- return impl->callConst<QModelIndex>(QRangeModelImplBase::Index, row, column, parent);
+ Q_D(const QRangeModel);
+ return d->call<QModelIndex>(QRangeModelImplBase::Index, row, column, parent);
}
/*!
@@ -520,7 +561,8 @@ QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent) c
*/
QModelIndex QRangeModel::parent(const QModelIndex &child) const
{
- return impl->callConst<QModelIndex>(QRangeModelImplBase::Parent, child);
+ Q_D(const QRangeModel);
+ return d->call<QModelIndex>(QRangeModelImplBase::Parent, child);
}
/*!
@@ -536,7 +578,8 @@ QModelIndex QRangeModel::parent(const QModelIndex &child) const
*/
QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index) const
{
- return impl->callConst<QModelIndex>(QRangeModelImplBase::Sibling, row, column, index);
+ Q_D(const QRangeModel);
+ return d->call<QModelIndex>(QRangeModelImplBase::Sibling, row, column, index);
}
/*!
@@ -554,7 +597,8 @@ QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index)
*/
int QRangeModel::rowCount(const QModelIndex &parent) const
{
- return impl->callConst<int>(QRangeModelImplBase::RowCount, parent);
+ Q_D(const QRangeModel);
+ return d->call<int>(QRangeModelImplBase::RowCount, parent);
}
/*!
@@ -572,7 +616,8 @@ int QRangeModel::rowCount(const QModelIndex &parent) const
*/
int QRangeModel::columnCount(const QModelIndex &parent) const
{
- return impl->callConst<int>(QRangeModelImplBase::ColumnCount, parent);
+ Q_D(const QRangeModel);
+ return d->call<int>(QRangeModelImplBase::ColumnCount, parent);
}
/*!
@@ -589,7 +634,8 @@ int QRangeModel::columnCount(const QModelIndex &parent) const
*/
Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
{
- return impl->callConst<Qt::ItemFlags>(QRangeModelImplBase::Flags, index);
+ Q_D(const QRangeModel);
+ return d->call<Qt::ItemFlags>(QRangeModelImplBase::Flags, index);
}
/*!
@@ -606,8 +652,8 @@ Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
*/
QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- return impl->callConst<QVariant>(QRangeModelImplBase::HeaderData,
- section, orientation, role);
+ Q_D(const QRangeModel);
+ return d->call<QVariant>(QRangeModelImplBase::HeaderData, section, orientation, role);
}
/*!
@@ -629,7 +675,8 @@ QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int r
*/
QVariant QRangeModel::data(const QModelIndex &index, int role) const
{
- return impl->callConst<QVariant>(QRangeModelImplBase::Data, index, role);
+ Q_D(const QRangeModel);
+ return d->call<QVariant>(QRangeModelImplBase::Data, index, role);
}
/*!
@@ -654,7 +701,8 @@ QVariant QRangeModel::data(const QModelIndex &index, int role) const
*/
bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int role)
{
- return impl->call<bool>(QRangeModelImplBase::SetData, index, data, role);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::SetData, index, data, role);
}
/*!
@@ -677,7 +725,8 @@ bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int ro
*/
QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
{
- return impl->callConst<QMap<int, QVariant>>(QRangeModelImplBase::ItemData, index);
+ Q_D(const QRangeModel);
+ return d->call<QMap<int, QVariant>>(QRangeModelImplBase::ItemData, index);
}
/*!
@@ -708,7 +757,8 @@ QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
*/
bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &data)
{
- return impl->call<bool>(QRangeModelImplBase::SetItemData, index, data);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::SetItemData, index, data);
}
/*!
@@ -721,7 +771,8 @@ bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
*/
bool QRangeModel::clearItemData(const QModelIndex &index)
{
- return impl->call<bool>(QRangeModelImplBase::ClearItemData, index);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::ClearItemData, index);
}
/*
@@ -746,7 +797,8 @@ bool QRangeModel::clearItemData(const QModelIndex &index)
*/
bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent)
{
- return impl->call<bool>(QRangeModelImplBase::InsertColumns, column, count, parent);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::InsertColumns, column, count, parent);
}
/*!
@@ -760,7 +812,8 @@ bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent
*/
bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent)
{
- return impl->call<bool>(QRangeModelImplBase::RemoveColumns, column, count, parent);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::RemoveColumns, column, count, parent);
}
/*!
@@ -775,9 +828,10 @@ bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent
bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count,
const QModelIndex &destinationParent, int destinationColumn)
{
- return impl->call<bool>(QRangeModelImplBase::MoveColumns,
- sourceParent, sourceColumn, count,
- destinationParent, destinationColumn);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::MoveColumns,
+ sourceParent, sourceColumn, count,
+ destinationParent, destinationColumn);
}
/*
@@ -804,7 +858,8 @@ bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn,
*/
bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent)
{
- return impl->call<bool>(QRangeModelImplBase::InsertRows, row, count, parent);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::InsertRows, row, count, parent);
}
/*!
@@ -817,7 +872,8 @@ bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent)
*/
bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent)
{
- return impl->call<bool>(QRangeModelImplBase::RemoveRows, row, count, parent);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::RemoveRows, row, count, parent);
}
/*!
@@ -832,9 +888,10 @@ bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent)
bool QRangeModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
const QModelIndex &destinationParent, int destinationRow)
{
- return impl->call<bool>(QRangeModelImplBase::MoveRows,
- sourceParent, sourceRow, count,
- destinationParent, destinationRow);
+ Q_D(QRangeModel);
+ return d->call<bool>(QRangeModelImplBase::MoveRows,
+ sourceParent, sourceRow, count,
+ destinationParent, destinationRow);
}
/*!
diff --git a/src/corelib/itemmodels/qrangemodel.h b/src/corelib/itemmodels/qrangemodel.h
index 328966f26fd..0d9add5def3 100644
--- a/src/corelib/itemmodels/qrangemodel.h
+++ b/src/corelib/itemmodels/qrangemodel.h
@@ -9,6 +9,8 @@
QT_BEGIN_NAMESPACE
+class QRangeModelPrivate;
+
class Q_CORE_EXPORT QRangeModel : public QAbstractItemModel
{
Q_OBJECT
@@ -103,10 +105,10 @@ protected:
private:
Q_DISABLE_COPY_MOVE(QRangeModel)
+ Q_DECLARE_PRIVATE(QRangeModel)
+ explicit QRangeModel(QRangeModelImplBase *impl, QObject *parent);
friend class QRangeModelImplBase;
- struct Deleter { void operator()(QRangeModelImplBase *that) { that->destroy(); } };
- std::unique_ptr<QRangeModelImplBase, Deleter> impl;
};
// implementation of forwarders
@@ -193,21 +195,21 @@ const QAbstractItemModel &QRangeModelImplBase::itemModel() const
template <typename Range, QRangeModelDetails::if_table_range<Range>>
QRangeModel::QRangeModel(Range &&range, QObject *parent)
- : QAbstractItemModel(parent)
- , impl(new QGenericTableItemModelImpl<Range>(std::forward<Range>(range), this))
+ : QRangeModel(new QGenericTableItemModelImpl<Range>(std::forward<Range>(range), this), parent)
{}
template <typename Range, QRangeModelDetails::if_tree_range<Range>>
QRangeModel::QRangeModel(Range &&range, QObject *parent)
- : QRangeModel(std::forward<Range>(range),
- QRangeModelDetails::DefaultTreeProtocol<Range>{}, parent)
+ : QRangeModel(std::forward<Range>(range), QRangeModelDetails::DefaultTreeProtocol<Range>{},
+ parent)
{}
template <typename Range, typename Protocol, QRangeModelDetails::if_tree_range<Range, Protocol>>
QRangeModel::QRangeModel(Range &&range, Protocol &&protocol, QObject *parent)
- : QAbstractItemModel(parent)
- , impl(new QGenericTreeItemModelImpl<Range, Protocol>(std::forward<Range>(range),
- std::forward<Protocol>(protocol), this))
+ : QRangeModel(new QGenericTreeItemModelImpl<Range, Protocol>(std::forward<Range>(range),
+ std::forward<Protocol>(protocol),
+ this),
+ parent)
{}
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h
index 38378fdcc64..34c9ba235a6 100644
--- a/src/corelib/itemmodels/qrangemodel_impl.h
+++ b/src/corelib/itemmodels/qrangemodel_impl.h
@@ -604,7 +604,7 @@ public:
void destroy()
{
- call<bool>(Destroy);
+ call_fn(Destroy, this, nullptr, nullptr);
}
private:
@@ -615,6 +615,7 @@ private:
using CallConstFN = decltype(callConst);
using CallTupleFN = decltype(call);
+ friend class QRangeModelPrivate;
CallConstFN *callConst_fn;
CallTupleFN *call_fn;
QRangeModel *m_rangeModel;
@@ -647,25 +648,6 @@ protected:
inline void endMoveRows();
inline QAbstractItemModel &itemModel();
inline const QAbstractItemModel &itemModel() const;
-
-public:
- template <typename Ret, typename ...Args>
- Ret callConst(ConstOp op, const Args &...args) const
- {
- Ret ret = {};
- const auto tuple = std::tie(args...);
- callConst_fn(op, this, &ret, &tuple);
- return ret;
- }
-
- template <typename Ret, typename ...Args>
- Ret call(Op op, const Args &...args)
- {
- Ret ret = {};
- const auto tuple = std::tie(args...);
- call_fn(op, this, &ret, &tuple);
- return ret;
- }
};
template <typename Structure, typename Range,
@@ -1357,7 +1339,7 @@ public:
bool removeRows(int row, int count, const QModelIndex &parent = {})
{
- if constexpr (Structure::canRemoveRows()) {
+ if constexpr (canRemoveRows()) {
const int prevRowCount = that().rowCount(parent);
if (row < 0 || row + count > prevRowCount)
return false;
@@ -1476,10 +1458,15 @@ protected:
// row elements.
return false;
} else {
- return Structure::canInsertRows();
+ return Structure::canInsertRowsImpl();
}
}
+ static constexpr bool canRemoveRows()
+ {
+ return Structure::canRemoveRowsImpl();
+ }
+
template <typename F>
bool writeAt(const QModelIndex &index, F&& writer)
{
@@ -1805,7 +1792,7 @@ protected:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
- static constexpr bool canInsertRows()
+ static constexpr bool canInsertRowsImpl()
{
// We must not insert rows if we cannot adjust the parents of the
// children of the following rows. We don't have to do that if the
@@ -1814,7 +1801,7 @@ protected:
&& Base::dynamicRows() && range_features::has_insert;
}
- static constexpr bool canRemoveRows()
+ static constexpr bool canRemoveRowsImpl()
{
// We must not remove rows if we cannot adjust the parents of the
// children of the following rows. We don't have to do that if the
@@ -2090,12 +2077,12 @@ protected:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren;
}
- static constexpr bool canInsertRows()
+ static constexpr bool canInsertRowsImpl()
{
return Base::dynamicRows() && range_features::has_insert;
}
- static constexpr bool canRemoveRows()
+ static constexpr bool canRemoveRowsImpl()
{
return Base::dynamicRows() && range_features::has_erase;
}
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index 428ce62984f..62741150144 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -137,9 +137,9 @@ QString QSystemError::windowsString(int errorCode)
QString QSystemError::windowsComString(HRESULT hr)
{
const _com_error comError(hr);
- QString result = "COM error 0x"_L1 + QString::number(ulong(hr), 16);
+ QString result = u"COM error 0x"_s + QString::number(ulong(hr), 16);
if (const wchar_t *msg = comError.ErrorMessage())
- result += ": "_L1 + QString::fromWCharArray(msg);
+ result += u": "_s + QString::fromWCharArray(msg);
return result;
}
diff --git a/src/corelib/platform/windows/qcomobject_p.h b/src/corelib/platform/windows/qcomobject_p.h
index bbf7796445d..bd6f81d1c28 100644
--- a/src/corelib/platform/windows/qcomobject_p.h
+++ b/src/corelib/platform/windows/qcomobject_p.h
@@ -80,18 +80,21 @@ public:
return tryQueryInterface<TFirstInterface, TAdditionalInterfaces...>(riid, ppvObject);
}
- // clang-format off
STDMETHODIMP_(ULONG) AddRef() override
{
- return ++m_referenceCount;
+ return m_referenceCount.fetch_add(1, std::memory_order_relaxed) + 1;
}
- // clang-format on
STDMETHODIMP_(ULONG) Release() override
{
- const LONG referenceCount = --m_referenceCount;
- if (referenceCount == 0)
+ const LONG referenceCount = m_referenceCount.fetch_sub(1, std::memory_order_release) - 1;
+ if (referenceCount == 0) {
+ // This acquire fence synchronizes with the release operation in other threads.
+ // It ensures that all memory writes made to this object by other threads
+ // are visible to this thread before we proceed to delete it.
+ std::atomic_thread_fence(std::memory_order_acquire);
delete this;
+ }
return referenceCount;
}
@@ -103,6 +106,9 @@ protected:
// Derived class should make its destructor private to force this behavior.
virtual ~QComObject() = default;
+ // allow derived classes to access the reference count
+ std::atomic<LONG> m_referenceCount = 1;
+
private:
template <typename TInterface, typename... TRest>
HRESULT tryQueryInterface(REFIID riid, void **ppvObject)
@@ -121,8 +127,6 @@ private:
return E_NOINTERFACE;
}
-
- std::atomic<LONG> m_referenceCount = 1;
};
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index 5e0eff698f9..c357d40c8f5 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -711,7 +711,7 @@ void QTextStreamPrivate::write(const QChar *data, qsizetype len)
/*!
\internal
*/
-inline void QTextStreamPrivate::write(QChar ch)
+void QTextStreamPrivate::write(QChar ch)
{
if (string) {
// ### What about seek()??
@@ -833,29 +833,29 @@ QTextStreamPrivate::PaddingResult QTextStreamPrivate::padding(qsizetype len) con
/*!
\internal
*/
-void QTextStreamPrivate::putString(const QChar *data, qsizetype len, bool number)
+template <typename StringView>
+void QTextStreamPrivate::putStringImpl(StringView data, bool number)
{
- if (Q_UNLIKELY(params.fieldWidth > len)) {
+ if (Q_UNLIKELY(params.fieldWidth > data.size())) {
// handle padding:
- const PaddingResult pad = padding(len);
+ const PaddingResult pad = padding(data.size());
if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
- const QChar sign = len > 0 ? data[0] : QChar();
+ const QChar sign = data.size() > 0 ? data.front() : QChar();
if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
// write the sign before the padding, then skip it later
- write(&sign, 1);
- ++data;
- --len;
+ write(sign);
+ data = data.sliced(1);
}
}
writePadding(pad.left);
- write(data, len);
+ write(data);
writePadding(pad.right);
} else {
- write(data, len);
+ write(data);
}
}
@@ -864,29 +864,20 @@ void QTextStreamPrivate::putString(const QChar *data, qsizetype len, bool number
*/
void QTextStreamPrivate::putString(QLatin1StringView data, bool number)
{
- if (Q_UNLIKELY(params.fieldWidth > data.size())) {
-
- // handle padding
-
- const PaddingResult pad = padding(data.size());
-
- if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
- const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar();
- if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
- // write the sign before the padding, then skip it later
- write(&sign, 1);
- data = QLatin1StringView(data.data() + 1, data.size() - 1);
- }
- }
+ putStringImpl(data, number);
+}
- writePadding(pad.left);
- write(data);
- writePadding(pad.right);
- } else {
- write(data);
- }
+/*!
+ \internal
+*/
+void QTextStreamPrivate::putString(QStringView data, bool number)
+{
+ putStringImpl(data, number);
}
+/*!
+ \internal
+*/
void QTextStreamPrivate::putString(QUtf8StringView data, bool number)
{
putString(data.toString(), number);
diff --git a/src/corelib/serialization/qtextstream_p.h b/src/corelib/serialization/qtextstream_p.h
index 7227c29c8fe..2da7fe8e9d5 100644
--- a/src/corelib/serialization/qtextstream_p.h
+++ b/src/corelib/serialization/qtextstream_p.h
@@ -145,15 +145,13 @@ public:
bool getReal(double *f);
inline void write(QStringView data) { write(data.begin(), data.size()); }
- inline void write(QChar ch);
+ void write(QChar ch);
void write(const QChar *data, qsizetype len);
void write(QLatin1StringView data);
void writePadding(qsizetype len);
- inline void putString(QStringView string, bool number = false)
- {
- putString(string.constData(), string.size(), number);
- }
- void putString(const QChar *data, qsizetype len, bool number = false);
+ void putString(QStringView string, bool number = false);
+ void putString(const QChar *data, qsizetype len, bool number = false)
+ { putString(QStringView{data, len}, number); }
void putString(QLatin1StringView data, bool number = false);
void putString(QUtf8StringView data, bool number = false);
inline void putChar(QChar ch);
@@ -168,6 +166,10 @@ public:
bool fillReadBuffer(qint64 maxBytes = -1);
void resetReadBuffer();
void flushWriteBuffer();
+
+private:
+ template <typename StringView>
+ void putStringImpl(StringView view, bool number);
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h
index 4740047356b..f2bcaf7065d 100644
--- a/src/corelib/tools/qduplicatetracker_p.h
+++ b/src/corelib/tools/qduplicatetracker_p.h
@@ -136,6 +136,12 @@ public:
set.clear();
#endif // __cpp_lib_memory_resource
}
+
+ using const_iterator = typename Set::const_iterator;
+ const_iterator begin() const { return set.cbegin(); }
+ const_iterator end() const { return set.cend(); }
+ const_iterator cbegin() const { return begin(); }
+ const_iterator cend() const { return end(); }
};
QT_END_NAMESPACE
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
index 36e7fab55d9..a87c07defcb 100644
--- a/src/dbus/dbus_minimal_p.h
+++ b/src/dbus/dbus_minimal_p.h
@@ -2,6 +2,7 @@
// Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: AFL-2.1 OR GPL-2.0-or-later
+// Qt-Security score:significant reason:default
#ifndef DBUS_MINIMAL_P_H
#define DBUS_MINIMAL_P_H
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index 78b7e049ef3..a3e3b202c12 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp
index df83cc6f462..b9c87797846 100644
--- a/src/dbus/qdbusabstractadaptor.cpp
+++ b/src/dbus/qdbusabstractadaptor.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusabstractadaptor.h"
#include "qdbusabstractadaptor_p.h"
diff --git a/src/dbus/qdbusabstractadaptor.h b/src/dbus/qdbusabstractadaptor.h
index f143056b43a..649dc4622d0 100644
--- a/src/dbus/qdbusabstractadaptor.h
+++ b/src/dbus/qdbusabstractadaptor.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSABSTRACTADAPTOR_H
#define QDBUSABSTRACTADAPTOR_H
diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h
index c047af18211..51dc727b2fb 100644
--- a/src/dbus/qdbusabstractadaptor_p.h
+++ b/src/dbus/qdbusabstractadaptor_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index 0c6dbf1b3b7..4e46fc8f743 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusabstractinterface.h"
#include "qdbusabstractinterface_p.h"
diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h
index 8d36fb37281..2bdbdc419db 100644
--- a/src/dbus/qdbusabstractinterface.h
+++ b/src/dbus/qdbusabstractinterface.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSABSTRACTINTERFACE_H
#define QDBUSABSTRACTINTERFACE_H
diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h
index 1bd5e96f2d4..aca8ed23253 100644
--- a/src/dbus/qdbusabstractinterface_p.h
+++ b/src/dbus/qdbusabstractinterface_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h
index 8370de74bb6..b79f675a9e4 100644
--- a/src/dbus/qdbusargument.h
+++ b/src/dbus/qdbusargument.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSARGUMENT_H
#define QDBUSARGUMENT_H
@@ -15,6 +16,8 @@
#include <QtCore/qvariant.h>
#include <QtDBus/qdbusextratypes.h>
+#include <tuple>
+
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
@@ -117,6 +120,27 @@ protected:
QDBusArgument(QDBusArgumentPrivate *d);
friend class QDBusArgumentPrivate;
mutable QDBusArgumentPrivate *d;
+
+private:
+ template <typename... T>
+ friend QDBusArgument &operator<<(QDBusArgument &argument, const std::tuple<T...> &tuple)
+ {
+ static_assert(sizeof...(T) != 0, "D-Bus doesn't allow empty structs");
+ argument.beginStructure();
+ std::apply([&argument](const auto &...elements) { (argument << ... << elements); }, tuple);
+ argument.endStructure();
+ return argument;
+ }
+
+ template <typename... T>
+ friend const QDBusArgument &operator>>(const QDBusArgument &argument, std::tuple<T...> &tuple)
+ {
+ static_assert(sizeof...(T) != 0, "D-Bus doesn't allow empty structs");
+ argument.beginStructure();
+ std::apply([&argument](auto &...elements) { (argument >> ... >> elements); }, tuple);
+ argument.endStructure();
+ return argument;
+ }
};
Q_DECLARE_SHARED(QDBusArgument)
@@ -321,26 +345,6 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, std::pair<T1, T
return arg;
}
-template <typename... T>
-QDBusArgument &operator<<(QDBusArgument &argument, const std::tuple<T...> &tuple)
-{
- static_assert(std::tuple_size_v<std::tuple<T...>> != 0, "D-Bus doesn't allow empty structs");
- argument.beginStructure();
- std::apply([&argument](const auto &...elements) { (argument << ... << elements); }, tuple);
- argument.endStructure();
- return argument;
-}
-
-template <typename... T>
-const QDBusArgument &operator>>(const QDBusArgument &argument, std::tuple<T...> &tuple)
-{
- static_assert(std::tuple_size_v<std::tuple<T...>> != 0, "D-Bus doesn't allow empty structs");
- argument.beginStructure();
- std::apply([&argument](auto &...elements) { (argument >> ... >> elements); }, tuple);
- argument.endStructure();
- return argument;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h
index d9a73827424..3d007ea2c7c 100644
--- a/src/dbus/qdbusargument_p.h
+++ b/src/dbus/qdbusargument_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSARGUMENT_P_H
#define QDBUSARGUMENT_P_H
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 08cec30afa3..aa2ba432fa5 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusconnection.h"
#include "qdbusconnection_p.h"
diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h
index be8acdc4ea5..45d3850faed 100644
--- a/src/dbus/qdbusconnection.h
+++ b/src/dbus/qdbusconnection.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSCONNECTION_H
#define QDBUSCONNECTION_H
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 5cb175c1cdc..b553cd62a03 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp
index f7dbbb01563..36636b355b0 100644
--- a/src/dbus/qdbusconnectioninterface.cpp
+++ b/src/dbus/qdbusconnectioninterface.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusconnectioninterface.h"
diff --git a/src/dbus/qdbusconnectioninterface.h b/src/dbus/qdbusconnectioninterface.h
index e728539a385..60742ea4043 100644
--- a/src/dbus/qdbusconnectioninterface.h
+++ b/src/dbus/qdbusconnectioninterface.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSCONNECTIONINTERFACE_H
#define QDBUSCONNECTIONINTERFACE_H
diff --git a/src/dbus/qdbusconnectionmanager.cpp b/src/dbus/qdbusconnectionmanager.cpp
index 73f11d82280..ef96231e1cc 100644
--- a/src/dbus/qdbusconnectionmanager.cpp
+++ b/src/dbus/qdbusconnectionmanager.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusconnectionmanager_p.h"
@@ -32,8 +33,8 @@ QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::B
return nullptr;
// we'll start in suspended delivery mode if we're in the main thread
- // (the event loop will resume delivery)
- bool suspendedDelivery = QThread::isMainThread();
+ // (the event loop will resume delivery) and QCoreApplication already exists
+ bool suspendedDelivery = QThread::isMainThread() && qApp;
const auto locker = qt_scoped_lock(defaultBusMutex);
if (defaultBuses[type])
diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h
index 644c3c8fb1c..1ef048e5d72 100644
--- a/src/dbus/qdbusconnectionmanager_p.h
+++ b/src/dbus/qdbusconnectionmanager_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbuscontext.cpp b/src/dbus/qdbuscontext.cpp
index b8cb1dc8b10..f788b398186 100644
--- a/src/dbus/qdbuscontext.cpp
+++ b/src/dbus/qdbuscontext.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusmessage.h"
#include "qdbusconnection.h"
diff --git a/src/dbus/qdbuscontext.h b/src/dbus/qdbuscontext.h
index 02620449e18..47ced171171 100644
--- a/src/dbus/qdbuscontext.h
+++ b/src/dbus/qdbuscontext.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSCONTEXT_H
#define QDBUSCONTEXT_H
diff --git a/src/dbus/qdbuscontext_p.h b/src/dbus/qdbuscontext_p.h
index 1a544b8e44e..edd7aa068f0 100644
--- a/src/dbus/qdbuscontext_p.h
+++ b/src/dbus/qdbuscontext_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp
index 0a5ba30d3a3..c168d8d471c 100644
--- a/src/dbus/qdbuserror.cpp
+++ b/src/dbus/qdbuserror.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbuserror.h"
diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h
index 292f967acbe..dcb0c6666a0 100644
--- a/src/dbus/qdbuserror.h
+++ b/src/dbus/qdbuserror.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSERROR_H
#define QDBUSERROR_H
diff --git a/src/dbus/qdbusextratypes.cpp b/src/dbus/qdbusextratypes.cpp
index 042014ceab0..c27c1cbd5db 100644
--- a/src/dbus/qdbusextratypes.cpp
+++ b/src/dbus/qdbusextratypes.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusextratypes.h"
#include "qdbusutil_p.h"
diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h
index 3b44bfc2175..3bfd38486a2 100644
--- a/src/dbus/qdbusextratypes.h
+++ b/src/dbus/qdbusextratypes.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSEXTRATYPES_H
#define QDBUSEXTRATYPES_H
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 4c9736dea6d..bfd3a092d39 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusintegrator_p.h"
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index ac9adf02100..f6486d87256 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp
index d4da36b35c4..7481229dccf 100644
--- a/src/dbus/qdbusinterface.cpp
+++ b/src/dbus/qdbusinterface.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusinterface.h"
#include "qdbusinterface_p.h"
diff --git a/src/dbus/qdbusinterface.h b/src/dbus/qdbusinterface.h
index fc02463ac72..bff0336fd82 100644
--- a/src/dbus/qdbusinterface.h
+++ b/src/dbus/qdbusinterface.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSINTERFACE_H
#define QDBUSINTERFACE_H
diff --git a/src/dbus/qdbusinterface_p.h b/src/dbus/qdbusinterface_p.h
index caf24e589d4..63b7196527f 100644
--- a/src/dbus/qdbusinterface_p.h
+++ b/src/dbus/qdbusinterface_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp
index 721564ed3cd..a46bc8e6c87 100644
--- a/src/dbus/qdbusinternalfilters.cpp
+++ b/src/dbus/qdbusinternalfilters.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusconnection_p.h"
diff --git a/src/dbus/qdbusintrospection.cpp b/src/dbus/qdbusintrospection.cpp
index 04b5ab77519..4f6c40743a5 100644
--- a/src/dbus/qdbusintrospection.cpp
+++ b/src/dbus/qdbusintrospection.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusintrospection_p.h"
#include "qdbusxmlparser_p.h"
diff --git a/src/dbus/qdbusintrospection_p.h b/src/dbus/qdbusintrospection_p.h
index 766cdffb621..3eccef8b7b0 100644
--- a/src/dbus/qdbusintrospection_p.h
+++ b/src/dbus/qdbusintrospection_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSINTROSPECTION_P_H
#define QDBUSINTROSPECTION_P_H
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index b10266ac8b7..f0a056e3127 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusmessage.h"
#include "qdbusmessage_p.h"
diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h
index 608b9779d22..5b631c2b847 100644
--- a/src/dbus/qdbusmessage.h
+++ b/src/dbus/qdbusmessage.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSMESSAGE_H
#define QDBUSMESSAGE_H
diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h
index 88ba78025e7..07cdeda4034 100644
--- a/src/dbus/qdbusmessage_p.h
+++ b/src/dbus/qdbusmessage_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSMESSAGE_P_H
#define QDBUSMESSAGE_P_H
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index c3590dc51cd..149392f9c3c 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusmetaobject_p.h"
diff --git a/src/dbus/qdbusmetaobject_p.h b/src/dbus/qdbusmetaobject_p.h
index 97d16d99d0e..473765a175c 100644
--- a/src/dbus/qdbusmetaobject_p.h
+++ b/src/dbus/qdbusmetaobject_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSMETAOBJECT_P_H
#define QDBUSMETAOBJECT_P_H
diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp
index 3ae7589480e..5a862528026 100644
--- a/src/dbus/qdbusmetatype.cpp
+++ b/src/dbus/qdbusmetatype.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qdbusmetatype.h"
#include "qdbusmetatype_p.h"
diff --git a/src/dbus/qdbusmetatype.h b/src/dbus/qdbusmetatype.h
index 3304a69e1ef..66b6b1b0456 100644
--- a/src/dbus/qdbusmetatype.h
+++ b/src/dbus/qdbusmetatype.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSMETATYPE_H
#define QDBUSMETATYPE_H
diff --git a/src/dbus/qdbusmetatype_p.h b/src/dbus/qdbusmetatype_p.h
index 86a59f587dd..b72c0c431e5 100644
--- a/src/dbus/qdbusmetatype_p.h
+++ b/src/dbus/qdbusmetatype_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSMETATYPE_P_H
#define QDBUSMETATYPE_P_H
diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp
index 635258c86d2..bf18b00d1cc 100644
--- a/src/dbus/qdbusmisc.cpp
+++ b/src/dbus/qdbusmisc.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include <string.h>
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index cd222c9ffa5..c0b382ca114 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbuspendingcall.h"
#include "qdbuspendingcall_p.h"
@@ -228,7 +229,7 @@ void QDBusPendingCallPrivate::waitForFinishedWithGui()
/*!
\fn QDBusPendingCall::QDBusPendingCall(QDBusPendingCall &&other)
- \since 6.11
+ \since 6.10
Moves \a other into this object.
diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h
index 0db6667e5ec..1907fab78b9 100644
--- a/src/dbus/qdbuspendingcall.h
+++ b/src/dbus/qdbuspendingcall.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSPENDINGCALL_H
#define QDBUSPENDINGCALL_H
diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h
index 2795cc3ecf8..407537c9bb0 100644
--- a/src/dbus/qdbuspendingcall_p.h
+++ b/src/dbus/qdbuspendingcall_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
//
// W A R N I N G
diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp
index 7bb23aa3e36..b0fb2d75af5 100644
--- a/src/dbus/qdbuspendingreply.cpp
+++ b/src/dbus/qdbuspendingreply.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbuspendingreply.h"
#include "qdbuspendingcall_p.h"
diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h
index 72e1bbdc313..7b76bcd1b7c 100644
--- a/src/dbus/qdbuspendingreply.h
+++ b/src/dbus/qdbuspendingreply.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSPENDINGREPLY_H
#define QDBUSPENDINGREPLY_H
diff --git a/src/dbus/qdbusreply.cpp b/src/dbus/qdbusreply.cpp
index 5b26250b10d..a90e7354ed2 100644
--- a/src/dbus/qdbusreply.cpp
+++ b/src/dbus/qdbusreply.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusreply.h"
#include "qdbusmetatype.h"
diff --git a/src/dbus/qdbusreply.h b/src/dbus/qdbusreply.h
index df488208c85..5dfb63f3b4b 100644
--- a/src/dbus/qdbusreply.h
+++ b/src/dbus/qdbusreply.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSREPLY_H
#define QDBUSREPLY_H
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index e9131a14c4b..9e1063424a5 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusserver.h"
#include "qdbusconnection_p.h"
diff --git a/src/dbus/qdbusserver.h b/src/dbus/qdbusserver.h
index 34985cc0554..04b7930d412 100644
--- a/src/dbus/qdbusserver.h
+++ b/src/dbus/qdbusserver.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSSERVER_H
#define QDBUSSERVER_H
diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp
index bf94f54f564..6b9675c19ec 100644
--- a/src/dbus/qdbusservicewatcher.cpp
+++ b/src/dbus/qdbusservicewatcher.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusservicewatcher.h"
#include "qdbusconnection.h"
diff --git a/src/dbus/qdbusservicewatcher.h b/src/dbus/qdbusservicewatcher.h
index 71c63084b18..d07ae0fe5d2 100644
--- a/src/dbus/qdbusservicewatcher.h
+++ b/src/dbus/qdbusservicewatcher.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSSERVICEWATCHER_H
#define QDBUSSERVICEWATCHER_H
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index bcbd1efb494..70fbf762d19 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSTHREADDEBUG_P_H
#define QDBUSTHREADDEBUG_P_H
diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp
index 365f6cbc76c..bc38d142b95 100644
--- a/src/dbus/qdbusunixfiledescriptor.cpp
+++ b/src/dbus/qdbusunixfiledescriptor.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusunixfiledescriptor.h"
diff --git a/src/dbus/qdbusunixfiledescriptor.h b/src/dbus/qdbusunixfiledescriptor.h
index cbcd8b53a95..c946ec1761b 100644
--- a/src/dbus/qdbusunixfiledescriptor.h
+++ b/src/dbus/qdbusunixfiledescriptor.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSUNIXFILEDESCRIPTOR_H
diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp
index 84ce5ed78dc..9c1c7e8edf3 100644
--- a/src/dbus/qdbusutil.cpp
+++ b/src/dbus/qdbusutil.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qdbusutil_p.h"
diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h
index 3db93849682..580a2b92c96 100644
--- a/src/dbus/qdbusutil_p.h
+++ b/src/dbus/qdbusutil_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
//
// W A R N I N G
diff --git a/src/dbus/qdbusvirtualobject.cpp b/src/dbus/qdbusvirtualobject.cpp
index 2e5df125d25..878152ad32d 100644
--- a/src/dbus/qdbusvirtualobject.cpp
+++ b/src/dbus/qdbusvirtualobject.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include "qdbusvirtualobject.h"
diff --git a/src/dbus/qdbusvirtualobject.h b/src/dbus/qdbusvirtualobject.h
index 573d731d201..451b0040069 100644
--- a/src/dbus/qdbusvirtualobject.h
+++ b/src/dbus/qdbusvirtualobject.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSVIRTUALOBJECT_H
#define QDBUSVIRTUALOBJECT_H
diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp
index 412ac180951..69d27a49f9f 100644
--- a/src/dbus/qdbusxmlgenerator.cpp
+++ b/src/dbus/qdbusxmlgenerator.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp
index c2e8df8be7e..b3e1b6b78b6 100644
--- a/src/dbus/qdbusxmlparser.cpp
+++ b/src/dbus/qdbusxmlparser.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qdbusxmlparser_p.h"
#include "qdbusutil_p.h"
diff --git a/src/dbus/qdbusxmlparser_p.h b/src/dbus/qdbusxmlparser_p.h
index 0476ba36281..6cee2da76cc 100644
--- a/src/dbus/qdbusxmlparser_p.h
+++ b/src/dbus/qdbusxmlparser_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QDBUSXMLPARSER_P_H
#define QDBUSXMLPARSER_P_H
diff --git a/src/dbus/qtdbusglobal.h b/src/dbus/qtdbusglobal.h
index 9724c066f6a..07cfa16a258 100644
--- a/src/dbus/qtdbusglobal.h
+++ b/src/dbus/qtdbusglobal.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QTDBUSGLOBAL_H
#define QTDBUSGLOBAL_H
diff --git a/src/dbus/qtdbusglobal_p.h b/src/dbus/qtdbusglobal_p.h
index 9d315de75c8..6e748c20ae3 100644
--- a/src/dbus/qtdbusglobal_p.h
+++ b/src/dbus/qtdbusglobal_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
#ifndef QTDBUSGLOBAL_P_H
#define QTDBUSGLOBAL_P_H
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 59c469ae6b6..b53e1a63870 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -552,7 +552,7 @@ void QSurfaceFormat::setAlphaBufferSize(int size)
and used choice is the former (16-bit), for example when high dynamic range
rendering is desired.
- \since 6.10
+ \since 6.11
\sa colorComponentType()
*/
@@ -567,7 +567,7 @@ void QSurfaceFormat::setColorComponentType(ColorComponentType type)
/*!
\return the color component type.
- \since 6.10
+ \since 6.11
\sa setColorComponentType()
*/
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 1703fa5b0fe..1e0f9295110 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -4,6 +4,8 @@
#include "qmatrix4x4.h"
#include <QtCore/qmath.h>
#include <QtCore/qvariant.h>
+
+#include <QtGui/qquaternion.h>
#include <QtGui/qtransform.h>
#include <cmath>
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index 80ba62ca36f..2ba274d4517 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -7,7 +7,6 @@
#include <QtGui/qtguiglobal.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
-#include <QtGui/qquaternion.h>
#include <QtGui/qgenericmatrix.h>
#include <QtCore/qrect.h>
@@ -15,6 +14,9 @@ class tst_QMatrixNxN;
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_QUATERNION
+class QQuaternion;
+#endif
#ifndef QT_NO_MATRIX4X4
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index b13b1bcad34..a6e540015d7 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -36,6 +36,8 @@
QT_BEGIN_NAMESPACE
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPainterPathPrivate)
+
static inline bool isValidCoord(qreal c)
{
if (sizeof(qreal) >= sizeof(double))
@@ -512,6 +514,15 @@ QPainterPath::QPainterPath() noexcept
QPainterPath::QPainterPath(const QPainterPath &other) = default;
/*!
+ \fn QPainterPath::QPainterPath(QPainterPath &&other)
+ \since 6.10
+
+ Move-constructs a new painter path from \a other.
+
+ The moved-from object \a other is placed in the default-constructed state.
+*/
+
+/*!
Creates a QPainterPath object with the given \a startPoint as its
current position.
*/
@@ -3193,9 +3204,10 @@ qreal QPainterPath::slopeAtPercent(qreal t) const
/*!
\since 6.10
- Returns the section of the path between the length fractions \a f1 and \a f2. The effective range
- of the fractions are from 0, denoting the start point of the path, to 1, denoting its end point.
- The fractions are linear with respect to path length, in contrast to the percentage \e t values.
+ Returns the section of the path between the length fractions \a fromFraction and \a toFraction.
+ The effective range of the fractions are from 0, denoting the start point of the path, to 1,
+ denoting its end point. The fractions are linear with respect to path length, in contrast to the
+ percentage \e t values.
The value of \a offset will be added to the fraction values. If that causes an over- or underflow
of the [0, 1] range, the values will be wrapped around, as will the resulting path. The effective
@@ -3206,13 +3218,13 @@ qreal QPainterPath::slopeAtPercent(qreal t) const
\sa length(), percentAtLength(), setCachingEnabled()
*/
-QPainterPath QPainterPath::trimmed(qreal f1, qreal f2, qreal offset) const
+QPainterPath QPainterPath::trimmed(qreal fromFraction, qreal toFraction, qreal offset) const
{
if (isEmpty())
return *this;
- f1 = qBound(qreal(0), f1, qreal(1));
- f2 = qBound(qreal(0), f2, qreal(1));
+ qreal f1 = qBound(qreal(0), fromFraction, qreal(1));
+ qreal f2 = qBound(qreal(0), toFraction, qreal(1));
if (f1 > f2)
qSwap(f1, f2);
if (qFuzzyCompare(f2 - f1, qreal(1))) // Shortcut for no trimming
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 2d502936dfd..2e449a8835e 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -17,7 +17,6 @@ QT_BEGIN_NAMESPACE
class QFont;
class QPainterPathPrivate;
-struct QPainterPathPrivateDeleter;
class QPainterPathStrokerPrivate;
class QPen;
class QPolygonF;
@@ -25,6 +24,7 @@ class QRegion;
class QTransform;
class QVectorPath;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR(QPainterPathPrivate)
class Q_GUI_EXPORT QPainterPath
{
public:
@@ -56,6 +56,7 @@ public:
explicit QPainterPath(const QPointF &startPoint);
QPainterPath(const QPainterPath &other);
QPainterPath &operator=(const QPainterPath &other);
+ QPainterPath(QPainterPath &&other) noexcept = default;
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QPainterPath)
~QPainterPath();
@@ -141,7 +142,7 @@ public:
QPointF pointAtPercent(qreal t) const;
qreal angleAtPercent(qreal t) const;
qreal slopeAtPercent(qreal t) const;
- [[nodiscard]] QPainterPath trimmed(qreal f1, qreal f2, qreal offset = 0) const;
+ [[nodiscard]] QPainterPath trimmed(qreal fromFraction, qreal toFraction, qreal offset = 0) const;
bool intersects(const QPainterPath &p) const;
bool contains(const QPainterPath &p) const;
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index de8aedb5be4..aaa22355cd8 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -100,7 +100,6 @@ public:
friend class QPainterPathStrokerPrivate;
friend class QTransform;
friend class QVectorPath;
- friend struct QPainterPathPrivateDeleter;
#ifndef QT_NO_DATASTREAM
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPainterPath &);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPainterPath &);
diff --git a/src/network/access/qhttp2connection.cpp b/src/network/access/qhttp2connection.cpp
index 6f8a318dae0..9b339a19a24 100644
--- a/src/network/access/qhttp2connection.cpp
+++ b/src/network/access/qhttp2connection.cpp
@@ -663,8 +663,10 @@ void QHttp2Stream::handleDATA(const Frame &inboundFrame)
{
QHttp2Connection *connection = getConnection();
- qCDebug(qHttp2ConnectionLog, "[%p] stream %u, received DATA frame with payload of %u bytes",
- connection, m_streamID, inboundFrame.payloadSize());
+ qCDebug(qHttp2ConnectionLog,
+ "[%p] stream %u, received DATA frame with payload of %u bytes, closing stream? %s",
+ connection, m_streamID, inboundFrame.payloadSize(),
+ inboundFrame.flags().testFlag(Http2::FrameFlag::END_STREAM) ? "yes" : "no");
// RFC 9113, 6.1: If a DATA frame is received whose stream is not in the "open" or "half-closed
// (local)" state, the recipient MUST respond with a stream error (Section 5.4.2) of type
@@ -1426,7 +1428,8 @@ void QHttp2Connection::handleHEADERS()
Q_ASSERT(inboundFrame.type() == FrameType::HEADERS);
const auto streamID = inboundFrame.streamID();
- qCDebug(qHttp2ConnectionLog, "[%p] Received HEADERS frame on stream %d", this, streamID);
+ qCDebug(qHttp2ConnectionLog, "[%p] Received HEADERS frame on stream %d, end stream? %s", this,
+ streamID, inboundFrame.flags().testFlag(Http2::FrameFlag::END_STREAM) ? "yes" : "no");
// RFC 9113, 6.2: If a HEADERS frame is received whose Stream Identifier field is 0x00, the
// recipient MUST respond with a connection error.
@@ -1849,6 +1852,10 @@ void QHttp2Connection::handleWINDOW_UPDATE()
void QHttp2Connection::handleCONTINUATION()
{
Q_ASSERT(inboundFrame.type() == FrameType::CONTINUATION);
+ auto streamID = inboundFrame.streamID();
+ qCDebug(qHttp2ConnectionLog,
+ "[%p] Received CONTINUATION frame on stream %d, end stream? %s", this, streamID,
+ inboundFrame.flags().testFlag(Http2::FrameFlag::END_STREAM) ? "yes" : "no");
if (continuedFrames.empty())
return connectionError(PROTOCOL_ERROR,
"CONTINUATION without a preceding HEADERS or PUSH_PROMISE");
diff --git a/src/network/kernel/qnetworkproxy_android.cpp b/src/network/kernel/qnetworkproxy_android.cpp
index d5b56bba865..2261572fea7 100644
--- a/src/network/kernel/qnetworkproxy_android.cpp
+++ b/src/network/kernel/qnetworkproxy_android.cpp
@@ -3,6 +3,7 @@
#include "qnetworkproxy.h"
+#include <QtCore/qapplicationstatic.h>
#include <QtCore/qcoreapplication_platform.h>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
@@ -21,7 +22,7 @@ public:
using namespace QNativeInterface;
using namespace QtJniTypes;
-Q_GLOBAL_STATIC(ProxyInfoObject, proxyInfoInstance)
+Q_APPLICATION_STATIC(ProxyInfoObject, proxyInfoInstance)
Q_DECLARE_JNI_CLASS(QtNetwork, "org/qtproject/qt/android/network/QtNetwork")
Q_DECLARE_JNI_CLASS(ProxyInfo, "android/net/ProxyInfo")
diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
index 6c02a73e7c8..7efe4d52d4c 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.cpp
+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2019 Volker Krause <[email protected]>
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:critical reason:file-handling
+// Qt-Security score:critical reason:data-parser
#include "androidcontentfileengine.h"
diff --git a/src/plugins/platforms/android/extract.cpp b/src/plugins/platforms/android/extract.cpp
index 48a2c4ecfaf..9160470e0cc 100644
--- a/src/plugins/platforms/android/extract.cpp
+++ b/src/plugins/platforms/android/extract.cpp
@@ -1,7 +1,6 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2014 BogDan Vatra <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:critical reason:data-serializing
#include <QtCore/QJniEnvironment>
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
index dc7f4583da8..909d8da8856 100644
--- a/src/plugins/platforms/wasm/qtloader.js
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -190,7 +190,8 @@ async function qtLoad(config)
const originalLocateFile = config.locateFile;
config.locateFile = filename => {
const originalLocatedFilename = originalLocateFile ? originalLocateFile(filename) : filename;
- if (originalLocatedFilename.startsWith('libQt6'))
+ if (originalLocatedFilename.startsWith(
+ 'libQt6')) // wasmqtdeploy rely on this behavior, update both in case of change
return `${config.qt.qtdir}/lib/${originalLocatedFilename}`;
return originalLocatedFilename;
}
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
index e5392f33cd7..44db371ca4d 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.cpp
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -48,10 +48,6 @@ static void commonCopyEvent(val event)
void QWasmClipboard::cut(val event)
{
- QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
- if (wasmInput && wasmInput->usingTextInput())
- return;
-
if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi()) {
// Send synthetic Ctrl+X to make the app cut data to Qt's clipboard
QWindowSystemInterface::handleKeyEvent(
@@ -63,10 +59,6 @@ void QWasmClipboard::cut(val event)
void QWasmClipboard::copy(val event)
{
- QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
- if (wasmInput && wasmInput->usingTextInput())
- return;
-
if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi()) {
// Send synthetic Ctrl+C to make the app copy data to Qt's clipboard
QWindowSystemInterface::handleKeyEvent(
@@ -77,10 +69,6 @@ void QWasmClipboard::copy(val event)
void QWasmClipboard::paste(val event)
{
- QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
- if (wasmInput && wasmInput->usingTextInput())
- return;
-
event.call<void>("preventDefault"); // prevent browser from handling drop event
QWasmIntegration::get()->getWasmClipboard()->sendClipboardData(event);
@@ -183,86 +171,42 @@ void QWasmClipboard::writeToClipboardApi()
{
Q_ASSERT(m_hasClipboardApi);
- // copy event
- // browser event handler detected ctrl c if clipboard API
- // or Qt call from keyboard event handler
-
- QMimeData *_mimes = mimeData(QClipboard::Clipboard);
- if (!_mimes)
+ QMimeData *mimeData = this->mimeData(QClipboard::Clipboard);
+ if (!mimeData)
return;
- emscripten::val clipboardWriteArray = emscripten::val::array();
- QByteArray ba;
-
- for (auto mimetype : _mimes->formats()) {
- // we need to treat binary and text differently, as the blob method below
- // fails for text mimetypes
- // ignore text types
-
- if (mimetype.contains("STRING", Qt::CaseSensitive) || mimetype.contains("TEXT", Qt::CaseSensitive))
- continue;
-
- if (_mimes->hasHtml()) { // prefer html over text
- ba = _mimes->html().toLocal8Bit();
- // force this mime
- mimetype = "text/html";
- } else if (mimetype.contains("text/plain")) {
- ba = _mimes->text().toLocal8Bit();
- } else if (mimetype.contains("image")) {
- QImage img = qvariant_cast<QImage>( _mimes->imageData());
+ // Support for plain text, html and images (png) are standardized,
+ // copy those to the clipboard data object.
+ emscripten::val clipboardData = emscripten::val::object();
+ for (const QString &mimetype: mimeData->formats()) {
+ if (mimetype == QLatin1String("text/plain")) {
+ emscripten::val text = mimeData->text().toEcmaString();
+ clipboardData.set(mimetype.toEcmaString(), text);
+ } else if (mimetype == QLatin1String("text/html")) {
+ emscripten::val html = mimeData->html().toEcmaString();
+ clipboardData.set(mimetype.toEcmaString(), html);
+ } else if (mimetype.contains(QLatin1String("image"))) {
+ // Serialize the Qt image data to browser supported png
+ QImage img = qvariant_cast<QImage>(mimeData->imageData());
+ QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG");
- mimetype = "image/png"; // chrome only allows png
- // clipboard error "NotAllowedError" "Type application/x-qt-image not supported on write."
- // safari silently fails
- // so we use png internally for now
- } else {
- // DATA
- ba = _mimes->data(mimetype);
- }
- // Create file data Blob
- const char *content = ba.data();
- int dataLength = ba.length();
- if (dataLength < 1) {
- qDebug() << "no content found";
- return;
+ qstdweb::Blob blob = qstdweb::Blob::fromArrayBuffer(qstdweb::Uint8Array::copyFrom(ba).buffer());
+ clipboardData.set(std::string("image/png"), blob.val());
}
-
- emscripten::val document = emscripten::val::global("document");
- emscripten::val window = emscripten::val::global("window");
-
- emscripten::val fileContentView =
- emscripten::val(emscripten::typed_memory_view(dataLength, content));
- emscripten::val fileContentCopy = emscripten::val::global("ArrayBuffer").new_(dataLength);
- emscripten::val fileContentCopyView =
- emscripten::val::global("Uint8Array").new_(fileContentCopy);
- fileContentCopyView.call<void>("set", fileContentView);
-
- emscripten::val contentArray = emscripten::val::array();
- contentArray.call<void>("push", fileContentCopyView);
-
- // we have a blob, now create a ClipboardItem
- emscripten::val type = emscripten::val::array();
- type.set("type", mimetype.toEcmaString());
-
- emscripten::val contentBlob = emscripten::val::global("Blob").new_(contentArray, type);
-
- emscripten::val clipboardItemObject = emscripten::val::object();
- clipboardItemObject.set(mimetype.toEcmaString(), contentBlob);
-
- val clipboardItemData = val::global("ClipboardItem").new_(clipboardItemObject);
-
- clipboardWriteArray.call<void>("push", clipboardItemData);
-
- // Clipboard write is only supported with one ClipboardItem at the moment
- // but somehow this still works?
- // break;
}
- val navigator = val::global("navigator");
+ // Return if there is no data (creating an empty ClipboardItem is an error)
+ if (val::global("Object").call<val>("keys", clipboardData)["length"].as<int>() == 0)
+ return;
+ // Write a single clipboard item containing the data formats to the clipboard
+ emscripten::val clipboardItem = val::global("ClipboardItem").new_(clipboardData);
+ emscripten::val clipboardItemArray = emscripten::val::array();
+ clipboardItemArray.call<void>("push", clipboardItem);
+ val navigator = val::global("navigator");
qstdweb::Promise::make(
navigator["clipboard"], "write",
{
@@ -272,7 +216,7 @@ void QWasmClipboard::writeToClipboardApi()
<< QString::fromStdString(error["message"].as<std::string>());
}
},
- clipboardWriteArray);
+ clipboardItemArray);
}
void QWasmClipboard::writeToClipboard()
diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp
index 2df7066b8e2..191e2947629 100644
--- a/src/plugins/platforms/wasm/qwasminputcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp
@@ -25,105 +25,88 @@ void QWasmInputContext::inputCallback(emscripten::val event)
{
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "isComposing : " << event["isComposing"].as<bool>();
- QString inputStr = (event["data"] != emscripten::val::null()
- && event["data"] != emscripten::val::undefined()) ?
- QString::fromStdString(event["data"].as<std::string>()) : QString();
-
- QWasmInputContext *wasmInput =
- reinterpret_cast<QWasmInputContext *>(event["target"]["data-qinputcontext"].as<quintptr>());
-
emscripten::val inputType = event["inputType"];
- if (inputType != emscripten::val::null()
- && inputType != emscripten::val::undefined()) {
- const auto inputTypeString = inputType.as<std::string>();
- // There are many inputTypes for InputEvent
- // https://www.w3.org/TR/input-events-1/
- // Some of them should be implemented here later.
- qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "inputType : " << inputTypeString;
- if (!inputTypeString.compare("deleteContentBackward")) {
- QWindowSystemInterface::handleKeyEvent(0,
- QEvent::KeyPress,
- Qt::Key_Backspace,
- Qt::NoModifier);
- QWindowSystemInterface::handleKeyEvent(0,
- QEvent::KeyRelease,
- Qt::Key_Backspace,
- Qt::NoModifier);
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("deleteContentForward")) {
- QWindowSystemInterface::handleKeyEvent(0,
- QEvent::KeyPress,
- Qt::Key_Delete,
- Qt::NoModifier);
- QWindowSystemInterface::handleKeyEvent(0,
- QEvent::KeyRelease,
- Qt::Key_Delete,
- Qt::NoModifier);
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("insertCompositionText")) {
- qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr;
- wasmInput->insertPreedit();
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("insertReplacementText")) {
- qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr;
- //auto ranges = event.call<emscripten::val>("getTargetRanges");
- //qCDebug(qLcQpaWasmInputContext) << ranges["length"].as<int>();
- // WA For Korean IME
- // insertReplacementText should have targetRanges but
- // Safari cannot have it and just it seems to be supposed
- // to replace previous input.
- wasmInput->insertText(inputStr, true);
-
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("deleteCompositionText")) {
- wasmInput->setPreeditString("", 0);
- wasmInput->insertPreedit();
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("insertFromComposition")) {
- wasmInput->setPreeditString(inputStr, 0);
- wasmInput->insertPreedit();
- event.call<void>("stopImmediatePropagation");
- return;
- } else if (!inputTypeString.compare("insertText")) {
- wasmInput->insertText(inputStr);
- event.call<void>("stopImmediatePropagation");
+ if (inputType.isNull() || inputType.isUndefined())
+ return;
+ const auto inputTypeString = inputType.as<std::string>();
+
+ emscripten::val inputData = event["data"];
+ QString inputStr = (!inputData.isNull() && !inputData.isUndefined())
+ ? QString::fromEcmaString(inputData) : QString();
+
+ // There are many inputTypes for InputEvent
+ // https://www.w3.org/TR/input-events-1/
+ // Some of them should be implemented here later.
+ qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "inputType : " << inputTypeString;
+ if (!inputTypeString.compare("deleteContentBackward")) {
+ QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
+ QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier);
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("deleteContentForward")) {
+ QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier);
+ QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, Qt::Key_Delete, Qt::NoModifier);
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("insertCompositionText")) {
+ qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr;
+ insertPreedit();
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("insertReplacementText")) {
+ qCDebug(qLcQpaWasmInputContext) << "inputString : " << inputStr;
+ //auto ranges = event.call<emscripten::val>("getTargetRanges");
+ //qCDebug(qLcQpaWasmInputContext) << ranges["length"].as<int>();
+ // WA For Korean IME
+ // insertReplacementText should have targetRanges but
+ // Safari cannot have it and just it seems to be supposed
+ // to replace previous input.
+ insertText(inputStr, true);
+
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("deleteCompositionText")) {
+ setPreeditString("", 0);
+ insertPreedit();
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("insertFromComposition")) {
+ setPreeditString(inputStr, 0);
+ insertPreedit();
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (!inputTypeString.compare("insertText")) {
+ insertText(inputStr);
+ event.call<void>("stopImmediatePropagation");
#if QT_CONFIG(clipboard)
- } else if (!inputTypeString.compare("insertFromPaste")) {
- wasmInput->insertText(QGuiApplication::clipboard()->text());
- event.call<void>("stopImmediatePropagation");
- // These can be supported here,
- // But now, keyCallback in QWasmWindow
- // will take them as exceptions.
- //} else if (!inputTypeString.compare("deleteByCut")) {
+ } else if (!inputTypeString.compare("insertFromPaste")) {
+ insertText(QGuiApplication::clipboard()->text());
+ event.call<void>("stopImmediatePropagation");
+ // These can be supported here,
+ // But now, keyCallback in QWasmWindow
+ // will take them as exceptions.
+ //} else if (!inputTypeString.compare("deleteByCut")) {
#endif
- } else {
- qCWarning(qLcQpaWasmInputContext) << Q_FUNC_INFO << "inputType \"" << inputType.as<std::string>() << "\" is not supported in Qt yet";
- }
+ } else {
+ qCWarning(qLcQpaWasmInputContext) << Q_FUNC_INFO << "inputType \"" <<
+ inputType.as<std::string>() << "\" is not supported in Qt yet";
}
}
void QWasmInputContext::compositionEndCallback(emscripten::val event)
{
- const auto inputStr = QString::fromStdString(event["data"].as<std::string>());
+ const auto inputStr = QString::fromEcmaString(event["data"]);
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << inputStr;
- QWasmInputContext *wasmInput =
- reinterpret_cast<QWasmInputContext *>(event["target"]["data-qinputcontext"].as<quintptr>());
-
- if (wasmInput->preeditString().isEmpty())
+ if (preeditString().isEmpty())
return;
- if (inputStr != wasmInput->preeditString()) {
+ if (inputStr != preeditString()) {
qCWarning(qLcQpaWasmInputContext) << Q_FUNC_INFO
<< "Composition string" << inputStr
- << "is differ from" << wasmInput->preeditString();
+ << "is differ from" << preeditString();
}
- wasmInput->commitPreeditAndClear();
+ commitPreeditAndClear();
}
void QWasmInputContext::compositionStartCallback(emscripten::val event)
@@ -151,19 +134,15 @@ static void beforeInputCallback(emscripten::val event)
void QWasmInputContext::compositionUpdateCallback(emscripten::val event)
{
- const auto compositionStr = QString::fromStdString(event["data"].as<std::string>());
+ const auto compositionStr = QString::fromEcmaString(event["data"]);
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << compositionStr;
- QWasmInputContext *wasmInput =
- reinterpret_cast<QWasmInputContext *>(event["target"]["data-qinputcontext"].as<quintptr>());
-
// WA for IOS.
// Not sure now because I cannot test it anymore.
// int replaceSize = 0;
// emscripten::val win = emscripten::val::global("window");
// emscripten::val sel = win.call<emscripten::val>("getSelection");
-// if (sel != emscripten::val::null()
-// && sel != emscripten::val::undefined()
+// if (!sel.isNull() && !sel.isUndefined()
// && sel["rangeCount"].as<int>() > 0) {
// QInputMethodQueryEvent queryEvent(Qt::ImQueryAll);
// QCoreApplication::sendEvent(QGuiApplication::focusObject(), &queryEvent);
@@ -172,8 +151,8 @@ void QWasmInputContext::compositionUpdateCallback(emscripten::val event)
// qCDebug(qLcQpaWasmInputContext) << "Qt text before cursor: " << queryEvent.value(Qt::ImTextBeforeCursor).toString();
// qCDebug(qLcQpaWasmInputContext) << "Qt text after cursor: " << queryEvent.value(Qt::ImTextAfterCursor).toString();
//
-// const QString &selectedStr = QString::fromUtf8(sel.call<emscripten::val>("toString").as<std::string>());
-// const auto &preeditStr = wasmInput->preeditString();
+// const QString &selectedStr = QString::fromEcmaString(sel.call<emscripten::val>("toString"));
+// const auto &preeditStr = preeditString();
// qCDebug(qLcQpaWasmInputContext) << "Selection.type : " << sel["type"].as<std::string>();
// qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "Selected: " << selectedStr;
// qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "PreeditString: " << preeditStr;
@@ -189,90 +168,13 @@ void QWasmInputContext::compositionUpdateCallback(emscripten::val event)
// qCDebug(qLcQpaWasmInputContext) << "Range.endOffset : " << range["endOffset"].as<int>();
// }
//
-// wasmInput->setPreeditString(compositionStr, replaceSize);
- wasmInput->setPreeditString(compositionStr, 0);
-}
-
-#if QT_CONFIG(clipboard)
-static void copyCallback(emscripten::val event)
-{
- qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
-
- QClipboard *clipboard = QGuiApplication::clipboard();
- QString inputStr = clipboard->text();
- qCDebug(qLcQpaWasmInputContext) << "QClipboard : " << inputStr;
- event["clipboardData"].call<void>("setData",
- emscripten::val("text/plain"),
- inputStr.toStdString());
- event.call<void>("preventDefault");
- event.call<void>("stopImmediatePropagation");
-}
-
-static void cutCallback(emscripten::val event)
-{
- qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
-
- QClipboard *clipboard = QGuiApplication::clipboard();
- QString inputStr = clipboard->text();
- qCDebug(qLcQpaWasmInputContext) << "QClipboard : " << inputStr;
- event["clipboardData"].call<void>("setData",
- emscripten::val("text/plain"),
- inputStr.toStdString());
- event.call<void>("preventDefault");
- event.call<void>("stopImmediatePropagation");
+// setPreeditString(compositionStr, replaceSize);
+ setPreeditString(compositionStr, 0);
}
-static void pasteCallback(emscripten::val event)
-{
- qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
-
- emscripten::val clipboardData = event["clipboardData"].call<emscripten::val>("getData", emscripten::val("text/plain"));
- QString clipboardStr = QString::fromStdString(clipboardData.as<std::string>());
- qCDebug(qLcQpaWasmInputContext) << "wasm clipboard : " << clipboardStr;
- QClipboard *clipboard = QGuiApplication::clipboard();
- if (clipboard->text() != clipboardStr)
- clipboard->setText(clipboardStr);
-
- // propagate to input event (insertFromPaste)
-}
-#endif // QT_CONFIG(clipboard)
-
QWasmInputContext::QWasmInputContext()
{
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
- emscripten::val document = emscripten::val::global("document");
- // This 'input' can be an issue to handle multiple lines,
- // 'textarea' can be used instead.
- m_inputElement = document.call<emscripten::val>("createElement", std::string("input"));
- m_inputElement.set("type", "text");
- m_inputElement.set("contenteditable","true");
- m_inputElement.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
-
- m_inputElement["style"].set("position", "absolute");
- m_inputElement["style"].set("left", 0);
- m_inputElement["style"].set("top", 0);
- m_inputElement["style"].set("opacity", 0);
- m_inputElement["style"].set("display", "");
- m_inputElement["style"].set("z-index", -2);
- m_inputElement["style"].set("width", "1px");
- m_inputElement["style"].set("height", "1px");
-
- m_inputElement.set("data-qinputcontext",
- emscripten::val(quintptr(reinterpret_cast<void *>(this))));
- emscripten::val body = document["body"];
- body.call<void>("appendChild", m_inputElement);
-
- m_inputCallback = QWasmEventHandler(m_inputElement, "input", QWasmInputContext::inputCallback);
- m_compositionEndCallback = QWasmEventHandler(m_inputElement, "compositionend", QWasmInputContext::compositionEndCallback);
- m_compositionStartCallback = QWasmEventHandler(m_inputElement, "compositionstart", QWasmInputContext::compositionStartCallback);
- m_compositionUpdateCallback = QWasmEventHandler(m_inputElement, "compositionupdate", QWasmInputContext::compositionUpdateCallback);
-
-#if QT_CONFIG(clipboard)
- // Clipboard for InputContext
- m_clipboardCut = QWasmEventHandler(m_inputElement, "cut", cutCallback);
- m_clipboardCopy = QWasmEventHandler(m_inputElement, "copy", copyCallback);
- m_clipboardPaste = QWasmEventHandler(m_inputElement, "paste", pasteCallback);
-#endif
}
QWasmInputContext::~QWasmInputContext()
@@ -303,6 +205,9 @@ void QWasmInputContext::showInputPanel()
void QWasmInputContext::updateGeometry()
{
+ if (m_inputElement.isNull())
+ return;
+
const QWindow *focusWindow = QGuiApplication::focusWindow();
if (!m_focusObject || !focusWindow || !m_inputMethodAccepted) {
m_inputElement["style"].set("left", "0px");
@@ -312,23 +217,12 @@ void QWasmInputContext::updateGeometry()
Q_ASSERT(m_focusObject);
Q_ASSERT(m_inputMethodAccepted);
- // Set the geometry
- QPoint globalPos;
- const QRect cursorRectangle = QPlatformInputContext::cursorRectangle().toRect();
- if (cursorRectangle.isValid()) {
- qCDebug(qLcQpaWasmInputContext)
- << Q_FUNC_INFO << "cursorRectangle: " << cursorRectangle;
- globalPos = focusWindow->mapToGlobal(cursorRectangle.topLeft());
- if (globalPos.x() > 0)
- globalPos.setX(globalPos.x() - 1);
- if (globalPos.y() > 0)
- globalPos.setY(globalPos.y() - 1);
- }
-
- const auto styleLeft = std::to_string(globalPos.x()) + "px";
- const auto styleTop = std::to_string(globalPos.y()) + "px";
- m_inputElement["style"].set("left", styleLeft);
- m_inputElement["style"].set("top", styleTop);
+ const QRect inputItemRectangle = QPlatformInputContext::inputItemRectangle().toRect();
+ qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "propagating inputItemRectangle:" << inputItemRectangle;
+ m_inputElement["style"].set("left", std::to_string(inputItemRectangle.x()) + "px");
+ m_inputElement["style"].set("top", std::to_string(inputItemRectangle.y()) + "px");
+ m_inputElement["style"].set("width", std::to_string(inputItemRectangle.width()) + "px");
+ m_inputElement["style"].set("height", std::to_string(inputItemRectangle.height()) + "px");
}
}
@@ -341,16 +235,21 @@ void QWasmInputContext::updateInputElement()
updateGeometry();
// If there is no focus object, or no visible input panel, remove focus
- const QWindow *focusWindow = QGuiApplication::focusWindow();
+ QWasmWindow *focusWindow = QWasmWindow::fromWindow(QGuiApplication::focusWindow());
if (!m_focusObject || !focusWindow || !m_inputMethodAccepted) {
- m_inputElement.set("value", "");
+ if (!m_inputElement.isNull()) {
+ m_inputElement.set("value", "");
+ m_inputElement.set("inputMode", std::string("none"));
+ }
- if (QWasmWindow *wasmwindow = QWasmWindow::fromWindow(focusWindow))
- wasmwindow->focus();
- else
- m_inputElement.call<void>("blur");
+ if (focusWindow) {
+ focusWindow->focus();
+ } else {
+ if (!m_inputElement.isNull())
+ m_inputElement.call<void>("blur");
+ }
- m_inputElement.set("inputMode", std::string("none"));
+ m_inputElement = emscripten::val::null();
return;
}
@@ -358,6 +257,8 @@ void QWasmInputContext::updateInputElement()
Q_ASSERT(m_focusObject);
Q_ASSERT(m_inputMethodAccepted);
+ m_inputElement = focusWindow->inputElement();
+
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << QRectF::fromDOMRect(m_inputElement.call<emscripten::val>("getBoundingClientRect"));
// Set the text input
@@ -375,7 +276,15 @@ void QWasmInputContext::updateInputElement()
m_inputElement.set("selectionStart", queryEvent.value(Qt::ImAnchorPosition).toUInt());
m_inputElement.set("selectionEnd", queryEvent.value(Qt::ImCursorPosition).toUInt());
+ QInputMethodQueryEvent query((Qt::InputMethodQueries(Qt::ImHints)));
+ QCoreApplication::sendEvent(m_focusObject, &query);
+ if (Qt::InputMethodHints(query.value(Qt::ImHints).toInt()).testFlag(Qt::ImhHiddenText))
+ m_inputElement.set("type", "password");
+ else
+ m_inputElement.set("type", "text");
+
m_inputElement.set("inputMode", std::string("text"));
+
m_inputElement.call<void>("focus");
}
@@ -383,16 +292,6 @@ void QWasmInputContext::setFocusObject(QObject *object)
{
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << object << inputMethodAccepted();
- QInputMethodQueryEvent query(Qt::InputMethodQueries(Qt::ImEnabled | Qt::ImHints));
- QCoreApplication::sendEvent(object, &query);
- if (query.value(Qt::ImEnabled).toBool()
- && Qt::InputMethodHints(query.value(Qt::ImHints).toInt()).testFlag(Qt::ImhHiddenText)) {
- m_inputElement.set("type", "password");
- } else {
- if (m_inputElement["type"].as<std::string>() != std::string("text"))
- m_inputElement.set("type", "text");
- }
-
// Commit the previous composition before change m_focusObject
if (m_focusObject && !m_preeditString.isEmpty())
commitPreeditAndClear();
diff --git a/src/plugins/platforms/wasm/qwasminputcontext.h b/src/plugins/platforms/wasm/qwasminputcontext.h
index 72476adfe1b..6d24c7fea0d 100644
--- a/src/plugins/platforms/wasm/qwasminputcontext.h
+++ b/src/plugins/platforms/wasm/qwasminputcontext.h
@@ -35,38 +35,33 @@ public:
void setPreeditString(QString preeditStr, int replaceSize);
void insertPreedit();
void commitPreeditAndClear();
- emscripten::val m_inputElement = emscripten::val::null();
void insertText(QString inputStr, bool replace = false);
- QWasmEventHandler m_inputCallback;
- QWasmEventHandler m_compositionEndCallback;
- QWasmEventHandler m_compositionStartCallback;
- QWasmEventHandler m_compositionUpdateCallback;
-
bool usingTextInput() const { return m_inputMethodAccepted; }
void setFocusObject(QObject *object) override;
- static void inputCallback(emscripten::val event);
- static void compositionEndCallback(emscripten::val event);
- static void compositionStartCallback(emscripten::val event);
- static void compositionUpdateCallback(emscripten::val event);
+ void inputCallback(emscripten::val event);
+ void compositionEndCallback(emscripten::val event);
+ void compositionStartCallback(emscripten::val event);
+ void compositionUpdateCallback(emscripten::val event);
void updateGeometry();
+ bool isActive() const {
+ return m_focusObject && m_inputMethodAccepted;
+ }
+
private:
void updateInputElement();
private:
- QWasmEventHandler m_clipboardCut;
- QWasmEventHandler m_clipboardCopy;
- QWasmEventHandler m_clipboardPaste;
-
QString m_preeditString;
int m_replaceSize = 0;
bool m_inputMethodAccepted = false;
QObject *m_focusObject = nullptr;
+ emscripten::val m_inputElement = emscripten::val::null();
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index d690bcfe10a..d27385be723 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -51,7 +51,10 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
m_decoratedWindow(m_document.call<emscripten::val>("createElement", emscripten::val("div"))),
m_window(m_document.call<emscripten::val>("createElement", emscripten::val("div"))),
m_a11yContainer(m_document.call<emscripten::val>("createElement", emscripten::val("div"))),
- m_canvas(m_document.call<emscripten::val>("createElement", emscripten::val("canvas")))
+ m_canvas(m_document.call<emscripten::val>("createElement", emscripten::val("canvas"))),
+ m_focusHelper(m_document.call<emscripten::val>("createElement", emscripten::val("div"))),
+ m_inputElement(m_document.call<emscripten::val>("createElement", emscripten::val("input")))
+
{
m_decoratedWindow.set("className", "qt-decorated-window");
m_decoratedWindow["style"].set("display", std::string("none"));
@@ -80,17 +83,6 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
m_canvas["classList"].call<void>("add", emscripten::val("qt-window-canvas"));
- // Set contentEditable for two reasons;
- // 1) so that the window gets clipboard events,
- // 2) For applications who will handle keyboard events, but without having inputMethodAccepted()
- //
- // Set inputMode to none to avoid keyboard popping up on push buttons
- // This is a tradeoff, we are not able to separate between a push button and
- // a widget that reads keyboard events.
- m_canvas.call<void>("setAttribute", std::string("inputmode"), std::string("none"));
- m_canvas.call<void>("setAttribute", std::string("contenteditable"), std::string("true"));
- m_canvas["style"].set("outline", std::string("none"));
-
#if QT_CONFIG(clipboard)
if (QWasmClipboard::shouldInstallWindowEventHandlers()) {
m_cutCallback = QWasmEventHandler(m_canvas, "cut", QWasmClipboard::cut);
@@ -99,9 +91,37 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
}
#endif
- // Set inputMode to none to stop the mobile keyboard from opening
- // when the user clicks on the window.
- m_window.set("inputMode", std::string("none"));
+ // Set up m_focusHelper, which is an invisible child element of the window which takes
+ // focus on behalf of the window any time the window has focus in general, but none
+ // of the special child elements such as the inputElment or a11y elements have focus.
+ // Set inputMode=none set to prevent the virtual keyboard from popping up.
+ m_focusHelper["classList"].call<void>("add", emscripten::val("qt-window-focus-helper"));
+ m_focusHelper.set("inputMode", std::string("none"));
+ m_focusHelper.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
+ m_focusHelper.call<void>("setAttribute", std::string("contenteditable"), std::string("true"));
+ m_focusHelper["style"].set("position", "absolute");
+ m_focusHelper["style"].set("left", 0);
+ m_focusHelper["style"].set("top", 0);
+ m_focusHelper["style"].set("width", "1px");
+ m_focusHelper["style"].set("height", "1px");
+ m_focusHelper["style"].set("z-index", -2);
+ m_focusHelper["style"].set("opacity", 0);
+ m_window.call<void>("appendChild", m_focusHelper);
+
+ // Set up m_inputElement, which takes focus whenever a Qt text input UI element has
+ // foucus.
+ m_inputElement["classList"].call<void>("add", emscripten::val("qt-window-input-element"));
+ m_inputElement.set("type", "text");
+ m_inputElement.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
+ m_inputElement["style"].set("position", "absolute");
+ m_inputElement["style"].set("left", 0);
+ m_inputElement["style"].set("top", 0);
+ m_inputElement["style"].set("width", "1px");
+ m_inputElement["style"].set("height", "1px");
+ m_inputElement["style"].set("z-index", -2);
+ m_inputElement["style"].set("opacity", 0);
+ m_inputElement["style"].set("display", "");
+ m_window.call<void>("appendChild", m_inputElement);
// Hide the canvas from screen readers.
m_canvas.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
@@ -193,21 +213,20 @@ void QWasmWindow::registerEventHandlers()
m_wheelEventCallback = QWasmEventHandler(m_window, "wheel",
[this](emscripten::val event) { this->handleWheelEvent(event); });
- QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
- if (wasmInput) {
- m_keyDownCallbackForInputContext =
- QWasmEventHandler(wasmInput->m_inputElement, "keydown",
- [this](emscripten::val event) { this->handleKeyForInputContextEvent(EventType::KeyDown, event); });
- m_keyUpCallbackForInputContext =
- QWasmEventHandler(wasmInput->m_inputElement, "keyup",
- [this](emscripten::val event) { this->handleKeyForInputContextEvent(EventType::KeyUp, event); });
- }
-
- m_keyDownCallback = QWasmEventHandler(m_canvas, "keydown",
+ m_keyDownCallback = QWasmEventHandler(m_window, "keydown",
[this](emscripten::val event) { this->handleKeyEvent(KeyEvent(EventType::KeyDown, event, m_deadKeySupport)); });
- m_keyUpCallback =QWasmEventHandler(m_canvas, "keyup",
+ m_keyUpCallback =QWasmEventHandler(m_window, "keyup",
[this](emscripten::val event) {this->handleKeyEvent(KeyEvent(EventType::KeyUp, event, m_deadKeySupport)); });
-}
+
+ m_inputCallback = QWasmEventHandler(m_window, "input",
+ [this](emscripten::val event){ handleInputEvent(event); });
+ m_compositionUpdateCallback = QWasmEventHandler(m_window, "compositionupdate",
+ [this](emscripten::val event){ handleCompositionUpdateEvent(event); });
+ m_compositionStartCallback = QWasmEventHandler(m_window, "compositionstart",
+ [this](emscripten::val event){ handleCompositionStartEvent(event); });
+ m_compositionEndCallback = QWasmEventHandler(m_window, "compositionend",
+ [this](emscripten::val event){ handleCompositionEndEvent(event); });
+ }
QWasmWindow::~QWasmWindow()
{
@@ -624,10 +643,15 @@ void QWasmWindow::commitParent(QWasmWindowTreeNode *parent)
void QWasmWindow::handleKeyEvent(const KeyEvent &event)
{
- qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
- if (processKey(event)) {
- event.webEvent.call<void>("preventDefault");
- event.webEvent.call<void>("stopPropagation");
+ qCDebug(qLcQpaWasmInputContext) << "handleKeyEvent";
+
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive()) {
+ handleKeyForInputContextEvent(event);
+ } else {
+ if (processKey(event)) {
+ event.webEvent.call<void>("preventDefault");
+ event.webEvent.call<void>("stopPropagation");
+ }
}
}
@@ -658,7 +682,7 @@ bool QWasmWindow::processKey(const KeyEvent &event)
#endif
}
-void QWasmWindow::handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event)
+void QWasmWindow::handleKeyForInputContextEvent(const KeyEvent &keyEvent)
{
//
// Things to consider:
@@ -668,40 +692,43 @@ void QWasmWindow::handleKeyForInputContextEvent(EventType eventType, const emscr
// complex (i.e Chinese et al) input handling
// Multiline text edit backspace at start of line
//
- const QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
- if (wasmInput) {
+ emscripten::val event = keyEvent.webEvent;
+ bool useInputContext = [event]() -> bool {
+ const QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
+ if (!wasmInput)
+ return false;
+
const auto keyString = QString::fromStdString(event["key"].as<std::string>());
qCDebug(qLcQpaWasmInputContext) << "Key callback" << keyString << keyString.size();
- if (keyString == "Unidentified") {
- // Android makes a bunch of KeyEvents as "Unidentified"
- // They will be processed just in InputContext.
- return;
- } else if (event["isComposing"].as<bool>()) {
- // Handled by the input context
- return;
- } else if (event["ctrlKey"].as<bool>()
- || event["altKey"].as<bool>()
- || event["metaKey"].as<bool>()) {
- // Not all platforms use 'isComposing' for '~' + 'a', in this
- // case send the key with state ('ctrl', 'alt', or 'meta') to
- // processKeyForInputContext
-
- ; // fallthrough
- } else if (keyString.size() != 1) {
- // This is like; 'Shift','ArrowRight','AltGraph', ...
- // send all of these to processKeyForInputContext
-
- ; // fallthrough
- } else if (wasmInput->inputMethodAccepted()) {
- // processed in inputContext with skipping processKey
- return;
- }
- }
- qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
- if (processKeyForInputContext(KeyEvent(eventType, event, m_deadKeySupport)))
- event.call<void>("preventDefault");
- event.call<void>("stopImmediatePropagation");
+ // Events with isComposing set are handled by the input context
+ bool composing = event["isComposing"].as<bool>();
+
+ // Android makes a bunch of KeyEvents as "Unidentified",
+ // make inputContext handle those.
+ bool androidUnidentified = (keyString == "Unidentified");
+
+ // Not all platforms use 'isComposing' for '~' + 'a', in this
+ // case send the key with state ('ctrl', 'alt', or 'meta') to
+ // processKeyForInputContext
+ bool hasModifiers = event["ctrlKey"].as<bool>()
+ || event["altKey"].as<bool>()
+ || event["metaKey"].as<bool>();
+
+ // This is like; 'Shift','ArrowRight','AltGraph', ...
+ // send all of these to processKeyForInputContext
+ bool hasNoncharacterKeyString = keyString.size() != 1;
+
+ bool overrideCompose = !hasModifiers && !hasNoncharacterKeyString && wasmInput->inputMethodAccepted();
+ return composing || androidUnidentified || overrideCompose;
+ }();
+
+ if (!useInputContext) {
+ qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
+ if (processKeyForInputContext(keyEvent))
+ event.call<void>("preventDefault");
+ event.call<void>("stopImmediatePropagation");
+ }
}
bool QWasmWindow::processKeyForInputContext(const KeyEvent &event)
@@ -729,6 +756,30 @@ bool QWasmWindow::processKeyForInputContext(const KeyEvent &event)
return result;
}
+void QWasmWindow::handleInputEvent(emscripten::val event)
+{
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive())
+ inputContext->inputCallback(event);
+}
+
+void QWasmWindow::handleCompositionStartEvent(emscripten::val event)
+{
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive())
+ inputContext->compositionStartCallback(event);
+}
+
+void QWasmWindow::handleCompositionUpdateEvent(emscripten::val event)
+{
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive())
+ inputContext->compositionUpdateCallback(event);
+}
+
+void QWasmWindow::handleCompositionEndEvent(emscripten::val event)
+{
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive())
+ inputContext->compositionEndCallback(event);
+}
+
void QWasmWindow::handlePointerEnterLeaveEvent(const PointerEvent &event)
{
if (processPointerEnterLeave(event))
@@ -1040,7 +1091,7 @@ void QWasmWindow::requestActivateWindow()
void QWasmWindow::focus()
{
- m_canvas.call<void>("focus");
+ m_focusHelper.call<void>("focus");
}
bool QWasmWindow::setMouseGrabEnabled(bool grab)
diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h
index 904e736a7e7..0c63ebdc16e 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.h
+++ b/src/plugins/platforms/wasm/qwasmwindow.h
@@ -100,6 +100,7 @@ public:
emscripten::val context2d() const { return m_context2d; }
emscripten::val a11yContainer() const { return m_a11yContainer; }
emscripten::val inputHandlerElement() const { return m_window; }
+ emscripten::val inputElement() const { return m_inputElement; }
// QNativeInterface::Private::QWasmWindow
emscripten::val document() const override { return m_document; }
@@ -137,8 +138,13 @@ private:
void handleKeyEvent(const KeyEvent &event);
bool processKey(const KeyEvent &event);
- void handleKeyForInputContextEvent(EventType eventType, const emscripten::val &event);
+ void handleKeyForInputContextEvent(const KeyEvent &event);
bool processKeyForInputContext(const KeyEvent &event);
+ void handleInputEvent(emscripten::val event);
+ void handleCompositionStartEvent(emscripten::val event);
+ void handleCompositionUpdateEvent(emscripten::val event);
+ void handleCompositionEndEvent(emscripten::val event);
+
void handlePointerEnterLeaveEvent(const PointerEvent &event);
bool processPointerEnterLeave(const PointerEvent &event);
void processPointer(const PointerEvent &event);
@@ -154,11 +160,14 @@ private:
QWasmDeadKeySupport *m_deadKeySupport;
QRect m_normalGeometry {0, 0, 0 ,0};
- emscripten::val m_document = emscripten::val::undefined();
- emscripten::val m_decoratedWindow = emscripten::val::undefined();
- emscripten::val m_window = emscripten::val::undefined();
- emscripten::val m_a11yContainer = emscripten::val::undefined();
- emscripten::val m_canvas = emscripten::val::undefined();
+ emscripten::val m_document;
+ emscripten::val m_decoratedWindow;
+ emscripten::val m_window;
+ emscripten::val m_a11yContainer;
+ emscripten::val m_canvas;
+ emscripten::val m_focusHelper;
+ emscripten::val m_inputElement;
+
emscripten::val m_context2d = emscripten::val::undefined();
std::unique_ptr<NonClientArea> m_nonClientArea;
@@ -169,6 +178,10 @@ private:
QWasmEventHandler m_keyUpCallback;
QWasmEventHandler m_keyDownCallbackForInputContext;
QWasmEventHandler m_keyUpCallbackForInputContext;
+ QWasmEventHandler m_inputCallback;
+ QWasmEventHandler m_compositionStartCallback;
+ QWasmEventHandler m_compositionUpdateCallback;
+ QWasmEventHandler m_compositionEndCallback;
QWasmEventHandler m_pointerDownCallback;
QWasmEventHandler m_pointerMoveCallback;
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 62269a21de1..84101b69e9f 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -2151,9 +2151,6 @@ void QWindows11Style::polish(QWidget* widget)
widget->setWindowFlag(Qt::NoDropShadowWindowHint);
widget->setAttribute(Qt::WA_RightToLeft, layoutDirection);
widget->setAttribute(Qt::WA_WState_Created, wasCreated);
- auto pal = widget->palette();
- pal.setColor(widget->backgroundRole(), Qt::transparent);
- widget->setPalette(pal);
if (!isScrollBar) {
bool inGraphicsView = widget->graphicsProxyWidget() != nullptr;
if (!inGraphicsView && comboBoxContainer && comboBoxContainer->parentWidget())
diff --git a/src/testlib/3rdparty/catch2/qt_attribution.json b/src/testlib/3rdparty/catch2/qt_attribution.json
index 1e4f2c5297c..ad231efd426 100644
--- a/src/testlib/3rdparty/catch2/qt_attribution.json
+++ b/src/testlib/3rdparty/catch2/qt_attribution.json
@@ -5,6 +5,7 @@
"QDocModule": "qttestlib",
"QtUsage": "Used for testing of the Qt Test module.",
"Comment": {
+ "OldBranch": "Stick to its v2.x branch; no suitable file in v3",
"UpstreamFile": "single_include/catch2/catch.hpp",
"Generator": "scripts/generateSingleHeader.py",
"General": "no relevant CPE found"
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 1ff52f8a84f..2f06cbcf67e 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -28,6 +28,10 @@ if(QT_FEATURE_macdeployqt)
add_subdirectory(macdeployqt)
endif()
+if(QT_FEATURE_wasmdeployqt)
+ add_subdirectory(wasmdeployqt)
+endif()
+
if(QT_FEATURE_windeployqt)
add_subdirectory(windeployqt)
endif()
diff --git a/src/tools/configure.cmake b/src/tools/configure.cmake
index 6a9c1b8e3f3..27ea90b89ac 100644
--- a/src/tools/configure.cmake
+++ b/src/tools/configure.cmake
@@ -18,6 +18,12 @@ qt_feature("macdeployqt" PRIVATE
AUTODETECT CMAKE_HOST_APPLE
CONDITION MACOS AND QT_FEATURE_thread)
+qt_feature("wasmdeployqt" PRIVATE
+ SECTION "Deployment"
+ LABEL "WebAssembly deployment tool"
+ PURPOSE "The WebAssembly deployment tool is designed to automate the process of creating a deployable folder especially for dynamic linking case variant."
+ CONDITION QT_FEATURE_process)
+
qt_feature("windeployqt" PRIVATE
SECTION "Deployment"
LABEL "Windows deployment tool"
diff --git a/src/tools/wasmdeployqt/CMakeLists.txt b/src/tools/wasmdeployqt/CMakeLists.txt
new file mode 100644
index 00000000000..7305c14c269
--- /dev/null
+++ b/src/tools/wasmdeployqt/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## wasmdeployqt Tool:
+#####################################################################
+
+qt_get_tool_target_name(target_name wasmdeployqt)
+qt_internal_add_tool(${target_name}
+ TOOLS_TARGET Core
+ USER_FACING
+ INSTALL_VERSIONED_LINK
+ TARGET_DESCRIPTION "Qt WebAssembly Deployment Tool"
+ SOURCES
+ main.cpp wasmbinary.cpp jsontools.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+qt_internal_return_unless_building_tools()
diff --git a/src/tools/wasmdeployqt/common.h b/src/tools/wasmdeployqt/common.h
new file mode 100644
index 00000000000..258d6161e67
--- /dev/null
+++ b/src/tools/wasmdeployqt/common.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <QHash>
+#include <QString>
+
+struct PreloadEntry
+{
+ QString source;
+ QString destination;
+
+ bool operator==(const PreloadEntry &other) const
+ {
+ return source == other.source && destination == other.destination;
+ }
+};
+
+inline uint qHash(const PreloadEntry &key, uint seed = 0)
+{
+ return qHash(key.source, seed) ^ qHash(key.destination, seed);
+}
+
+#endif
diff --git a/src/tools/wasmdeployqt/jsontools.cpp b/src/tools/wasmdeployqt/jsontools.cpp
new file mode 100644
index 00000000000..d76f9190b73
--- /dev/null
+++ b/src/tools/wasmdeployqt/jsontools.cpp
@@ -0,0 +1,101 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QDir>
+#include <QJsonArray>
+#include <QJsonObject>
+
+#include "jsontools.h"
+#include "common.h"
+
+#include <iostream>
+#include <optional>
+
+namespace JsonTools {
+
+bool savePreloadFile(QSet<PreloadEntry> preload, QString destFile)
+{
+
+ QJsonArray jsonArray;
+ for (const PreloadEntry &entry : preload) {
+ QJsonObject obj;
+ obj["source"] = entry.source;
+ obj["destination"] = entry.destination;
+ jsonArray.append(obj);
+ }
+ QJsonDocument doc(jsonArray);
+
+ QFile outFile(destFile);
+ if (outFile.exists()) {
+ if (!outFile.remove()) {
+ std::cout << "ERROR: Failed to delete old file: " << outFile.fileName().toStdString()
+ << std::endl;
+ return false;
+ }
+ }
+ if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ std::cout << "ERROR: Failed to open file for writing:" << outFile.fileName().toStdString()
+ << std::endl;
+ return false;
+ }
+ if (outFile.write(doc.toJson(QJsonDocument::Indented)) == -1) {
+ std::cout << "ERROR: Failed writing into file :" << outFile.fileName().toStdString()
+ << std::endl;
+ return false;
+ }
+ if (!outFile.flush()) {
+ std::cout << "ERROR: Failed flushing the file :" << outFile.fileName().toStdString()
+ << std::endl;
+ return false;
+ }
+ outFile.close();
+ return true;
+}
+
+std::optional<QSet<PreloadEntry>> getPreloadsFromQmlImportScannerOutput(QString output)
+{
+ QString qtLibPath = "$QTDIR/lib";
+ QString qtQmlPath = "$QTDIR/qml";
+ QString qtDeployQmlPath = "/qt/qml";
+ QSet<PreloadEntry> res;
+ auto addImport = [&res](const PreloadEntry &entry) {
+ // qDebug() << "adding " << entry.source << "" << entry.destination;
+ res.insert(entry);
+ };
+
+ QJsonParseError parseError;
+ QJsonDocument doc = QJsonDocument::fromJson(output.toUtf8(), &parseError);
+
+ if (parseError.error != QJsonParseError::NoError) {
+ std::cout << "ERROR: QmlImport JSON parse error: " << parseError.errorString().toStdString()
+ << std::endl;
+ return std::nullopt;
+ }
+ if (!doc.isArray()) {
+ std::cout << "ERROR: QmlImport JSON is not an array." << std::endl;
+ return std::nullopt;
+ }
+
+ QJsonArray jsonArray = doc.array();
+ for (const QJsonValue &value : jsonArray) {
+ if (value.isObject()) {
+ QJsonObject obj = value.toObject();
+ auto relativePath = obj["relativePath"].toString();
+ auto plugin = obj["plugin"].toString();
+ if (plugin.isEmpty() || relativePath.isEmpty()) {
+ continue;
+ }
+ auto pluginFilename = "lib" + plugin + ".so";
+ addImport(PreloadEntry{
+ QDir::cleanPath(qtQmlPath + "/" + relativePath + "/" + pluginFilename),
+ QDir::cleanPath(qtDeployQmlPath + "/" + relativePath + "/" + pluginFilename) });
+ addImport(PreloadEntry{
+ QDir::cleanPath(qtQmlPath + "/" + relativePath + "/" + "qmldir"),
+ QDir::cleanPath(qtDeployQmlPath + "/" + relativePath + "/" + "qmldir") });
+ }
+ }
+
+ return res;
+}
+
+}; // namespace JsonTools
diff --git a/src/tools/wasmdeployqt/jsontools.h b/src/tools/wasmdeployqt/jsontools.h
new file mode 100644
index 00000000000..a1691a2be8d
--- /dev/null
+++ b/src/tools/wasmdeployqt/jsontools.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef JSONTOOLS_H
+#define JSONTOOLS_H
+
+#include <QFileInfo>
+#include <QSet>
+
+#include "common.h"
+
+#include <optional>
+
+namespace JsonTools {
+bool savePreloadFile(QSet<PreloadEntry> preload, QString destFile);
+std::optional<QSet<PreloadEntry>> getPreloadsFromQmlImportScannerOutput(QString output);
+}; // namespace JsonTools
+
+#endif
diff --git a/src/tools/wasmdeployqt/main.cpp b/src/tools/wasmdeployqt/main.cpp
new file mode 100644
index 00000000000..3bf2647cfaf
--- /dev/null
+++ b/src/tools/wasmdeployqt/main.cpp
@@ -0,0 +1,417 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "common.h"
+#include "jsontools.h"
+#include "wasmbinary.h"
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QDirListing>
+#include <QDirIterator>
+#include <QtGlobal>
+#include <QLibraryInfo>
+#include <QJsonDocument>
+#include <QStringList>
+#include <QtCore/QCommandLineOption>
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QProcess>
+#include <QQueue>
+#include <QMap>
+#include <QSet>
+
+#include <optional>
+#include <iostream>
+#include <ostream>
+
+struct Parameters
+{
+ std::optional<QString> argAppPath;
+ QString appWasmPath;
+ std::optional<QDir> qtHostDir;
+ std::optional<QDir> qtWasmDir;
+ QList<QDir> libPaths;
+ std::optional<QDir> qmlRootPath;
+
+ QSet<QString> loadedQtLibraries;
+};
+
+bool parseArguments(Parameters &params)
+{
+ QCoreApplication::setApplicationName("wasmdeployqt");
+ QCoreApplication::setApplicationVersion("1.0");
+ QCommandLineParser parser;
+ parser.setApplicationDescription(
+ QStringLiteral("Qt for WebAssembly deployment tool \n\n"
+ "Example:\n"
+ "wasmdeployqt app.wasm --qml-root-path=repo/myapp "
+ "--qt-wasm-dir=/home/user/qt/shared-qt-wasm/bin"));
+ parser.addHelpOption();
+
+ QStringList args = QCoreApplication::arguments();
+
+ parser.addPositionalArgument("app", "Path to the application.");
+ QCommandLineOption libPathOption("lib-path", "Colon-separated list of library directories.",
+ "paths");
+ parser.addOption(libPathOption);
+ QCommandLineOption qtWasmDirOption("qt-wasm-dir", "Path to the Qt for WebAssembly directory.",
+ "dir");
+ parser.addOption(qtWasmDirOption);
+ QCommandLineOption qtHostDirOption("qt-host-dir", "Path to the Qt host directory.", "dir");
+ parser.addOption(qtHostDirOption);
+ QCommandLineOption qmlRootPathOption("qml-root-path", "Root directory for QML files.", "dir");
+ parser.addOption(qmlRootPathOption);
+ parser.process(args);
+
+ const QStringList positionalArgs = parser.positionalArguments();
+ if (positionalArgs.size() > 1) {
+ std::cout << "ERROR: Expected only one positional argument with path to the app. Received: "
+ << positionalArgs.join(" ").toStdString() << std::endl;
+ return false;
+ }
+ if (!positionalArgs.isEmpty()) {
+ params.argAppPath = positionalArgs.first();
+ }
+
+ if (parser.isSet(libPathOption)) {
+ QStringList paths = parser.value(libPathOption).split(';', Qt::SkipEmptyParts);
+ for (const QString &path : paths) {
+ QDir dir(path);
+ if (dir.exists()) {
+ params.libPaths.append(dir);
+ } else {
+ std::cout << "ERROR: Directory does not exist: " << path.toStdString() << std::endl;
+ return false;
+ }
+ }
+ }
+ if (parser.isSet(qtWasmDirOption)) {
+ QDir dir(parser.value(qtWasmDirOption));
+ if (dir.cdUp() && dir.exists())
+ params.qtWasmDir = dir;
+ else {
+ std::cout << "ERROR: Directory does not exist: " << dir.absolutePath().toStdString()
+ << std::endl;
+ return false;
+ }
+ }
+ if (parser.isSet(qtHostDirOption)) {
+ QDir dir(parser.value(qtHostDirOption));
+ if (dir.cdUp() && dir.exists())
+ params.qtHostDir = dir;
+ else {
+ std::cout << "ERROR: Directory does not exist: " << dir.absolutePath().toStdString()
+ << std::endl;
+ return false;
+ }
+ }
+ if (parser.isSet(qmlRootPathOption)) {
+ QDir dir(parser.value(qmlRootPathOption));
+ if (dir.exists()) {
+ params.qmlRootPath = dir;
+ } else {
+ std::cout << "ERROR: Directory specified for qml-root-path does not exist: "
+ << dir.absolutePath().toStdString() << std::endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+std::optional<QString> detectAppName()
+{
+ QDirIterator it(QDir::currentPath(), QStringList() << "*.html" << "*.wasm" << "*.js",
+ QDir::NoFilter);
+ QMap<QString, QSet<QString>> fileGroups;
+ while (it.hasNext()) {
+ QFileInfo fileInfo(it.next());
+ QString baseName = fileInfo.completeBaseName();
+ QString suffix = fileInfo.suffix();
+ fileGroups[baseName].insert(suffix);
+ }
+ for (auto it = fileGroups.constBegin(); it != fileGroups.constEnd(); ++it) {
+ const QSet<QString> &extensions = it.value();
+ if (extensions.contains("html") && extensions.contains("js")
+ && extensions.contains("wasm")) {
+ return it.key();
+ }
+ }
+ return std::nullopt;
+}
+
+bool verifyPaths(Parameters &params)
+{
+ if (params.argAppPath) {
+ QFileInfo fileInfo(*params.argAppPath);
+ if (!fileInfo.exists()) {
+ std::cout << "ERROR: Cannot find " << params.argAppPath->toStdString() << std::endl;
+ std::cout << "Make sure that the path is valid." << std::endl;
+ return false;
+ }
+ params.appWasmPath = fileInfo.absoluteFilePath();
+ } else {
+ auto appName = detectAppName();
+ if (!appName) {
+ std::cout << "ERROR: Cannot find the application in current directory. Specify the "
+ "path as an argument:"
+ "wasmdeployqt <path-to-app-wasm-binary>"
+ << std::endl;
+ return false;
+ }
+ params.appWasmPath = QDir::current().filePath(*appName + ".wasm");
+ std::cout << "Automatically detected " << params.appWasmPath.toStdString() << std::endl;
+ }
+ if (!params.qtWasmDir) {
+ std::cout << "ERROR: Please set path to Qt WebAssembly installation as "
+ "--qt-wasm-dir=<path_to_qt_wasm_bin>"
+ << std::endl;
+ return false;
+ }
+ if (!params.qtHostDir) {
+ auto qtHostPath = QLibraryInfo::path(QLibraryInfo::BinariesPath);
+ if (qtHostPath.length() == 0) {
+ std::cout << "ERROR: Cannot read Qt host path or detect it from environment. Please "
+ "pass it explicitly with --qt-host-dir=<path>. "
+ << std::endl;
+ } else {
+ auto qtHostDir = QDir(qtHostPath);
+ if (!qtHostDir.cdUp()) {
+ std::cout << "ERROR: Invalid Qt host path: "
+ << qtHostDir.absolutePath().toStdString() << std::endl;
+ return false;
+ }
+ params.qtHostDir = qtHostDir;
+ }
+ }
+ params.libPaths.push_front(params.qtWasmDir->filePath("lib"));
+ params.libPaths.push_front(*params.qtWasmDir);
+ return true;
+}
+
+bool copyFile(QString srcPath, QString destPath)
+{
+ auto file = QFile(destPath);
+ if (file.exists()) {
+ file.remove();
+ }
+ QFileInfo destInfo(destPath);
+ if (!QDir().mkpath(destInfo.path())) {
+ std::cout << "ERROR: Cannot create path " << destInfo.path().toStdString() << std::endl;
+ return false;
+ }
+ if (!QFile::copy(srcPath, destPath)) {
+
+ std::cout << "ERROR: Failed to copy " << srcPath.toStdString() << " to "
+ << destPath.toStdString() << std::endl;
+
+ return false;
+ }
+ return true;
+}
+
+bool copyDirectDependencies(QList<QString> dependencies, const Parameters &params)
+{
+ for (auto &&depFilename : dependencies) {
+ if (params.loadedQtLibraries.contains(depFilename)) {
+ continue; // dont copy library that has been already copied
+ }
+
+ std::optional<QString> libPath;
+ for (auto &&libDir : params.libPaths) {
+ auto path = libDir.filePath(depFilename);
+ QFileInfo file(path);
+ if (file.exists()) {
+ libPath = path;
+ }
+ }
+ if (!libPath) {
+ std::cout << "ERROR: Cannot find required library " << depFilename.toStdString()
+ << std::endl;
+ return false;
+ }
+ if (!copyFile(*libPath, QDir::current().filePath(depFilename)))
+ return false;
+ }
+ std::cout << "INFO: Succesfully copied direct dependencies." << std::endl;
+ return true;
+}
+
+QStringList findSoFiles(const QString &directory)
+{
+ QStringList soFiles;
+ QDir baseDir(directory);
+ if (!baseDir.exists())
+ return soFiles;
+
+ QDirIterator it(directory, QStringList() << "*.so", QDir::Files, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ it.next();
+ QString absPath = it.filePath();
+ QString filePath = baseDir.relativeFilePath(absPath);
+ soFiles.append(filePath);
+ }
+ return soFiles;
+}
+
+bool copyQtLibs(Parameters &params)
+{
+ Q_ASSERT(params.qtWasmDir);
+ auto qtLibDir = *params.qtWasmDir;
+ if (!qtLibDir.cd("lib")) {
+ std::cout << "ERROR: Cannot find lib directory in Qt installation." << std::endl;
+ return false;
+ }
+ auto qtLibTargetDir = QDir(QDir(QDir::current().filePath("qt")).filePath("lib"));
+
+ auto soFiles = findSoFiles(qtLibDir.absolutePath());
+ for (auto &&soFilePath : soFiles) {
+ auto relativeFilePath = QDir("lib").filePath(soFilePath);
+ auto srcPath = qtLibDir.absoluteFilePath(soFilePath);
+ auto destPath = qtLibTargetDir.absoluteFilePath(soFilePath);
+ if (!copyFile(srcPath, destPath))
+ return false;
+ params.loadedQtLibraries.insert(QFileInfo(srcPath).fileName());
+ }
+ std::cout << "INFO: Succesfully deployed qt lib shared objects." << std::endl;
+ return true;
+}
+
+bool copyPreloadPlugins(Parameters &params)
+{
+ Q_ASSERT(params.qtWasmDir);
+ auto qtPluginsDir = *params.qtWasmDir;
+ if (!qtPluginsDir.cd("plugins")) {
+ std::cout << "ERROR: Cannot find plugins directory in Qt installation." << std::endl;
+ return false;
+ }
+ auto qtPluginsTargetDir = QDir(QDir(QDir::current().filePath("qt")).filePath("plugins"));
+
+ // copy files
+ auto soFiles = findSoFiles(qtPluginsDir.absolutePath());
+ for (auto &&soFilePath : soFiles) {
+ auto relativeFilePath = QDir("plugins").filePath(soFilePath);
+ params.loadedQtLibraries.insert(QFileInfo(relativeFilePath).fileName());
+ auto srcPath = qtPluginsDir.absoluteFilePath(soFilePath);
+ auto destPath = qtPluginsTargetDir.absoluteFilePath(soFilePath);
+ if (!copyFile(srcPath, destPath))
+ return false;
+ }
+
+ // qt_plugins.json
+ QSet<PreloadEntry> preload{ { { "qt.conf" }, { "/qt.conf" } } };
+ for (auto &&plugin : soFiles) {
+ PreloadEntry entry;
+ entry.source = QDir("$QTDIR").filePath("plugins") + QDir::separator()
+ + QDir(qtPluginsDir).relativeFilePath(plugin);
+ entry.destination = "/qt/plugins/" + QDir(qtPluginsTargetDir).relativeFilePath(plugin);
+ preload.insert(entry);
+ }
+ JsonTools::savePreloadFile(preload, QDir::current().filePath("qt_plugins.json"));
+
+ QString qtconfContent = "[Paths]\nPrefix = /qt\n";
+ QString filePath = QDir::current().filePath("qt.conf");
+
+ QFile file(filePath);
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QTextStream out(&file);
+ out << qtconfContent;
+ if (!file.flush()) {
+ std::cout << "ERROR: Failed flushing the file :" << file.fileName().toStdString()
+ << std::endl;
+ return false;
+ }
+ file.close();
+ } else {
+ std::cout << "ERROR: Failed to write to qt.conf." << std::endl;
+ return false;
+ }
+ std::cout << "INFO: Succesfully deployed qt plugins." << std::endl;
+ return true;
+}
+
+bool copyPreloadQmlImports(Parameters &params)
+{
+ Q_ASSERT(params.qtWasmDir);
+ if (!params.qmlRootPath) {
+ std::cout << "WARNING: qml-root-path not specified. Skipping generating preloads for QML "
+ "imports."
+ << std::endl;
+ std::cout << "WARNING: This may lead to erronous behaviour if applications requires QML "
+ "imports."
+ << std::endl;
+ QSet<PreloadEntry> preload;
+ JsonTools::savePreloadFile(preload, QDir::current().filePath("qt_qml_imports.json"));
+ return true;
+ }
+ auto qmlImportScannerPath = params.qtHostDir
+ ? QDir(params.qtHostDir->filePath("libexec")).filePath("qmlimportscanner")
+ : "qmlimportscanner";
+ QProcess process;
+ auto qmlImportPath = *params.qtWasmDir;
+ qmlImportPath.cd("qml");
+ if (!qmlImportPath.exists()) {
+ std::cout << "ERROR: Cannot find qml import path: "
+ << qmlImportPath.absolutePath().toStdString() << std::endl;
+ return -1;
+ }
+
+ QStringList args{ "-rootPath", params.qmlRootPath->absolutePath(), "-importPath",
+ qmlImportPath.absolutePath() };
+ process.start(qmlImportScannerPath, args);
+ if (!process.waitForFinished()) {
+ std::cout << "ERROR: Failed to execute qmlImportScanner." << std::endl;
+ return false;
+ }
+
+ QString stdoutOutput = process.readAllStandardOutput();
+ auto qmlImports = JsonTools::getPreloadsFromQmlImportScannerOutput(stdoutOutput);
+ if (!qmlImports) {
+ return false;
+ }
+ JsonTools::savePreloadFile(*qmlImports, QDir::current().filePath("qt_qml_imports.json"));
+ for (const PreloadEntry &import : *qmlImports) {
+ auto relativePath = import.source;
+ relativePath.remove("$QTDIR/");
+
+ auto srcPath = params.qtWasmDir->absoluteFilePath(relativePath);
+ auto destPath = QDir(QDir::current().filePath("qt")).absoluteFilePath(relativePath);
+ if (!copyFile(srcPath, destPath))
+ return false;
+ }
+ std::cout << "INFO: Succesfully deployed qml imports." << std::endl;
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ Parameters params;
+ if (!parseArguments(params)) {
+ return -1;
+ }
+ if (!verifyPaths(params)) {
+ return -1;
+ }
+ std::cout << "INFO: Target: " << params.appWasmPath.toStdString() << std::endl;
+ WasmBinary wasmBinary(params.appWasmPath);
+ if (wasmBinary.type == WasmBinary::Type::INVALID) {
+ return -1;
+ } else if (wasmBinary.type == WasmBinary::Type::STATIC) {
+ std::cout << "INFO: This is statically linked WebAssembly binary." << std::endl;
+ std::cout << "INFO: No extra steps required!" << std::endl;
+ return 0;
+ }
+ std::cout << "INFO: Verified as shared module." << std::endl;
+
+ if (!copyQtLibs(params))
+ return -1;
+ if (!copyPreloadPlugins(params))
+ return -1;
+ if (!copyPreloadQmlImports(params))
+ return -1;
+ if (!copyDirectDependencies(wasmBinary.dependencies, params))
+ return -1;
+
+ std::cout << "INFO: Deployment done!" << std::endl;
+ return 0;
+}
diff --git a/src/tools/wasmdeployqt/wasmbinary.cpp b/src/tools/wasmdeployqt/wasmbinary.cpp
new file mode 100644
index 00000000000..1a041c94066
--- /dev/null
+++ b/src/tools/wasmdeployqt/wasmbinary.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "wasmbinary.h"
+
+#include <QFile>
+
+#include <iostream>
+
+WasmBinary::WasmBinary(QString filepath)
+{
+ QFile file(filepath);
+ if (!file.open(QIODevice::ReadOnly)) {
+ std::cout << "ERROR: Cannot open the file " << filepath.toStdString() << std::endl;
+ std::cout << file.errorString().toStdString() << std::endl;
+ type = WasmBinary::Type::INVALID;
+ return;
+ }
+ auto bytes = file.readAll();
+ if (!parsePreambule(bytes)) {
+ type = WasmBinary::Type::INVALID;
+ }
+}
+
+bool WasmBinary::parsePreambule(QByteArrayView data)
+{
+ const auto preambuleSize = 24;
+ if (data.size() < preambuleSize) {
+ std::cout << "ERROR: Preambule of binary shorter than expected!" << std::endl;
+ return false;
+ }
+ uint32_t int32View[6];
+ std::memcpy(int32View, data.data(), sizeof(int32View));
+ if (int32View[0] != 0x6d736100) {
+ std::cout << "ERROR: Magic WASM number not found in binary. Binary corrupted?" << std::endl;
+ return false;
+ }
+ if (data[8] != 0) {
+ type = WasmBinary::Type::STATIC;
+ return true;
+ } else {
+ type = WasmBinary::Type::SHARED;
+ }
+ const auto sectionStart = 9;
+ size_t offset = sectionStart;
+ auto sectionSize = getLeb(data, offset);
+ auto sectionEnd = sectionStart + sectionSize;
+ auto name = getString(data, offset);
+ if (name != "dylink.0") {
+ type = WasmBinary::Type::INVALID;
+ std::cout << "ERROR: dylink.0 was not found in supposedly dynamically linked module"
+ << std::endl;
+ return false;
+ }
+
+ const auto WASM_DYLINK_NEEDED = 0x2;
+ while (offset < sectionEnd) {
+ auto subsectionType = data[offset++];
+ auto subsectionSize = getLeb(data, offset);
+ if (subsectionType == WASM_DYLINK_NEEDED) {
+ auto neededDynlibsCount = getLeb(data, offset);
+ while (neededDynlibsCount--) {
+ dependencies.append(getString(data, offset));
+ }
+ } else {
+ offset += subsectionSize;
+ }
+ }
+ return true;
+}
+
+size_t WasmBinary::getLeb(QByteArrayView data, size_t &offset)
+{
+ auto ret = 0;
+ auto mul = 1;
+ while (true) {
+ auto byte = data[offset++];
+ ret += (byte & 0x7f) * mul;
+ mul *= 0x80;
+ if (!(byte & 0x80))
+ break;
+ }
+ return ret;
+}
+
+QString WasmBinary::getString(QByteArrayView data, size_t &offset)
+{
+ auto length = getLeb(data, offset);
+ offset += length;
+ return QString::fromUtf8(data.sliced(offset - length, length));
+}
diff --git a/src/tools/wasmdeployqt/wasmbinary.h b/src/tools/wasmdeployqt/wasmbinary.h
new file mode 100644
index 00000000000..c3bb3f0eaa4
--- /dev/null
+++ b/src/tools/wasmdeployqt/wasmbinary.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef WASMBINARY_H
+#define WASMBINARY_H
+
+#include <QString>
+#include <QList>
+
+class WasmBinary
+{
+public:
+ enum class Type { INVALID, STATIC, SHARED };
+ WasmBinary(QString filepath);
+ Type type;
+ QList<QString> dependencies;
+
+private:
+ bool parsePreambule(QByteArrayView data);
+ size_t getLeb(QByteArrayView data, size_t &offset);
+ QString getString(QByteArrayView data, size_t &offset);
+};
+
+#endif
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index e57cc732ee2..820a7b4bdb5 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -7,7 +7,6 @@
#include <qfile.h>
#include <qdatetime.h>
#include <qdir.h>
-#include <qset.h>
#include <qstandardpaths.h>
#include <qstring.h>
#include <qtemporarydir.h>
@@ -15,6 +14,9 @@
#include <QtTest/private/qtesthelpers_p.h>
+#include <QtCore/private/qduplicatetracker_p.h>
+#include <QtCore/qscopeguard.h>
+
#if defined(Q_OS_WIN)
# include <shlwapi.h>
# include <qt_windows.h>
@@ -549,18 +551,20 @@ void tst_QTemporaryFile::openOnRootDrives()
void tst_QTemporaryFile::stressTest()
{
- const int iterations = 1000;
+ constexpr int iterations = 1000;
+
+ QDuplicateTracker<QString, iterations> names;
+
+ const auto remover = qScopeGuard([&] {
+ for (const QString &s : std::as_const(names))
+ QFile::remove(s);
+ });
- QSet<QString> names;
for (int i = 0; i < iterations; ++i) {
QTemporaryFile file;
file.setAutoRemove(false);
QVERIFY2(file.open(), qPrintable(file.errorString()));
- QVERIFY(!names.contains(file.fileName()));
- names.insert(file.fileName());
- }
- for (QSet<QString>::const_iterator it = names.constBegin(); it != names.constEnd(); ++it) {
- QFile::remove(*it);
+ QVERIFY(!names.hasSeen(file.fileName()));
}
}
@@ -821,37 +825,26 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename()
#if defined(Q_OS_VXWORKS)
QSKIP("QTBUG-130066");
#endif
- struct CleanOnReturn
- {
- ~CleanOnReturn()
- {
+
+ QString tempName;
+ auto cleaner = qScopeGuard([&] {
if (!tempName.isEmpty())
QFile::remove(tempName);
- }
-
- void reset()
- {
- tempName.clear();
- }
-
- QString tempName;
- };
-
- CleanOnReturn cleaner;
+ });
{
QTemporaryFile file;
QVERIFY( file.open() );
- cleaner.tempName = file.fileName();
+ tempName = file.fileName();
- QVERIFY( QFile::exists(cleaner.tempName) );
+ QVERIFY(QFile::exists(tempName));
QVERIFY( !QFileInfo("i-do-not-exist").isDir() );
QVERIFY( !file.rename("i-do-not-exist/file.txt") );
- QVERIFY( QFile::exists(cleaner.tempName) );
+ QVERIFY(QFile::exists(tempName));
}
- QVERIFY( !QFile::exists(cleaner.tempName) );
- cleaner.reset();
+ QVERIFY(!QFile::exists(tempName));
+ cleaner.dismiss(); // would fail: file is known to no longer exist
}
void tst_QTemporaryFile::createNativeFile_data()
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index 0254cbd1360..f03be6cc69e 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -23,6 +23,8 @@
#include "../../../network-settings.h"
#include <QtTest/private/qemulationdetector_p.h>
+using namespace Qt::StringLiterals;
+
QT_BEGIN_NAMESPACE
template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
{ enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
@@ -1379,12 +1381,12 @@ void tst_QTextStream::pos2()
// ------------------------------------------------------------------------------
void tst_QTextStream::pos3LargeFile()
{
+ // NOTE: The unusual spacing is to ensure non-1-character whitespace.
+ constexpr auto lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n"_L1;
{
QFile file(testFileName);
QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
QTextStream out( &file );
- // NOTE: The unusual spacing is to ensure non-1-character whitespace.
- QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
// Approximately 5kb text file (more is too slow (QTBUG-138435))
const int NbLines = (5 * 1024) / lineString.size() + 1;
for (int line = 0; line < NbLines; ++line)
@@ -1395,8 +1397,15 @@ void tst_QTextStream::pos3LargeFile()
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream in( &file );
constexpr int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ qint64 expectedLineEnd = 0;
+#ifdef Q_OS_WIN // CRLF platform
+ constexpr int crlfAdjustment = 1;
+#else
+ constexpr int crlfAdjustment = 0;
+#endif
+ const auto expectedLineLength = lineString.size() + crlfAdjustment;
+ QCOMPARE(in.pos(), 0);
while (true) {
- in.pos();
for (size_t i = 0; i < std::size(testValues); ++i) {
int value = -42;
if (!(in >> value)) {
@@ -1407,6 +1416,9 @@ void tst_QTextStream::pos3LargeFile()
}
QCOMPARE(value, testValues[i]);
}
+ expectedLineEnd += expectedLineLength;
+ // Final space and newline are not consumed until next read.
+ QCOMPARE(in.pos(), expectedLineEnd - 2 - crlfAdjustment);
}
}
@@ -2997,14 +3009,41 @@ void tst_QTextStream::int_write_with_locale_data()
QTest::addColumn<int>("numberFlags");
QTest::addColumn<int>("input");
QTest::addColumn<QString>("output");
+ QTest::addColumn<int>("fieldWidth");
+ QTest::addColumn<QTextStream::FieldAlignment>("fieldAlignment");
+
+ const auto alignDefault = QTextStream().fieldAlignment();
+ constexpr int forceSign = QTextStream::ForceSign;
+
+ QTest::newRow("C -123") << u"C"_s << 0 << -123 << u"-123"_s << 0 << alignDefault;
+ QTest::newRow("C +123") << u"C"_s << forceSign << 123 << u"+123"_s << 0 << alignDefault;
+ QTest::newRow("C 12345") << u"C"_s << 0 << 12345 << u"12345"_s << 0 << alignDefault;
- QTest::newRow("C -123") << QString("C") << 0 << -123 << QString("-123");
- QTest::newRow("C +123") << QString("C") << (int)QTextStream::ForceSign << 123 << QString("+123");
- QTest::newRow("C 12345") << QString("C") << 0 << 12345 << QString("12345");
+ QTest::newRow("de_DE -123") << u"de_DE"_s << 0 << -123 << u"-123"_s << 0 << alignDefault;
+ QTest::newRow("de_DE +123") << u"de_DE"_s << forceSign << 123 << u"+123"_s << 0 << alignDefault;
+ QTest::newRow("de_DE 12345") << u"de_DE"_s << 0 << 12345 << u"12.345"_s << 0 << alignDefault;
- QTest::newRow("de_DE -123") << QString("de_DE") << 0 << -123 << QString("-123");
- QTest::newRow("de_DE +123") << QString("de_DE") << (int)QTextStream::ForceSign << 123 << QString("+123");
- QTest::newRow("de_DE 12345") << QString("de_DE") << 0 << 12345 << QString("12.345");
+ constexpr auto alignAccountingStyle = QTextStream::FieldAlignment::AlignAccountingStyle;
+
+ {
+ const QLocale loc("ar_EG"_L1);
+ // Arabic as spoken in Egypt has a two-code-point negativeSign():
+ const auto minus = loc.negativeSign();
+ QCOMPARE(minus.size(), 2);
+ // ditto positiveSign():
+ const auto plus = loc.positiveSign();
+ QCOMPARE(plus.size(), 2);
+
+ QTest::addRow("ar_EG -123") << u"ar_EG"_s << 0 << -123
+ << (minus + u" ١٢٣")
+ << 10 << alignAccountingStyle;
+ QTest::newRow("ar_EG +123") << u"ar_EG"_s << forceSign << 123
+ << (plus + u" ١٢٣")
+ << 10 << alignAccountingStyle;
+ QTest::newRow("ar_EG 12345") << u"ar_EG"_s << 0 << 12345
+ << u" ١٢٬٣٤٥"_s
+ << 10 << alignAccountingStyle;
+ }
}
void tst_QTextStream::int_write_with_locale()
@@ -3013,13 +3052,21 @@ void tst_QTextStream::int_write_with_locale()
QFETCH(int, numberFlags);
QFETCH(int, input);
QFETCH(QString, output);
+ QFETCH(const int, fieldWidth);
+ QFETCH(const QTextStream::FieldAlignment, fieldAlignment);
QString result;
QTextStream stream(&result);
stream.setLocale(QLocale(locale));
+ stream.setFieldAlignment(fieldAlignment);
if (numberFlags)
stream.setNumberFlags(QTextStream::NumberFlags(numberFlags));
+ if (fieldWidth)
+ stream.setFieldWidth(fieldWidth);
+
QVERIFY(stream << input);
+ QEXPECT_FAIL("ar_EG -123", "QTBUG-138484", Continue);
+ QEXPECT_FAIL("ar_EG +123", "QTBUG-138484", Continue);
QCOMPARE(result, output);
}
diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
index bfc6074689b..50e17728cf3 100644
--- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
@@ -78,6 +78,9 @@ private slots:
void negativeZero_data();
void negativeZero();
+ void signsNeverCompareEqualToNullCharacter_data() { testNames_data(); }
+ void signsNeverCompareEqualToNullCharacter();
+
void dayOfWeek();
void dayOfWeek_data();
void formatDate();
@@ -2114,6 +2117,19 @@ void tst_QLocale::negativeZero()
QCOMPARE(locale.toString(std::copysign(0.0, -1.0)), expect);
}
+void tst_QLocale::signsNeverCompareEqualToNullCharacter() // otherwise QTextStream has a problem
+{
+ QFETCH(QLocale::Language, language);
+ QFETCH(const QLocale::Territory, country);
+
+ if (language == QLocale::AnyLanguage && country == QLocale::AnyTerritory)
+ language = QLocale::C;
+
+ const QLocale loc(language, country);
+ QCOMPARE_NE(loc.negativeSign(), QChar());
+ QCOMPARE_NE(loc.positiveSign(), QChar());
+}
+
void tst_QLocale::dayOfWeek_data()
{
QTest::addColumn<QDate>("date");
diff --git a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
index eecc8b52d28..bd95174c932 100644
--- a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
+++ b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
@@ -120,6 +120,11 @@ void tst_QDuplicateTracker::appendTo()
QList<int> b;
tracker.appendTo(b);
+ // iteration order is append order:
+ QVERIFY(std::equal(b.cbegin(), b.cend(),
+ tracker.cbegin(), tracker.cend()));
+ QVERIFY(std::equal(b.cbegin(), b.cend(),
+ tracker.begin(), tracker.end()));
std::sort(b.begin(), b.end());
QCOMPARE(b, QList<int>({ 0, 1 }));
diff --git a/tests/auto/dbus/qdbusconnection/CMakeLists.txt b/tests/auto/dbus/qdbusconnection/CMakeLists.txt
index 56ae21f2911..cbbe76a7dc7 100644
--- a/tests/auto/dbus/qdbusconnection/CMakeLists.txt
+++ b/tests/auto/dbus/qdbusconnection/CMakeLists.txt
@@ -19,3 +19,15 @@ qt_internal_add_test(tst_qdbusconnection
TESTDATA
tst_qdbusconnection.conf
)
+
+qt_internal_add_executable(qdbusdelayeddeliveryreenablehelper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ qdbusdelayeddeliveryreenablehelper.cpp
+ LIBRARIES
+ Qt::DBus
+)
+
+add_dependencies(tst_qdbusconnection
+ qdbusdelayeddeliveryreenablehelper
+)
diff --git a/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp b/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp
new file mode 100644
index 00000000000..cd916d5b639
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection/qdbusdelayeddeliveryreenablehelper.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2025 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QTimer>
+#include <QtCore/QCoreApplication>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+
+#include <stdio.h>
+
+using namespace Qt::StringLiterals;
+using namespace std::chrono_literals;
+
+static QString myInterface()
+{
+ return u"local.qdbusdelayeddeliveryreenablehelper"_s;
+}
+
+static void makeSynchronousCall(QDBusConnection &conn)
+{
+ QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus.Peer", "Ping");
+ conn.call(msg);
+}
+
+static void emitSignal(QDBusConnection &conn)
+{
+ QDBusMessage msg = QDBusMessage::createSignal("/", myInterface(), "quit");
+ conn.send(msg);
+}
+
+int main(int argc, char **argv)
+{
+ // Open a connection to the bus *before* QCoreApplication exists;
+ // this will put the connection in delayed delivery mode
+ QDBusConnection session = QDBusConnection::sessionBus();
+ if (!session.isConnected()) {
+ fprintf(stderr, "Session bus did not connect!");
+ return 1;
+ }
+ makeSynchronousCall(session);
+
+ QCoreApplication app(argc, argv);
+ QTimer::singleShot(15s, qApp, [] {
+ fprintf(stderr, "Did not receive signal.\n");
+ qApp->exit(1);
+ });
+
+ // connect a remote, wildcard signal to qApp->quit()
+ session.connect(QString(), QString(), myInterface(), "quit", &app, SLOT(quit()));
+
+ // send ourselves the signal to quit, via D-Bus
+ emitSignal(session);
+
+ return app.exec();
+}
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index ab750dff330..fe9214c5513 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -13,11 +13,6 @@
#include <QDBusInterface>
#include <QDBusConnectionInterface>
-#ifdef Q_OS_UNIX
-# include <sys/types.h>
-# include <signal.h>
-#endif
-
void MyObject::method(const QDBusMessage &msg)
{
path = msg.path();
@@ -1473,6 +1468,31 @@ void tst_QDBusConnection::parentClassSignal()
QTRY_COMPARE(recv.signalsReceived, 2);
}
+// see also tst_qdbusconnection_delayed
+void tst_QDBusConnection::delayedDeliveryReenabledAfterUsedInMainThread()
+{
+#if !QT_CONFIG(process)
+ QSKIP("Test requires QProcess");
+#elif defined(HAS_HOOKSETUPFUNCTION)
+ QSKIP("No difference to run by tst_QDBusConnection");
+#else
+# if defined(Q_OS_WIN)
+# define EXE ".exe"
+# else
+# define EXE ""
+# endif
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
+ QProcess process;
+ process.start(QFINDTESTDATA("qdbusdelayeddeliveryreenablehelper" EXE));
+ QVERIFY2(process.waitForFinished(25000), qPrintable(process.errorString()));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.exitCode(), 0);
+# undef EXE
+#endif
+}
+
QString MyObject::path;
QString MyObjectWithoutInterface::path;
QString MyObjectWithoutInterface::interface;
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
index 4137859414c..dc37e3157b4 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
@@ -126,6 +126,8 @@ private slots:
void parentClassSignal();
+ void delayedDeliveryReenabledAfterUsedInMainThread();
+
public:
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
bool callMethod(const QDBusConnection &conn, const QString &path);
diff --git a/tests/benchmarks/corelib/CMakeLists.txt b/tests/benchmarks/corelib/CMakeLists.txt
index 890cbcfc6b8..42e1d2cb96d 100644
--- a/tests/benchmarks/corelib/CMakeLists.txt
+++ b/tests/benchmarks/corelib/CMakeLists.txt
@@ -14,3 +14,4 @@ add_subdirectory(time)
add_subdirectory(tools)
add_subdirectory(plugin)
add_subdirectory(serialization)
+add_subdirectory(platform)
diff --git a/tests/benchmarks/corelib/platform/CMakeLists.txt b/tests/benchmarks/corelib/platform/CMakeLists.txt
new file mode 100644
index 00000000000..68844c1c8f7
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(ANDROID)
+ add_subdirectory(androiditemmodel)
+endif()
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt b/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt
new file mode 100644
index 00000000000..b72d0564c1a
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_androiditemmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_bench_androiditemmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_bench_androiditemmodel
+ SOURCES
+ tst_bench_androiditemmodel.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::CorePrivate
+)
+
+set_property(TARGET tst_androiditemmodel PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR}/testdata
+)
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java b/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java
new file mode 100644
index 00000000000..79b07b3fd04
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/testdata/src/org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.qt.android.benchmark;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.qtproject.qt.android.QtAbstractItemModel;
+import org.qtproject.qt.android.QtModelIndex;
+
+public class BenchQtAbstractItemModel
+ extends QtAbstractItemModel
+{
+ int m_rows = 1;
+ int m_cols = 1;
+
+ @Override
+ public int columnCount(QtModelIndex parent)
+ {
+ return m_cols;
+ }
+
+ @Override
+ public Object data(QtModelIndex index, int role)
+ {
+ return null;
+ }
+
+ @Override
+ public QtModelIndex index(int row, int column, QtModelIndex parent)
+ {
+ return createIndex(row, column, 0);
+ }
+
+ @Override
+ public QtModelIndex parent(QtModelIndex qtModelIndex)
+ {
+ return new QtModelIndex();
+ }
+
+ @Override
+ public int rowCount(QtModelIndex parent)
+ {
+ return m_rows;
+ }
+
+ @Override
+ public HashMap<Integer, String> roleNames()
+ {
+ final HashMap<Integer, String> roles = new HashMap<Integer, String>();
+ roles.put(0, "integerRole");
+ return roles;
+ }
+}
diff --git a/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp b/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp
new file mode 100644
index 00000000000..c7079e147a7
--- /dev/null
+++ b/tests/benchmarks/corelib/platform/androiditemmodel/tst_bench_androiditemmodel.cpp
@@ -0,0 +1,144 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest/QTest>
+
+#include <QtCore/private/qandroiditemmodelproxy_p.h>
+#include <QtCore/private/qandroidmodelindexproxy_p.h>
+#include <QtCore/private/qandroidtypes_p.h>
+
+#include <QGuiApplication>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qjniobject.h>
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qstring.h>
+#include <QSignalSpy>
+#include <memory>
+
+using namespace Qt::Literals;
+
+Q_DECLARE_JNI_CLASS(BenchQtAbstractItemModel,
+ "org/qtproject/qt/android/benchmark/BenchQtAbstractItemModel")
+
+class BenchNativeAbstractItemModel : public QAbstractItemModel {
+ Q_OBJECT
+ int m_rows = 1;
+ int m_cols = 1;
+
+ public:
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override {
+ return m_cols;
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override {
+ return m_rows;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override {
+ return QVariant();
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent) const override {
+ return createIndex(row, column, quintptr(0));
+ }
+
+ QModelIndex parent(const QModelIndex &index) const override
+ {
+ return QModelIndex();
+ }
+
+ QHash<int, QByteArray> roleNames() const override {
+ static QHash<int, QByteArray> roles = {
+ {0, "integerRole"}
+ };
+ return roles;
+ }
+
+};
+
+class tst_BenchAndroidItemModel : public QObject
+{
+ Q_OBJECT
+ QtJniTypes::BenchQtAbstractItemModel m_jModel;
+ std::unique_ptr<QAbstractItemModel> qProxy;
+ std::unique_ptr<QAbstractItemModel> nativeModel;
+
+private slots:
+ void init();
+
+ void proxiedData();
+ void nativeData();
+
+ void proxiedRowCount();
+ void nativeRowCount();
+
+ void proxiedColumnCount();
+ void nativeColumnCount();
+
+ void proxiedIndex();
+ void nativeIndex();
+};
+
+void tst_BenchAndroidItemModel::init()
+{
+ m_jModel = QJniObject::construct<QtJniTypes::BenchQtAbstractItemModel>();
+ QVERIFY(m_jModel.isValid());
+ qProxy = std::unique_ptr<QAbstractItemModel>(QAndroidItemModelProxy::createNativeProxy(jModel));
+ nativeModel = std::make_unique<BenchNativeAbstractItemModel>();
+ QVERIFY(qProxy);
+}
+
+void tst_BenchAndroidItemModel::proxiedData()
+{
+ QCOMPARE(qProxy->rowCount(), 1);
+ QCOMPARE(qProxy->columnCount(), 1);
+
+ QModelIndex idx = qProxy->index(0, 0, QModelIndex());
+
+ QBENCHMARK { qProxy->data(idx, 0); }
+}
+
+void tst_BenchAndroidItemModel::nativeData()
+{
+ QCOMPARE(nativeModel->rowCount(), 1);
+ QCOMPARE(nativeModel->columnCount(), 1);
+
+ QModelIndex idx = nativeModel->index(0, 0, QModelIndex());
+
+ QBENCHMARK { nativeModel->data(idx, 0); }
+}
+
+void tst_BenchAndroidItemModel::proxiedRowCount()
+{
+ QBENCHMARK { qProxy->rowCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeRowCount()
+{
+ QBENCHMARK { nativeModel->rowCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::proxiedColumnCount()
+{
+ QBENCHMARK { qProxy->columnCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeColumnCount()
+{
+ QBENCHMARK { nativeModel->columnCount(QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::proxiedIndex()
+{
+ QBENCHMARK { qProxy->index(0, 0, QModelIndex()); }
+}
+
+void tst_BenchAndroidItemModel::nativeIndex()
+{
+ QBENCHMARK { nativeModel->index(0, 0, QModelIndex()); }
+}
+
+#include "tst_bench_androiditemmodel.moc"
+
+QTEST_MAIN(tst_BenchAndroidItemModel)
diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
index 59f1f00cc59..1fd6e0a0c4f 100644
--- a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
+++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
@@ -7,7 +7,7 @@
using namespace emscripten;
-const int timerTimeout = 10;
+const std::chrono::milliseconds timerTimeout{10};
// Test QWasmSuspendResumeControl suspend/resume and event processing,
// via QWasmTimer native timer events.
diff --git a/util/wasm/preload/generate_default_preloads.sh.in b/util/wasm/preload/generate_default_preloads.sh.in
deleted file mode 100644
index b38d308fa45..00000000000
--- a/util/wasm/preload/generate_default_preloads.sh.in
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-TARGET_DIR="@TARGET_DIR@"
-SOURCE_DIR="@SOURCE_DIR@"
-QT_HOST_DIR="@QT_HOST_DIR@"
-QT_WASM_DIR="@QT_WASM_DIR@"
-QT_INSTALL_DIR="@QT_INSTALL_DIR@"
-
-python3 \
- "$QT_WASM_DIR/libexec/preload_qt_plugins.py" \
- "$QT_INSTALL_DIR" \
- "$TARGET_DIR"
-
-python3 \
- "$QT_WASM_DIR/libexec/preload_qml_imports.py" \
- "$SOURCE_DIR" \
- "$QT_HOST_DIR" \
- "$QT_INSTALL_DIR" \
- "$TARGET_DIR"
diff --git a/util/wasm/preload/preload_qml_imports.py b/util/wasm/preload/preload_qml_imports.py
deleted file mode 100755
index b78ef5ee744..00000000000
--- a/util/wasm/preload/preload_qml_imports.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import os
-import sys
-import subprocess
-import json
-
-# Paths to shared libraries and qml imports on the Qt installation on the web server.
-# "$QTDIR" is replaced by qtloader.js at load time (defaults to "qt"), and makes
-# possible to relocate the application build relative to the Qt build on the web server.
-qt_lib_path = "$QTDIR/lib"
-qt_qml_path = "$QTDIR/qml"
-
-# Path to QML imports on the in-memory file system provided by Emscripten. This script emits
-# preload commands which copies QML imports to this directory. In addition, preload_qt_plugins.py
-# creates (and preloads) a qt.conf file which makes Qt load QML plugins from this location.
-qt_deploy_qml_path = "/qt/qml"
-
-
-def preload_file(source, destination):
- preload_files.append({"source": source, "destination": destination})
-
-
-def extract_preload_files_from_imports(imports):
- libraries = []
- for qml_import in imports:
- try:
- relative_path = qml_import["relativePath"]
- plugin = qml_import["plugin"]
-
- # plugin .so
- plugin_filename = "lib" + plugin + ".so"
- so_plugin_source_path = os.path.join(
- qt_qml_path, relative_path, plugin_filename
- )
- so_plugin_destination_path = os.path.join(
- qt_deploy_qml_path, relative_path, plugin_filename
- )
-
- preload_file(so_plugin_source_path, so_plugin_destination_path)
- so_plugin_qt_install_path = os.path.join(
- qt_wasm_path, "qml", relative_path, plugin_filename
- )
-
- # qmldir file
- qmldir_source_path = os.path.join(qt_qml_path, relative_path, "qmldir")
- qmldir_destination_path = os.path.join(
- qt_deploy_qml_path, relative_path, "qmldir"
- )
- preload_file(qmldir_source_path, qmldir_destination_path)
- except Exception as e:
- continue
- return libraries
-
-
-if __name__ == "__main__":
- if len(sys.argv) != 5:
- print("Usage: python preload_qml_imports.py <qml-source-path> <qt-host-path> <qt-wasm-path> <output-dir>")
- sys.exit(1)
-
- qml_source_path = sys.argv[1]
- qt_host_path = sys.argv[2]
- qt_wasm_path = sys.argv[3]
- output_dir = sys.argv[4]
-
- qml_import_path = os.path.join(qt_wasm_path, "qml")
- qmlimportsscanner_path = os.path.join(qt_host_path, "libexec/qmlimportscanner")
-
- command = [qmlimportsscanner_path, "-rootPath", qml_source_path, "-importPath", qml_import_path]
- result = subprocess.run(command, stdout=subprocess.PIPE)
- imports = json.loads(result.stdout)
-
- preload_files = []
- libraries = extract_preload_files_from_imports(imports)
-
- # Deploy plugin dependencies, that is, shared libraries used by the plugins.
- # Skip some of the obvious libraries which will be
- skip_libraries = [
- "libQt6Core.so",
- "libQt6Gui.so",
- "libQt6Quick.so",
- "libQt6Qml.so" "libQt6Network.so",
- "libQt6OpenGL.so",
- ]
-
- libraries = set(libraries) - set(skip_libraries)
- for library in libraries:
- source = os.path.join(qt_lib_path, library)
- # Emscripten looks for shared libraries on "/", shared libraries
- # most be deployed there instead of at /qt/lib
- destination = os.path.join("/", library)
- preload_file(source, destination)
-
- with open(f"{output_dir}/qt_qml_imports.json", "w") as f:
- f.write(json.dumps(preload_files, indent=2))
-
diff --git a/util/wasm/preload/preload_qt_plugins.py b/util/wasm/preload/preload_qt_plugins.py
deleted file mode 100755
index 4b9b3683a70..00000000000
--- a/util/wasm/preload/preload_qt_plugins.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import os
-import sys
-import json
-
-# Path to plugins on the Qt installation on the web server. "$QTPATH" is replaced by qtloader.js
-# at load time (defaults to "qt"), which makes it possible to relocate the application build relative
-# to the Qt build on the web server.
-qt_plugins_path = "$QTDIR/plugins"
-
-# Path to plugins on the in-memory file system provided by Emscripten. This script emits
-# preload commands which copies plugins to this directory.
-qt_deploy_plugins_path = "/qt/plugins"
-
-
-def find_so_files(directory):
- so_files = []
- for root, dirs, files in os.walk(directory):
- for file in files:
- if file.endswith(".so"):
- relative_path = os.path.relpath(os.path.join(root, file), directory)
- so_files.append(relative_path)
- return so_files
-
-
-if __name__ == "__main__":
- if len(sys.argv) != 3:
- print("Usage: python preload_qt_plugins.py <qt-wasm-path> <output-dir>")
- sys.exit(1)
-
- qt_wasm_path = sys.argv[1]
- output_dir = sys.argv[2]
-
- # preload all plugins
- plugins = find_so_files(os.path.join(qt_wasm_path, "plugins"))
- preload = [
- {
- "source": os.path.join(qt_plugins_path, plugin),
- "destination": os.path.join(qt_deploy_plugins_path, plugin),
- }
- for plugin in plugins
- ]
-
- # Create and preload qt.conf which will tell Qt to look for plugins
- # and QML imports in /qt/plugins and /qt/qml. The qt.conf file is
- # written to the current directory.
- qtconf = "[Paths]\nPrefix = /qt\n"
- with open(f"{output_dir}/qt.conf", "w") as f:
- f.write(qtconf)
- preload.append({"source": "qt.conf", "destination": "/qt.conf"})
-
- with open(f"{output_dir}/qt_plugins.json", "w") as f:
- f.write(json.dumps(preload, indent=2))
-