From 936570a3b3440ed2508bacb9b9916381cb864ffb Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 6 Mar 2018 13:52:33 +0100 Subject: QQuickWindow: skip mouse synthesis for touch events from trackpads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A trackpad is primarily a mouse-emulating device, which can also recognize gestures, and furthermore can send raw touches iff it is asked to. So, every touch event from a trackpad is likely to be followed by a mouse or gesture event (especially when the MouseEmulation capability confirms that it is able to do that). Therefore mouse event synthesis is redundant. In this bug scenario, MultiPointTouchArea enables touch events within its rectangular bounds. A Flickable is on top. As you flick with two fingers on the trackpad, macOS sends touch events with two touch points (because MPTA enabled touch events) and also a series of QWheelEvents as it recognizes the flick gesture. The Flickable receives mouse events sythesized from one touch point, and reacts as if you were dragging with one finger on a touchscreen, while it simultaneously also reacts to the QWheelEvents. Meanwhile the remaining touchpoint falls through to the MPTA underneath; so the user ends up interacting with both at the same time and making the Flickable jump around besides. This patch just fixes the jumpiness in Flickable: it will no longer receive the synth-mouse events, so it will not be dragged, and will react only to the wheel events. But MPTA still gets the touches. Task-number: QTBUG-66329 Change-Id: I6f535a2c9e47bcb284eaf9ae1fdaa39f8b510af9 Reviewed-by: Jan Arve Sæther --- src/quick/items/qquickevents_p_p.h | 1 + src/quick/items/qquickwindow.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index c4f0b60d92..2a1e9dc184 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -597,6 +597,7 @@ public: Area = QTouchDevice::Area, Pressure = QTouchDevice::Pressure, Velocity = QTouchDevice::Velocity, + MouseEmulation = QTouchDevice::MouseEmulation, // some bits reserved in case we need more of QTouchDevice::Capabilities Scroll = 0x0100, // mouse has a wheel, or there is OS-level scroll gesture recognition (dubious?) Hover = 0x0200, diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index aefdaea2b7..48eba6a7a0 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -654,6 +654,12 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve Q_Q(QQuickWindow); auto device = pointerEvent->device(); + // A touch event from a trackpad is likely to be followed by a mouse or gesture event, so mouse event synth is redundant + if (device->type() == QQuickPointerDevice::TouchPad && device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) { + qCDebug(DBG_TOUCH_TARGET) << "skipping delivery of synth-mouse event from" << device; + return false; + } + // FIXME: make this work for mouse events too and get rid of the asTouchEvent in here. Q_ASSERT(pointerEvent->asPointerTouchEvent()); QScopedPointer event(pointerEvent->asPointerTouchEvent()->touchEventForItem(item)); @@ -2831,7 +2837,11 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event // In versions prior to Qt 6, we can't trust item->acceptTouchEvents() here, because it defaults to true. bool acceptsTouchEvents = false; #endif - if (acceptsTouchEvents || receiver->acceptedMouseButtons()) { + auto device = pte->device(); + if (device->type() == QQuickPointerDevice::TouchPad && + device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) { + qCDebug(DBG_TOUCH_TARGET) << "skipping filtering of synth-mouse event from" << device; + } else if (acceptsTouchEvents || receiver->acceptedMouseButtons()) { // get a touch event customized for delivery to filteringParent QScopedPointer filteringParentTouchEvent(pte->touchEventForItem(receiver, true)); if (filteringParentTouchEvent) { -- cgit v1.2.3 From 62dd8b20055fd5ccec1dc2eb33523aae2e6ad7b9 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 12 Mar 2018 11:05:08 +0100 Subject: Improve SpriteSequence's documentation Change-Id: I7e9e09ba3b6c0ec3c0b4bed75b24ed87fbe9660f Reviewed-by: Venugopal Shivashankar --- src/quick/items/qquickspritesequence.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp index 0a39c09ebc..72761ab82b 100644 --- a/src/quick/items/qquickspritesequence.cpp +++ b/src/quick/items/qquickspritesequence.cpp @@ -73,38 +73,38 @@ QT_BEGIN_NAMESPACE Whether the sprite is animating or not. - Default is true + Default is \c true. */ /*! \qmlproperty bool QtQuick::SpriteSequence::interpolate - If true, interpolation will occur between sprite frames to make the + If \c true, interpolation will occur between sprite frames to make the animation appear smoother. - Default is true. + Default is \c true. */ /*! \qmlproperty string QtQuick::SpriteSequence::currentSprite - The name of the Sprite which is currently animating. + The name of the \l Sprite that is currently animating. */ /*! \qmlproperty string QtQuick::SpriteSequence::goalSprite - The name of the Sprite which the animation should move to. + The name of the \l Sprite that the animation should move to. - Sprite states have defined durations and transitions between them, setting goalState - will cause it to disregard any path weightings (including 0) and head down the path - which will reach the goalState quickest (fewest animations). It will pass through + Sprite states have defined durations and transitions between them; setting \c goalSprite + will cause it to disregard any path weightings (including \c 0) and head down the path + that will reach the \c goalSprite quickest (fewest animations). It will pass through intermediate states on that path, and animate them for their duration. - If it is possible to return to the goalState from the starting point of the goalState - it will continue to do so until goalState is set to "" or an unreachable state. + If it is possible to return to the \c goalSprite from the starting point of the \c goalSprite, + it will continue to do so until \c goalSprite is set to \c "" or an unreachable state. */ /*! \qmlmethod QtQuick::SpriteSequence::jumpTo(string sprite) - This function causes the SpriteSequence to jump to the specified sprite immediately, intermediate - sprites are not played. The \a sprite argument is the name of the sprite you wish to jump to. + This function causes the SpriteSequence to jump to the specified \a sprite immediately; + intermediate sprites are not played. */ /*! \qmlproperty list QtQuick::SpriteSequence::sprites -- cgit v1.2.3 From 928a5d40377853aafbb2860feccf6d65bf81417b Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 12 Mar 2018 10:35:43 +0100 Subject: Improve AnimatedSprite's documentation Change-Id: Icc86afe67fd5a432798ce3173da51275bed1bf64 Reviewed-by: Shawn Rutledge Reviewed-by: Venugopal Shivashankar --- src/quick/items/qquickanimatedsprite.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 741e4607e5..190c48ac88 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -152,10 +152,10 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty qreal QtQuick::AnimatedSprite::frameRate - Frames per second to show in the animation. Values equal to or below 0 are invalid. + Frames per second to show in the animation. Values less than or equal to \c 0 are invalid. - If frameRate is valid then it will be used to calculate the duration of the frames. - If not, and frameDuration is valid , then frameDuration will be used. + If \c frameRate is valid, it will be used to calculate the duration of the frames. + If not, and \l frameDuration is valid, \c frameDuration will be used. Changing this parameter will restart the animation. */ @@ -163,10 +163,10 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty int QtQuick::AnimatedSprite::frameDuration - Duration of each frame of the animation in milliseconds. Values equal to or below 0 are invalid. + Duration of each frame of the animation in milliseconds. Values less than or equal to \c 0 are invalid. - If frameRate is valid then it will be used to calculate the duration of the frames. - If not, and frameDuration is valid, then frameDuration will be used. + If frameRate is valid, it will be used to calculate the duration of the frames. + If not, and \l frameDuration is valid, \c frameDuration will be used. Changing this parameter will restart the animation. */ @@ -218,21 +218,21 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty bool QtQuick::AnimatedSprite::reverse - If true, then the animation will be played in reverse. + If \c true, the animation will be played in reverse. - Default is false. + Default is \c false. */ /*! \qmlproperty bool QtQuick::AnimatedSprite::frameSync - If true, then the animation will have no duration. Instead, the animation will advance + If \c true, the animation will have no duration. Instead, the animation will advance one frame each time a frame is rendered to the screen. This synchronizes it with the painting rate as opposed to elapsed time. If frameSync is set to true, it overrides both frameRate and frameDuration. - Default is false. + Default is \c false. Changing this parameter will restart the animation. */ @@ -242,9 +242,9 @@ QT_BEGIN_NAMESPACE After playing the animation this many times, the animation will automatically stop. Negative values are invalid. - If this is set to AnimatedSprite.Infinite the animation will not stop playing on its own. + If this is set to \c AnimatedSprite.Infinite the animation will not stop playing on its own. - Default is AnimatedSprite.Infinite + Default is \c AnimatedSprite.Infinite */ /*! @@ -252,13 +252,13 @@ QT_BEGIN_NAMESPACE When paused, the current frame can be advanced manually. - Default is false. + Default is \c false. */ /*! \qmlproperty int QtQuick::AnimatedSprite::currentFrame - When paused, the current frame can be advanced manually by setting this property or calling advance(). + When paused, the current frame can be advanced manually by setting this property or calling \l advance(). */ @@ -452,7 +452,7 @@ void QQuickAnimatedSprite::maybeUpdate() \qmlmethod int QtQuick::AnimatedSprite::pause() Pauses the sprite animation. This does nothing if - \l paused is true. + \l paused is \c true. \sa resume() */ @@ -471,7 +471,7 @@ void QQuickAnimatedSprite::pause() /*! \qmlmethod int QtQuick::AnimatedSprite::resume() - Resumes the sprite animation if \l paused is true; + Resumes the sprite animation if \l paused is \c true; otherwise, this does nothing. \sa pause() -- cgit v1.2.3 From 3339bf866a68ba129e88fd7d27a2abbea0d1c6ba Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 8 Mar 2018 15:02:45 +0100 Subject: When deactivating a loader, do not immediately clear its context In 2eb2d6386da304cd1164264ae0bff685c796d89c, deactivating/clearing the loader would now prevent any subsequent bindings from being evaluated. The problem there was that the item created by the loader wouldn't have a parent item (among things) anymore, so references to it in the bindings would result in errors. The way to prevent it was done by invalidating the context of the item, which in turn would detach it from the root context. This is a problem if objects in the root context are referenced after deactivating/clearing the loader: onSomethingChanged: { loader.source = "" objectInRootContext.doIt() } This would result in a ReferenceError when resolving objectInRootContext and break the behavior present before the fix mentioned above. The correct way is to recursively clear the context set on all bindings, but leave everything in place. This way, no subsequent bindings will be evaluated, but the currently "running" scripts will still be able to reach the root context. Task-number: QTBUG-66822 Change-Id: Ic9c2ab0a752093a26967da4783cb4c29cf83d2ca Reviewed-by: Simon Hausmann Reviewed-by: Michael Brasser --- src/quick/items/qquickloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 34f30e81a3..6960e16bd9 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -102,7 +102,7 @@ void QQuickLoaderPrivate::clear() // this we may get transient errors from use of 'parent', for example. QQmlContext *context = qmlContext(object); if (context) - QQmlContextData::get(context)->invalidate(); + QQmlContextData::get(context)->clearContextRecursively(); if (loadingFromSource && component) { // disconnect since we deleteLater @@ -363,7 +363,7 @@ void QQuickLoader::setActive(bool newVal) // this we may get transient errors from use of 'parent', for example. QQmlContext *context = qmlContext(d->object); if (context) - QQmlContextData::get(context)->invalidate(); + QQmlContextData::get(context)->clearContextRecursively(); if (d->item) { QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); -- cgit v1.2.3 From 271e0c1e6e90bb3efd327ebee318c9f0ac95fd71 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 23 Mar 2018 09:35:35 +0100 Subject: Doc: correct Sprite's detailed description Task-number: QTBUG-58641 Change-Id: Ib339746d459328bdac8fa0eeff80300df99ff482 Reviewed-by: Venugopal Shivashankar --- src/quick/items/qquicksprite.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp index 99b1b1f430..6b8567439b 100644 --- a/src/quick/items/qquicksprite.cpp +++ b/src/quick/items/qquicksprite.cpp @@ -51,8 +51,8 @@ QT_BEGIN_NAMESPACE \ingroup qtquick-visual-utility \brief Specifies sprite animations - QQuickSprite renders sprites of one or more frames and animates them. The sprites - can be in the middle of an image file, or split along multiple rows, as long as they form + Sprite defines a series of one or more frames to be animated and rendered by SpriteSequence. + The sprites can be in the middle of an image file, or split along multiple rows, as long as they form a contiguous line wrapping to the next row of the file from the left edge of the file. For full details, see the \l{Sprite Animations} overview. -- cgit v1.2.3 From d868bb4f3e4b0424fd4a2989ff1c82692b0f014c Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Wed, 4 Apr 2018 13:23:00 +0200 Subject: Fix Flickable mouse wheel handling on macOS On macOS a special movementEnding timer was added to the wheelEvent handling to fix QTBUG-63026. This has introduced a regression with wrong vData/hData.moving flags: When the timer fires before the Qt::ScrollEnd phase is reached, movementEnding is invoked early (can be reproduced with very slow scrolling using the Magic Mouse). In this case movementEnding sets vData.moving = false but not vMoved = false because scrollingPhase is still true. This will prevent any further invocation of movementStarting from inside the drag method (it expects a change in vMoved) so once this situation has occurred the "moving" flags will be out of sync. Visible effect: If a ListView has a currentItem set with setCurrentIndex, its viewportMoved method will no longer correctly set the moveReason to "Mouse" because the check depends on "moving" flag as an indicator for mouse interaction. This results in the view permanently jumping back to the current item on any scroll operation because the moveReason will be stuck at "SetIndex". The fix is to ignore the timer event if scrollingPhase is still true. Task-number: QTBUG-67460 Change-Id: I7cf02b8c625b7baf249ad26c4e0c3df874a18eae Reviewed-by: Richard Moe Gustavsen Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 8cb64377cc..9c775f7e93 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1649,10 +1649,12 @@ void QQuickFlickable::timerEvent(QTimerEvent *event) } } else if (event->timerId() == d->movementEndingTimer.timerId()) { d->movementEndingTimer.stop(); - d->pressed = false; - d->stealMouse = false; - if (!d->velocityTimeline.isActive() && !d->timeline.isActive()) - movementEnding(true, true); + if (!d->scrollingPhase) { + d->pressed = false; + d->stealMouse = false; + if (!d->velocityTimeline.isActive() && !d->timeline.isActive()) + movementEnding(true, true); + } } } -- cgit v1.2.3 From d1a5adb5d6d6d64bf648cbeda70663751c8b982d Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 9 Apr 2018 13:45:57 +0200 Subject: Improve QQuickItemGrabResult::image() docs It can return a null image. An "empty" image is confusing, as there's no function in QImage with that name, requiring the user to consult the docs. Change-Id: Iaa805510804162fe3a7df00394b4a9ad61ac1d20 Reviewed-by: J-P Nurmi --- src/quick/items/qquickitemgrabresult.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index 003fde8c9e..b45cb09c4b 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -139,7 +139,7 @@ public: * This property holds the pixel results from a grab. * * If the grab is not yet complete or if it failed, - * an empty image is returned. + * a null image is returned (\c {image.isNull()} will return \c true). */ /*! -- cgit v1.2.3 From ccad6b577016c8a0986f56b2656471896b5817ea Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 3 Apr 2018 12:37:04 +0200 Subject: clear() the loader before destroying it This prevents bindings in children being evaluated and removes spurious qml errors on the command line. Amends 2eb2d6386da304cd1164264ae0bff685c796d89c. Task-number: QTBUG-63729 Change-Id: I88b85ed40c6b8c5fbb422831055942cc0f4ee424 Reviewed-by: Simon Hausmann --- src/quick/items/qquickloader.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 6960e16bd9..cd48896e58 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -311,10 +311,7 @@ QQuickLoader::QQuickLoader(QQuickItem *parent) QQuickLoader::~QQuickLoader() { Q_D(QQuickLoader); - if (d->item) { - QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); - p->removeItemChangeListener(d, watchedChanges); - } + d->clear(); } /*! -- cgit v1.2.3 From 539d724890aec3f00eadb39aeae973670e664ec6 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 28 Feb 2018 15:35:36 +0100 Subject: Doc: Describe new 5.11 features in Image element Add user documentation of the compressed texture file support and the file extension auto detection. Change-Id: Icfae8574dd3acba30e8275ccd6ff3438fa037868 Reviewed-by: Mitch Curtis --- src/quick/items/qquickimage.cpp | 46 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index dc2cd17b4e..db5cfd2526 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -135,6 +135,48 @@ QQuickImagePrivate::QQuickImagePrivate() \clearfloat + \section1 OpenGL Texture Files + + When the default OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in + use, images can also be supplied in compressed texture files. The content + must be a simple RGB(A) format 2D texture. Supported compression schemes + are only limited by the underlying OpenGL driver and GPU. The following + container file formats are supported: + + \list + \li \c PKM (since Qt 5.10) + \li \c KTX (since Qt 5.11) + \endlist + + \note Semi-transparent original images require alpha pre-multiplication + prior to texture compression in order to be correctly displayed in Qt + Quick. This can be done with the following ImageMagick command + line: + \badcode + convert MYORIGIMAGE \( +clone -alpha Extract \) -channel RGB -compose Multiply -composite MYPMIMAGE + \endcode + + \section1 Automatic Detection of File Extension + + If the \l source URL indicates a non-existing local file or resource, the + Image element attempts to auto-detect the file extension. If an existing + file can be found by appending any of the supported image file extensions + to the \l source URL, then that file will be loaded. + + If the OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in use, the + file search the attempts the OpenGL texture file extensions first. If the + search is unsuccessful, it attempts to search with the file extensions for + the \l{QImageReader::supportedImageFormats()}{conventional image file + types}. For example: + + \snippet qml/image-ext.qml ext + + This functionality facilitates deploying different image asset file types + on different target platforms. This can be useful in order to tune + application performance and adapt to different graphics hardware. + + This functionality was introduced in Qt 5.11. + \section1 Performance By default, locally available images are loaded immediately, and the user interface @@ -154,7 +196,7 @@ QQuickImagePrivate::QQuickImagePrivate() size bounded via the \l sourceSize property. This is especially important for content that is loaded from external sources or provided by the user. - \sa {Qt Quick Examples - Image Elements}, QQuickImageProvider + \sa {Qt Quick Examples - Image Elements}, QQuickImageProvider, QImageReader::setAutoDetectImageFormat() */ QQuickImage::QQuickImage(QQuickItem *parent) @@ -461,7 +503,7 @@ qreal QQuickImage::paintedHeight() const The URL may be absolute, or relative to the URL of the component. - \sa QQuickImageProvider + \sa QQuickImageProvider {OpenGL Texture Files} {Automatic Detection of File Extension} */ /*! -- cgit v1.2.3 From 56ade46b4234bb828b8e4f9a6bf83b5687bd122e Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 9 Apr 2018 14:05:53 +0200 Subject: Fix Text with ElideRight not being rendered when reparented Consider the following example: Item { width: 100 height: 30 Text { width: parent ? parent.width : 0 height: parent ? parent.height : 0 elide: Text.ElideRight text: "wot" } } When setting the Text item's parent to null, its explicit width and height are set to 0. When restoring its parent (the Item), its explicit width and height are set to 100 and 30 again, but the text itself is still not rendered. The cause can be seen here: if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed if (newGeometry.height() > oldGeometry.height()) { if (!d->heightExceeded) // Height is adequate and growing. goto geomChangeDone; heightExceeded was false, because 30 > 12 (or whatever the implicit height happened to be), so the text was not laid out again, even though it went from having an explicit height of 0 to an explicit height of 30. Fix the issue by only executing the goto if the old explicit height wasn't 0. Task-number: QTBUG-60328 Task-number: QTBUG-67145 Change-Id: I7f4d2f95bc95c850133ba91ac2d1a02c7ee159b6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/quick/items/qquicktext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 383aa2b821..9eaf9f8d6d 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2318,8 +2318,10 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed if (newGeometry.height() > oldGeometry.height()) { - if (!d->heightExceeded) // Height is adequate and growing. + if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) { + // Height is adequate and growing, and it wasn't 0 previously. goto geomChangeDone; + } if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing. goto geomChangeDone; } else if (newGeometry.height() < oldGeometry.height()) { -- cgit v1.2.3