summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp76
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h4
-rw-r--r--src/imports/location/qdeclarativegeomapgesturearea.cpp174
-rw-r--r--src/imports/location/qdeclarativegeomapgesturearea_p.h21
-rw-r--r--tests/auto/declarative_ui/tst_map_mouse.qml26
5 files changed, 212 insertions, 89 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index 4c4b8888..a2d139e9 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -58,7 +58,6 @@
#include <QtQml/QQmlContext>
#include <QtQml/qqmlinfo.h>
#include <QModelIndex>
-#include <QtQuick/QQuickWindow>
#include <QtQuick/QSGSimpleRectNode>
#include <QtGui/QGuiApplication>
#include <QCoreApplication>
@@ -196,7 +195,7 @@ QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent)
{
QLOC_TRACE0;
setAcceptHoverEvents(false);
- setAcceptedMouseButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton);
+ setAcceptedMouseButtons(Qt::LeftButton);
setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape);
setFiltersChildMouseEvents(true);
@@ -322,8 +321,7 @@ void QDeclarativeGeoMap::componentComplete()
*/
void QDeclarativeGeoMap::mousePressEvent(QMouseEvent *event)
{
- if (!mouseEvent(event))
- event->ignore();
+ event->setAccepted(gestureArea_->mousePressEvent(event));
}
/*!
@@ -331,8 +329,7 @@ void QDeclarativeGeoMap::mousePressEvent(QMouseEvent *event)
*/
void QDeclarativeGeoMap::mouseMoveEvent(QMouseEvent *event)
{
- if (!mouseEvent(event))
- event->ignore();
+ event->setAccepted(gestureArea_->mouseMoveEvent(event));
}
/*!
@@ -340,31 +337,17 @@ void QDeclarativeGeoMap::mouseMoveEvent(QMouseEvent *event)
*/
void QDeclarativeGeoMap::mouseReleaseEvent(QMouseEvent *event)
{
- if (!mouseEvent(event))
- event->ignore();
+ event->setAccepted(gestureArea_->mouseReleaseEvent(event));
}
/*!
\internal
- returns whether flickable used the event
*/
-bool QDeclarativeGeoMap::mouseEvent(QMouseEvent *event)
+void QDeclarativeGeoMap::mouseUngrabEvent()
{
- if (!mappingManagerInitialized_)
- return false;
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- return gestureArea_->mousePressEvent(event);
- case QEvent::MouseButtonRelease:
- return gestureArea_->mouseReleaseEvent(event);
- case QEvent::MouseMove:
- return gestureArea_->mouseMoveEvent(event);
- default:
- return false;
- }
+ gestureArea_->mouseUngrabEvent();
}
-
/*!
\qmlproperty MapGestureArea QtLocation::Map::gesture
@@ -839,8 +822,7 @@ void QDeclarativeGeoMap::touchEvent(QTouchEvent *event)
return;
}
QLOC_TRACE0;
- event->accept();
- gestureArea_->touchEvent(event);
+ event->setAccepted(gestureArea_->touchEvent(event));
}
/*!
@@ -859,29 +841,51 @@ void QDeclarativeGeoMap::wheelEvent(QWheelEvent *event)
*/
bool QDeclarativeGeoMap::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
- Q_UNUSED(item)
+ if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove ||
+ event->type() == QEvent::MouseButtonRelease ||
+ event->type() == QEvent::MouseButtonDblClick) {
+ // Check if we have already grabbed input. This can happen if the previous touch event
+ // immediately triggers a gesture, the synthesized mouse event is still generated. Filter
+ // these events so that child items do no receive them.
+ if (gestureArea_->hasGrabbedInput())
+ return true;
+
+ // Ignore synthesized mouse events, but don't filter them, as child items may not handle
+ // touch events directly. After a gesture is recognized and an input grab obtained these
+ // events should cease to be generated, except for the case above.
+ QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ if (me->source() != Qt::MouseEventNotSynthesized)
+ return false;
+ } else if (event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate ||
+ event->type() == QEvent::TouchEnd) {
+ // Check if already grabbed mouse, if so filter out touch events.
+ // FIXME: Returning true here gives priority to touch input, which is not what is intended.
+ // In response to returning true ungrabMouse() is called and touch input will be handled
+ // thereafter.
+ if (gestureArea_->hasGrabbedInput())
+ return true;
+ }
+
QLOC_TRACE0;
switch (event->type()) {
case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
if (item->keepMouseGrab())
return false;
- if (!gestureArea_->filterMapChildMouseEvent(static_cast<QMouseEvent *>(event)))
- return false;
- grabMouse();
- return true;
- case QEvent::UngrabMouse:
return gestureArea_->filterMapChildMouseEvent(static_cast<QMouseEvent *>(event));
+ case QEvent::MouseButtonRelease:
+ return gestureArea_->filterMapChildMouseEvent(static_cast<QMouseEvent *>(event));
+ case QEvent::UngrabMouse:
+ // Never filter ungrab mouse events. This event notifies 'item' that the mouse has been
+ // grabbed and it should cancel any outstanding input event processing. For example, press
+ // and hold timers.
+ return false;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
if (item->keepMouseGrab())
return false;
- if (!gestureArea_->filterMapChildTouchEvent(static_cast<QTouchEvent *>(event)))
- return false;
- grabMouse();
- return true;
+ return gestureArea_->filterMapChildTouchEvent(static_cast<QTouchEvent *>(event));
case QEvent::Wheel:
return gestureArea_->wheelEvent(static_cast<QWheelEvent *>(event));
default:
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index 256ddcfb..ce66acaa 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -146,9 +146,6 @@ public:
QT_DEPRECATED Q_INVOKABLE QPointF toScreenPosition(const QGeoCoordinate &coordinate) const;
#endif
- // callback for map mouse areas
- bool mouseEvent(QMouseEvent *event);
-
QDeclarativeGeoMapGestureArea *gesture();
Q_INVOKABLE void fitViewportToGeoShape(const QVariant &shape);
@@ -163,6 +160,7 @@ protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
+ void mouseUngrabEvent();
void touchEvent(QTouchEvent *event);
void wheelEvent(QWheelEvent *event);
diff --git a/src/imports/location/qdeclarativegeomapgesturearea.cpp b/src/imports/location/qdeclarativegeomapgesturearea.cpp
index 0fbf5557..bdba9110 100644
--- a/src/imports/location/qdeclarativegeomapgesturearea.cpp
+++ b/src/imports/location/qdeclarativegeomapgesturearea.cpp
@@ -40,6 +40,7 @@
#include <QtGui/QWheelEvent>
#include <QtGui/QStyleHints>
#include <QtQml/qqmlinfo.h>
+#include <QtQuick/QQuickWindow>
#include <QPropertyAnimation>
#include <QDebug>
#include "math.h"
@@ -329,6 +330,8 @@ QDeclarativeGeoMapGestureArea::QDeclarativeGeoMapGestureArea(QDeclarativeGeoMap
: QObject(parent),
declarativeMap_(map),
enabled_(true),
+ hasGrab_(false),
+ activeInput_(NoInput),
activeGestures_(ZoomGesture | PanGesture | FlickGesture)
{
map_ = 0;
@@ -339,8 +342,8 @@ QDeclarativeGeoMapGestureArea::QDeclarativeGeoMapGestureArea(QDeclarativeGeoMap
touchPointState_ = touchPoints0;
pinchState_ = pinchInactive;
panState_ = panInactive;
-
}
+
/*!
\internal
*/
@@ -356,6 +359,11 @@ void QDeclarativeGeoMapGestureArea::setMap(QGeoMap *map)
map_, SLOT(cameraStopped()));
}
+bool QDeclarativeGeoMapGestureArea::hasGrabbedInput() const
+{
+ return hasGrab_;
+}
+
QDeclarativeGeoMapGestureArea::~QDeclarativeGeoMapGestureArea()
{
}
@@ -563,6 +571,11 @@ bool QDeclarativeGeoMapGestureArea::mousePressEvent(QMouseEvent *event)
if (!(enabled_ && activeGestures_))
return false;
+ if (activeInput_ == TouchInput)
+ return false;
+
+ activeInput_ = MouseInput;
+
touchPoints_.clear();
touchPoints_ << makeTouchPointFromMouseEvent(event, Qt::TouchPointPressed);
@@ -578,6 +591,9 @@ bool QDeclarativeGeoMapGestureArea::mouseMoveEvent(QMouseEvent *event)
if (!(enabled_ && activeGestures_))
return false;
+ if (activeInput_ != MouseInput)
+ return false;
+
touchPoints_.clear();
touchPoints_ << makeTouchPointFromMouseEvent(event, Qt::TouchPointMoved);
@@ -593,23 +609,63 @@ bool QDeclarativeGeoMapGestureArea::mouseReleaseEvent(QMouseEvent *)
if (!(enabled_ && activeGestures_))
return false;
+ if (activeInput_ == TouchInput)
+ return false;
+
touchPoints_.clear();
update();
+
+ activeInput_ = NoInput;
+
return true;
}
/*!
\internal
*/
-void QDeclarativeGeoMapGestureArea::touchEvent(QTouchEvent *event)
+void QDeclarativeGeoMapGestureArea::mouseUngrabEvent()
{
+ touchPoints_.clear();
+ hasGrab_ = false;
+ if (activeInput_ == MouseInput)
+ activeInput_ = NoInput;
+ update();
+}
+
+/*!
+ \internal
+*/
+bool QDeclarativeGeoMapGestureArea::touchEvent(QTouchEvent *event)
+{
+ if (!(enabled_ && activeGestures_))
+ return false;
+
+ if (activeInput_ == MouseInput)
+ return false;
+
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
- touchPoints_.clear();
- for (int i = 0; i < event->touchPoints().count(); ++i) {
- if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
- touchPoints_ << event->touchPoints().at(i);
+ activeInput_ = TouchInput;
+ foreach (const QTouchEvent::TouchPoint &p, event->touchPoints()) {
+ QList<QTouchEvent::TouchPoint>::iterator i;
+ for (i = touchPoints_.begin(); i != touchPoints_.end(); ++i) {
+ if (i->id() == p.id()) {
+ i = touchPoints_.erase(i);
+ break;
+ }
+ }
+ switch (p.state()) {
+ case Qt::TouchPointPressed:
+ case Qt::TouchPointMoved:
+ case Qt::TouchPointStationary:
+ touchPoints_.insert(i, p);
+ break;
+ case Qt::TouchPointReleased:
+ // already removed
+ break;
+ default:
+ break;
}
}
update();
@@ -617,11 +673,14 @@ void QDeclarativeGeoMapGestureArea::touchEvent(QTouchEvent *event)
case QEvent::TouchEnd:
touchPoints_.clear();
update();
+ activeInput_ = NoInput;
break;
default:
// no-op
break;
}
+
+ return true;
}
bool QDeclarativeGeoMapGestureArea::wheelEvent(QWheelEvent *event)
@@ -635,26 +694,25 @@ bool QDeclarativeGeoMapGestureArea::wheelEvent(QWheelEvent *event)
*/
bool QDeclarativeGeoMapGestureArea::filterMapChildMouseEvent(QMouseEvent *event)
{
- bool used = false;
+ if (!(enabled_ && activeGestures_))
+ return false;
+
+ // We have not grabbed the mouse yet. Process it but don't filter it so the child can use it
+ // (until we grab it).
switch (event->type()) {
case QEvent::MouseButtonPress:
- used = mousePressEvent(event);
+ mousePressEvent(event);
break;
case QEvent::MouseButtonRelease:
- used = mouseReleaseEvent(event);
+ mouseReleaseEvent(event);
break;
case QEvent::MouseMove:
- used = mouseMoveEvent(event);
- break;
- case QEvent::UngrabMouse:
- touchPoints_.clear();
- update();
+ mouseMoveEvent(event);
break;
default:
- used = false;
break;
}
- return used && (isPanActive() || isPinchActive());
+ return false;
}
/*!
@@ -662,8 +720,13 @@ bool QDeclarativeGeoMapGestureArea::filterMapChildMouseEvent(QMouseEvent *event)
*/
bool QDeclarativeGeoMapGestureArea::filterMapChildTouchEvent(QTouchEvent *event)
{
+ if (!(enabled_ && activeGestures_))
+ return false;
+
+ // We have not grabbed the touch id associated with this touch event yet. Process it but don't
+ // filter it so the child can use it (until we grab it).
touchEvent(event);
- return isPanActive() || isPinchActive();
+ return false;
}
/*!
@@ -724,6 +787,31 @@ void QDeclarativeGeoMapGestureArea::update()
// the whole gesture (enabled_ flag), this keeps the enabled_ consistent with the pinch
if (isPanActive() || (enabled_ && pan_.enabled_ && (activeGestures_ & (PanGesture | FlickGesture))))
panStateMachine();
+
+ if (pinchState_ != pinchInactive || panState_ == panActive) {
+ if (!hasGrab_) {
+ if (activeInput_ == MouseInput) {
+ hasGrab_ = true;
+ declarativeMap_->grabMouse();
+ } else if (activeInput_ == TouchInput) {
+ hasGrab_ = true;
+ QVector<int> ids;
+ foreach (const QTouchEvent::TouchPoint &tp, touchPoints_)
+ ids.append(tp.id());
+ declarativeMap_->grabTouchPoints(ids);
+ }
+ }
+ } else {
+ if (hasGrab_) {
+ if (activeInput_ == MouseInput) {
+ hasGrab_ = false;
+ declarativeMap_->ungrabMouse();
+ } else if (activeInput_ == TouchInput) {
+ hasGrab_ = false;
+ declarativeMap_->ungrabTouchPoints();
+ }
+ }
+ }
}
/*!
@@ -738,7 +826,7 @@ void QDeclarativeGeoMapGestureArea::touchPointStateMachine()
clearTouchData();
startOneTouchPoint();
touchPointState_ = touchPoints1;
- } else if (touchPoints_.count() == 2) {
+ } else if (touchPoints_.count() >= 2) {
clearTouchData();
startTwoTouchPoints();
touchPointState_ = touchPoints2;
@@ -842,43 +930,49 @@ void QDeclarativeGeoMapGestureArea::updateTwoTouchPoints()
/*!
\internal
*/
-void QDeclarativeGeoMapGestureArea::setPinchActive(bool active)
-{
- if ((active && pinchState_ == pinchActive) || (!active && pinchState_ != pinchActive))
- return;
- pinchState_ = active ? pinchActive : pinchInactive;
- emit pinchActiveChanged();
-}
-
-
-/*!
- \internal
-*/
void QDeclarativeGeoMapGestureArea::pinchStateMachine()
{
PinchState lastState = pinchState_;
// Transitions:
switch (pinchState_) {
case pinchInactive:
- if (canStartPinch()) {
- startPinch();
- setPinchActive(true);
+ if (touchPoints_.count() >= 2) {
+ if (canStartPinch()) {
+ startPinch();
+ pinchState_ = pinchActive;
+ } else {
+ pinchState_ = pinchInactiveTwoPoints;
+ }
+ }
+ break;
+ case pinchInactiveTwoPoints:
+ if (touchPoints_.count() <= 1) {
+ pinchState_ = pinchInactive;
+ } else {
+ if (canStartPinch()) {
+ startPinch();
+ pinchState_ = pinchActive;
+ }
}
break;
case pinchActive:
if (touchPoints_.count() <= 1) {
endPinch();
- setPinchActive(false);
+ pinchState_ = pinchInactive;
}
break;
}
// This line implements an exclusive state machine, where the transitions and updates don't
// happen on the same frame
- if (pinchState_ != lastState)
- return;
+ if (pinchState_ != lastState) {
+ emit pinchActiveChanged();
+ return;
+ }
+
// Update
switch (pinchState_) {
case pinchInactive:
+ case pinchInactiveTwoPoints:
break; // do nothing
case pinchActive:
updatePinch();
@@ -1026,6 +1120,10 @@ void QDeclarativeGeoMapGestureArea::panStateMachine()
}
break;
}
+
+ if (panState_ != lastState)
+ emit panActiveChanged();
+
// Update
switch (panState_) {
case panInactive: // do nothing
@@ -1147,10 +1245,11 @@ void QDeclarativeGeoMapGestureArea::stopPan()
if (panState_ == panFlick) {
endFlick();
} else if (panState_ == panActive) {
+ panState_ = panInactive;
emit panFinished();
+ emit panActiveChanged();
emit movementStopped();
}
- panState_ = panInactive;
}
/*!
@@ -1163,6 +1262,7 @@ void QDeclarativeGeoMapGestureArea::endFlick()
pan_.animation_->stop();
emit flickFinished();
panState_ = panInactive;
+ emit panActiveChanged();
emit movementStopped();
}
diff --git a/src/imports/location/qdeclarativegeomapgesturearea_p.h b/src/imports/location/qdeclarativegeomapgesturearea_p.h
index 24b209d3..863d4bdd 100644
--- a/src/imports/location/qdeclarativegeomapgesturearea_p.h
+++ b/src/imports/location/qdeclarativegeomapgesturearea_p.h
@@ -109,7 +109,7 @@ class QDeclarativeGeoMapGestureArea: public QObject
Q_PROPERTY(bool pinchEnabled READ pinchEnabled WRITE setPinchEnabled NOTIFY pinchEnabledChanged)
Q_PROPERTY(bool panEnabled READ panEnabled WRITE setPanEnabled NOTIFY panEnabledChanged)
Q_PROPERTY(bool isPinchActive READ isPinchActive NOTIFY pinchActiveChanged)
- Q_PROPERTY(bool isPanActive READ isPanActive)
+ Q_PROPERTY(bool isPanActive READ isPanActive NOTIFY panActiveChanged)
Q_PROPERTY(ActiveGestures activeGestures READ activeGestures WRITE setActiveGestures NOTIFY activeGesturesChanged)
Q_PROPERTY(qreal maximumZoomLevelChange READ maximumZoomLevelChange WRITE setMaximumZoomLevelChange NOTIFY maximumZoomLevelChangeChanged)
Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
@@ -129,7 +129,6 @@ public:
void setActiveGestures(ActiveGestures activeGestures);
bool isPinchActive() const;
- void setPinchActive(bool active);
bool isPanActive() const;
bool enabled() const;
@@ -147,13 +146,14 @@ public:
qreal flickDeceleration() const;
void setFlickDeceleration(qreal deceleration);
- void touchEvent(QTouchEvent *event);
+ bool touchEvent(QTouchEvent *event);
bool wheelEvent(QWheelEvent *event);
bool mousePressEvent(QMouseEvent *event);
bool mouseMoveEvent(QMouseEvent *event);
bool mouseReleaseEvent(QMouseEvent *event);
+ void mouseUngrabEvent();
bool filterMapChildMouseEvent(QMouseEvent *event);
bool filterMapChildTouchEvent(QTouchEvent *event);
@@ -166,7 +166,10 @@ public:
void setMap(QGeoMap *map);
+ bool hasGrabbedInput() const;
+
Q_SIGNALS:
+ void panActiveChanged();
void pinchActiveChanged();
void enabledChanged();
void maximumZoomLevelChangeChanged();
@@ -222,6 +225,15 @@ private:
QGeoMap *map_;
QDeclarativeGeoMap *declarativeMap_;
bool enabled_;
+ bool hasGrab_;
+
+ enum InputType
+ {
+ NoInput,
+ MouseInput,
+ TouchInput
+ };
+ InputType activeInput_;
struct Pinch
{
@@ -283,6 +295,7 @@ private:
enum PinchState
{
pinchInactive,
+ pinchInactiveTwoPoints,
pinchActive
} pinchState_;
@@ -295,6 +308,6 @@ private:
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QDeclarativeGeoMapGestureArea);
+QML_DECLARE_TYPE(QDeclarativeGeoMapGestureArea)
#endif // QDECLARATIVEGEOMAPGESTUREAREA_P_H
diff --git a/tests/auto/declarative_ui/tst_map_mouse.qml b/tests/auto/declarative_ui/tst_map_mouse.qml
index 0e2472c8..8841c45a 100644
--- a/tests/auto/declarative_ui/tst_map_mouse.qml
+++ b/tests/auto/declarative_ui/tst_map_mouse.qml
@@ -494,14 +494,21 @@ Item {
compare(mouseUpper.lastWasHeld, false)
compare(mouseUpper.lastX, 5)
compare(mouseUpper.lastY, 5) // remember 20 offset of the mouse area
- mousePress(map, 5, 26)
+
+ mouseRelease(map, 5, 25)
compare(mouseUpperPressedSpy.count, 1)
+ compare(mouseUpperReleasedSpy.count, 1)
+ compare(mouseLowerPressedSpy.count, 0)
+ compare(mouseLowerReleasedSpy.count, 0)
+
+ mousePress(map, 5, 26)
+ compare(mouseUpperPressedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 0)
compare(mouseOverlapperPressedSpy.count, 0)
mouseRelease(map, 5, 26)
- compare(mouseUpperPressedSpy.count, 1)
- compare(mouseUpperReleasedSpy.count, 1)
+ compare(mouseUpperPressedSpy.count, 2)
+ compare(mouseUpperReleasedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 0)
compare(mouseLowerReleasedSpy.count, 0)
compare(mouseUpper.lastAccepted, true)
@@ -512,7 +519,7 @@ Item {
compare(mouseUpper.lastY, 6) // remember 20 offset of the mouse area
mousePress(map, 5, 75)
- compare(mouseUpperPressedSpy.count, 1)
+ compare(mouseUpperPressedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 1)
compare(mouseOverlapperPressedSpy.count, 0)
compare(mouseLower.lastAccepted, true)
@@ -523,18 +530,19 @@ Item {
compare(mouseLower.lastY, 25) // remember 50 offset of the mouse area
mouseRelease(map, 5, 75)
- compare(mouseUpperPressedSpy.count, 1)
- compare(mouseUpperReleasedSpy.count, 1)
+ compare(mouseUpperPressedSpy.count, 2)
+ compare(mouseUpperReleasedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 1)
compare(mouseLowerReleasedSpy.count, 1)
+
mousePress(map, 55, 75)
- compare(mouseUpperPressedSpy.count, 1)
+ compare(mouseUpperPressedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 1)
compare(mouseOverlapperPressedSpy.count, 1)
compare(mouseOverlapperReleasedSpy.count, 0)
mouseRelease(map, 55, 25)
- compare(mouseUpperPressedSpy.count, 1)
- compare(mouseUpperReleasedSpy.count, 1)
+ compare(mouseUpperPressedSpy.count, 2)
+ compare(mouseUpperReleasedSpy.count, 2)
compare(mouseLowerPressedSpy.count, 1)
compare(mouseLowerReleasedSpy.count, 1)
compare(mouseOverlapperReleasedSpy.count, 1)