aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2025-12-15 16:14:22 +0200
committerTarja Sundqvist <tarja.sundqvist@qt.io>2025-12-15 16:14:22 +0200
commitb58ec3b086518da5aa573f99426235854c23e35f (patch)
tree861a9935d8f1cdba2fdca546836a351736dbddbf /src/quicktemplates
parent4826f86e274f1b29bd769e6790824f9e62a40f62 (diff)
parent22032227d16c39211e2ebceef97d21f4d89c7c87 (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.qdoc13
-rw-r--r--src/quicktemplates/qquickcombobox.cpp11
-rw-r--r--src/quicktemplates/qquickdeferredexecute.cpp25
-rw-r--r--src/quicktemplates/qquickmenu.cpp8
-rw-r--r--src/quicktemplates/qquickmenu_p_p.h1
-rw-r--r--src/quicktemplates/qquickoverlay.cpp33
-rw-r--r--src/quicktemplates/qquickpopup.cpp15
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);