aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickcanvas.cpp14
-rw-r--r--src/quick/items/qquickmousearea.cpp87
-rw-r--r--src/quick/items/qquickmousearea_p.h5
-rw-r--r--src/quick/items/qquickmousearea_p_p.h2
-rw-r--r--tests/auto/quick/qquickmousearea/data/simple.qml12
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp128
6 files changed, 203 insertions, 45 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 2de8fd5030..e7134c1230 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -1187,7 +1187,7 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
event->setAccepted(me->isAccepted());
if (me->isAccepted())
return true;
- if (mouseGrabberItem)
+ if (mouseGrabberItem && !event->buttons())
mouseGrabberItem->ungrabMouse();
}
}
@@ -1229,7 +1229,7 @@ void QQuickCanvas::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickCanvas);
#ifdef MOUSE_DEBUG
- qWarning() << "QQuickCanvas::mousePressEvent()" << event->pos() << event->button() << event->buttons();
+ qWarning() << "QQuickCanvas::mousePressEvent()" << event->localPos() << event->button() << event->buttons();
#endif
d->deliverMouseEvent(event);
@@ -1240,7 +1240,7 @@ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickCanvas);
#ifdef MOUSE_DEBUG
- qWarning() << "QQuickCanvas::mouseReleaseEvent()" << event->pos() << event->button() << event->buttons();
+ qWarning() << "QQuickCanvas::mouseReleaseEvent()" << event->localPos() << event->button() << event->buttons();
#endif
if (!d->mouseGrabberItem) {
@@ -1249,7 +1249,7 @@ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event)
}
d->deliverMouseEvent(event);
- if (d->mouseGrabberItem)
+ if (d->mouseGrabberItem && !event->buttons())
d->mouseGrabberItem->ungrabMouse();
}
@@ -1258,7 +1258,7 @@ void QQuickCanvas::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickCanvas);
#ifdef MOUSE_DEBUG
- qWarning() << "QQuickCanvas::mouseDoubleClickEvent()" << event->pos() << event->button() << event->buttons();
+ qWarning() << "QQuickCanvas::mouseDoubleClickEvent()" << event->localPos() << event->button() << event->buttons();
#endif
if (!d->mouseGrabberItem && (event->buttons() & event->button()) == event->buttons()) {
@@ -1293,7 +1293,7 @@ void QQuickCanvas::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickCanvas);
#ifdef MOUSE_DEBUG
- qWarning() << "QQuickCanvas::mouseMoveEvent()" << event->pos() << event->button() << event->buttons();
+ qWarning() << "QQuickCanvas::mouseMoveEvent()" << event->localPos() << event->button() << event->buttons();
#endif
if (!d->mouseGrabberItem) {
@@ -1423,7 +1423,7 @@ void QQuickCanvas::wheelEvent(QWheelEvent *event)
{
Q_D(QQuickCanvas);
#ifdef MOUSE_DEBUG
- qWarning() << "QQuickCanvas::wheelEvent()" << event->pos() << event->pixelDelta() << event->angleDelta();
+ qWarning() << "QQuickCanvas::wheelEvent()" << event->pixelDelta() << event->angleDelta();
#endif
//if the actual wheel event was accepted, accept the compatability wheel event and return early
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index a2522a4f47..a26c7c97f9 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -193,9 +193,9 @@ QQuickDragAttached *QQuickDrag::qmlAttachedProperties(QObject *obj)
#endif // QT_NO_DRAGANDDROP
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
-: enabled(true), hovered(false), pressed(false), longPress(false),
+: enabled(true), hovered(false), longPress(false),
moved(false), dragX(true), dragY(true), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false)
+ propagateComposedEvents(false), pressed(0)
#ifndef QT_NO_DRAGANDDROP
, drag(0)
#endif
@@ -693,12 +693,14 @@ void QQuickMouseArea::setPropagateComposedEvents(bool prevent)
\snippet qml/mousearea/mousearea.qml mousebuttons
+ \note this property only handles buttons specified in \l acceptedButtons.
+
\sa acceptedButtons
*/
Qt::MouseButtons QQuickMouseArea::pressedButtons() const
{
Q_D(const QQuickMouseArea);
- return d->lastButtons;
+ return d->pressed;
}
void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
@@ -706,9 +708,9 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
Q_D(QQuickMouseArea);
d->moved = false;
d->stealMouse = d->preventStealing;
- if (!d->enabled)
+ if (!d->enabled || !(event->button() & acceptedMouseButtons())) {
QQuickItem::mousePressEvent(event);
- else {
+ } else {
d->longPress = false;
d->saveEvent(event);
#ifndef QT_NO_DRAGANDDROP
@@ -719,7 +721,7 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
d->startScene = event->windowPos();
d->pressAndHoldTimer.start(PressAndHoldDelay, this);
setKeepMouseGrab(d->stealMouse);
- event->setAccepted(setPressed(true));
+ event->setAccepted(setPressed(event->button(), true));
#ifndef QT_NO_DRAGANDDROP
if (d->drag) {
@@ -827,19 +829,21 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
QQuickItem::mouseReleaseEvent(event);
} else {
d->saveEvent(event);
- setPressed(false);
+ setPressed(event->button(), false);
+ if (!d->pressed) {
+ // no other buttons are pressed
#ifndef QT_NO_DRAGANDDROP
- if (d->drag)
- d->drag->setActive(false);
+ if (d->drag)
+ d->drag->setActive(false);
#endif
- // If we don't accept hover, we need to reset containsMouse.
- if (!acceptHoverEvents())
- setHovered(false);
- QQuickCanvas *c = canvas();
- if (c && c->mouseGrabberItem() == this)
- ungrabMouse();
- setKeepMouseGrab(false);
-
+ // If we don't accept hover, we need to reset containsMouse.
+ if (!acceptHoverEvents())
+ setHovered(false);
+ QQuickCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
}
d->doubleClick = false;
}
@@ -924,11 +928,12 @@ void QQuickMouseArea::ungrabMouse()
if (d->pressed) {
// if our mouse grab has been removed (probably by Flickable), fix our
// state
- d->pressed = false;
+ d->pressed = 0;
d->stealMouse = false;
setKeepMouseGrab(false);
emit canceled();
emit pressedChanged();
+ emit pressedButtonsChanged();
if (d->hovered) {
d->hovered = false;
emit hoveredChanged();
@@ -975,15 +980,19 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event)
}
if (event->type() == QEvent::MouseButtonRelease) {
if (d->pressed) {
- d->pressed = false;
- d->stealMouse = false;
- if (c && c->mouseGrabberItem() == this)
- ungrabMouse();
- emit canceled();
- emit pressedChanged();
- if (d->hovered) {
- d->hovered = false;
- emit hoveredChanged();
+ d->pressed &= ~event->button();
+ emit pressedButtonsChanged();
+ if (!d->pressed) {
+ // no other buttons are pressed
+ d->stealMouse = false;
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ emit canceled();
+ emit pressedChanged();
+ if (d->hovered) {
+ d->hovered = false;
+ emit hoveredChanged();
+ }
}
}
}
@@ -1116,7 +1125,7 @@ bool QQuickMouseArea::hovered() const
/*!
\qmlproperty bool QtQuick2::MouseArea::pressed
- This property holds whether the mouse area is currently pressed.
+ This property holds whether any of the \l acceptedButtons are currently pressed.
*/
bool QQuickMouseArea::pressed() const
{
@@ -1176,31 +1185,39 @@ void QQuickMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
}
}
-bool QQuickMouseArea::setPressed(bool p)
+bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p)
{
Q_D(QQuickMouseArea);
+
#ifndef QT_NO_DRAGANDDROP
bool dragged = d->drag && d->drag->active();
#else
bool dragged = false;
#endif
- bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
+ bool wasPressed = d->pressed & button;
+ bool isclick = wasPressed && p == false && dragged == false && d->hovered == true;
+ Qt::MouseButtons oldPressed = d->pressed;
- if (d->pressed != p) {
- d->pressed = p;
+ if (wasPressed != p) {
QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
- if (d->pressed) {
+ if (p) {
+ d->pressed |= button;
if (!d->doubleClick)
emit pressed(&me);
me.setPosition(d->lastPos);
emit mouseXChanged(&me);
me.setPosition(d->lastPos);
emit mouseYChanged(&me);
- emit pressedChanged();
+ if (!oldPressed)
+ emit pressedChanged();
+ emit pressedButtonsChanged();
} else {
+ d->pressed &= ~button;
emit released(&me);
me.setPosition(d->lastPos);
- emit pressedChanged();
+ if (!d->pressed)
+ emit pressedChanged();
+ emit pressedButtonsChanged();
if (isclick && !d->longPress && !d->doubleClick){
me.setAccepted(d->isClickConnected());
emit clicked(&me);
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 14b74f45d0..8a8de3bdc3 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -135,7 +135,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedChanged)
+ Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedButtonsChanged)
Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
#ifndef QT_NO_DRAGANDDROP
@@ -187,6 +187,7 @@ Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
void enabledChanged();
+ void pressedButtonsChanged();
void acceptedButtonsChanged();
void hoverEnabledChanged();
#ifndef QT_NO_CURSOR
@@ -210,7 +211,7 @@ Q_SIGNALS:
protected:
void setHovered(bool);
- bool setPressed(bool);
+ bool setPressed(Qt::MouseButton button, bool);
bool sendMouseEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index 39a06161b7..aa28da88bc 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -87,7 +87,6 @@ public:
bool enabled : 1;
bool hovered : 1;
- bool pressed : 1;
bool longPress : 1;
bool moved : 1;
bool dragX : 1;
@@ -96,6 +95,7 @@ public:
bool doubleClick : 1;
bool preventStealing : 1;
bool propagateComposedEvents : 1;
+ Qt::MouseButtons pressed;
#ifndef QT_NO_DRAGANDDROP
QQuickDrag *drag;
#endif
diff --git a/tests/auto/quick/qquickmousearea/data/simple.qml b/tests/auto/quick/qquickmousearea/data/simple.qml
new file mode 100644
index 0000000000..56d561e5af
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/data/simple.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: whiteRect
+ width: 200
+ height: 200
+ color: "white"
+ MouseArea {
+ objectName: "mousearea"
+ anchors.fill: parent
+ }
+}
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 686c05719d..7d42eb2261 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -82,6 +82,8 @@ private slots:
void onWheel();
void transformedMouseArea_data();
void transformedMouseArea();
+ void pressedMultipleButtons_data();
+ void pressedMultipleButtons();
private:
void acceptedButton_data();
@@ -1175,6 +1177,132 @@ void tst_QQuickMouseArea::transformedMouseArea()
delete canvas;
}
+void tst_QQuickMouseArea::pressedMultipleButtons_data()
+{
+ QTest::addColumn<Qt::MouseButtons>("accepted");
+ QTest::addColumn<QList<Qt::MouseButtons> >("buttons");
+ QTest::addColumn<QList<bool> >("pressed");
+ QTest::addColumn<QList<Qt::MouseButtons> >("pressedButtons");
+ QTest::addColumn<int>("changeCount");
+
+ QList<Qt::MouseButtons> buttons;
+ QList<bool> pressed;
+ QList<Qt::MouseButtons> pressedButtons;
+ buttons << Qt::LeftButton
+ << (Qt::LeftButton | Qt::RightButton)
+ << Qt::LeftButton
+ << 0;
+ pressed << true
+ << true
+ << true
+ << false;
+ pressedButtons << Qt::LeftButton
+ << Qt::LeftButton
+ << Qt::LeftButton
+ << 0;
+ QTest::newRow("Accept Left - Press left, Press Right, Release Right")
+ << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
+
+ buttons.clear();
+ pressed.clear();
+ pressedButtons.clear();
+ buttons << Qt::LeftButton
+ << (Qt::LeftButton | Qt::RightButton)
+ << Qt::RightButton
+ << 0;
+ pressed << true
+ << true
+ << false
+ << false;
+ pressedButtons << Qt::LeftButton
+ << Qt::LeftButton
+ << 0
+ << 0;
+ QTest::newRow("Accept Left - Press left, Press Right, Release Left")
+ << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
+
+ buttons.clear();
+ pressed.clear();
+ pressedButtons.clear();
+ buttons << Qt::LeftButton
+ << (Qt::LeftButton | Qt::RightButton)
+ << Qt::LeftButton
+ << 0;
+ pressed << true
+ << true
+ << true
+ << false;
+ pressedButtons << Qt::LeftButton
+ << (Qt::LeftButton | Qt::RightButton)
+ << Qt::LeftButton
+ << 0;
+ QTest::newRow("Accept Left|Right - Press left, Press Right, Release Right")
+ << (Qt::LeftButton | Qt::RightButton) << buttons << pressed << pressedButtons << 4;
+
+ buttons.clear();
+ pressed.clear();
+ pressedButtons.clear();
+ buttons << Qt::RightButton
+ << (Qt::LeftButton | Qt::RightButton)
+ << Qt::LeftButton
+ << 0;
+ pressed << true
+ << true
+ << false
+ << false;
+ pressedButtons << Qt::RightButton
+ << Qt::RightButton
+ << 0
+ << 0;
+ QTest::newRow("Accept Right - Press Right, Press Left, Release Right")
+ << Qt::MouseButtons(Qt::RightButton) << buttons << pressed << pressedButtons << 2;
+}
+
+void tst_QQuickMouseArea::pressedMultipleButtons()
+{
+ QFETCH(Qt::MouseButtons, accepted);
+ QFETCH(QList<Qt::MouseButtons>, buttons);
+ QFETCH(QList<bool>, pressed);
+ QFETCH(QList<Qt::MouseButtons>, pressedButtons);
+ QFETCH(int, changeCount);
+
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("simple.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea *>("mousearea");
+ QVERIFY(mouseArea != 0);
+
+ QSignalSpy pressedSpy(mouseArea, SIGNAL(pressedChanged()));
+ QSignalSpy pressedButtonsSpy(mouseArea, SIGNAL(pressedButtonsChanged()));
+ mouseArea->setAcceptedMouseButtons(accepted);
+
+ QPoint point(10,10);
+
+ int prevButtons = 0;
+ for (int i = 0; i < buttons.count(); ++i) {
+ int btns = buttons.at(i);
+
+ // The windowsysteminterface takes care of sending releases
+ QTest::mousePress(canvas, (Qt::MouseButton)btns, 0, point);
+
+ QCOMPARE(mouseArea->pressed(), pressed.at(i));
+ QCOMPARE(mouseArea->pressedButtons(), pressedButtons.at(i));
+
+ prevButtons = buttons.at(i);
+ }
+
+ QTest::mousePress(canvas, Qt::NoButton, 0, point);
+ QCOMPARE(mouseArea->pressed(), false);
+
+ QCOMPARE(pressedSpy.count(), 2);
+ QCOMPARE(pressedButtonsSpy.count(), changeCount);
+
+ delete canvas;
+}
+
QTEST_MAIN(tst_QQuickMouseArea)
#include "tst_qquickmousearea.moc"