diff options
| author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-12-15 16:14:22 +0200 |
|---|---|---|
| committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-12-15 16:14:22 +0200 |
| commit | b58ec3b086518da5aa573f99426235854c23e35f (patch) | |
| tree | 861a9935d8f1cdba2fdca546836a351736dbddbf /src/quicktemplates | |
| parent | 4826f86e274f1b29bd769e6790824f9e62a40f62 (diff) | |
| parent | 22032227d16c39211e2ebceef97d21f4d89c7c87 (diff) | |
Merge tag 'v6.5.8-lts-lgpl' into 6.56.5
Qt 6.5.8-lts-lgpl release
Diffstat (limited to 'src/quicktemplates')
| -rw-r--r-- | src/quicktemplates/doc/src/qtquicktemplates-qmltypes.qdoc | 13 | ||||
| -rw-r--r-- | src/quicktemplates/qquickcombobox.cpp | 11 | ||||
| -rw-r--r-- | src/quicktemplates/qquickdeferredexecute.cpp | 25 | ||||
| -rw-r--r-- | src/quicktemplates/qquickmenu.cpp | 8 | ||||
| -rw-r--r-- | src/quicktemplates/qquickmenu_p_p.h | 1 | ||||
| -rw-r--r-- | src/quicktemplates/qquickoverlay.cpp | 33 | ||||
| -rw-r--r-- | src/quicktemplates/qquickpopup.cpp | 15 |
7 files changed, 98 insertions, 8 deletions
diff --git a/src/quicktemplates/doc/src/qtquicktemplates-qmltypes.qdoc b/src/quicktemplates/doc/src/qtquicktemplates-qmltypes.qdoc index c2c183ae72..10bdc2af58 100644 --- a/src/quicktemplates/doc/src/qtquicktemplates-qmltypes.qdoc +++ b/src/quicktemplates/doc/src/qtquicktemplates-qmltypes.qdoc @@ -10,6 +10,11 @@ The \l {Qt Quick Templates 2} module provides a set of non-visual templates that can be used to build user interface controls in QML using \l {Qt Quick}. + These types should be used when you want to implement a control from + scratch, rather than \l {Customizing a Control}{customizing an existing + control}. This is most commonly the case when \l {Creating a Custom + Style}{creating a custom style}. + The QML types can be imported using the following import statement in your \c .qml file: @@ -17,10 +22,10 @@ import QtQuick.Templates as T \endqml - For the sake of clarity, there is a one-to-one mapping between the types - provided by the \c QtQuick.Templates and \c QtQuick.Controls imports. For - every type available in the \c QtQuick.Controls import, a non-visual template - type by the same name exists in the \c QtQuick.Templates import. + There is a one-to-one mapping between the types provided by the \c + QtQuick.Templates and \c QtQuick.Controls imports. For every type available + in the \c QtQuick.Controls import, a non-visual template type by the same + name exists in the \c QtQuick.Templates import. \note It is recommended to use a namespace for the templates import to avoid overlap with the types provided by the \c QtQuick.Controls import. diff --git a/src/quicktemplates/qquickcombobox.cpp b/src/quicktemplates/qquickcombobox.cpp index 6e08019000..d9832aaf94 100644 --- a/src/quicktemplates/qquickcombobox.cpp +++ b/src/quicktemplates/qquickcombobox.cpp @@ -1037,10 +1037,15 @@ void QQuickComboBox::setModel(const QVariant& m) } /*! - \internal + \readonly \qmlproperty model QtQuick.Controls::ComboBox::delegateModel - This property holds the model providing delegate instances for the combo box. + This property holds the model that provides delegate instances for the combo box. + + It is typically assigned to a \l ListView in the \l {Popup::}{contentItem} + of the \l popup. + + \sa {Customizing ComboBox} */ QQmlInstanceModel *QQuickComboBox::delegateModel() const { @@ -1869,7 +1874,7 @@ QString QQuickComboBox::textAt(int index) const \value Qt.MatchWildcard The search term matches using wildcards. \value Qt.MatchFixedString The search term matches as a fixed string. \value Qt.MatchStartsWith The search term matches the start of the item. - \value Qt.MatchEndsWidth The search term matches the end of the item. + \value Qt.MatchEndsWith The search term matches the end of the item. \value Qt.MatchContains The search term is contained in the item. \value Qt.MatchCaseSensitive The search is case sensitive. diff --git a/src/quicktemplates/qquickdeferredexecute.cpp b/src/quicktemplates/qquickdeferredexecute.cpp index 239b0fa6a6..8e63ae2188 100644 --- a/src/quicktemplates/qquickdeferredexecute.cpp +++ b/src/quicktemplates/qquickdeferredexecute.cpp @@ -13,6 +13,31 @@ QT_BEGIN_NAMESPACE +/*! + \internal + + For the history behind why these functions were introduced, see + the comments of QTBUG-50992, specifically + \l {https://bugreports.qt.io/browse/QTBUG-50992?focusedId=325677&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325677}{this}. + + The first commit to the QML engine to support deferred properties seems to + be 59b8d719d6122d86a4cc650911788cc4d778ce29. + + The first commit to add support for it in Controls was + 458eb65f730178bc93ba7b18f0e4dd2a13efad2e. + + In short, deferred execution solved two issues: + + \list 1 + \li Incubation issues when using asynchronous loaders, AKA QTBUG-50992. + \li Performance issues from creating two items unnecessarily when a + styled control was customized, which is explained in more detail + in the commit message of 458eb65f730178bc93ba7b18f0e4dd2a13efad2e. + \endlist + + \sa qmlExecuteDeferred +*/ + namespace QtQuickPrivate { static void cancelDeferred(QQmlData *ddata, int propertyIndex) diff --git a/src/quicktemplates/qquickmenu.cpp b/src/quicktemplates/qquickmenu.cpp index d46a2a862f..f53e9a9091 100644 --- a/src/quicktemplates/qquickmenu.cpp +++ b/src/quicktemplates/qquickmenu.cpp @@ -471,6 +471,14 @@ bool QQuickMenuPrivate::blockInput(QQuickItem *item, const QPointF &point) const return (cascade && parentMenu && contains(point)) || QQuickPopupPrivate::blockInput(item, point); } +bool QQuickMenuPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + // Don't propagate mouse event as it can cause underlying item to receive + // events + return QQuickPopupPrivate::handlePress(item, point, timestamp) + || (popupItem == item); +} + void QQuickMenuPrivate::onItemHovered() { Q_Q(QQuickMenu); diff --git a/src/quicktemplates/qquickmenu_p_p.h b/src/quicktemplates/qquickmenu_p_p.h index 509614d2d1..82f66abff0 100644 --- a/src/quicktemplates/qquickmenu_p_p.h +++ b/src/quicktemplates/qquickmenu_p_p.h @@ -66,6 +66,7 @@ public: bool prepareEnterTransition() override; bool prepareExitTransition() override; bool blockInput(QQuickItem *item, const QPointF &point) const override; + bool handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) override; void onItemHovered(); void onItemTriggered(); diff --git a/src/quicktemplates/qquickoverlay.cpp b/src/quicktemplates/qquickoverlay.cpp index c9d3cf9892..091b2f8fb3 100644 --- a/src/quicktemplates/qquickoverlay.cpp +++ b/src/quicktemplates/qquickoverlay.cpp @@ -97,9 +97,32 @@ bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos) return false; } +static QQuickItem *findRootOfOverlaySubtree(QQuickItem *source, const QQuickOverlay *overlay) +{ + QQuickItem *sourceAncestor = source; + while (sourceAncestor) { + QQuickItem *parentItem = sourceAncestor->parentItem(); + if (parentItem == overlay) + return sourceAncestor; + sourceAncestor = parentItem; + } + // Not an ancestor of the overlay. + return nullptr; +} + bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target) { + Q_Q(const QQuickOverlay); if (target) { + // childMouseEventFilter will cause this function to get called for each active popup. + // If any of those active popups block inputs, the delivery agent won't send the press event to source. + // A popup will block input, if it's modal, and the item isn't an ancestor of the popup's popup item. + // If source doesn't belong to a popup, but exists in an overlay subtree, it makes sense to not filter the event. + const QList<QQuickItem *> childItems = paintOrderChildItems(); + if (childItems.indexOf(findRootOfOverlaySubtree(source, q)) + > childItems.indexOf(QQuickPopupPrivate::get(target)->popupItem)) + return false; + if (target->overlayEvent(source, event)) { setMouseGrabberPopup(target); return true; @@ -143,7 +166,17 @@ bool QQuickOverlayPrivate::handleMove(QQuickItem *source, QEvent *event, QQuickP bool QQuickOverlayPrivate::handleRelease(QQuickItem *source, QEvent *event, QQuickPopup *target) { + Q_Q(const QQuickOverlay); if (target) { + // childMouseEventFilter will cause this function to get called for each active popup. + // If any of those active popups block inputs, the delivery agent won't send the press event to source. + // A popup will block input, if it's modal, and the item isn't an ancestor of the popup's popup item. + // If source doesn't belong to a popup, but exists in an overlay subtree, it makes sense to not filter the event. + const QList<QQuickItem *> childItems = paintOrderChildItems(); + if (childItems.indexOf(findRootOfOverlaySubtree(source, q)) + > childItems.indexOf(QQuickPopupPrivate::get(target)->popupItem)) + return false; + setMouseGrabberPopup(nullptr); if (target->overlayEvent(source, event)) { setMouseGrabberPopup(nullptr); diff --git a/src/quicktemplates/qquickpopup.cpp b/src/quicktemplates/qquickpopup.cpp index e48f944936..bc573a3313 100644 --- a/src/quicktemplates/qquickpopup.cpp +++ b/src/quicktemplates/qquickpopup.cpp @@ -467,7 +467,8 @@ bool QQuickPopupPrivate::blockInput(QQuickItem *item, const QPointF &point) cons // don't block presses and releases // a) outside a non-modal popup, // b) to popup children/content, or - // b) outside a modal popups's background dimming + // c) outside a modal popups's background dimming + return modal && ((popupItem != item) && !popupItem->isAncestorOf(item)) && (!dimmer || dimmer->contains(dimmer->mapFromScene(point))); } @@ -2797,6 +2798,18 @@ void QQuickPopup::mouseUngrabEvent() d->handleUngrab(); } +/*! + \internal + + Called whenever the window receives a Wheel/Hover/Mouse/Touch event, + and has an active popup (with popupType: Popup.Item) in its scene. + + The purpose is to close popups when the press/release event happened outside of it, + and the closePolicy allows for it to happen. + + If the function is called from childMouseEventFilter, then the return value of this + function will determine whether the event will be filtered, or delivered to \a item. +*/ bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) { Q_D(QQuickPopup); |
