diff options
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | src/imports/controls/DialogButtonBox.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/fusion/DialogButtonBox.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/imagine/DialogButtonBox.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/imagine/qquickninepatchimage.cpp | 2 | ||||
-rw-r--r-- | src/imports/controls/material/DialogButtonBox.qml | 1 | ||||
-rw-r--r-- | src/imports/controls/universal/DialogButtonBox.qml | 1 | ||||
-rw-r--r-- | src/imports/platform/qquickplatformfiledialog.cpp | 8 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontrol.cpp | 7 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktextarea.cpp | 6 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_dialogbuttonbox.qml | 84 | ||||
-rw-r--r-- | tests/auto/qquickcontrol/tst_qquickcontrol.cpp | 7 | ||||
-rw-r--r-- | tests/auto/qquickimaginestyle/data/tst_imagine.qml | 56 |
13 files changed, 168 insertions, 9 deletions
diff --git a/.qmake.conf b/.qmake.conf index aee6e65e..edff2782 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -5,4 +5,4 @@ DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST QQC2_SOURCE_TREE = $$PWD -MODULE_VERSION = 5.15.9 +MODULE_VERSION = 5.15.10 diff --git a/src/imports/controls/DialogButtonBox.qml b/src/imports/controls/DialogButtonBox.qml index 3c9d5b48..cc148ac4 100644 --- a/src/imports/controls/DialogButtonBox.qml +++ b/src/imports/controls/DialogButtonBox.qml @@ -55,6 +55,7 @@ T.DialogButtonBox { } contentItem: ListView { + implicitWidth: contentWidth model: control.contentModel spacing: control.spacing orientation: ListView.Horizontal diff --git a/src/imports/controls/fusion/DialogButtonBox.qml b/src/imports/controls/fusion/DialogButtonBox.qml index a0b0f243..4673e421 100644 --- a/src/imports/controls/fusion/DialogButtonBox.qml +++ b/src/imports/controls/fusion/DialogButtonBox.qml @@ -56,6 +56,7 @@ T.DialogButtonBox { delegate: Button { } contentItem: ListView { + implicitWidth: contentWidth model: control.contentModel spacing: control.spacing orientation: ListView.Horizontal diff --git a/src/imports/controls/imagine/DialogButtonBox.qml b/src/imports/controls/imagine/DialogButtonBox.qml index c24b29fc..fd27a876 100644 --- a/src/imports/controls/imagine/DialogButtonBox.qml +++ b/src/imports/controls/imagine/DialogButtonBox.qml @@ -66,6 +66,7 @@ T.DialogButtonBox { } contentItem: ListView { + implicitWidth: contentWidth model: control.contentModel spacing: control.spacing orientation: ListView.Horizontal diff --git a/src/imports/controls/imagine/qquickninepatchimage.cpp b/src/imports/controls/imagine/qquickninepatchimage.cpp index 71243988..ed388ec1 100644 --- a/src/imports/controls/imagine/qquickninepatchimage.cpp +++ b/src/imports/controls/imagine/qquickninepatchimage.cpp @@ -439,6 +439,8 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode QSizeF sz = size(); QImage image = d->pix.image(); if (!sz.isValid() || image.isNull()) { + if (d->provider) + d->provider->updateTexture(nullptr); delete oldNode; return nullptr; } diff --git a/src/imports/controls/material/DialogButtonBox.qml b/src/imports/controls/material/DialogButtonBox.qml index c53b8210..d148fb24 100644 --- a/src/imports/controls/material/DialogButtonBox.qml +++ b/src/imports/controls/material/DialogButtonBox.qml @@ -60,6 +60,7 @@ T.DialogButtonBox { delegate: Button { flat: true } contentItem: ListView { + implicitWidth: contentWidth model: control.contentModel spacing: control.spacing orientation: ListView.Horizontal diff --git a/src/imports/controls/universal/DialogButtonBox.qml b/src/imports/controls/universal/DialogButtonBox.qml index 0458c39d..103b46c2 100644 --- a/src/imports/controls/universal/DialogButtonBox.qml +++ b/src/imports/controls/universal/DialogButtonBox.qml @@ -59,6 +59,7 @@ T.DialogButtonBox { } contentItem: ListView { + implicitWidth: contentWidth model: control.contentModel spacing: control.spacing orientation: ListView.Horizontal diff --git a/src/imports/platform/qquickplatformfiledialog.cpp b/src/imports/platform/qquickplatformfiledialog.cpp index 81b851a5..af5475fa 100644 --- a/src/imports/platform/qquickplatformfiledialog.cpp +++ b/src/imports/platform/qquickplatformfiledialog.cpp @@ -552,8 +552,14 @@ QUrl QQuickPlatformFileDialog::addDefaultSuffix(const QUrl &file) const QUrl url = file; const QString path = url.path(); const QString suffix = m_options->defaultSuffix(); - if (!suffix.isEmpty() && !path.endsWith(QLatin1Char('/')) && path.lastIndexOf(QLatin1Char('.')) == -1) + // Urls with "content" scheme do not require suffixes. Such schemes are + // used on Android. + const bool isContentScheme = url.scheme() == QStringLiteral("content"); + if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(QLatin1Char('/')) + && path.lastIndexOf(QLatin1Char('.')) == -1) { url.setPath(path + QLatin1Char('.') + suffix); + } + return url; } diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index bbbd0e62..409fb582 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -179,9 +179,10 @@ bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) // If the control is on a Flickable that has a pressDelay, then the press is never // sent as a touch event, therefore we need to check for this case. - if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased && - point.pos() == previousPressPos) { - return true; + if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased) { + const auto delta = QVector2D(point.pos() - previousPressPos); + if (!QQuickWindowPrivate::dragOverThreshold(delta)) + return true; } return false; } diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index d09d9c3b..64fc631d 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -1086,7 +1086,11 @@ QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * if (d->flickable) clipper = d->flickable; - const QRectF cr = clipper->clipRect().adjusted(leftPadding(), topPadding(), -rightPadding(), -bottomPadding()); + const QRectF cr = clipper->clipRect().adjusted( + leftPadding(), topPadding(), + (!d->cursorItem && effectiveHAlign() == HAlignment::AlignRight ? 1 : 0) - rightPadding(), + -bottomPadding()); + clipNode->setRect(!d->flickable ? cr : cr.translated(d->flickable->contentX(), d->flickable->contentY())); clipNode->update(); diff --git a/tests/auto/controls/data/tst_dialogbuttonbox.qml b/tests/auto/controls/data/tst_dialogbuttonbox.qml index a651713a..63cefa46 100644 --- a/tests/auto/controls/data/tst_dialogbuttonbox.qml +++ b/tests/auto/controls/data/tst_dialogbuttonbox.qml @@ -398,7 +398,7 @@ TestCase { // QTBUG-72886 function test_changeCustomButtonText(data) { - var control = createTemporaryObject(customButtonBox, testCase, {}) + var control = createTemporaryObject(data.component, testCase, {}) verify(control) var listView = control.contentItem @@ -418,6 +418,88 @@ TestCase { } Component { + id: customButtonBoxInDialog + + Dialog { + width: 300 + visible: true + + footer: DialogButtonBox { + objectName: "customButtonBoxInDialog" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + } + } + } + + Component { + id: customButtonBoxTwoButtonsInDialog + + Dialog { + width: 300 + visible: true + + footer: DialogButtonBox { + objectName: "customButtonBoxTwoButtonsInDialog" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + text: "Cancel" + + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + } + } + + function test_changeCustomButtonImplicitWidth_data() { + return [ + { tag: "oneButton", component: customButtonBoxInDialog }, + { tag: "twoButtons", component: customButtonBoxTwoButtonsInDialog }, + ] + } + + // QTBUG-102558 + function test_changeCustomButtonImplicitWidth(data) { + let dialog = createTemporaryObject(data.component, testCase, {}) + verify(dialog) + + let control = dialog.footer + verify(control) + + let listView = control.contentItem + waitForRendering(listView) + + let button = control.okButton + verify(button) + button.implicitWidth *= 1.5 + + // The button should never go outside of the box. + tryVerify(function() { return button.mapToItem(control, 0, 0).x >= 0 }, + 1000, "Expected left edge of button to be within left edge of DialogButtonBox (i.e. greater than or equal to 0)" + + ", but it's " + button.mapToItem(control, 0, 0).x) + tryVerify(function() { return button.mapToItem(control, 0, 0).x + button.width <= control.width }, + 1000, "Expected right edge of button to be within right edge of DialogButtonBox (i.e. less than or equal to " + + control.width + "), but it's " + (button.mapToItem(control, 0, 0).x + button.width)) + } + + Component { id: noRolesDialog Dialog { diff --git a/tests/auto/qquickcontrol/tst_qquickcontrol.cpp b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp index c8d34756..df3b31c8 100644 --- a/tests/auto/qquickcontrol/tst_qquickcontrol.cpp +++ b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp @@ -98,9 +98,12 @@ void tst_QQuickControl::flickable() QSignalSpy buttonClickedSpy(button, SIGNAL(clicked())); QVERIFY(buttonClickedSpy.isValid()); - QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(button->width() / 2, button->height() / 2)); + QPoint p(button->width() / 2, button->height() / 2); + QTest::touchEvent(window, touchDevice.data()).press(0, p); QTRY_COMPARE(buttonPressedSpy.count(), 1); - QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(button->width() / 2, button->height() / 2)); + p += QPoint(1, 1); // less than the drag threshold + QTest::touchEvent(window, touchDevice.data()).move(0, p); + QTest::touchEvent(window, touchDevice.data()).release(0, p); QTRY_COMPARE(buttonReleasedSpy.count(), 1); QTRY_COMPARE(buttonClickedSpy.count(), 1); } diff --git a/tests/auto/qquickimaginestyle/data/tst_imagine.qml b/tests/auto/qquickimaginestyle/data/tst_imagine.qml index b9078d78..f4ba1c71 100644 --- a/tests/auto/qquickimaginestyle/data/tst_imagine.qml +++ b/tests/auto/qquickimaginestyle/data/tst_imagine.qml @@ -153,4 +153,60 @@ TestCase { // Shouldn't result in a crash. afterRenderingSpy.wait(1000) } + + Component { + id: invalidNinePatchImageProvider + Item { + width: 200 + height: 200 + property alias ninePatchImage: np + + NinePatchImage { + id: np + source : "qrc:/test-assets/button-background-1.png" + cache: false + visible: false + } + ShaderEffect { + width: 300 + height: 300 + property variant src: np + vertexShader: " + uniform highp mat4 qt_Matrix; + attribute highp vec4 qt_Vertex; + attribute highp vec2 qt_MultiTexCoord0; + varying highp vec2 coord; + void main() { + coord = qt_MultiTexCoord0; + gl_Position = qt_Matrix * qt_Vertex; + }" + fragmentShader: " + varying highp vec2 coord; + uniform sampler2D src; + uniform lowp float qt_Opacity; + void main() { + lowp vec4 tex = texture2D(src, coord); + gl_FragColor = vec4(vec3(dot(tex.rgb, + vec3(0.344, 0.5, 0.156))), + tex.a) * qt_Opacity; + }" + } + } + } + + function test_invalidNinePatchImageProvide() { + var container = createTemporaryObject(invalidNinePatchImageProvider, testCase) + verify(container); + + var afterRenderingSpy = signalSpyComponent.createObject(null, + { target: testCase.Window.window, signalName: "afterRendering" }) + verify(afterRenderingSpy.valid) + + afterRenderingSpy.wait(100) + container.ninePatchImage.source = "" + testCase.Window.window.update() + // Shouldn't result in a crash. + wait(10) + afterRenderingSpy.wait(100) + } } |