aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/nodes/tst_nodestest.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml34
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp54
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_line.qml31
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml8
-rw-r--r--tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml13
-rw-r--r--tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp45
-rw-r--r--tests/auto/quick/qquickitem2/data/focusableItemReparentedToLoadedComponent.qml51
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp31
-rw-r--r--tests/auto/quick/qquicktextinput/data/focusReason.qml39
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp80
12 files changed, 392 insertions, 2 deletions
diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp
index 249ecd5aa5..a4f138c8df 100644
--- a/tests/auto/quick/nodes/tst_nodestest.cpp
+++ b/tests/auto/quick/nodes/tst_nodestest.cpp
@@ -125,12 +125,12 @@ public:
setRootNode(root);
}
- void render() {
+ void render() override {
++renderCount;
renderingOrder = ++globalRendereringOrder;
}
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state) {
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override {
changedNode = node;
changedState = state;
QSGBatchRenderer::Renderer::nodeChanged(node, state);
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml
new file mode 100644
index 0000000000..b24812c914
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragHandlerUnderModalLayer.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.15
+
+import Test 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ anchors.fill: parent
+ color: "grey"
+
+ Rectangle {
+ x: 200
+ y: 200
+ width: 100
+ height: 100
+ color: "orange"
+ DragHandler {
+ grabPermissions: DragHandler.CanTakeOverFromAnything // but not anything with keepMouseGrab!
+ }
+ }
+ }
+
+ ModalLayer {
+ anchors.fill: parent
+
+ Rectangle {
+ anchors.fill: parent
+ color: "red"
+ opacity: 0.4
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 4d6866041e..f71febbaf9 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -68,6 +68,7 @@ private slots:
void touchPassiveGrabbers_data();
void touchPassiveGrabbers();
void touchPinchAndMouseMove();
+ void underModalLayer();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
@@ -811,6 +812,59 @@ void tst_DragHandler::touchPinchAndMouseMove()
}
}
+class ModalLayer : public QQuickItem {
+public:
+ explicit ModalLayer(QQuickItem* parent = nullptr) : QQuickItem(parent) {
+ this->setAcceptedMouseButtons(Qt::AllButtons);
+ this->setAcceptTouchEvents(true);
+ this->setKeepMouseGrab(true);
+ this->setKeepTouchGrab(true);
+ }
+
+ bool event(QEvent* event) override {
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseTrackingChange:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchCancel:
+ case QEvent::TouchEnd: {
+ qCDebug(lcPointerTests) << "BLOCK!" << event->type();
+ return true;
+ }
+ default: break;
+ }
+ return QQuickItem::event(event);
+ }
+};
+
+void tst_DragHandler::underModalLayer() // QTBUG-78258
+{
+ qmlRegisterType<ModalLayer>("Test", 1, 0, "ModalLayer");
+
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "dragHandlerUnderModalLayer.qml");
+ QQuickView * window = windowPtr.data();
+ QPointer<QQuickDragHandler> dragHandler = window->rootObject()->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QPoint p1(250, 250);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!dragHandler->active());
+ QTest::mouseRelease(window, Qt::LeftButton);
+}
+
QTEST_MAIN(tst_DragHandler)
#include "tst_qquickdraghandler.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
index 19fdae3b44..2b8ddd197d 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
@@ -217,6 +217,7 @@ void tst_QQuickPinchHandler::scale()
QQuickPinchHandler *pinchHandler = window->rootObject()->findChild<QQuickPinchHandler*>("pinchHandler");
QVERIFY(pinchHandler != nullptr);
+ QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QQuickEventPoint::GrabTransition, QQuickEventPoint*)));
QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
QVERIFY(root != nullptr);
@@ -238,6 +239,7 @@ void tst_QQuickPinchHandler::scale()
// it is outside its bounds.
pinchSequence.stationary(0).press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(grabChangedSpy.count(), 1); // passive grab
QPoint pd(10, 10);
// move one point until PinchHandler activates
@@ -247,6 +249,8 @@ void tst_QQuickPinchHandler::scale()
QQuickTouchUtils::flush(window);
}
QCOMPARE(pinchHandler->active(), true);
+ // first point got a passive grab; both points got exclusive grabs
+ QCOMPARE(grabChangedSpy.count(), 3);
QLineF line(p0, p1);
const qreal startLength = line.length();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
index dc960a24d0..fb4db5ae54 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml
@@ -894,6 +894,37 @@ CanvasTestCase {
comparePixel(ctx, 39,0, 0,0,0,0);
}
+ function test_lineDashReset(row) {
+ var canvas = createCanvasObject(row);
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.strokeStyle = "#ff0000";
+ ctx.lineWidth = 2;
+ var pattern = [2, 3, 5, 1, 6, 3]
+ ctx.setLineDash(pattern)
+
+ compare(ctx.getLineDash(), pattern);
+
+ pattern = []
+ ctx.setLineDash(pattern)
+ compare(ctx.getLineDash(), pattern);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(40, 0);
+ ctx.stroke();
+
+ comparePixel(ctx, 0,0, 255,0,0,255);
+ comparePixel(ctx, 4,0, 255,0,0,255);
+ comparePixel(ctx, 5,0, 255,0,0,255);
+ comparePixel(ctx, 14,0, 255,0,0,255);
+ comparePixel(ctx, 20,0, 255,0,0,255);
+ comparePixel(ctx, 21,0, 255,0,0,255);
+ comparePixel(ctx, 22,0, 255,0,0,255);
+ comparePixel(ctx, 34,0, 255,0,0,255);
+ comparePixel(ctx, 35,0, 255,0,0,255);
+ }
+
function test_lineDashOffset(row) {
var canvas = createCanvasObject(row);
var ctx = canvas.getContext('2d');
diff --git a/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml
new file mode 100644
index 0000000000..ec419f8935
--- /dev/null
+++ b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Item {
+ id: myObject
+ readonly property int testProperty: 0
+ readonly property QtObject myproperty: myObject
+}
+
diff --git a/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml
new file mode 100644
index 0000000000..88fd8509cc
--- /dev/null
+++ b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.11
+
+Rectangle {
+ objectName: "rootItem"
+ color: "white"
+ width: 800
+ height: 600
+
+ RecursiveProperty {
+ objectName: "recursiveProperty"
+
+ }
+}
diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
index b44977bd5a..0471619049 100644
--- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
+++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp
@@ -62,6 +62,7 @@ private slots:
void testNotifyPropertyChangeCallBack();
void testFixResourcePathsForObjectCallBack();
void testComponentOnCompleteSignal();
+ void testPropertyNames();
};
void tst_qquickdesignersupport::customData()
@@ -586,6 +587,50 @@ void tst_qquickdesignersupport::testComponentOnCompleteSignal()
}
}
+void tst_qquickdesignersupport::testPropertyNames()
+{
+#ifdef Q_CC_MINGW
+ QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869");
+#endif
+
+ QScopedPointer<QQuickView> view(new QQuickView);
+ view->engine()->setOutputWarningsToStandardError(false);
+ view->setSource(testFileUrl("propertyNameTest.qml"));
+
+ QVERIFY(view->errors().isEmpty());
+ QQuickItem *rootItem = view->rootObject();
+ QVERIFY(rootItem);
+
+ QQuickDesignerSupport::PropertyNameList names = QQuickDesignerSupportProperties::allPropertyNames(rootItem);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("width"));
+ QVERIFY(names.contains("height"));
+ QVERIFY(names.contains("clip"));
+ QVERIFY(names.contains("opacity"));
+ QVERIFY(names.contains("childrenRect"));
+ QVERIFY(names.contains("activeFocus"));
+ QVERIFY(names.contains("border.width"));
+ names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(rootItem);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("width"));
+ QVERIFY(names.contains("height"));
+ QVERIFY(names.contains("opacity"));
+ QVERIFY(names.contains("clip"));
+ QVERIFY(!names.contains("childrenRect"));
+ QVERIFY(!names.contains("activeFocus"));
+ QVERIFY(names.contains("border.width"));
+
+ QQuickItem *recursiveProperty = findItem<QQuickItem>(rootItem, QLatin1String("recursiveProperty"));
+ QVERIFY(recursiveProperty);
+ names = QQuickDesignerSupportProperties::allPropertyNames(recursiveProperty);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(names.contains("testProperty"));
+ QVERIFY(names.contains("myproperty.testProperty"));
+
+ names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(recursiveProperty);
+ QVERIFY(!names.isEmpty());
+ QVERIFY(!names.contains("testProperty"));
+}
QTEST_MAIN(tst_qquickdesignersupport)
diff --git a/tests/auto/quick/qquickitem2/data/focusableItemReparentedToLoadedComponent.qml b/tests/auto/quick/qquickitem2/data/focusableItemReparentedToLoadedComponent.qml
new file mode 100644
index 0000000000..a690c4243b
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/focusableItemReparentedToLoadedComponent.qml
@@ -0,0 +1,51 @@
+import QtQuick 2.12
+
+Item {
+ width: 240; height: 240
+ Loader {
+ id: loader
+ sourceComponent: surfaceParent
+ anchors.fill: parent
+
+ onStatusChanged: {
+ if (status === Loader.Ready) {
+ holder.create()
+ holder.item.parent = item
+ } else if (status === Loader.Null){
+ holder.item.parent = null
+ }
+ }
+ }
+
+ property var holder: QtObject {
+ property bool created: false
+ function create()
+ {
+ if (!created)
+ surfaceComponent.createObject(item)
+ created = true
+ }
+
+ property Item item: Item {
+ anchors.fill: parent
+ Component {
+ id: surfaceComponent
+ Item {
+ anchors.fill: parent
+ TextInput {
+ width: parent.width
+ font.pixelSize: 40
+ text: "focus me"
+ }
+ }
+ }
+ }
+ }
+
+ Component {
+ id: surfaceParent
+ Rectangle {
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index f65650cf9c..c8f251dbe1 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -33,6 +33,7 @@
#include <QtQuick/qquickitemgrabresult.h>
#include <QtQuick/qquickview.h>
#include <QtGui/private/qinputmethod_p.h>
+#include <QtQuick/private/qquickloader_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquicktextinput_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
@@ -75,6 +76,7 @@ private slots:
void qtbug_50516();
void qtbug_50516_2_data();
void qtbug_50516_2();
+ void focusableItemReparentedToLoadedComponent();
void keys();
#if QT_CONFIG(shortcut)
@@ -1312,6 +1314,35 @@ void tst_QQuickItem::qtbug_50516_2()
delete window;
}
+void tst_QQuickItem::focusableItemReparentedToLoadedComponent() // QTBUG-89736
+{
+ QQuickView window;
+ window.setSource(testFileUrl("focusableItemReparentedToLoadedComponent.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QCOMPARE(QGuiApplication::focusWindow(), &window);
+ QQuickLoader *loader = window.rootObject()->findChild<QQuickLoader *>();
+ QVERIFY(loader);
+ QTRY_VERIFY(loader->status() == QQuickLoader::Ready);
+ QQuickTextInput *textInput = window.rootObject()->findChild<QQuickTextInput *>();
+ QVERIFY(textInput);
+
+ // click to focus
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, {10, 10});
+ QTRY_VERIFY(textInput->hasActiveFocus());
+
+ // unload and reload
+ auto component = loader->sourceComponent();
+ loader->resetSourceComponent();
+ QTRY_VERIFY(loader->status() == QQuickLoader::Null);
+ loader->setSourceComponent(component);
+ QTRY_VERIFY(loader->status() == QQuickLoader::Ready);
+
+ // click to focus again
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, {10, 10});
+ QTRY_VERIFY(textInput->hasActiveFocus());
+}
+
void tst_QQuickItem::keys()
{
QQuickView *window = new QQuickView(nullptr);
diff --git a/tests/auto/quick/qquicktextinput/data/focusReason.qml b/tests/auto/quick/qquicktextinput/data/focusReason.qml
new file mode 100644
index 0000000000..7ac913d363
--- /dev/null
+++ b/tests/auto/quick/qquicktextinput/data/focusReason.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.2
+
+Rectangle {
+ width: 400
+ height: 400
+
+ Column {
+ spacing: 5
+ TextInput {
+ id: first
+ objectName: "first"
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.backtab: third
+ KeyNavigation.tab: second
+ KeyNavigation.down: second
+ }
+ TextInput {
+ id: second
+ objectName: "second"
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.up: first
+ KeyNavigation.backtab: first
+ KeyNavigation.tab: third
+ }
+ TextInput {
+ objectName: "third"
+ id: third
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.backtab: second
+ KeyNavigation.tab: first
+ }
+ Component.onCompleted: {
+ first.focus = true
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index ac502bcb28..7c5c09055d 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -237,6 +237,8 @@ private slots:
void QTBUG_77814_InsertRemoveNoSelection();
void checkCursorDelegateWhenPaddingChanged();
+
+ void focusReason();
private:
void simulateKey(QWindow *, int key);
@@ -7084,6 +7086,84 @@ void tst_qquicktextinput::checkCursorDelegateWhenPaddingChanged()
QCOMPARE(cursorDelegate->y(), textInput->topPadding());
}
+/*!
+ Verifies that TextInput items get focus in/out events with the
+ correct focus reason set.
+
+ Up and Down keys translates to Backtab and Tab focus reasons.
+
+ See QTBUG-75862.
+*/
+void tst_qquicktextinput::focusReason()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("focusReason.qml"));
+
+ QQuickTextInput *first = view.rootObject()->findChild<QQuickTextInput *>("first");
+ QQuickTextInput *second = view.rootObject()->findChild<QQuickTextInput *>("second");
+ QQuickTextInput *third = view.rootObject()->findChild<QQuickTextInput *>("third");
+ QVERIFY(first && second && third);
+
+ class FocusEventFilter : public QObject
+ {
+ public:
+ using QObject::QObject;
+
+ QHash<QObject*, Qt::FocusReason> lastFocusReason;
+ protected:
+ bool eventFilter(QObject *o, QEvent *e)
+ {
+ if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
+ QFocusEvent *fe = static_cast<QFocusEvent*>(e);
+ lastFocusReason[o] = fe->reason();
+ }
+ return QObject::eventFilter(o, e);
+ }
+ } eventFilter;
+ first->installEventFilter(&eventFilter);
+ second->installEventFilter(&eventFilter);
+ third->installEventFilter(&eventFilter);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QCOMPARE(qApp->focusObject(), first);
+ // on some platforms we don't get ActiveWindowFocusReason; tolerate this,
+ // it's not what we are testing in this test
+ if (eventFilter.lastFocusReason[first] != Qt::ActiveWindowFocusReason) {
+ QEXPECT_FAIL("", qPrintable(QString("No window activation event on the %1 platform")
+ .arg(QGuiApplication::platformName())),
+ Continue);
+ }
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::ActiveWindowFocusReason);
+
+ QTest::mouseClick(&view, Qt::LeftButton, {},
+ (second->boundingRect().center() + second->position()).toPoint());
+ QTRY_COMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::MouseFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::MouseFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Tab);
+ QCOMPARE(qApp->focusObject(), third);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[third], Qt::TabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Backtab);
+ QCOMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[third], Qt::BacktabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Up);
+ QCOMPARE(qApp->focusObject(), first);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::BacktabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Down);
+ QCOMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::TabFocusReason);
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"