aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickflickable.cpp4
-rw-r--r--src/quick/items/qquickitem.cpp60
-rw-r--r--src/quick/items/qquickitemview.cpp4
-rw-r--r--src/quick/items/qquicklistview.cpp46
-rw-r--r--src/quick/items/qquickmousearea.cpp9
-rw-r--r--src/quick/items/qquickscreen.cpp2
-rw-r--r--src/quick/items/qquickwindow.cpp29
-rw-r--r--src/quick/items/qquickwindow_p.h1
8 files changed, 113 insertions, 42 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 77a4bef646..29b2bafa0e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1726,7 +1726,9 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
|| (yflick() && qAbs(d->accumulatedWheelPixelDelta.y()) > qAbs(d->accumulatedWheelPixelDelta.x() * 2))) {
d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta,
true, !d->scrollingPhase, true, velocity);
- event->accept();
+ d->updateBeginningEnd();
+ if ((xflick() && !isAtXBeginning() && !isAtXEnd()) || (yflick() && !isAtYBeginning() && !isAtYEnd()))
+ event->accept();
} else {
qCDebug(lcWheel) << "not dragging: accumulated deltas" << d->accumulatedWheelPixelDelta <<
"moving?" << isMoving() << "can flick horizontally?" << xflick() << "vertically?" << yflick();
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 1e4af6838d..82587a178a 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2375,6 +2375,20 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
if (item == item->window()->contentItem())
return true;
+ const auto tabFocus = QGuiApplication::styleHints()->tabFocusBehavior();
+ if (tabFocus == Qt::NoTabFocus)
+ return false;
+ if (tabFocus == Qt::TabFocusAllControls)
+ return true;
+
+ QVariant editable = item->property("editable");
+ if (editable.isValid())
+ return editable.toBool();
+
+ QVariant readonly = item->property("readOnly");
+ if (readonly.isValid())
+ return !readonly.toBool() && item->property("text").isValid();
+
#if QT_CONFIG(accessibility)
QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole();
if (role == QAccessible::EditableText || role == QAccessible::Table || role == QAccessible::List) {
@@ -2385,14 +2399,6 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
}
#endif
- QVariant editable = item->property("editable");
- if (editable.isValid())
- return editable.toBool();
-
- QVariant readonly = item->property("readOnly");
- if (readonly.isValid() && !readonly.toBool() && item->property("text").isValid())
- return true;
-
return false;
}
@@ -2473,8 +2479,6 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
if (!contentItem)
return item;
- bool all = QGuiApplication::styleHints()->tabFocusBehavior() == Qt::TabFocusAllControls;
-
QQuickItem *from = nullptr;
bool isTabFence = item->d_func()->isTabFence;
if (forward) {
@@ -2594,7 +2598,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
}
}
} while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()
- || !(all || QQuickItemPrivate::canAcceptTabFocus(current)));
+ || !(QQuickItemPrivate::canAcceptTabFocus(current)));
return current;
}
@@ -2666,9 +2670,10 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
while (!scopeItem->isFocusScope() && scopeItem->parentItem())
scopeItem = scopeItem->parentItem();
if (d->window) {
- d->deliveryAgentPrivate()->
- clearFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
+ if (QQuickDeliveryAgentPrivate *da = d->deliveryAgentPrivate()) {
+ da->clearFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
QQuickDeliveryAgentPrivate::DontChangeFocusProperty);
+ }
if (scopeFocusedItem != this)
QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
} else {
@@ -2742,9 +2747,10 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
emit scopeFocusedItem->focusChanged(false);
} else {
if (d->window) {
- d->deliveryAgentPrivate()->
- setFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
+ if (QQuickDeliveryAgentPrivate *da = d->deliveryAgentPrivate()) {
+ da->setFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
QQuickDeliveryAgentPrivate::DontChangeFocusProperty);
+ }
} else {
QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
}
@@ -6499,9 +6505,10 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
dirty(Visible);
if (parentItem)
QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
- if (window)
- if (auto agent = deliveryAgentPrivate(); agent)
+ if (window) {
+ if (auto agent = deliveryAgentPrivate())
agent->removeGrabber(q, true, true, true);
+ }
bool childVisibilityChanged = false;
for (int ii = 0; ii < childItems.size(); ++ii)
@@ -6839,12 +6846,26 @@ void QQuickItem::setSmooth(bool smooth)
key events used by Keys or KeyNavigation have precedence over
focus chain behavior; ignore the events in other key handlers
to allow it to propagate.
+
+ \note {QStyleHints::tabFocusBehavior}{tabFocusBehavior} can further limit focus
+ to only specific types of controls, such as only text or list controls. This is
+ the case on macOS, where focus to particular controls may be restricted based on
+ system settings.
+
+ \sa QStyleHints::tabFocusBehavior, focusPolicy
*/
/*!
\property QQuickItem::activeFocusOnTab
This property holds whether the item wants to be in the tab focus
chain. By default, this is set to \c false.
+
+ \note {QStyleHints::tabFocusBehavior}{tabFocusBehavior} can further limit focus
+ to only specific types of controls, such as only text or list controls. This is
+ the case on macOS, where focus to particular controls may be restricted based on
+ system settings.
+
+ \sa QStyleHints::tabFocusBehavior, focusPolicy
*/
bool QQuickItem::activeFocusOnTab() const
{
@@ -8381,7 +8402,8 @@ void QQuickItem::ungrabTouchPoints()
Q_D(QQuickItem);
if (!d->window)
return;
- d->deliveryAgentPrivate()->removeGrabber(this, false, true);
+ if (QQuickDeliveryAgentPrivate *da = d->deliveryAgentPrivate())
+ da->removeGrabber(this, false, true);
}
/*!
@@ -9877,7 +9899,7 @@ QRectF QQuickItem::mapFromItem(const QQuickItem *item, qreal x, qreal y, qreal w
//! \internal
QPointF QQuickItem::mapToItem(const QQuickItem *item, qreal x, qreal y)
-{ return mapToItem(item, QPoint(x, y)); }
+{ return mapToItem(item, QPointF(x, y)); }
//! \internal
QRectF QQuickItem::mapToItem(const QQuickItem *item, const QRectF &rect) const
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 210759585b..2da1f172f1 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2497,7 +2497,9 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::Reu
// One case where this can happen is moving an item out of one ObjectModel and into another.
QQuickItemPrivate::get(item->item)->setCulled(true);
}
- if (!isClearing)
+ // If deleteLater was called, the item isn't long for this world and so we shouldn't store references to it.
+ // This can happen when a Repeater is used to populate items in SwipeView's ListView contentItem.
+ if (!isClearing && !QObjectPrivate::get(item->item)->deleteLaterCalled)
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
} else if (flags & QQmlInstanceModel::Destroyed) {
item->item->setParentItem(nullptr);
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 92b66ca5ed..063c48260a 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -2077,7 +2077,7 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *
The list view itself is a focus scope (see \l{Keyboard Focus in Qt Quick} for more details).
Delegates are instantiated as needed and may be destroyed at any time.
- As such, state should \e never be stored in a delegate.
+ As such, \l {Avoid Storing State in Delegates}{state should \e never be stored in a delegate}.
Delegates are usually parented to ListView's \l {Flickable::contentItem}{contentItem}, but
typically depending on whether it's visible in the view or not, the \e parent
can change, and sometimes be \c null. Because of that, binding to
@@ -2215,8 +2215,9 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *
item is reused. This includes \c index and \c row, but also
any model roles.
- \note Avoid storing any state inside a delegate. If you do, reset it
- manually on receiving the \l ListView::reused signal.
+ \note \l {Avoid Storing State in Delegates}{Avoid storing any state inside
+ a delegate}. If you do, reset it manually on receiving the
+ \l ListView::reused signal.
If an item has timers or animations, consider pausing them on receiving
the \l ListView::pooled signal. That way you avoid using the CPU resources
@@ -2248,6 +2249,45 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *
items, at the expense of additional memory usage. \l{ListView::section}{Sections}
have the same effect because they attach and elongate the section label to the
first item within the section.
+
+ \section1 Avoid Storing State in Delegates
+
+ ListView's delegates are instantiated as needed and may be destroyed when
+ out of view. For an illustration of this, run the following example:
+
+ \snippet qml/listview/stateInDelegate.qml ListView
+
+ When an item is clicked, \c channelActivated is set to \c true. However,
+ because delegates can be \l {Reusing Items}{reused} and destroyed, all
+ state is lost when the view is moved far enough. When the delegate becomes
+ visible again, it will have its default, unmodified state (or, in the case
+ of an item that was reused, old state from a previous item).
+
+ To avoid this, state should be stored in the model:
+
+ \snippet qml/listview/stateInModel.qml ListView
+
+ \section1 Hiding Delegates
+
+ Setting a delegate's \l {Item::}{visible} property to \c false will hide
+ that item, but the space it occupied in the view will remain. It is
+ possible to set the item's \l {Item::}{height} to \c 0 (for a \l
+ {ListView::orientation}{vertical} ListView):
+
+ \snippet qml/listview/hideDelegate.qml ListView
+
+ Note that the hidden state is stored in the model, following the advice of
+ the \l {Avoid Storing State in Delegates} section.
+
+ However, if \l spacing is non-zero, there will be uneven gaps between
+ delegates.
+
+ A better option is to filter your model so that items that should not be
+ visible are not loaded by the view at all. This can be achieved with
+ \l QSortFilterProxyModel.
+
+ Another option is to \l {Item::enabled}{disable} the delegate instead of
+ hiding it.
*/
QQuickListView::QQuickListView(QQuickItem *parent)
: QQuickItemView(*(new QQuickListViewPrivate), parent)
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 44cbec55b8..b24a733501 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -825,6 +825,7 @@ void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event)
me.setPosition(d->lastPos);
emit mouseYChanged(&me);
me.setPosition(d->lastPos);
+ emit positionChanged(&me);
}
// A MouseArea should not block hover events
@@ -1224,6 +1225,10 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventS
{
Q_D(QQuickMouseArea);
+ // Don't allow entering pressed state while invisible
+ if (p && !d->effectiveVisible)
+ return false;
+
#if QT_CONFIG(quick_draganddrop)
bool dragged = d->drag && d->drag->active();
#else
@@ -1320,6 +1325,10 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventS
\endcode
The default value is \c Qt.ArrowCursor.
+
+ \note If the \c cursorShape property is set to \c undefined, the \c MouseArea will
+ not change the existing shape when entering it.
+
\sa Qt::CursorShape
*/
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index c8405ca9ad..cdcab39773 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -197,8 +197,8 @@ QT_BEGIN_NAMESPACE
QQuickScreenInfo::QQuickScreenInfo(QObject *parent, QScreen *wrappedScreen)
: QObject(parent)
- , m_screen(wrappedScreen)
{
+ setWrappedScreen(wrappedScreen);
}
QString QQuickScreenInfo::name() const
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 9de90f8d82..d5d5454f22 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -826,13 +826,17 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- return QQmlListProperty<QObject>(q_func(), nullptr,
- QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear,
- QQuickWindowPrivate::data_replace,
- QQuickWindowPrivate::data_removeLast);
+ QQmlListProperty<QObject> ret;
+
+ ret.object = q_func();
+ ret.append = QQuickWindowPrivate::data_append;
+ ret.count = QQuickWindowPrivate::data_count;
+ ret.at = QQuickWindowPrivate::data_at;
+ ret.clear = QQuickWindowPrivate::data_clear;
+ // replace is not supported by QQuickItem. Don't synthesize it.
+ ret.removeLast = QQuickWindowPrivate::data_removeLast;
+
+ return ret;
}
void QQuickWindowPrivate::dirtyItem(QQuickItem *)
@@ -1840,13 +1844,6 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
itemProperty.clear(&itemProperty);
}
-void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, qsizetype i, QObject *o)
-{
- QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
- QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
- itemProperty.replace(&itemProperty, i, o);
-}
-
void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
{
QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
@@ -4166,8 +4163,8 @@ void QQuickWindow::setGraphicsConfiguration(const QQuickGraphicsConfiguration &c
}
/*!
- \return the QQuickGraphicsDevice passed to setGraphicsDevice(), or a
- default constructed one otherwise
+ \return the QQuickGraphicsConfiguration passed to
+ setGraphicsConfiguration(), or a default constructed one otherwise.
\since 6.0
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 558c7d8fc2..6393e4a0cb 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -231,7 +231,6 @@ public:
static qsizetype data_count(QQmlListProperty<QObject> *);
static QObject *data_at(QQmlListProperty<QObject> *, qsizetype);
static void data_clear(QQmlListProperty<QObject> *);
- static void data_replace(QQmlListProperty<QObject> *, qsizetype, QObject *);
static void data_removeLast(QQmlListProperty<QObject> *);
static void rhiCreationFailureMessage(const QString &backendName,