diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-07-11 12:06:15 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-07-11 12:57:13 +0200 |
commit | d2d0e08e584c780b4b70a37e7b39c6bbcc7bc63e (patch) | |
tree | 22582b82dd5bb370205aa66302fb238bf5edaa6e | |
parent | c3431db7a3eb6b0c6e325e2d1e16eb6def9a4b4d (diff) | |
parent | 744164e6c92cb721d2a339cee8c465e1685723f9 (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
.qmake.conf
tests/auto/controls/data/tst_scrollindicator.qml
Change-Id: I1f5581ae7814c0d4152e4c9b79a30a8af5a3a17b
46 files changed, 563 insertions, 149 deletions
diff --git a/dist/changes-5.9.1 b/dist/changes-5.9.1 new file mode 100644 index 00000000..46c62047 --- /dev/null +++ b/dist/changes-5.9.1 @@ -0,0 +1,75 @@ +Qt 5.9.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + + - [QTBUG-58571] Enabled the use of QML caching at build time. + - [QTBUG-61144] Added a configure feature for disabling multi- touch + support (configure -no-feature-quicktemplates2-multitouch). + +**************************************************************************** +* Controls * +**************************************************************************** + + - ApplicationWindow: + * [QTBUG-60893] Fixed access to revisioned members in base classes. + + - ComboBox: + * [QTBUG-60684] Fixed an empty popup being shown after model is cleared. + + - Container: + * [QTBUG-61310] Fixed a crash that occurred with Repeater under certain + circumstances. + + - Menu: + * Fixed key navigation to skip separators. + + - Page: + * [QTBUG-61109] Fixed the initial content layouting of dynamically created + Page instances. + + - Popup: + * [QTBUG-61114] Fixed font inheritance for popups. + + - SpinBox: + * [QTBUG-61426] Fixed valueModified() to get emitted on repeated value + changes during long press. + + - StackView: + * Fixed clear() to not emit depthChanged() when the view is empty. + +**************************************************************************** +* Styles * +**************************************************************************** + + - QQuickStyle: + * [QTBUG-60973] Fixed availableStyles() to exclude debug symbol folders + (.dSYM) on macOS. + +Default +-------- + - RangeSlider: + * Fixed the second handle to visualize its pressed state. + +Material & Universal +-------------------- + - ScrollBar: + * Fixed flashing when calling decrease() or increase() for key navigation. diff --git a/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml b/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml index 289b4545..150fd004 100644 --- a/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml @@ -83,7 +83,7 @@ ApplicationWindow { Image { id: avatar - source: "qrc:/" + modelData + ".png" + source: "qrc:/" + modelData.replace(" ", "_") + ".png" } } } diff --git a/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml index 80f2bad6..200fa0ae 100644 --- a/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml @@ -80,7 +80,7 @@ Page { Image { id: avatar - source: "qrc:/" + modelData + ".png" + source: "qrc:/" + modelData.replace(" ", "_") + ".png" } } } diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml index 23c414fb..1051b189 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml @@ -82,7 +82,7 @@ Page { Image { id: avatar - source: "qrc:/" + model.display + ".png" + source: "qrc:/" + model.display.replace(" ", "_") + ".png" } } } diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml index 490202b6..bcae4b99 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml @@ -104,7 +104,7 @@ Page { Image { id: avatar - source: !sentByMe ? "qrc:/" + model.author + ".png" : "" + source: !sentByMe ? "qrc:/" + model.author.replace(" ", "_") + ".png" : "" } Rectangle { diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml index 1ea449fe..ad37ba5f 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml @@ -82,7 +82,7 @@ Page { Image { id: avatar - source: "qrc:/" + model.display + ".png" + source: "qrc:/" + model.display.replace(" ", "_") + ".png" } } } diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml index 6f873162..2ec6a55e 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml @@ -104,7 +104,7 @@ Page { Image { id: avatar - source: !sentByMe ? "qrc:/" + model.author + ".png" : "" + source: !sentByMe ? "qrc:/" + model.author.replace(" ", "_") + ".png" : "" } Rectangle { diff --git a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc index 173403ac..519d1c7a 100644 --- a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc +++ b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc @@ -149,7 +149,7 @@ how to navigate between several pages. \printuntil } We replace the default \c{MainForm {...}} code block with a Page, which is -sized to occupy all the space on the window using the \l{anchors.fill} +sized to occupy all the space on the window using the \l {Item::}{anchors.fill} property. Then, we assign a \l Label to its \l {Page::}{header} property. Label extends @@ -245,7 +245,7 @@ Here is our ListView: \section2 Sizing and Positioning The first thing we do is set a size for the view. It should fill the available -space on the page, so we use \l {Item::anchors}{anchors.fill}. Note that +space on the page, so we use \l {Item::}{anchors.fill}. Note that Page ensures that its header and footer have enough of their own space reserved, so the view in this case will sit below the header, for example. diff --git a/examples/quickcontrols2/chattutorial/shared/Albert Einstein.png b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein.png Binary files differindex 47cb15f6..47cb15f6 100644 --- a/examples/quickcontrols2/chattutorial/shared/Albert Einstein.png +++ b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein.png diff --git a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@2x.png b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@2x.png Binary files differindex c80ddd15..c80ddd15 100644 --- a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@2x.png +++ b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@2x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@3x.png b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@3x.png Binary files differindex 41778835..41778835 100644 --- a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@3x.png +++ b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@3x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@4x.png b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@4x.png Binary files differindex 88768902..88768902 100644 --- a/examples/quickcontrols2/chattutorial/shared/Albert Einstein@4x.png +++ b/examples/quickcontrols2/chattutorial/shared/Albert_Einstein@4x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway.png b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway.png Binary files differindex 988c2416..988c2416 100644 --- a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway.png +++ b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway.png diff --git a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@2x.png b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@2x.png Binary files differindex efffc1f2..efffc1f2 100644 --- a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@2x.png +++ b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@2x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@3x.png b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@3x.png Binary files differindex 12633ec2..12633ec2 100644 --- a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@3x.png +++ b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@3x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@4x.png b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@4x.png Binary files differindex f5639280..f5639280 100644 --- a/examples/quickcontrols2/chattutorial/shared/Ernest Hemingway@4x.png +++ b/examples/quickcontrols2/chattutorial/shared/Ernest_Hemingway@4x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Hans Gude.png b/examples/quickcontrols2/chattutorial/shared/Hans_Gude.png Binary files differindex 7367a4a4..7367a4a4 100644 --- a/examples/quickcontrols2/chattutorial/shared/Hans Gude.png +++ b/examples/quickcontrols2/chattutorial/shared/Hans_Gude.png diff --git a/examples/quickcontrols2/chattutorial/shared/Hans Gude@2x.png b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@2x.png Binary files differindex c3a394e1..c3a394e1 100644 --- a/examples/quickcontrols2/chattutorial/shared/Hans Gude@2x.png +++ b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@2x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Hans Gude@3x.png b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@3x.png Binary files differindex 38ec67ee..38ec67ee 100644 --- a/examples/quickcontrols2/chattutorial/shared/Hans Gude@3x.png +++ b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@3x.png diff --git a/examples/quickcontrols2/chattutorial/shared/Hans Gude@4x.png b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@4x.png Binary files differindex 8c75d3e0..8c75d3e0 100644 --- a/examples/quickcontrols2/chattutorial/shared/Hans Gude@4x.png +++ b/examples/quickcontrols2/chattutorial/shared/Hans_Gude@4x.png diff --git a/examples/quickcontrols2/chattutorial/shared/shared.qrc b/examples/quickcontrols2/chattutorial/shared/shared.qrc index 8e112513..9eda6aa2 100644 --- a/examples/quickcontrols2/chattutorial/shared/shared.qrc +++ b/examples/quickcontrols2/chattutorial/shared/shared.qrc @@ -1,16 +1,16 @@ <RCC> <qresource prefix="/"> - <file>Albert Einstein.png</file> - <file>Albert Einstein@2x.png</file> - <file>Albert Einstein@3x.png</file> - <file>Albert Einstein@4x.png</file> - <file>Ernest Hemingway.png</file> - <file>Ernest Hemingway@2x.png</file> - <file>Ernest Hemingway@3x.png</file> - <file>Ernest Hemingway@4x.png</file> - <file>Hans Gude.png</file> - <file>Hans Gude@2x.png</file> - <file>Hans Gude@3x.png</file> - <file>Hans Gude@4x.png</file> + <file>Albert_Einstein.png</file> + <file>Albert_Einstein@2x.png</file> + <file>Albert_Einstein@3x.png</file> + <file>Albert_Einstein@4x.png</file> + <file>Ernest_Hemingway.png</file> + <file>Ernest_Hemingway@2x.png</file> + <file>Ernest_Hemingway@3x.png</file> + <file>Ernest_Hemingway@4x.png</file> + <file>Hans_Gude.png</file> + <file>Hans_Gude@2x.png</file> + <file>Hans_Gude@3x.png</file> + <file>Hans_Gude@4x.png</file> </qresource> </RCC> diff --git a/src/imports/controls/designer/LabelSpecifics.qml b/src/imports/controls/designer/LabelSpecifics.qml index 20f5013b..48cf8d05 100644 --- a/src/imports/controls/designer/LabelSpecifics.qml +++ b/src/imports/controls/designer/LabelSpecifics.qml @@ -48,6 +48,30 @@ Column { showVerticalAlignment: true } + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Text Color") + + ColorEditor { + caption: qsTr("Text Color") + backendValue: backendValues.color + supportGradient: false + } + } + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Style Color") + + ColorEditor { + caption: qsTr("Style Color") + backendValue: backendValues.styleColor + supportGradient: false + } + } + FontSection { width: parent.width } diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp index 817ec370..5e6d9f5a 100644 --- a/src/quickcontrols2/qquicktumblerview.cpp +++ b/src/quickcontrols2/qquicktumblerview.cpp @@ -36,7 +36,6 @@ #include "qquicktumblerview_p.h" -#include <QtQml/private/qqmldelegatemodel_p.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicklistview_p.h> #include <QtQuick/private/qquickpathview_p.h> @@ -126,7 +125,17 @@ void QQuickTumblerView::createView() // the count yet, because we rely on the view to tell us the count. if (m_tumbler->wrap()) { if (m_listView) { - delete m_listView; + // It's necessary to call deleteLater() rather than delete, + // as this code is most likely being run in rensponse to a signal + // emission somewhere in the list view's internals, so we need to + // wait until that has finished. + m_listView->deleteLater(); + QQml_setParent_noEvent(m_listView, nullptr); + // The auto tests pass with unparenting the list view alone, but + // just to be sure, we unset some other things as well. + m_listView->setParentItem(nullptr); + m_listView->setVisible(false); + m_listView->setModel(QVariant()); m_listView = nullptr; } @@ -143,12 +152,16 @@ void QQuickTumblerView::createView() // Give the view a size. updateView(); - // Ensure that the model is set eventually. - polish(); + // Set the model. + updateModel(); } } else { if (m_pathView) { - delete m_pathView; + m_pathView->deleteLater(); + QQml_setParent_noEvent(m_pathView, nullptr); + m_pathView->setParentItem(nullptr); + m_pathView->setVisible(false); + m_pathView->setModel(QVariant()); m_pathView = nullptr; } @@ -164,8 +177,8 @@ void QQuickTumblerView::createView() // Give the view a size. updateView(); - // Ensure that the model is set eventually. - polish(); + // Set the model. + updateModel(); } } } @@ -193,6 +206,56 @@ void QQuickTumblerView::updateView() } } +void QQuickTumblerView::updateModel() +{ + if (m_pathView && !m_pathView->model().isValid() && m_model.isValid()) { + // QQuickPathView::setPathItemCount() resets the offset animation, + // so we just skip the animation while constructing the view. + const int oldHighlightMoveDuration = m_pathView->highlightMoveDuration(); + m_pathView->setHighlightMoveDuration(0); + + // Setting model can change the count, which can affect the wrap, which can cause + // the current view to be deleted before setModel() is finished, which causes a crash. + // Since QQuickTumbler can't know about QQuickTumblerView, we use its private API to + // inform it that it should delay setting wrap. + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); + tumblerPrivate->lockWrap(); + m_pathView->setModel(m_model); + tumblerPrivate->unlockWrap(); + + // The count-depends-on-wrap behavior could cause wrap to change after + // the call above, so we must check that we're still using a PathView. + if (m_pathView) + m_pathView->setHighlightMoveDuration(oldHighlightMoveDuration); + } else if (m_listView && !m_listView->model().isValid() && m_model.isValid()) { + const int currentIndex = m_tumbler->currentIndex(); + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); + + // setModel() causes QQuickTumblerPrivate::_q_onViewCountChanged() to + // be called called, which calls QQuickTumbler::setCurrentIndex(), + // which results in QQuickItemViewPrivate::createHighlightItem() being + // called. When the highlight item is created, + // QQuickTumblerPrivate::itemChildAdded() is notified and + // QQuickTumblerPrivate::_q_updateItemHeights() is called, which causes + // a geometry change in the item and createHighlight() is called again. + // However, since the highlight item hadn't been assigned yet in the + // previous call frame, the "if (highlight) { delete highlight; }" + // check doesn't succeed, so the item is never deleted. + // + // To avoid this, we tell QQuickTumblerPrivate to ignore signals while + // setting the model, and manually call _q_onViewCountChanged() to + // ensure the correct sequence of calls happens (_q_onViewCountChanged() + // has to be within the ignoreSignals scope, because it also generates + // recursion otherwise). + tumblerPrivate->ignoreSignals = true; + m_listView->setModel(m_model); + m_listView->setCurrentIndex(currentIndex); + + tumblerPrivate->_q_onViewCountChanged(); + tumblerPrivate->ignoreSignals = false; + } +} + void QQuickTumblerView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { QQuickItem::geometryChanged(newGeometry, oldGeometry); @@ -223,42 +286,6 @@ void QQuickTumblerView::itemChange(QQuickItem::ItemChange change, const QQuickIt } } -void QQuickTumblerView::updatePolish() -{ - // There are certain cases where model count changes can potentially cause problems. - // An example of this is a ListModel that appends items in a for loop in Component.onCompleted. - // If we didn't delay assignment of the model, the PathView/ListView would be deleted in - // response to it emitting countChanged(), causing a crash. To avoid this issue, - // and to avoid the overhead of count affecting the wrap property, which in turn may - // unnecessarily create delegates that are never seen, we delay setting the model. This ensures that - // Component.onCompleted would have been finished, for example. - if (m_pathView && !m_pathView->model().isValid() && m_model.isValid()) { - // QQuickPathView::setPathItemCount() resets the offset animation, - // so we just skip the animation while constructing the view. - const int oldHighlightMoveDuration = m_pathView->highlightMoveDuration(); - m_pathView->setHighlightMoveDuration(0); - - // Setting model can change the count, which can affect the wrap, which can cause - // the current view to be deleted before setModel() is finished, which causes a crash. - // Since QQuickTumbler can't know about QQuickTumblerView, we use its private API to - // inform it that it should delay setting wrap. - QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); - tumblerPrivate->lockWrap(); - m_pathView->setModel(m_model); - tumblerPrivate->unlockWrap(); - - // The count-depends-on-wrap behavior could cause wrap to change after - // the call above, so we must check that we're still using a PathView. - if (m_pathView) - m_pathView->setHighlightMoveDuration(oldHighlightMoveDuration); - } else if (m_listView && !m_listView->model().isValid() && m_model.isValid()) { - // Usually we'd do this in QQuickTumbler::setWrap(), but that will be too early for polishes. - const int currentIndex = m_tumbler->currentIndex(); - m_listView->setModel(m_model); - m_listView->setCurrentIndex(currentIndex); - } -} - QQuickItem *QQuickTumblerView::view() { if (!m_tumbler) diff --git a/src/quickcontrols2/qquicktumblerview_p.h b/src/quickcontrols2/qquicktumblerview_p.h index e83a8bd2..0ab0c3a9 100644 --- a/src/quickcontrols2/qquicktumblerview_p.h +++ b/src/quickcontrols2/qquicktumblerview_p.h @@ -87,12 +87,12 @@ protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; void componentComplete() override; void itemChange(ItemChange change, const ItemChangeData &data) override; - void updatePolish() override; private: QQuickItem *view(); void createView(); void updateView(); + void updateModel(); void wrapChange(); diff --git a/src/quicktemplates2/qquickbusyindicator.cpp b/src/quicktemplates2/qquickbusyindicator.cpp index 883066d7..e4f20d83 100644 --- a/src/quicktemplates2/qquickbusyindicator.cpp +++ b/src/quicktemplates2/qquickbusyindicator.cpp @@ -115,6 +115,13 @@ void QQuickBusyIndicator::setRunning(bool running) emit runningChanged(); } +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickBusyIndicator::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-61785 +} +#endif + #if QT_CONFIG(accessibility) QAccessible::Role QQuickBusyIndicator::accessibleRole() const { diff --git a/src/quicktemplates2/qquickbusyindicator_p.h b/src/quicktemplates2/qquickbusyindicator_p.h index 3607cc1f..f140764b 100644 --- a/src/quicktemplates2/qquickbusyindicator_p.h +++ b/src/quicktemplates2/qquickbusyindicator_p.h @@ -69,6 +69,10 @@ Q_SIGNALS: void runningChanged(); protected: +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; #endif diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index dca50244..4b85e444 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1482,13 +1482,8 @@ void QQuickControl::touchEvent(QTouchEvent *event) Q_D(QQuickControl); switch (event->type()) { case QEvent::TouchBegin: - for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { - if (d->acceptTouch(point)) - d->handlePress(point.pos()); - } - break; - case QEvent::TouchUpdate: + case QEvent::TouchEnd: for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { if (!d->acceptTouch(point)) continue; @@ -1509,13 +1504,6 @@ void QQuickControl::touchEvent(QTouchEvent *event) } break; - case QEvent::TouchEnd: - for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { - if (d->acceptTouch(point)) - d->handleRelease(point.pos()); - } - break; - case QEvent::TouchCancel: d->handleUngrab(); break; diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index 8e77b966..007ce4e6 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -40,6 +40,7 @@ #include <QtGui/qstylehints.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlinfo.h> #include <QtQuick/private/qquickwindow_p.h> #include <QtQuick/private/qquickanimation_p.h> #include <QtQuick/private/qquicktransition_p.h> @@ -540,20 +541,32 @@ bool QQuickDrawerPrivate::prepareExitTransition() return QQuickPopupPrivate::prepareExitTransition(); } -void QQuickDrawerPrivate::setEdge(Qt::Edge e) +bool QQuickDrawerPrivate::setEdge(Qt::Edge e) { - edge = e; - if (edge == Qt::LeftEdge || edge == Qt::RightEdge) { + Q_Q(QQuickDrawer); + switch (e) { + case Qt::LeftEdge: + case Qt::RightEdge: allowVerticalMove = true; allowVerticalResize = true; allowHorizontalMove = false; allowHorizontalResize = false; - } else { + break; + case Qt::TopEdge: + case Qt::BottomEdge: allowVerticalMove = false; allowVerticalResize = false; allowHorizontalMove = true; allowHorizontalResize = true; + break; + default: + qmlWarning(q) << "invalid edge value - valid values are: " + << "Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge"; + return false; } + + edge = e; + return true; } QQuickDrawer::QQuickDrawer(QObject *parent) @@ -588,7 +601,9 @@ void QQuickDrawer::setEdge(Qt::Edge edge) if (d->edge == edge) return; - d->setEdge(edge); + if (!d->setEdge(edge)) + return; + if (isComponentComplete()) d->reposition(); emit edgeChanged(); diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h index 72a83343..010f1d49 100644 --- a/src/quicktemplates2/qquickdrawer_p_p.h +++ b/src/quicktemplates2/qquickdrawer_p_p.h @@ -88,7 +88,7 @@ public: bool prepareEnterTransition() override; bool prepareExitTransition() override; - void setEdge(Qt::Edge edge); + bool setEdge(Qt::Edge edge); Qt::Edge edge; qreal offset; diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index 12158f06..ed3d3d45 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -150,6 +150,11 @@ bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos) return false; } +static bool isTouchEvent(QEvent *event) +{ + return event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate || event->type() == QEvent::TouchEnd; +} + bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target) { if (target) { @@ -158,7 +163,7 @@ bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuick return true; } return false; - } else if (!mouseGrabberPopup) { + } else if (!mouseGrabberPopup || isTouchEvent(event)) { // allow non-modal popups to close themselves, // and non-dimming modal popups to block the event const auto popups = stackingOrderPopups(); diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp index b4c9c14c..df720c91 100644 --- a/src/quicktemplates2/qquickpageindicator.cpp +++ b/src/quicktemplates2/qquickpageindicator.cpp @@ -98,11 +98,16 @@ public: { } - QQuickItem *itemAt(const QPoint &pos) const; - void updatePressed(bool pressed, const QPoint &pos = QPoint()); + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + QQuickItem *itemAt(const QPointF &pos) const; + void updatePressed(bool pressed, const QPointF &pos = QPointF()); void setContextProperty(QQuickItem *item, const QString &name, const QVariant &value); - void itemChildAdded(QQuickItem *, QQuickItem *child); + void itemChildAdded(QQuickItem *, QQuickItem *child) override; int count; int currentIndex; @@ -111,7 +116,39 @@ public: QQuickItem *pressedItem; }; -QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPoint &pos) const +void QQuickPageIndicatorPrivate::handlePress(const QPointF &point) +{ + QQuickControlPrivate::handlePress(point); + if (interactive) + updatePressed(true, point); +} + +void QQuickPageIndicatorPrivate::handleMove(const QPointF &point) +{ + QQuickControlPrivate::handleMove(point); + if (interactive) + updatePressed(true, point); +} + +void QQuickPageIndicatorPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickPageIndicator); + QQuickControlPrivate::handleRelease(point); + if (interactive) { + if (pressedItem && contentItem) + q->setCurrentIndex(contentItem->childItems().indexOf(pressedItem)); + updatePressed(false); + } +} + +void QQuickPageIndicatorPrivate::handleUngrab() +{ + QQuickControlPrivate::handleUngrab(); + if (interactive) + updatePressed(false); +} + +QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPointF &pos) const { Q_Q(const QQuickPageIndicator); if (!contentItem || !q->contains(pos)) @@ -144,7 +181,7 @@ QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPoint &pos) const return nearest; } -void QQuickPageIndicatorPrivate::updatePressed(bool pressed, const QPoint &pos) +void QQuickPageIndicatorPrivate::updatePressed(bool pressed, const QPointF &pos) { QQuickItem *prevItem = pressedItem; pressedItem = pressed ? itemAt(pos) : nullptr; @@ -298,41 +335,16 @@ void QQuickPageIndicator::contentItemChange(QQuickItem *newItem, QQuickItem *old QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); } -void QQuickPageIndicator::mousePressEvent(QMouseEvent *event) -{ - Q_D(QQuickPageIndicator); - if (d->interactive) { - d->updatePressed(true, event->pos()); - event->accept(); - } -} - -void QQuickPageIndicator::mouseMoveEvent(QMouseEvent *event) -{ - Q_D(QQuickPageIndicator); - if (d->interactive) { - d->updatePressed(true, event->pos()); - event->accept(); - } -} - -void QQuickPageIndicator::mouseReleaseEvent(QMouseEvent *event) -{ - Q_D(QQuickPageIndicator); - if (d->interactive) { - if (d->pressedItem) - setCurrentIndex(d->contentItem->childItems().indexOf(d->pressedItem)); - d->updatePressed(false); - event->accept(); - } -} - -void QQuickPageIndicator::mouseUngrabEvent() +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickPageIndicator::touchEvent(QTouchEvent *event) { Q_D(QQuickPageIndicator); if (d->interactive) - d->updatePressed(false); + QQuickControl::touchEvent(event); + else + event->ignore(); // QTBUG-61785 } +#endif #if QT_CONFIG(accessibility) QAccessible::Role QQuickPageIndicator::accessibleRole() const diff --git a/src/quicktemplates2/qquickpageindicator_p.h b/src/quicktemplates2/qquickpageindicator_p.h index 921fe7e8..01352016 100644 --- a/src/quicktemplates2/qquickpageindicator_p.h +++ b/src/quicktemplates2/qquickpageindicator_p.h @@ -87,10 +87,9 @@ Q_SIGNALS: protected: void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void mouseUngrabEvent() override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 6927699c..81e50642 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -384,15 +384,10 @@ bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) { switch (event->type()) { case QEvent::TouchBegin: - for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { - if (acceptTouch(point)) - return handlePress(item, item->mapToScene(point.pos()), event->timestamp()); - } - break; - case QEvent::TouchUpdate: + case QEvent::TouchEnd: for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { - if (!acceptTouch(point)) + if (!acceptTouch(point) && !blockInput(item, point.pos())) continue; switch (point.state()) { @@ -408,13 +403,6 @@ bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) } break; - case QEvent::TouchEnd: - for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { - if (acceptTouch(point)) - return handleRelease(item, item->mapToScene(point.pos()), event->timestamp()); - } - break; - case QEvent::TouchCancel: handleUngrab(); break; @@ -493,7 +481,13 @@ void QQuickPopupPrivate::finalizeExitTransition() destroyOverlay(); if (hadActiveFocusBeforeExitTransition && window) { - if (!qobject_cast<QQuickPopupItem *>(window->activeFocusItem())) { + // restore focus to the next popup in chain, or to the window content if there are no other popups open + QQuickPopup *popup = nullptr; + if (QQuickOverlay *overlay = QQuickOverlay::overlay(window)) + popup = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups().value(0); + if (popup && popup->hasFocus()) { + popup->forceActiveFocus(); + } else { QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window); if (applicationWindow) applicationWindow->contentItem()->setFocus(true); diff --git a/src/quicktemplates2/qquickscrollindicator.cpp b/src/quicktemplates2/qquickscrollindicator.cpp index d14138af..ee1078e4 100644 --- a/src/quicktemplates2/qquickscrollindicator.cpp +++ b/src/quicktemplates2/qquickscrollindicator.cpp @@ -567,6 +567,13 @@ void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical) emit verticalChanged(); } +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickScrollIndicator::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-61785 +} +#endif + #if QT_CONFIG(accessibility) QAccessible::Role QQuickScrollIndicator::accessibleRole() const { diff --git a/src/quicktemplates2/qquickscrollindicator_p.h b/src/quicktemplates2/qquickscrollindicator_p.h index 6f08ef31..c1065a3f 100644 --- a/src/quicktemplates2/qquickscrollindicator_p.h +++ b/src/quicktemplates2/qquickscrollindicator_p.h @@ -94,6 +94,10 @@ Q_SIGNALS: void orientationChanged(); protected: +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; #endif diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 5cdd140d..80ab71ea 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -97,7 +97,8 @@ QQuickTumblerPrivate::QQuickTumblerPrivate() currentIndex(-1), pendingCurrentIndex(-1), ignoreCurrentIndexChanges(false), - count(0) + count(0), + ignoreSignals(false) { } @@ -163,6 +164,9 @@ QQuickTumblerPrivate *QQuickTumblerPrivate::get(QQuickTumbler *tumbler) void QQuickTumblerPrivate::_q_updateItemHeights() { + if (ignoreSignals) + return; + // Can't use our own private padding members here, as the padding property might be set, // which doesn't affect them, only their getters. Q_Q(const QQuickTumbler); @@ -174,6 +178,9 @@ void QQuickTumblerPrivate::_q_updateItemHeights() void QQuickTumblerPrivate::_q_updateItemWidths() { + if (ignoreSignals) + return; + Q_Q(const QQuickTumbler); const qreal availableWidth = q->availableWidth(); const auto items = viewContentItemChildItems(); @@ -195,6 +202,8 @@ void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged() void QQuickTumblerPrivate::_q_onViewCountChanged() { Q_Q(QQuickTumbler); + if (ignoreSignals) + return; setCount(view->property("count").toInt()); @@ -336,7 +345,9 @@ void QQuickTumbler::setCurrentIndex(int currentIndex) couldSet = true; } else { d->ignoreCurrentIndexChanges = true; + d->ignoreSignals = true; d->view->setProperty("currentIndex", currentIndex); + d->ignoreSignals = false; d->ignoreCurrentIndexChanges = false; couldSet = d->view->property("currentIndex").toInt() == currentIndex; diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h index 301b8402..0dcae762 100644 --- a/src/quicktemplates2/qquicktumbler_p_p.h +++ b/src/quicktemplates2/qquicktumbler_p_p.h @@ -88,6 +88,7 @@ public: int pendingCurrentIndex; bool ignoreCurrentIndexChanges; int count; + bool ignoreSignals; void _q_updateItemHeights(); void _q_updateItemWidths(); diff --git a/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml b/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml index 015e03bc..f0499a3a 100644 --- a/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml +++ b/tests/auto/applicationwindow/data/focusAfterPopupClosed.qml @@ -57,9 +57,12 @@ ApplicationWindow { visible: true signal focusScopeKeyPressed + signal focusPopupKeyPressed + property alias fileMenu: fileMenu property alias toolButton: toolButton property alias focusScope: focusScope + property alias focusPopup: focusPopup header: ToolBar { ToolButton { @@ -92,5 +95,17 @@ ApplicationWindow { Keys.onSpacePressed: focusScopeKeyPressed() } + + Popup { + id: focusPopup + focus: true + width: parent.width + height: parent.height + + Item { + focus: true + Keys.onSpacePressed: focusPopupKeyPressed() + } + } } diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp index e04c9450..dd50caf0 100644 --- a/tests/auto/applicationwindow/tst_applicationwindow.cpp +++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp @@ -46,6 +46,8 @@ #include <QtQuickTemplates2/private/qquickoverlay_p.h> #include <QtQuickTemplates2/private/qquickcontrol_p.h> #include <QtQuickTemplates2/private/qquicklabel_p.h> +#include <QtQuickTemplates2/private/qquickmenu_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> #include <QtQuickTemplates2/private/qquicktextarea_p.h> #include <QtQuickTemplates2/private/qquicktextfield_p.h> #include <QtQuickControls2/private/qquickproxytheme_p.h> @@ -713,9 +715,9 @@ void tst_applicationwindow::focusAfterPopupClosed() QVERIFY(focusScope); QVERIFY(focusScope->hasActiveFocus()); - QSignalSpy spy(window.data(), SIGNAL(focusScopeKeyPressed())); + QSignalSpy focusScopeSpy(window.data(), SIGNAL(focusScopeKeyPressed())); QTest::keyClick(window.data(), Qt::Key_Space); - QCOMPARE(spy.count(), 1); + QCOMPARE(focusScopeSpy.count(), 1); // Open the menu. QQuickItem* toolButton = window->property("toolButton").value<QQuickItem*>(); @@ -726,14 +728,48 @@ void tst_applicationwindow::focusAfterPopupClosed() // The FocusScope shouldn't receive any key events while the menu is open. QTest::keyClick(window.data(), Qt::Key_Space); - QCOMPARE(spy.count(), 1); + QCOMPARE(focusScopeSpy.count(), 1); // Close the menu. The FocusScope should regain focus. QTest::keyClick(window.data(), Qt::Key_Escape); QVERIFY(focusScope->hasActiveFocus()); QTest::keyClick(window.data(), Qt::Key_Space); - QCOMPARE(spy.count(), 2); + QCOMPARE(focusScopeSpy.count(), 2); + + QQuickPopup *focusPopup = window->property("focusPopup").value<QQuickPopup*>(); + QVERIFY(focusPopup); + QVERIFY(!focusPopup->hasActiveFocus()); + + focusPopup->open(); + QVERIFY(focusPopup->isVisible()); + + QSignalSpy focusPopupSpy(window.data(), SIGNAL(focusPopupKeyPressed())); + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 1); + + QQuickMenu *fileMenu = window->property("fileMenu").value<QQuickMenu*>(); + QVERIFY(fileMenu); + fileMenu->open(); + QVERIFY(fileMenu->isVisible()); + + // The Popup shouldn't receive any key events while the menu is open. + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 1); + + // Close the menu. The Popup should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusPopup->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 2); + + // Close the popup. The FocusScope should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusScope->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusScopeSpy.count(), 3); } void tst_applicationwindow::clearFocusOnDestruction() diff --git a/tests/auto/controls/data/TumblerDatePicker.qml b/tests/auto/controls/data/TumblerDatePicker.qml index ac04284a..72e57bed 100644 --- a/tests/auto/controls/data/TumblerDatePicker.qml +++ b/tests/auto/controls/data/TumblerDatePicker.qml @@ -87,6 +87,7 @@ Row { id: yearTumbler objectName: "yearTumbler" model: ListModel { + objectName: "yearTumblerListModel" Component.onCompleted: { for (var i = 2000; i < 2100; ++i) { append({value: i.toString()}); diff --git a/tests/auto/controls/data/tst_busyindicator.qml b/tests/auto/controls/data/tst_busyindicator.qml index 77a2d5ba..3de8c795 100644 --- a/tests/auto/controls/data/tst_busyindicator.qml +++ b/tests/auto/controls/data/tst_busyindicator.qml @@ -65,6 +65,11 @@ TestCase { BusyIndicator { } } + Component { + id: mouseArea + MouseArea { } + } + function test_running() { var control = createTemporaryObject(busyIndicator, testCase) verify(control) @@ -73,4 +78,26 @@ TestCase { control.running = false compare(control.running, false) } + + // QTBUG-61785 + function test_mouseArea() { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = busyIndicator.createObject(ma, {width: testCase.width, height: testCase.height}) + verify(control) + + mousePress(control) + verify(ma.pressed) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + verify(ma.pressed) + + touch.release(0, control).commit() + verify(!ma.pressed) + } } diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml index 617e7677..5446b969 100644 --- a/tests/auto/controls/data/tst_drawer.qml +++ b/tests/auto/controls/data/tst_drawer.qml @@ -73,6 +73,16 @@ TestCase { compare(control.parent, Overlay.overlay) } + function test_invalidEdge() { + var control = createTemporaryObject(drawer, testCase) + compare(control.edge, Qt.LeftEdge) + + // Test an invalid value - it should warn and ignore it. + ignoreWarning(Qt.resolvedUrl("tst_drawer.qml") + ":65:9: QML Drawer: invalid edge value - valid values are: Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge") + control.edge = Drawer.Right + compare(control.edge, Qt.LeftEdge) + } + Component { id: rectDrawer diff --git a/tests/auto/controls/data/tst_pageindicator.qml b/tests/auto/controls/data/tst_pageindicator.qml index 86c0bd8b..70813cb8 100644 --- a/tests/auto/controls/data/tst_pageindicator.qml +++ b/tests/auto/controls/data/tst_pageindicator.qml @@ -65,6 +65,11 @@ TestCase { PageIndicator { } } + Component { + id: mouseArea + MouseArea { } + } + function test_count() { var control = createTemporaryObject(pageIndicator, testCase) verify(control) @@ -83,20 +88,35 @@ TestCase { compare(control.currentIndex, 5) } - function test_interactive() { + function test_interactive_data() { + return [ + { tag: "mouse", touch: false }, + { tag: "touch", touch: true } + ] + } + + function test_interactive(data) { var control = createTemporaryObject(pageIndicator, testCase, {count: 5, spacing: 10, padding: 10}) verify(control) verify(!control.interactive) compare(control.currentIndex, 0) - mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) + var touch = touchEvent(control) + + if (data.touch) + touch.press(0, control).commit().release(0, control).commit() + else + mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.currentIndex, 0) control.interactive = true verify(control.interactive) - mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) + if (data.touch) + touch.press(0, control).commit().release(0, control).commit() + else + mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.currentIndex, 2) // test also clicking outside delegates => the nearest should be selected @@ -108,10 +128,44 @@ TestCase { compare(control.currentIndex, -1) var pos = control.mapFromItem(child, x, y) - mouseClick(control, pos.x, pos.y, Qt.LeftButton) + if (data.touch) + touch.press(0, control, pos.x, pos.y).commit().release(0, control, pos.x, pos.y).commit() + else + mouseClick(control, pos.x, pos.y, Qt.LeftButton) compare(control.currentIndex, i) } } } } + + function test_mouseArea_data() { + return [ + { tag: "interactive", interactive: true }, + { tag: "non-interactive", interactive: false } + ] + } + + // QTBUG-61785 + function test_mouseArea(data) { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = pageIndicator.createObject(ma, {count: 5, interactive: data.interactive, width: testCase.width, height: testCase.height}) + verify(control) + + compare(control.interactive, data.interactive) + + mousePress(control) + compare(ma.pressed, !data.interactive) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + compare(ma.pressed, !data.interactive) + + touch.release(0, control).commit() + verify(!ma.pressed) + } } diff --git a/tests/auto/controls/data/tst_scrollindicator.qml b/tests/auto/controls/data/tst_scrollindicator.qml index 1e28c4f5..a6275f91 100644 --- a/tests/auto/controls/data/tst_scrollindicator.qml +++ b/tests/auto/controls/data/tst_scrollindicator.qml @@ -66,6 +66,11 @@ TestCase { } Component { + id: mouseArea + MouseArea { } + } + + Component { id: flickable Flickable { width: 100 @@ -231,4 +236,26 @@ TestCase { compare(control.horizontal, true) compare(control.vertical, false) } + + // QTBUG-61785 + function test_mouseArea() { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = scrollIndicator.createObject(ma, {active: true, size: 0.9, width: testCase.width, height: testCase.height}) + verify(control) + + mousePress(control) + verify(ma.pressed) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + verify(ma.pressed) + + touch.release(0, control).commit() + verify(!ma.pressed) + } } diff --git a/tests/auto/controls/data/tst_tumbler.qml b/tests/auto/controls/data/tst_tumbler.qml index 00d13e23..aaf888c2 100644 --- a/tests/auto/controls/data/tst_tumbler.qml +++ b/tests/auto/controls/data/tst_tumbler.qml @@ -389,7 +389,7 @@ TestCase { compare(tumbler.monthTumbler.currentIndex, 0); compare(tumbler.monthTumbler.count, 12); compare(tumbler.yearTumbler.currentIndex, 0); - compare(tumbler.yearTumbler.count, 100); + tryCompare(tumbler.yearTumbler, "count", 100); verify(findView(tumbler.dayTumbler).children.length >= tumbler.dayTumbler.visibleItemCount); verify(findView(tumbler.monthTumbler).children.length >= tumbler.monthTumbler.visibleItemCount); @@ -1057,4 +1057,41 @@ TestCase { compare(tumbler.moving, true) tryCompare(tumbler, "moving", false) } + + Component { + id: qtbug61374Component + + Row { + property alias tumbler: tumbler + property alias label: label + + Component.onCompleted: { + tumbler.currentIndex = 2 + } + + Tumbler { + id: tumbler + model: 5 + // ... + } + + Label { + id: label + text: tumbler.currentItem.text + } + } + } + + function test_qtbug61374() { + var row = createTemporaryObject(qtbug61374Component, testCase); + verify(row); + + var tumbler = row.tumbler; + tryCompare(tumbler, "currentIndex", 2); + + tumblerView = findView(tumbler); + + var label = row.label; + compare(label.text, "2"); + } } diff --git a/tests/auto/popup/tst_popup.cpp b/tests/auto/popup/tst_popup.cpp index 48295e10..7566ceff 100644 --- a/tests/auto/popup/tst_popup.cpp +++ b/tests/auto/popup/tst_popup.cpp @@ -307,6 +307,40 @@ void tst_popup::overlay() QVERIFY(!popup->isVisible()); QCOMPARE(overlay->isVisible(), popup->isVisible()); + + // multi-touch + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QVERIFY(!button->isPressed()); + + QTest::touchEvent(window, device.data()).press(0, button->mapToScene(QPointF(1, 1)).toPoint()); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QCOMPARE(button->isPressed(), !modal); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + + QTest::touchEvent(window, device.data()).stationary(0).press(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint()); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QCOMPARE(button->isPressed(), !modal); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + + QTest::touchEvent(window, device.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1); + QVERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + QVERIFY(!button->isPressed()); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount); + + QTest::touchEvent(window, device.data()).release(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint()); + QVERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + QVERIFY(!button->isPressed()); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); } void tst_popup::zOrder_data() |