From d76efbe8efab30eddbdf48b77fbbec712e2e7652 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 28 Feb 2022 15:28:34 +0100 Subject: QQuickLoader: Check for QQmlEngine before using it The loader's context may have been removed from the context hierarchy or it may not have a context in the first place. We should not crash then. Fixes: QTBUG-67950 Change-Id: I1058d5b1f978aa040f8b2f018c4357dd7a3ef333 Reviewed-by: Fabian Kosmale (cherry picked from commit 79e885537f8546a18d7d9d902d6efe40b1915c96) --- src/quick/items/qquickloader.cpp | 26 +++++++++++++++++++------- src/quick/items/qquickloader_p_p.h | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 93cff95b7b..7b08ec5a66 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -439,9 +439,8 @@ void QQuickLoader::loadFromSource() } if (isComponentComplete()) { - QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous; if (!d->component) - d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); + d->createComponent(); d->load(); } } @@ -806,11 +805,8 @@ void QQuickLoader::componentComplete() Q_D(QQuickLoader); QQuickItem::componentComplete(); if (active()) { - if (d->loadingFromSource) { - QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous; - if (!d->component) - d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); - } + if (d->loadingFromSource && !d->component) + d->createComponent(); d->load(); } } @@ -1044,6 +1040,22 @@ void QQuickLoaderPrivate::updateStatus() } } +void QQuickLoaderPrivate::createComponent() +{ + Q_Q(QQuickLoader); + const QQmlComponent::CompilationMode mode = asynchronous + ? QQmlComponent::Asynchronous + : QQmlComponent::PreferSynchronous; + if (QQmlContext *context = qmlContext(q)) { + if (QQmlEngine *engine = context->engine()) { + component.setObject(new QQmlComponent(engine, source, mode, q), q); + return; + } + } + + qmlWarning(q) << "createComponent: Cannot find a QML engine."; +} + #include QT_END_NAMESPACE diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h index 5fc231a8e6..4c63b82b6a 100644 --- a/src/quick/items/qquickloader_p_p.h +++ b/src/quick/items/qquickloader_p_p.h @@ -98,6 +98,7 @@ public: QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error); QQuickLoader::Status computeStatus() const; void updateStatus(); + void createComponent(); qreal getImplicitWidth() const override; qreal getImplicitHeight() const override; -- cgit v1.2.3 From 253922cc74ebb4c62c224e70fccee02a72016d35 Mon Sep 17 00:00:00 2001 From: Jaishree Vyas Date: Mon, 28 Mar 2022 15:24:55 +0200 Subject: Doc: Improve cursorPosition description in TextInput and TextEdit docs Fixes: QTBUG-97169 Change-Id: I060be767dd980c489d8e5426d67f2e8b6d21e96c Reviewed-by: Leena Miettinen Reviewed-by: Shawn Rutledge Reviewed-by: Ivan Tkachenko Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 79807f37b5e9e9744fdaf7af380fd7bfb7ed85f4) Reviewed-by: Qt Cherry-pick Bot --- src/quick/items/qquicktextedit.cpp | 10 +++++++++- src/quick/items/qquicktextinput.cpp | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 2d0402a9c2..c21844f1d6 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1204,7 +1204,15 @@ void QQuickTextEdit::setCursorVisible(bool on) /*! \qmlproperty int QtQuick::TextEdit::cursorPosition - The position of the cursor in the TextEdit. + The position of the cursor in the TextEdit. The cursor is positioned between + characters. + + \note The \e characters in this case refer to the string of \l QChar objects, + therefore 16-bit Unicode characters, and the position is considered an index + into this string. This does not necessarily correspond to individual graphemes + in the writing system, as a single grapheme may be represented by multiple + Unicode characters, such as in the case of surrogate pairs, linguistic + ligatures or diacritics. */ int QQuickTextEdit::cursorPosition() const { diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 4c76352171..631c687ee7 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -831,7 +831,20 @@ void QQuickTextInput::setCursorVisible(bool on) /*! \qmlproperty int QtQuick::TextInput::cursorPosition - The position of the cursor in the TextInput. + The position of the cursor in the TextInput. The cursor is positioned between + characters. + + \note The \e characters in this case refer to the string of \l QChar objects, + therefore 16-bit Unicode characters, and the position is considered an index + into this string. This does not necessarily correspond to individual graphemes + in the writing system, as a single grapheme may be represented by multiple + Unicode characters, such as in the case of surrogate pairs, linguistic + ligatures or diacritics. + + \l displayText is different if echoMode is set to \l TextInput.Password: then + each passwordMaskCharacter is a "narrow" character + (the cursorPosition always moves by 1), even if the text in the TextInput is not. + */ int QQuickTextInput::cursorPosition() const { -- cgit v1.2.3 From d4021a8d62287219a4be9fbd555b9ba91130737a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 29 Apr 2022 15:18:08 +0200 Subject: MouseArea: don't get stuck in doubleClick if handler caused ungrab The bug scenario went like this: 1) QQuickMouseArea::mouseDoubleClickEvent() emits doubleClicked 2) onDoubleClicked in QML hid the MouseArea somehow 3) QQuickMouseArea::ungrabMouse() is called; it sets d->pressed = Qt::NoButton and d->doubleClick = false (and others) 4) eventually we get back to the continuation of mouseDoubleClickEvent() which sets d->doubleClick back to true 5) mouse release: this MouseArea is not involved (no grab anymore) 6) next mouse press: QQuickMouseArea::setPressed() has if (!d->doubleClick) emit pressed(&me); pressed() is not emitted because of leftover state So either we need to avoid setting d->doubleClick to true if d->pressed has been set to Qt::NoButton in QQuickMouseArea::ungrabMouse(); or else we should reorder the statements in mouseDoubleClickEvent() to set d->doubleClick before emitting doubleClicked, so that it will not be overridden after the QML handler is called. This patch takes the first approach. Fixes: QTBUG-35995 Fixes: QTBUG-102158 Change-Id: Ibe5c9bfbc9c7a70772dd5ebfbc9ce401c6c226d3 Reviewed-by: Fabian Kosmale (cherry picked from commit 089c3b15b95fc0ddbf2385378f96702a999771c8) --- src/quick/items/qquickmousearea.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index 39e0652605..7f5272a142 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -825,7 +825,8 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) emit this->doubleClicked(&me); if (!me.isAccepted()) d->propagate(&me, QQuickMouseAreaPrivate::DoubleClick); - d->doubleClick = d->isDoubleClickConnected() || me.isAccepted(); + if (d->pressed) + d->doubleClick = d->isDoubleClickConnected() || me.isAccepted(); } QQuickItem::mouseDoubleClickEvent(event); } -- cgit v1.2.3 From 4afd45162c1c63a24f6cd1e73c4ad3e368c5a11a Mon Sep 17 00:00:00 2001 From: Nicholas Bennett Date: Wed, 4 May 2022 13:57:59 +0300 Subject: Docs: Document textInput.acceptableInput as read only Added \readonly to the qml property comment. Fixes: QTBUG-103224 Change-Id: I42ddad6501700c586fe4154cd675d881a4686f8d Reviewed-by: Shawn Rutledge (cherry picked from commit c00e9fbbf397bb155da43b2b0c18ca5e8e2697cd) Reviewed-by: Qt Cherry-pick Bot --- src/quick/items/qquicktextinput.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 631c687ee7..8ceb8827f5 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1165,6 +1165,7 @@ void QQuickTextInput::setInputMask(const QString &im) /*! \qmlproperty bool QtQuick::TextInput::acceptableInput + \readonly This property is always true unless a validator or input mask has been set. If a validator or input mask has been set, this property will only be true -- cgit v1.2.3 From 9a18deda600d22e564a3b723b7d8a0021cfcb8bf Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 2 May 2022 15:51:45 +0200 Subject: PinchArea: ignore ZoomNativeGesture and RotateNativeGesture if told to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As with most event-handling Items, the user can reject the first event by setting accepted to false in QML. It was implemented for touch events, but not for native gesture events. Amends d896d76b0f2ff0387cd09a04107ea5df087268e1 Fixes: QTBUG-101628 Change-Id: I05a15cb71e6c97c35d6e56a58d9d59028fe33462 Reviewed-by: Jan Arve Sæther (cherry picked from commit 175681bbbc5f69426330aa3061abd280264670b6) Reviewed-by: Qt Cherry-pick Bot --- src/quick/items/qquickpincharea.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index 994bdc54a9..93b68b061a 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -710,6 +710,8 @@ bool QQuickPinchArea::event(QEvent *event) clearPinch(); break; case Qt::ZoomNativeGesture: { + if (d->pinchRejected) + break; qreal scale = d->pinchLastScale * (1.0 + gesture->value()); QQuickPinchEvent pe(d->pinchStartCenter, scale, d->pinchLastAngle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -727,7 +729,10 @@ bool QQuickPinchArea::event(QEvent *event) else emit pinchStarted(&pe); d->inPinch = true; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; case Qt::SmartZoomNativeGesture: { if (gesture->value() > 0.0 && d->pinch && d->pinch->target()) { @@ -751,6 +756,8 @@ bool QQuickPinchArea::event(QEvent *event) emit smartZoom(&pe); } break; case Qt::RotateNativeGesture: { + if (d->pinchRejected) + break; qreal angle = d->pinchLastAngle + gesture->value(); QQuickPinchEvent pe(d->pinchStartCenter, d->pinchLastScale, angle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -769,7 +776,10 @@ bool QQuickPinchArea::event(QEvent *event) emit pinchStarted(&pe); d->inPinch = true; d->pinchRotation = angle; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; default: return QQuickItem::event(event); -- cgit v1.2.3 From 6269589ae2804d0c5d5a7b9bd4e78acdac799de0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 28 Apr 2022 17:43:38 +0200 Subject: Quick: includemocs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including moc files directly into their classes' TU tends to improve codegen and enables extended compiler warnings, e.g. about unused private functions or fields. Manual conflict resolutions: - dropped all inclusions into non-existing files - qsgabstractrenderer_p.h doesn't contain a Q_OBJECT in 5.15 - QQuickAnchorLine isn't a Q_GADGET in 5.15 Task-number: QTBUG-102948 Change-Id: I695daa12613de3bada67eb69a26a8dce07c4b85e Reviewed-by: Mårten Nordheim (cherry picked from commit 6a23f186138dff2a7007288a02702bce23d7ca70) Reviewed-by: Qt CI Bot Reviewed-by: Ulf Hermann --- src/quick/items/qquickevents.cpp | 2 ++ src/quick/items/qquickflickable.cpp | 2 ++ src/quick/items/qquickimage.cpp | 4 ++++ src/quick/items/qquickitemsmodule.cpp | 2 ++ src/quick/items/qquickscalegrid.cpp | 2 ++ src/quick/items/qquicktableview.cpp | 2 ++ 6 files changed, 14 insertions(+) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index d433b194a5..0e63c17e98 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -2274,3 +2274,5 @@ Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickEventPoint *eve #endif QT_END_NAMESPACE + +#include "moc_qquickevents_p_p.cpp" diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 3a36a0082b..c64825166a 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -2937,4 +2937,6 @@ void QQuickFlickable::setBoundsMovement(BoundsMovement movement) QT_END_NAMESPACE +#include "moc_qquickflickable_p_p.cpp" + #include "moc_qquickflickable_p.cpp" diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index ab00eccd5e..0b1cd55396 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -945,3 +945,7 @@ void QQuickImage::setMipmap(bool use) */ QT_END_NAMESPACE + +#include "moc_qquickimage_p_p.cpp" + +#include "moc_qquickimage_p.cpp" diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 922a7fec96..e996d4b553 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -128,6 +128,8 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcTransient) QT_END_NAMESPACE +#include "moc_qquickitemsmodule_p.cpp" + static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent) { // When setting a parent (especially during dynamic object creation) in QML, diff --git a/src/quick/items/qquickscalegrid.cpp b/src/quick/items/qquickscalegrid.cpp index 8ae09de535..aa32d3e96a 100644 --- a/src/quick/items/qquickscalegrid.cpp +++ b/src/quick/items/qquickscalegrid.cpp @@ -217,3 +217,5 @@ QString QQuickGridScaledImage::pixmapUrl() const } QT_END_NAMESPACE + +#include "moc_qquickscalegrid_p_p.cpp" diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 7fc6b6572d..2a8a8ccae0 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -3096,3 +3096,5 @@ QQuickTableSectionSizeProviderPrivate::~QQuickTableSectionSizeProviderPrivate() #include "moc_qquicktableview_p.cpp" QT_END_NAMESPACE + +#include "moc_qquicktableview_p_p.cpp" -- cgit v1.2.3 From 0121c6737c7374d6b21eee4eeed861da2ef77999 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 3 May 2022 12:23:18 +0200 Subject: MPTA: don't allow more than one touchpoint to react to mouse On mouse press, if MPTA filters events for a child, addTouchPoint() can be called once during filtering and start reacting to that point, and then called again during direct delivery of the same mouse press. Now it will ignore the second of the declared touchpoint prototypes because the first one is already "taken", and a mouse event can never provide more than one point. Followup to 0012f8bd152a36a67abc696465f27d612625b5d9 Fixes: QTBUG-83662 Change-Id: Ia97600441f0a2633f77b0db9c83cc4de3a9e5931 Reviewed-by: Fabian Kosmale (cherry picked from commit 9b64eee22d9e2d40d1283e8844cb1d8899232547) Reviewed-by: Shawn Rutledge --- src/quick/items/qquickmultipointtoucharea.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 58ad929b19..480731aee9 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -685,7 +685,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) emit released(_releasedTouchPoints); if (moved) emit updated(_movedTouchPoints); - if (started) + if (started && !_pressedTouchPoints.isEmpty()) emit pressed(_pressedTouchPoints); if (ended || moved || started) emit touchUpdated(_touchPoints.values()); } @@ -730,12 +730,15 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) { QQuickTouchPoint *dtp = nullptr; - for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) + for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) { if (!tp->inUse()) { tp->setInUse(true); dtp = tp; break; + } else if (_mouseTouchPoint == tp) { + return; // do not allow more than one touchpoint to react to the mouse (QTBUG-83662) } + } if (dtp == nullptr) dtp = new QQuickTouchPoint(false); -- cgit v1.2.3 From ea898f614dcded4012d45a254b044dc7b37c40c0 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 2 May 2022 17:22:46 +0200 Subject: Text: don't fall back to full-width layout if availableWidth == 0 If Text.width == Text.rightPadding, there is no space to render any text; but in that case, QQuickTextPrivate::availableWidth() returns 0: it's incorrect to fall back to layout.maximumWidth() and allow rendering the whole line. Prior to 6ec2693d4a3c95ca9ff0c349d3c587a7f1402c05 we were checking width() here, so let's do that again. Fixes: QTBUG-83413 Change-Id: I3ee3b49406577c3aa005a3ca3606308ff0a21d8d Reviewed-by: Oliver Eftevaag (cherry picked from commit 406ff6b53d02b8db4231e473982fe593fb1e48c6) Reviewed-by: Shawn Rutledge --- src/quick/items/qquicktext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index b348ce74a8..844a25b010 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -965,7 +965,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) const qreal availWidth = availableWidth(); const qreal availHeight = availableHeight(); - lineWidth = q->widthValid() && availWidth > 0 ? availWidth : naturalWidth; + lineWidth = q->widthValid() && q->width() > 0 ? availWidth : naturalWidth; maxHeight = q->heightValid() ? availHeight : FLT_MAX; // If the width of the item has changed and it's possible the result of wrapping, -- cgit v1.2.3