diff options
Diffstat (limited to 'src')
36 files changed, 166 insertions, 72 deletions
diff --git a/src/qml/doc/src/tools/qtqml-tooling-qmllint.qdoc b/src/qml/doc/src/tools/qtqml-tooling-qmllint.qdoc index 1aa59839ea..8ced3cc537 100644 --- a/src/qml/doc/src/tools/qtqml-tooling-qmllint.qdoc +++ b/src/qml/doc/src/tools/qtqml-tooling-qmllint.qdoc @@ -16,6 +16,10 @@ for ease of use. It also warns about some QML anti-patterns. If you want to disable a specific warning type, you can find the appropriate flag for doing so by passing \c{--help} on the command line. +\note When using IDE, such as Qt Creator, you don't need to run \c qmllint +manually. The IDE uses \l {QML Language Server#Linting}{QML Language Server}, +that provides real-time linting output and diagnostics as you type. + By default, some issues will result in warnings that will be printed. If there are more warnings than a limit which can be configured with \c{--max-warnings}, the exit code will be non-zero. diff --git a/src/qml/doc/src/tools/qtqml-tooling-svgtoqml.qdoc b/src/qml/doc/src/tools/qtqml-tooling-svgtoqml.qdoc index e64ca28121..637a41a2f8 100644 --- a/src/qml/doc/src/tools/qtqml-tooling-svgtoqml.qdoc +++ b/src/qml/doc/src/tools/qtqml-tooling-svgtoqml.qdoc @@ -45,6 +45,10 @@ In addition, it supports the following options: \li Enables the curve renderer backend for \l{Qt Quick Shapes}. This enables smooth, antialiased shapes in the scene without multi-sampling, but at some extra cost. \row + \li \c{-a}, \c{--asynchronous-shapes} + \li Enables the {QtQuick.Shapes::Shape::asynchronous}{asynchronous} mode on all \l{Shape} + elements in the generated scene. This may improve CPU utilization and responsiveness. +\row \li \c{-p}, \c{--optimize-paths} \li Enables optimization of paths before committing them to the QML file, potentially making them faster to load and render later. @@ -53,7 +57,7 @@ In addition, it supports the following options: \li Stroke the outline (contour) of the filled shape instead of the original path. \row \li \c{-t}, \c{--type-name <string>} - \li In place of \l{Shape}, the output will use the type name <string> instead. This is + \li In place of \l{Shape}, the output will use the type name <string> instead. This enables using a custom item to override the default behavior of \l{Shape} items. \row \li \c{-v}, \c{--view} diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 950838c11c..1f9429651e 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -3167,6 +3167,8 @@ void QObjectMethod::callInternalWithMetaTypes( QV4::coerceAndCall( v4, &metaMethod, argv, types, argc, [v4, thisMeta, object](void **argv, int) { + if (!argv[0]) + return; *static_cast<QString *>(argv[0]) = QObjectWrapper::objectToString(v4, thisMeta, object.qObject()); }); diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 326b252c45..09c8033418 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -826,7 +826,7 @@ static void doRegisterTypeAndRevisions( uniqueRevisions(&revisions, type.version, added); AliasRegistrar aliasRegistrar(&elementNames); - for (QTypeRevision revision : revisions) { + for (QTypeRevision revision : std::as_const(revisions)) { if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion()) break; diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index ee7e4eb61e..b969b31b44 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -544,7 +544,10 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt QQmlImport::RecursionRestriction recursionRestriction, QList<QQmlError> *errors) const { - QQmlType t = QQmlMetaType::qmlType(type, uri, version); + // QQmlMetaType assumes that without a URI, it should look for types in any module + // But QQmlImportInstance without a URI represents a directory import, and _must not_ find + // types from completely unrelated modules + QQmlType t = uri.isEmpty() ? QQmlType() : QQmlMetaType::qmlType(type, uri, version); if (t.isValid()) { if (version_return) *version_return = version; diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 267e008466..e2c33776e4 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -184,12 +184,12 @@ public: { switch (reason) { case OverrideSemantics::Status::MissingBase: - return tr("Nothing to override. Remove override keyword"); + return tr("Nothing to override. Remove \"override\" keyword"); case OverrideSemantics::Status::OverridingFinal: return tr("Cannot override FINAL property"); case OverrideSemantics::Status::OverridingNonVirtual: - return tr("Cannot override non virtual property. Add virtual to the property of the " - "base object"); + return tr("Cannot override non virtual property. Add \"virtual\" to the property of " + "the base object"); default: return tr("unknown"); } diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h index 60081d79b1..4cdb7d1a53 100644 --- a/src/qml/qml/qqmltype_p_p.h +++ b/src/qml/qml/qqmltype_p_p.h @@ -39,7 +39,7 @@ public: { ~ProxyMetaObjects() { - for (const QQmlProxyMetaObject::ProxyData &metaObject : data) + for (const QQmlProxyMetaObject::ProxyData &metaObject : std::as_const(data)) free(metaObject.metaObject); } diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index ff2cc87ff1..bbbe805e63 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -387,11 +387,14 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions( const QQmlType type = typeRef ? typeRef->type() : QQmlType(); if (type.isValid()) { COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.") - .arg(typeName).arg(originalPropertyName).arg(type.module()) + .arg(typeName, originalPropertyName, type.module()) .arg(type.version().majorVersion()) .arg(type.version().minorVersion())); } else { - COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName)); + COMPILE_EXCEPTION( + binding, + tr("\"%1.%2\" is not available due to component versioning.") + .arg(typeName, originalPropertyName)); } } diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index e3947d15df..50e1fb3f4f 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -812,7 +812,7 @@ void QQmlTypeData::continueLoadFromIR() { assertTypeLoaderThread(); - for (auto const& object: m_document->objects) { + for (auto const& object: std::as_const(m_document->objects)) { for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) { QString const nameString = m_document->stringAt(it->nameIndex); auto importUrl = finalUrl(); @@ -1181,7 +1181,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version, error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database")); } error.setUrl(m_importCache->baseUrl()); - error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description())); + error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName, error.description())); } if (lineNumber != -1) diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp index 916f30b125..2efdb826f6 100644 --- a/src/qmlcompiler/qqmljscompiler.cpp +++ b/src/qmlcompiler/qqmljscompiler.cpp @@ -23,6 +23,7 @@ #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> #include <QtCore/qloggingcategory.h> +#include <QtCore/qelapsedtimer.h> #include <QtQml/private/qqmlsignalnames_p.h> @@ -797,15 +798,16 @@ QQmlJSAotFunction QQmlJSAotCompiler::doCompileAndRecordAotStats( const QV4::Compiler::Context *context, QQmlJSCompilePass::Function *function, const QString &name, QQmlJS::SourceLocation location) { - auto t1 = std::chrono::high_resolution_clock::now(); + QElapsedTimer timer {}; + timer.start(); QQmlJSAotFunction result; if (!m_logger->currentFunctionHasCompileError()) result = doCompile(context, function); - auto t2 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::milliseconds { timer.elapsed() }; if (QQmlJS::QQmlJSAotCompilerStats::recordAotStats()) { QQmlJS::AotStatsEntry entry; - entry.codegenDuration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1); + entry.codegenDuration = elapsed; entry.functionName = name; entry.message = m_logger->currentFunctionWasSkipped() ? m_logger->currentFunctionCompileSkipMessage() diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 02d3f2b004..4117255158 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -261,7 +261,7 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) "attachedType, " "valueType, exports, interfaces, isSingleton, isCreatable, " "isStructured, isComposite, hasCustomParser, enforcesScopedEnums, " - "aliases, exportMetaObjectRevisions, deferredNames, metaObjectHash," + "aliases, exportMetaObjectRevisions, deferredNames, metaObjectHash, " "and immediateNames in script bindings, not \"%1\".") .arg(name)); } @@ -439,8 +439,7 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ tr("Expected only type, name, lineNumber, revision, isPointer, " "isTypeConstant, isReadonly, isRequired, " "isFinal, isList, bindable, read, write, isPropertyConstant, reset, " - "notify, index, and " - "privateClass and script bindings.")); + "notify, index, privateClass and script bindings.")); } } diff --git a/src/quick/doc/src/cmake/qt_target_qml_from_svg.qdoc b/src/quick/doc/src/cmake/qt_target_qml_from_svg.qdoc index 3c72c14ecd..b6e95b6a06 100644 --- a/src/quick/doc/src/cmake/qt_target_qml_from_svg.qdoc +++ b/src/quick/doc/src/cmake/qt_target_qml_from_svg.qdoc @@ -24,6 +24,7 @@ find_package(Qt6 REQUIRED COMPONENTS QuickTools) \badcode qt_target_qml_from_svg(target [CURVE_RENDERER] + [ASYNCHRONOUS_SHAPES] [OPTIMIZE_PATHS] [OUTLINE_STROKE_MODE] [TYPE_NAME "MyShapeName"] @@ -61,9 +62,9 @@ the generated file with a custom type. This can be useful to make general custom the shapes in the provided SVG files. The \c{TYPE_NAME} should refer to a QML type which is available in the \c{target} QML module. -The options \c CURVE_RENDERER, \c OPTIMIZE_PATHS and \c OUTLINE_STROKE_MODE correspond to the -\c{--curve-renderer}, \c{--optimize-paths} and \c{--outline-stroke-mode} in \l{svgtoqml} -respectively. +The options \c CURVE_RENDERER, \c ASYNCHRONOUS_SHAPES, \c OPTIMIZE_PATHS and \c OUTLINE_STROKE_MODE +correspond to the \c{--curve-renderer}, \c{--asynchronous-shapes}, \c{--optimize-paths} and +\c{--outline-stroke-mode} in \l{svgtoqml} respectively. */ diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 0558495332..be89a90bdf 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -5955,7 +5955,7 @@ QRectF QQuickItem::boundingRect() const QRectF QQuickItem::clipRect() const { Q_D(const QQuickItem); - QRectF ret(0, 0, d->width, d->height); + QRectF ret(0, 0, d->width.valueBypassingBindings(), d->height.valueBypassingBindings()); if (flags().testFlag(QQuickItem::ItemObservesViewport)) { if (QQuickItem *viewport = viewportItem()) { // if the viewport is already "this", there's nothing to intersect; diff --git a/src/quickcontrols/doc/src/includes/qquickicon.qdocinc b/src/quickcontrols/doc/src/includes/qquickicon.qdocinc index eadaea5983..c5427dbdc1 100644 --- a/src/quickcontrols/doc/src/includes/qquickicon.qdocinc +++ b/src/quickcontrols/doc/src/includes/qquickicon.qdocinc @@ -47,6 +47,6 @@ For more information, see \l {Image::}{cache}. - This property was introduced in QtQuick.Controls 2.13. + This property was introduced in \l[QML]{QtQuick.Controls} 2.13. \endtable //! [grouped-properties] diff --git a/src/quickcontrols/doc/src/qtquickcontrols-customize.qdoc b/src/quickcontrols/doc/src/qtquickcontrols-customize.qdoc index 0084861833..768d11262a 100644 --- a/src/quickcontrols/doc/src/qtquickcontrols-customize.qdoc +++ b/src/quickcontrols/doc/src/qtquickcontrols-customize.qdoc @@ -556,7 +556,7 @@ ApplicationWindow consists of one visual item: \l {ApplicationWindow::background}{background}. - \code + \qml import QtQuick import QtQuick.Controls.Basic @@ -570,7 +570,7 @@ } } } - \endcode + \endqml \section2 Customizing BusyIndicator diff --git a/src/quickcontrols/doc/src/qtquickcontrols-fileselectors.qdoc b/src/quickcontrols/doc/src/qtquickcontrols-fileselectors.qdoc index a03970d1d8..e8d7352744 100644 --- a/src/quickcontrols/doc/src/qtquickcontrols-fileselectors.qdoc +++ b/src/quickcontrols/doc/src/qtquickcontrols-fileselectors.qdoc @@ -34,7 +34,7 @@ \c Material selector will be present and the \c +Material/CustomButton.qml version will be used instead. - \code + \qml // main.qml import QtQuick import QtQuick.Controls @@ -48,12 +48,12 @@ anchors.centerIn: parent } } - \endcode + \endqml The base implementation of the custom button is a simple rounded flat button. - \code + \qml // CustomButton.qml import QtQuick import QtQuick.Controls @@ -68,13 +68,13 @@ color: control.pressed ? "#ccc" : "#eee" } } - \endcode + \endqml The Material style's implementation of the custom button imports the Material style, requests a dark theme to get light text, and creates a drop shadow for the background. - \code + \qml // +Material/CustomButton.qml import QtQuick import QtQuick.Effects @@ -102,7 +102,7 @@ } } } - \endcode + \endqml \note It is recommended to use \l QQmlApplicationEngine, which internally creates a \l QQmlFileSelector instance. This is all that is needed to take diff --git a/src/quickcontrols/doc/src/qtquickcontrols-qmltypes.qdoc b/src/quickcontrols/doc/src/qtquickcontrols-qmltypes.qdoc index f1ff074b57..5bf879c1cd 100644 --- a/src/quickcontrols/doc/src/qtquickcontrols-qmltypes.qdoc +++ b/src/quickcontrols/doc/src/qtquickcontrols-qmltypes.qdoc @@ -34,7 +34,7 @@ type in Qt Quick Templates. Each \l {Definition of a Style}{style} that wants to provide a Menu must have a Menu.qml available, and the root item in that file must be the Menu from Qt Quick Templates. When you - import QtQuick.Controls and create a Menu in QML, the type you get is + import \c {QtQuick.Controls} and create a Menu in QML, the type you get is actually the QML Menu defined by the style's Menu.qml. In order to use a control as the type in a property declaration, you should diff --git a/src/quickcontrols/doc/src/qtquickcontrols-styles.qdoc b/src/quickcontrols/doc/src/qtquickcontrols-styles.qdoc index cfb7099eb3..d22e95212f 100644 --- a/src/quickcontrols/doc/src/qtquickcontrols-styles.qdoc +++ b/src/quickcontrols/doc/src/qtquickcontrols-styles.qdoc @@ -113,7 +113,7 @@ } \endqml - Notice that QtQuick.Controls (which is responsible for run-time style + Notice that \c {QtQuick.Controls} (which is responsible for run-time style selection) is not imported. The fallback style is specified by the qmldir of the style: @@ -127,7 +127,7 @@ \l {The QML script compiler}{QML compiler} knows which specific style is in use and can generate C++ code for bindings. - Another benefit is that the QtQuick.Controls plugin is not used and + Another benefit is that the \c {QtQuick.Controls} plugin is not used and therefore does not need to be deployed with the application. Explicit imports are also necessary if your application is built @@ -148,7 +148,7 @@ import QtQuick.Controls \endqml - The QtQuick.Controls plugin will import the style that was set at runtime + The \c{QtQuick.Controls} plugin will import the style that was set at runtime via one of the following approaches: \list diff --git a/src/quickcontrols/macos/SearchField.qml b/src/quickcontrols/macos/SearchField.qml index b81d83e95b..40b5e898b0 100644 --- a/src/quickcontrols/macos/SearchField.qml +++ b/src/quickcontrols/macos/SearchField.qml @@ -31,8 +31,8 @@ NativeStyle.DefaultSearchField { id: search control: control subControl: NativeStyle.SearchField.Search - x: searchIndicator.indicator.x - y: searchIndicator.indicator.y + x: searchIndicator.indicator ? searchIndicator.indicator.x : 0 + y: searchIndicator.indicator ? searchIndicator.indicator.y : 0 useNinePatchImage: false } @@ -49,8 +49,8 @@ NativeStyle.DefaultSearchField { visible: control.text.length > 0 control: control subControl: NativeStyle.SearchField.Clear - x: clearIndicator.indicator.x - y: clearIndicator.indicator.y + x: clearIndicator.indicator ? clearIndicator.indicator.x : 0 + y: clearIndicator.indicator ? clearIndicator.indicator.y : 0 useNinePatchImage: false } diff --git a/src/quickdialogs/quickdialogsquickimpl/CMakeLists.txt b/src/quickdialogs/quickdialogsquickimpl/CMakeLists.txt index 2c6d8fc5a1..61fedf8272 100644 --- a/src/quickdialogs/quickdialogsquickimpl/CMakeLists.txt +++ b/src/quickdialogs/quickdialogsquickimpl/CMakeLists.txt @@ -8,6 +8,7 @@ set(qml_files "qml/ColorDialog.qml" "qml/ColorInputs.qml" + "qml/DelegateBackground.qml" "qml/FileDialog.qml" "qml/FileDialogDelegate.qml" "qml/FileDialogDelegateLabel.qml" diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/ColorDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/ColorDialog.qml index 585aee6b9d..0c23ffe00e 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/ColorDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/ColorDialog.qml @@ -80,7 +80,7 @@ ColorDialogImpl { Layout.alignment: Qt.AlignRight Layout.rightMargin: 6 - Accessible.name: qsTr("Eye dropper") + Accessible.name: qsTr("Eyedropper") } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/ColorDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/ColorDialog.qml index 1a9ebe69f1..81cd1b83f6 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/ColorDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/ColorDialog.qml @@ -84,7 +84,7 @@ ColorDialogImpl { Layout.alignment: Qt.AlignRight Layout.rightMargin: 16 - Accessible.name: qsTr("Eye dropper") + Accessible.name: qsTr("Eyedropper") } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Material/ColorDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Material/ColorDialog.qml index 024da80b8b..e2a18e6b7c 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Material/ColorDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Material/ColorDialog.qml @@ -77,7 +77,7 @@ ColorDialogImpl { Layout.alignment: Qt.AlignRight Layout.rightMargin: 24 - Accessible.name: qsTr("Eye dropper") + Accessible.name: qsTr("Eyedropper") } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/ColorDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/ColorDialog.qml index f4ec10a7c8..514e47d466 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/ColorDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/ColorDialog.qml @@ -80,7 +80,7 @@ ColorDialogImpl { Layout.alignment: Qt.AlignRight Layout.rightMargin: 18 - Accessible.name: qsTr("Eye dropper") + Accessible.name: qsTr("Eyedropper") } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/ColorDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/ColorDialog.qml index 48e57ad625..c311898598 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/ColorDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/ColorDialog.qml @@ -77,7 +77,7 @@ ColorDialogImpl { Layout.alignment: Qt.AlignRight Layout.rightMargin: 6 - Accessible.name: qsTr("Eye dropper") + Accessible.name: qsTr("Eyedropper") } } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/DelegateBackground.qml b/src/quickdialogs/quickdialogsquickimpl/qml/DelegateBackground.qml new file mode 100644 index 0000000000..d0da7e8410 --- /dev/null +++ b/src/quickdialogs/quickdialogsquickimpl/qml/DelegateBackground.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2025 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 + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +Rectangle { + required property T.Control control + + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted || control.visualFocus + color: Color.blend(control.down ? control.palette.midlight : control.palette.light, + control.palette.highlight, control.highlighted ? 0.15 : 0.0) +} diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/FileDialogDelegate.qml b/src/quickdialogs/quickdialogsquickimpl/qml/FileDialogDelegate.qml index a38d64daf0..1600dbcf12 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/FileDialogDelegate.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/FileDialogDelegate.qml @@ -49,11 +49,7 @@ DialogsQuickImpl.FileDialogDelegate { fileDetailRowWidth: control.fileDetailRowWidth } - background: Rectangle { - implicitWidth: 100 - implicitHeight: 40 - visible: control.down || control.highlighted || control.visualFocus - color: Color.blend(control.down ? control.palette.midlight : control.palette.light, - control.palette.highlight, control.highlighted ? 0.15 : 0.0) + background: DelegateBackground { + control: control } } diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml b/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml index 2080100814..d10041edaa 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/SideBar.qml @@ -33,25 +33,32 @@ DialogsQuickImpl.SideBar { buttonDelegate: Button { id: buttonDelegateRoot + + required property int index + required property string folderName + flat: true highlighted: control.currentIndex === index width: listView.width - + text: folderName + spacing: 5 + icon.color: highlighted ? palette.highlightedText : palette.text contentItem: IconLabel { - spacing: 5 leftPadding: 10 topPadding: 3 bottomPadding: 3 + alignment: Qt.AlignLeft + spacing: buttonDelegateRoot.spacing icon: buttonDelegateRoot.icon - text: buttonDelegateRoot.folderName + text: buttonDelegateRoot.text font: buttonDelegateRoot.font - // same as the icon color - color: buttonDelegateRoot.icon.color - alignment: Qt.AlignLeft + defaultIconColor: buttonDelegateRoot.icon.color + color: defaultIconColor } - required property int index - required property string folderName + background: DelegateBackground { + control: buttonDelegateRoot + } Accessible.name: folderName } @@ -71,23 +78,30 @@ DialogsQuickImpl.SideBar { addFavoriteDelegate: Button { id: addFavoriteDelegateRoot + + required property string labelText + required property bool dragHovering + flat: true width: control.width + spacing: 5 + icon.color: highlighted ? palette.highlightedText : palette.text contentItem: IconLabel { - spacing: 5 leftPadding: 10 topPadding: 3 bottomPadding: 3 + alignment: Qt.AlignLeft + spacing: addFavoriteDelegateRoot.spacing icon: addFavoriteDelegateRoot.icon text: addFavoriteDelegateRoot.labelText font: addFavoriteDelegateRoot.font - // same as the icon color - color: addFavoriteDelegateRoot.icon.color - alignment: Qt.AlignLeft + defaultIconColor: addFavoriteDelegateRoot.icon.color + color: defaultIconColor opacity: addFavoriteDelegateRoot.dragHovering ? 0.2 : 1.0 } - required property string labelText - required property bool dragHovering + background: DelegateBackground { + control: addFavoriteDelegateRoot + } } } diff --git a/src/quicktemplates/qquickmenu.cpp b/src/quicktemplates/qquickmenu.cpp index 38f226bd08..2ec652ef5a 100644 --- a/src/quicktemplates/qquickmenu.cpp +++ b/src/quicktemplates/qquickmenu.cpp @@ -1733,15 +1733,11 @@ void QQuickMenu::setVisible(bool visible) Q_D(QQuickMenu); if (visible == d->visible) return; - if (visible && !parentItem()) { - qmlWarning(this) << "cannot show menu: parent is null"; - return; - } - if (visible) { + + auto *window = this->window(); + if (visible && window) { // If a right mouse button event opens a menu, don't synthesize QContextMenuEvent // (avoid opening redundant menus, e.g. in parent items). - auto *window = this->window(); - Q_ASSERT(window); QQuickWindowPrivate::get(window)->rmbContextMenuEventEnabled = false; // Also, if users have their own custom non-ContextMenu-based text editing context menus, // we want those to take priority over our own. The check above handles that when diff --git a/src/quicktemplates/qquickpopup.cpp b/src/quicktemplates/qquickpopup.cpp index 24eb5cf284..a928015ff3 100644 --- a/src/quicktemplates/qquickpopup.cpp +++ b/src/quicktemplates/qquickpopup.cpp @@ -2497,6 +2497,7 @@ void QQuickPopup::setVisible(bool visible) // d->visible is true. if (d->visible && visible && d->transitionState != QQuickPopupPrivate::ExitTransition) return; + if (!d->visible && !visible) return; @@ -2505,6 +2506,11 @@ void QQuickPopup::setVisible(bool visible) return; } + if (visible && !parentItem()) { + qmlWarning(this) << "cannot show popup: parent is null"; + return; + } + if (visible) d->transitionManager.transitionEnter(); else diff --git a/src/quicktemplates/qquickpopupwindow.cpp b/src/quicktemplates/qquickpopupwindow.cpp index cc19777aff..e576755ae4 100644 --- a/src/quicktemplates/qquickpopupwindow.cpp +++ b/src/quicktemplates/qquickpopupwindow.cpp @@ -264,7 +264,9 @@ bool QQuickPopupWindowPrivate::filterPopupSpecialCases(QEvent *event) // Note that A QQuickPopupWindow can be bigger than the // menu itself, to make room for a drop-shadow. But if the press was on top // of the shadow, targetMenu will still be nullptr. - closePopupAndParentMenus(); + // On WASM in particular, it's possible for dialogs to receive the event, when clicking in the non-client area. Don't close in those cases. + if (event->type() != QEvent::NonClientAreaMouseButtonPress && event->type() != QEvent::NonClientAreaMouseButtonDblClick) + closePopupAndParentMenus(); return false; } } else if (pe->isUpdateEvent()){ @@ -300,7 +302,9 @@ bool QQuickPopupWindowPrivate::filterPopupSpecialCases(QEvent *event) } else if (pe->isEndEvent()) { if (!targetPopup && !targetMenuBar && closePolicy.testAnyFlags(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent)) { // Released outside either a popup window, or a menu or menubar that owns a menu using popup windows. - closePopupAndParentMenus(); + // This should normally close the current popup window, unless it's inside the non-client area, which can happen in WASM dialogs. + if (event->type() != QEvent::NonClientAreaMouseButtonRelease) + closePopupAndParentMenus(); return false; } diff --git a/src/quickvectorimage/generator/qquickqmlgenerator.cpp b/src/quickvectorimage/generator/qquickqmlgenerator.cpp index a7bafb2be5..319d8be36c 100644 --- a/src/quickvectorimage/generator/qquickqmlgenerator.cpp +++ b/src/quickvectorimage/generator/qquickqmlgenerator.cpp @@ -534,6 +534,8 @@ void QQuickQmlGenerator::generatePath(const PathNodeInfo &info, const QRectF &ov if (m_flags.testFlag(QQuickVectorImageGenerator::GeneratorFlag::CurveRenderer)) stream() << "preferredRendererType: Shape.CurveRenderer"; + if (m_flags.testFlag(QQuickVectorImageGenerator::GeneratorFlag::AsyncShapes)) + stream() << "asynchronous: true"; optimizePaths(info, overrideBoundingRect); //qCDebug(lcQuickVectorGraphics) << *node->qpath(); generateNodeEnd(info); @@ -1031,6 +1033,8 @@ void QQuickQmlGenerator::generatePathContainer(const StructureNodeInfo &info) m_indentLevel++; if (m_flags.testFlag(QQuickVectorImageGenerator::GeneratorFlag::CurveRenderer)) stream() << "preferredRendererType: Shape.CurveRenderer"; + if (m_flags.testFlag(QQuickVectorImageGenerator::GeneratorFlag::AsyncShapes)) + stream() << "asynchronous: true"; m_indentLevel--; m_inShapeItemLevel++; diff --git a/src/quickvectorimage/qquickvectorimage.cpp b/src/quickvectorimage/qquickvectorimage.cpp index a55cc0d705..681f52472b 100644 --- a/src/quickvectorimage/qquickvectorimage.cpp +++ b/src/quickvectorimage/qquickvectorimage.cpp @@ -83,6 +83,8 @@ void QQuickVectorImagePrivate::loadFile() flags.setFlag(QQuickVectorImageGenerator::CurveRenderer); if (assumeTrustedSource) flags.setFlag(QQuickVectorImageGenerator::AssumeTrustedSource); + if (m_asyncShapes) + flags.setFlag(QQuickVectorImageGenerator::AsyncShapes); if (!m_qmlContext || m_qmlContext->engine() != qmlContext(q)->engine()) m_qmlContext.reset(new QQmlContext(qmlContext(q)->engine())); @@ -301,6 +303,35 @@ void QQuickVectorImage::setPreferredRendererType(RendererType newPreferredRender } /*! + \qmlproperty bool QtQuick.VectorImage::VectorImage::asynchronousShapes + \since 6.11 + + This property controls the {QtQuick.Shapes::Shape::asynchronous}{asynchronous} property of the + \l Shape items in the Quick scene that VectorImage builds to represent the image. + + Setting this property to \c true will offload the CPU part of the rendering processing of the + shapes to separate worker threads. This can improve CPU utilization and user interface + responsiveness. + + By default this property is \c false. +*/ + +bool QQuickVectorImage::asynchronousShapes() const +{ + Q_D(const QQuickVectorImage); + return d->m_asyncShapes; +} + +void QQuickVectorImage::setAsynchronousShapes(bool asynchronous) +{ + Q_D(QQuickVectorImage); + if (d->m_asyncShapes == asynchronous) + return; + d->m_asyncShapes = asynchronous; + emit asynchronousShapesChanged(); +} + +/*! \qmlproperty bool QtQuick.VectorImage::VectorImage::assumeTrustedSource \since 6.10 diff --git a/src/quickvectorimage/qquickvectorimage_p.h b/src/quickvectorimage/qquickvectorimage_p.h index f5d3aa0f51..796dfcb937 100644 --- a/src/quickvectorimage/qquickvectorimage_p.h +++ b/src/quickvectorimage/qquickvectorimage_p.h @@ -33,6 +33,7 @@ class Q_QUICKVECTORIMAGE_EXPORT QQuickVectorImage : public QQuickItem Q_PROPERTY(RendererType preferredRendererType READ preferredRendererType WRITE setPreferredRendererType NOTIFY preferredRendererTypeChanged) Q_PROPERTY(QQuickVectorImageAnimations *animations READ animations CONSTANT REVISION(6, 10) FINAL) Q_PROPERTY(bool assumeTrustedSource READ assumeTrustedSource WRITE setAssumeTrustedSource NOTIFY assumeTrustedSourceChanged FINAL) + Q_PROPERTY(bool asynchronousShapes READ asynchronousShapes WRITE setAsynchronousShapes NOTIFY asynchronousShapesChanged REVISION(6, 11) FINAL) QML_NAMED_ELEMENT(VectorImage) public: @@ -61,6 +62,9 @@ public: RendererType preferredRendererType() const; void setPreferredRendererType(RendererType newPreferredRendererType); + bool asynchronousShapes() const; + void setAsynchronousShapes(bool asynchronous); + QQuickVectorImageAnimations *animations(); bool assumeTrustedSource() const; @@ -73,6 +77,7 @@ signals: void fillModeChanged(); void preferredRendererTypeChanged(); + void asynchronousShapesChanged(); void assumeTrustedSourceChanged(); private slots: diff --git a/src/quickvectorimage/qquickvectorimage_p_p.h b/src/quickvectorimage/qquickvectorimage_p_p.h index 5c7a552fdf..5599c414d7 100644 --- a/src/quickvectorimage/qquickvectorimage_p_p.h +++ b/src/quickvectorimage/qquickvectorimage_p_p.h @@ -43,6 +43,7 @@ public: QQuickVectorImage::RendererType preferredRendererType = QQuickVectorImage::GeometryRenderer; QQuickVectorImageAnimations *animations = nullptr; bool assumeTrustedSource = false; + bool m_asyncShapes = false; std::unique_ptr<QQmlContext> m_qmlContext; }; diff --git a/src/quickvectorimage/qquickvectorimageglobal_p.h b/src/quickvectorimage/qquickvectorimageglobal_p.h index 61c673b04d..4515cf077d 100644 --- a/src/quickvectorimage/qquickvectorimageglobal_p.h +++ b/src/quickvectorimage/qquickvectorimageglobal_p.h @@ -33,6 +33,7 @@ namespace QQuickVectorImageGenerator CurveRenderer = 0x02, OutlineStrokeMode = 0x04, AssumeTrustedSource = 0x08, + AsyncShapes = 0x10 }; Q_DECLARE_FLAGS(GeneratorFlags, GeneratorFlag); |
