aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp9
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h1
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp7
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp104
-rw-r--r--src/quicktemplates2/qquickcontrol_p.h3
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h6
-rw-r--r--src/quicktemplates2/qquickdial.cpp9
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp6
-rw-r--r--src/quicktemplates2/qquickscrollbar_p_p.h1
-rw-r--r--src/quicktemplates2/qquickslider.cpp7
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp7
-rw-r--r--tests/auto/focus/tst_focus.cpp55
12 files changed, 172 insertions, 43 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 7c2ced66..de954570 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -121,7 +121,6 @@ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate()
autoExclusive(false),
autoRepeat(false),
wasHeld(false),
- touchId(-1),
holdTimer(0),
delayTimer(0),
repeatTimer(0),
@@ -165,7 +164,6 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
Q_Q(QQuickAbstractButton);
bool wasPressed = pressed;
q->setPressed(false);
- touchId = -1;
if (!wasHeld && (keepPressed || q->contains(point)))
q->nextCheckState();
@@ -191,7 +189,6 @@ void QQuickAbstractButtonPrivate::handleCancel()
return;
q->setPressed(false);
- touchId = -1;
stopPressRepeat();
stopPressAndHold();
emit q->canceled();
@@ -579,7 +576,8 @@ void QQuickAbstractButton::focusOutEvent(QFocusEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::focusOutEvent(event);
- d->handleCancel();
+ if (d->touchId == -1) // don't ungrab on multi-touch if another control gets focused
+ d->handleCancel();
}
void QQuickAbstractButton::keyPressEvent(QKeyEvent *event)
@@ -713,9 +711,10 @@ void QQuickAbstractButton::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickAbstractButton::touchUngrabEvent()
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index e27f5c82..6d149b4f 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -95,7 +95,6 @@ public:
bool autoExclusive;
bool autoRepeat;
bool wasHeld;
- int touchId;
int holdTimer;
int delayTimer;
int repeatTimer;
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 09a5eede..5c763d21 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -257,7 +257,6 @@ public:
bool hasCurrentIndex;
int highlightedIndex;
int currentIndex;
- int touchId;
QVariant model;
QString textRole;
QString currentText;
@@ -296,7 +295,6 @@ QQuickComboBoxPrivate::QQuickComboBoxPrivate()
hasCurrentIndex(false),
highlightedIndex(-1),
currentIndex(-1),
- touchId(-1),
delegateModel(nullptr),
delegate(nullptr),
indicator(nullptr),
@@ -648,14 +646,12 @@ void QQuickComboBoxPrivate::handleRelease(const QPointF &)
q->setPressed(false);
togglePopup(false);
}
- touchId = -1;
}
void QQuickComboBoxPrivate::handleUngrab()
{
Q_Q(QQuickComboBox);
q->setPressed(false);
- touchId = -1;
}
QQuickComboBox::QQuickComboBox(QQuickItem *parent)
@@ -1580,9 +1576,10 @@ void QQuickComboBox::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickComboBox::touchUngrabEvent()
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index eb66f313..b086f3ee 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -120,6 +120,7 @@ QQuickControlPrivate::QQuickControlPrivate()
hovered(false),
explicitHoverEnabled(false),
#endif
+ touchId(-1),
padding(0),
topPadding(0),
leftPadding(0),
@@ -144,6 +145,36 @@ QQuickControlPrivate::~QQuickControlPrivate()
#endif
}
+void QQuickControlPrivate::handlePress(const QPointF &)
+{
+ Q_Q(QQuickControl);
+ if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
+ q->forceActiveFocus(Qt::MouseFocusReason);
+}
+
+void QQuickControlPrivate::handleMove(const QPointF &point)
+{
+#if QT_CONFIG(quicktemplates2_hover)
+ Q_Q(QQuickControl);
+ q->setHovered(hoverEnabled && q->contains(point));
+#else
+ Q_UNUSED(point);
+#endif
+}
+
+void QQuickControlPrivate::handleRelease(const QPointF &)
+{
+ Q_Q(QQuickControl);
+ if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
+ q->forceActiveFocus(Qt::MouseFocusReason);
+ touchId = -1;
+}
+
+void QQuickControlPrivate::handleUngrab()
+{
+ touchId = -1;
+}
+
void QQuickControlPrivate::mirrorChange()
{
Q_Q(QQuickControl);
@@ -1287,30 +1318,85 @@ void QQuickControl::hoverLeaveEvent(QHoverEvent *event)
void QQuickControl::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickControl);
- if ((d->focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
- forceActiveFocus(Qt::MouseFocusReason);
-
+ d->handlePress(event->localPos());
event->accept();
}
void QQuickControl::mouseMoveEvent(QMouseEvent *event)
{
-#if QT_CONFIG(quicktemplates2_hover)
Q_D(QQuickControl);
- setHovered(d->hoverEnabled && contains(event->pos()));
-#endif
+ d->handleMove(event->localPos());
event->accept();
}
void QQuickControl::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickControl);
- if ((d->focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
- forceActiveFocus(Qt::MouseFocusReason);
-
+ d->handleRelease(event->localPos());
event->accept();
}
+void QQuickControl::mouseUngrabEvent()
+{
+ Q_D(QQuickControl);
+ d->handleUngrab();
+}
+
+void QQuickControl::touchEvent(QTouchEvent *event)
+{
+ Q_D(QQuickControl);
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() == d->touchId)
+ d->handlePress(point.pos());
+ }
+ break;
+
+ case QEvent::TouchUpdate:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() != d->touchId)
+ continue;
+
+ switch (point.state()) {
+ case Qt::TouchPointPressed:
+ d->handlePress(point.pos());
+ break;
+ case Qt::TouchPointMoved:
+ d->handleMove(point.pos());
+ break;
+ case Qt::TouchPointReleased:
+ d->handleRelease(point.pos());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case QEvent::TouchEnd:
+ for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
+ if (point.id() == d->touchId)
+ d->handleRelease(point.pos());
+ }
+ break;
+
+ case QEvent::TouchCancel:
+ d->handleUngrab();
+ break;
+
+ default:
+ QQuickItem::touchEvent(event);
+ break;
+ }
+}
+
+void QQuickControl::touchUngrabEvent()
+{
+ Q_D(QQuickControl);
+ d->handleUngrab();
+}
+
#if QT_CONFIG(wheelevent)
void QQuickControl::wheelEvent(QWheelEvent *event)
{
diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h
index a94ef01d..6ad89376 100644
--- a/src/quicktemplates2/qquickcontrol_p.h
+++ b/src/quicktemplates2/qquickcontrol_p.h
@@ -184,6 +184,9 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseUngrabEvent() override;
+ void touchEvent(QTouchEvent *event) override;
+ void touchUngrabEvent() override;
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *event) override;
#endif
diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h
index 14a468f3..2c79c887 100644
--- a/src/quicktemplates2/qquickcontrol_p_p.h
+++ b/src/quicktemplates2/qquickcontrol_p_p.h
@@ -78,6 +78,11 @@ public:
return control->d_func();
}
+ void handlePress(const QPointF &point);
+ void handleMove(const QPointF &point);
+ void handleRelease(const QPointF &point);
+ void handleUngrab();
+
void mirrorChange() override;
void setTopPadding(qreal value, bool reset = false);
@@ -136,6 +141,7 @@ public:
bool hovered;
bool explicitHoverEnabled;
#endif
+ int touchId;
qreal padding;
qreal topPadding;
qreal leftPadding;
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 5b98992b..285dda49 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -96,8 +96,7 @@ class QQuickDialPrivate : public QQuickControlPrivate
public:
QQuickDialPrivate()
- : touchId(-1),
- from(0),
+ : from(0),
to(1),
value(0),
position(0),
@@ -123,7 +122,6 @@ public:
void handleRelease(const QPointF &point);
void handleUngrab();
- int touchId;
qreal from;
qreal to;
qreal value;
@@ -242,14 +240,12 @@ void QQuickDialPrivate::handleRelease(const QPointF &point)
q->setPressed(false);
pressPoint = QPointF();
- touchId = -1;
}
void QQuickDialPrivate::handleUngrab()
{
Q_Q(QQuickDial);
pressPoint = QPointF();
- touchId = -1;
q->setPressed(false);
}
@@ -729,9 +725,10 @@ void QQuickDial::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickDial::touchUngrabEvent()
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index b0d55dfb..be97f071 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -165,7 +165,6 @@ QQuickScrollBarPrivate::QQuickScrollBarPrivate()
moving(false),
interactive(true),
explicitInteractive(false),
- touchId(-1),
orientation(Qt::Vertical),
snapMode(QQuickScrollBar::NoSnap),
policy(QQuickScrollBar::AsNeeded)
@@ -269,7 +268,6 @@ void QQuickScrollBarPrivate::handleRelease(const QPointF &point)
pos = snapPosition(pos);
q->setPosition(pos);
offset = 0.0;
- touchId = -1;
q->setPressed(false);
}
@@ -277,7 +275,6 @@ void QQuickScrollBarPrivate::handleUngrab()
{
Q_Q(QQuickScrollBar);
offset = 0.0;
- touchId = -1;
q->setPressed(false);
}
@@ -657,9 +654,10 @@ void QQuickScrollBar::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickScrollBar::touchUngrabEvent()
diff --git a/src/quicktemplates2/qquickscrollbar_p_p.h b/src/quicktemplates2/qquickscrollbar_p_p.h
index 409b952b..cbbef2c8 100644
--- a/src/quicktemplates2/qquickscrollbar_p_p.h
+++ b/src/quicktemplates2/qquickscrollbar_p_p.h
@@ -88,7 +88,6 @@ public:
bool moving;
bool interactive;
bool explicitInteractive;
- int touchId;
Qt::Orientation orientation;
QQuickScrollBar::SnapMode snapMode;
QQuickScrollBar::Policy policy;
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index 77e5856c..ef074c73 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -96,7 +96,6 @@ public:
stepSize(0),
live(true),
pressed(false),
- touchId(-1),
orientation(Qt::Horizontal),
snapMode(QQuickSlider::NoSnap),
handle(nullptr)
@@ -120,7 +119,6 @@ public:
qreal stepSize;
bool live;
bool pressed;
- int touchId;
QPointF pressPoint;
Qt::Orientation orientation;
QQuickSlider::SnapMode snapMode;
@@ -209,7 +207,6 @@ void QQuickSliderPrivate::handleMove(const QPointF &point)
void QQuickSliderPrivate::handleRelease(const QPointF &point)
{
Q_Q(QQuickSlider);
- touchId = -1;
pressPoint = QPointF();
const qreal oldPos = position;
qreal pos = positionAt(point);
@@ -230,7 +227,6 @@ void QQuickSliderPrivate::handleRelease(const QPointF &point)
void QQuickSliderPrivate::handleUngrab()
{
Q_Q(QQuickSlider);
- touchId = -1;
pressPoint = QPointF();
q->setPressed(false);
}
@@ -693,9 +689,10 @@ void QQuickSlider::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickSlider::touchUngrabEvent()
diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp
index b70366ea..9558cfc5 100644
--- a/src/quicktemplates2/qquickspinbox.cpp
+++ b/src/quicktemplates2/qquickspinbox.cpp
@@ -114,7 +114,6 @@ public:
stepSize(1),
delayTimer(0),
repeatTimer(0),
- touchId(-1),
up(nullptr),
down(nullptr),
validator(nullptr),
@@ -150,7 +149,6 @@ public:
int stepSize;
int delayTimer;
int repeatTimer;
- int touchId;
QQuickSpinButton *up;
QQuickSpinButton *down;
QValidator *validator;
@@ -323,7 +321,6 @@ bool QQuickSpinBoxPrivate::handleRelease(const QPointF &point)
if (value != oldValue)
emit q->valueModified();
- touchId = -1;
q->setAccessibleProperty("pressed", false);
stopPressRepeat();
return wasPressed;
@@ -335,7 +332,6 @@ bool QQuickSpinBoxPrivate::handleUngrab()
up->setPressed(false);
down->setPressed(false);
- touchId = -1;
q->setAccessibleProperty("pressed", false);
stopPressRepeat();
return false;
@@ -870,9 +866,10 @@ void QQuickSpinBox::touchEvent(QTouchEvent *event)
break;
default:
- QQuickControl::touchEvent(event);
break;
}
+
+ QQuickControl::touchEvent(event);
}
void QQuickSpinBox::touchUngrabEvent()
diff --git a/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp
index e423835c..c5c24233 100644
--- a/tests/auto/focus/tst_focus.cpp
+++ b/tests/auto/focus/tst_focus.cpp
@@ -44,6 +44,7 @@
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qstylehints.h>
+#include <QtGui/qtouchdevice.h>
#include "../shared/util.h"
#include "../shared/visualtestutil.h"
@@ -59,6 +60,7 @@ private slots:
void navigation_data();
void navigation();
+ void policy_data();
void policy();
void reason_data();
@@ -122,11 +124,24 @@ void tst_focus::navigation()
QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1));
}
+void tst_focus::policy_data()
+{
+ QTest::addColumn<QString>("name");
+
+ QTest::newRow("Control") << "Control";
+ QTest::newRow("ComboBox") << "ComboBox";
+ QTest::newRow("Button") << "Button";
+ QTest::newRow("Slider") << "Slider";
+ QTest::newRow("ScrollBar") << "ScrollBar";
+}
+
void tst_focus::policy()
{
+ QFETCH(QString, name);
+
QQmlEngine engine;
QQmlComponent component(&engine);
- component.setData("import QtQuick.Controls 2.1; ApplicationWindow { width: 100; height: 100; Control { anchors.fill: parent } }", QUrl());
+ component.setData(QString("import QtQuick.Controls 2.1; ApplicationWindow { width: 100; height: 100; %1 { anchors.fill: parent } }").arg(name).toUtf8(), QUrl());
QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create()));
QVERIFY(window);
@@ -141,6 +156,22 @@ void tst_focus::policy()
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ struct TouchDeviceDeleter
+ {
+ static inline void cleanup(QTouchDevice *device)
+ {
+ QWindowSystemInterface::unregisterTouchDevice(device);
+ delete device;
+ }
+ };
+
+ QScopedPointer<QTouchDevice, TouchDeviceDeleter> device(new QTouchDevice);
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device.data());
+
+ control->setFocusPolicy(Qt::NoFocus);
+ QCOMPARE(control->focusPolicy(), Qt::NoFocus);
+
// Qt::TabFocus vs. QQuickItem::activeFocusOnTab
control->setActiveFocusOnTab(true);
QCOMPARE(control->focusPolicy(), Qt::TabFocus);
@@ -162,7 +193,8 @@ void tst_focus::policy()
control->setFocus(false);
QVERIFY(!control->hasActiveFocus());
- // Qt::ClickFocus
+ // Qt::ClickFocus (mouse)
+ control->setFocusPolicy(Qt::NoFocus);
control->setAcceptedMouseButtons(Qt::LeftButton);
QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2));
QVERIFY(!control->hasActiveFocus());
@@ -178,6 +210,25 @@ void tst_focus::policy()
control->setFocus(false);
QVERIFY(!control->hasActiveFocus());
+ // Qt::ClickFocus (touch)
+ control->setFocusPolicy(Qt::NoFocus);
+ QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2));
+ QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2));
+ QVERIFY(!control->hasActiveFocus());
+ QVERIFY(!control->hasVisualFocus());
+
+ control->setFocusPolicy(Qt::ClickFocus);
+ QCOMPARE(control->focusPolicy(), Qt::ClickFocus);
+ QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2));
+ QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2));
+ QEXPECT_FAIL("Control", "TODO: Control::touchEvent should set the touchId", Continue);
+ QVERIFY(control->hasActiveFocus());
+ QVERIFY(!control->hasVisualFocus());
+
+ // reset
+ control->setFocus(false);
+ QVERIFY(!control->hasActiveFocus());
+
// Qt::WheelFocus
QWheelEvent wheelEvent(QPoint(control->width() / 2, control->height() / 2), 10, Qt::NoButton, Qt::NoModifier);
QGuiApplication::sendEvent(control, &wheelEvent);