summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qnamespace.h2
-rw-r--r--src/corelib/global/qnamespace.qdoc9
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/gui/kernel/qevent.cpp26
-rw-r--r--src/gui/kernel/qevent.h4
-rw-r--r--src/gui/kernel/qguiapplication.cpp46
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qwindow.cpp82
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp40
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h5
-rw-r--r--src/plugins/platforms/cocoa/qmultitouch_mac.mm2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_maemo.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp35
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp170
15 files changed, 304 insertions, 124 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index d3b048579f..ee4000498f 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -481,6 +481,8 @@ public:
AA_MacDontSwapCtrlAndMeta = 7,
AA_Use96Dpi = 8,
AA_X11InitThreads = 10,
+ AA_SynthesizeTouchForUnhandledMouseEvents = 11,
+ AA_SynthesizeMouseForUnhandledTouchEvents = 12,
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 3c2697e1f8..3add1a48c7 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -167,6 +167,15 @@
construction in order to make Xlib calls thread-safe. This
attribute must be set before QApplication is constructed.
+ \value AA_SynthesizeTouchForUnhandledMouseEvents All mouse events
+ that are not accepted by the application will be translated
+ to touch events instead.
+
+ \value AA_SynthesizeMouseForUnhandledTouchEvents All touch events
+ that are not accepted by the application will be translated
+ to left button mouse events instead. This attribute is enabled
+ by default.
+
\omitvalue AA_AttributeCount
*/
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 7a4618be34..05f26cc87f 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -300,7 +300,7 @@ Q_CORE_EXPORT uint qGlobalPostedEventsCount()
QCoreApplication *QCoreApplication::self = 0;
QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
-uint QCoreApplicationPrivate::attribs;
+uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents);
#ifdef Q_OS_UNIX
Qt::HANDLE qt_application_thread_id = 0;
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index e0ce334321..61ccaa5cfd 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3323,7 +3323,7 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
\section1 Event Delivery and Propagation
- By default, QWidget::event() translates the first non-primary touch point in a QTouchEvent into
+ By default, QGuiApplication translates the first touch point in a QTouchEvent into
a QMouseEvent. This makes it possible to enable touch events on existing widgets that do not
normally handle QTouchEvent. See below for information on some special considerations needed
when doing this.
@@ -3361,17 +3361,12 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
This makes it possible for sibling widgets to handle touch events independently while making
sure that the sequence of QTouchEvents is always correct.
- \section1 Mouse Events and the Primary Touch Point
+ \section1 Mouse Events and Touch Event synthesizing
- QTouchEvent delivery is independent from that of QMouseEvent. On some windowing systems, mouse
- events are also sent for the \l{QTouchEvent::TouchPoint::isPrimary()}{primary touch point}.
- This means it is possible for your widget to receive both QTouchEvent and QMouseEvent for the
- same user interaction point. You can use the QTouchEvent::TouchPoint::isPrimary() function to
- identify the primary touch point.
-
- Note that on some systems, it is possible to receive touch events without a primary touch
- point. All this means is that there will be no mouse event generated for the touch points in
- the QTouchEvent.
+ QTouchEvent delivery is independent from that of QMouseEvent. The application flags
+ Qt::AA_SynthesizeTouchForUnhandledMouseEvents and Qt::AA_SynthesizeMouseForUnhandledTouchEvents
+ can be used to enable or disable automatic synthesizing of touch events to mouse events and
+ mouse events to touch events.
\section1 Caveats
@@ -3593,15 +3588,6 @@ Qt::TouchPointState QTouchEvent::TouchPoint::state() const
}
/*!
- Returns true if this touch point is the primary touch point. The primary touch point is the
- point for which the windowing system generates mouse events.
-*/
-bool QTouchEvent::TouchPoint::isPrimary() const
-{
- return (d->flags & Primary) != 0;
-}
-
-/*!
Returns the position of this touch point, relative to the widget
or QGraphicsItem that received the event.
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 5d54d39378..a59b178cec 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -690,8 +690,7 @@ public:
{
public:
enum InfoFlag {
- Primary = 0x0001,
- Pen = 0x0002
+ Pen = 0x0001
};
Q_DECLARE_FLAGS(InfoFlags, InfoFlag)
@@ -702,7 +701,6 @@ public:
int id() const;
Qt::TouchPointState state() const;
- bool isPrimary() const;
QPointF pos() const;
QPointF startPos() const;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 9f1eaeacfd..f92e66b38e 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -113,6 +113,7 @@ static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
static bool force_reverse = false;
QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
+QTouchDevice *QGuiApplicationPrivate::m_fakeTouchDevice = 0;
#ifndef QT_NO_CLIPBOARD
QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
@@ -689,7 +690,38 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
cursors.at(i).data()->pointerEvent(ev);
#endif
QGuiApplication::sendSpontaneousEvent(window, &ev);
- return;
+ if (!e->synthetic && !ev.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) {
+ if (!m_fakeTouchDevice) {
+ m_fakeTouchDevice = new QTouchDevice;
+ QWindowSystemInterface::registerTouchDevice(m_fakeTouchDevice);
+ }
+ QList<QWindowSystemInterface::TouchPoint> points;
+ QWindowSystemInterface::TouchPoint point;
+ point.id = 1;
+ point.area = QRectF(globalPoint.x() - 2, globalPoint.y() - 2, 4, 4);
+
+ // only translate left button related events to
+ // avoid strange touch event sequences when several
+ // buttons are pressed
+ if (type == QEvent::MouseButtonPress && button == Qt::LeftButton) {
+ point.state = Qt::TouchPointPressed;
+ } else if (type == QEvent::MouseButtonRelease && button == Qt::LeftButton) {
+ point.state = Qt::TouchPointReleased;
+ } else if (type == QEvent::MouseMove && (buttons & Qt::LeftButton)) {
+ point.state = Qt::TouchPointMoved;
+ } else {
+ return;
+ }
+
+ points << point;
+
+ QEvent::Type type;
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+
+ QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
+ fake.synthetic = true;
+ processTouchEvent(&fake);
+ }
}
}
@@ -999,6 +1031,18 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
}
QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
+ if (!e->synthetic && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) {
+ // exclude touchpads as those generate their own mouse events
+ if (touchEvent.device()->type() != QTouchDevice::TouchPad) {
+ Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton;
+
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().first();
+
+ QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp, touchPoint.pos(), touchPoint.screenPos(), b, e->modifiers);
+ fake.synthetic = true;
+ processMouseEvent(&fake);
+ }
+ }
}
// Remove released points from the hash table only after the event is
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index b1269178d0..9c965cd109 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -205,6 +205,7 @@ private:
void init();
static QGuiApplicationPrivate *self;
+ static QTouchDevice *m_fakeTouchDevice;
};
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 0d08316945..97c6b0cbc9 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -788,78 +788,83 @@ bool QWindow::close()
return true;
}
-void QWindow::exposeEvent(QExposeEvent *)
+void QWindow::exposeEvent(QExposeEvent *ev)
{
+ ev->ignore();
}
-void QWindow::moveEvent(QMoveEvent *)
+void QWindow::moveEvent(QMoveEvent *ev)
{
+ ev->ignore();
}
-void QWindow::resizeEvent(QResizeEvent *)
+void QWindow::resizeEvent(QResizeEvent *ev)
{
+ ev->ignore();
}
-void QWindow::showEvent(QShowEvent *)
+void QWindow::showEvent(QShowEvent *ev)
{
+ ev->ignore();
}
-void QWindow::hideEvent(QHideEvent *)
+void QWindow::hideEvent(QHideEvent *ev)
{
+ ev->ignore();
}
-bool QWindow::event(QEvent *event)
+bool QWindow::event(QEvent *ev)
{
- switch (event->type()) {
+ switch (ev->type()) {
case QEvent::MouseMove:
- mouseMoveEvent(static_cast<QMouseEvent*>(event));
+ mouseMoveEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonPress:
- mousePressEvent(static_cast<QMouseEvent*>(event));
+ mousePressEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonRelease:
- mouseReleaseEvent(static_cast<QMouseEvent*>(event));
+ mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::MouseButtonDblClick:
- mouseDoubleClickEvent(static_cast<QMouseEvent*>(event));
+ mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
- touchEvent(static_cast<QTouchEvent *>(event));
+ touchEvent(static_cast<QTouchEvent *>(ev));
break;
case QEvent::Move:
- moveEvent(static_cast<QMoveEvent*>(event));
+ moveEvent(static_cast<QMoveEvent*>(ev));
break;
case QEvent::Resize:
- resizeEvent(static_cast<QResizeEvent*>(event));
+ resizeEvent(static_cast<QResizeEvent*>(ev));
break;
case QEvent::KeyPress:
- keyPressEvent(static_cast<QKeyEvent *>(event));
+ keyPressEvent(static_cast<QKeyEvent *>(ev));
break;
case QEvent::KeyRelease:
- keyReleaseEvent(static_cast<QKeyEvent *>(event));
+ keyReleaseEvent(static_cast<QKeyEvent *>(ev));
break;
case QEvent::FocusIn:
- focusInEvent(static_cast<QFocusEvent *>(event));
+ focusInEvent(static_cast<QFocusEvent *>(ev));
break;
case QEvent::FocusOut:
- focusOutEvent(static_cast<QFocusEvent *>(event));
+ focusOutEvent(static_cast<QFocusEvent *>(ev));
break;
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
- wheelEvent(static_cast<QWheelEvent*>(event));
+ wheelEvent(static_cast<QWheelEvent*>(ev));
break;
#endif
@@ -872,66 +877,75 @@ bool QWindow::event(QEvent *event)
break; }
case QEvent::Expose:
- exposeEvent(static_cast<QExposeEvent *>(event));
+ exposeEvent(static_cast<QExposeEvent *>(ev));
break;
case QEvent::Show:
- showEvent(static_cast<QShowEvent *>(event));
+ showEvent(static_cast<QShowEvent *>(ev));
break;
case QEvent::Hide:
- hideEvent(static_cast<QHideEvent *>(event));
+ hideEvent(static_cast<QHideEvent *>(ev));
break;
default:
- return QObject::event(event);
+ return QObject::event(ev);
}
return true;
}
-void QWindow::keyPressEvent(QKeyEvent *)
+void QWindow::keyPressEvent(QKeyEvent *ev)
{
+ ev->ignore();
}
-void QWindow::keyReleaseEvent(QKeyEvent *)
+void QWindow::keyReleaseEvent(QKeyEvent *ev)
{
+ ev->ignore();
}
-void QWindow::focusInEvent(QFocusEvent *)
+void QWindow::focusInEvent(QFocusEvent *ev)
{
+ ev->ignore();
}
-void QWindow::focusOutEvent(QFocusEvent *)
+void QWindow::focusOutEvent(QFocusEvent *ev)
{
+ ev->ignore();
}
-void QWindow::mousePressEvent(QMouseEvent *)
+void QWindow::mousePressEvent(QMouseEvent *ev)
{
+ ev->ignore();
}
-void QWindow::mouseReleaseEvent(QMouseEvent *)
+void QWindow::mouseReleaseEvent(QMouseEvent *ev)
{
+ ev->ignore();
}
-void QWindow::mouseDoubleClickEvent(QMouseEvent *)
+void QWindow::mouseDoubleClickEvent(QMouseEvent *ev)
{
+ ev->ignore();
}
-void QWindow::mouseMoveEvent(QMouseEvent *)
+void QWindow::mouseMoveEvent(QMouseEvent *ev)
{
+ ev->ignore();
}
#ifndef QT_NO_WHEELEVENT
-void QWindow::wheelEvent(QWheelEvent *)
+void QWindow::wheelEvent(QWheelEvent *ev)
{
+ ev->ignore();
}
#endif //QT_NO_WHEELEVENT
-void QWindow::touchEvent(QTouchEvent *)
+void QWindow::touchEvent(QTouchEvent *ev)
{
+ ev->ignore();
}
-
/*!
\fn QPoint QWindow::mapToGlobal(const QPoint &pos) const
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index 29d134c51c..4a7ebd1c0c 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -226,21 +226,14 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
handleTouchEvent(w, time, device, points, mods);
}
-void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device,
- const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
+QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type)
{
- if (!points.size()) // Touch events must have at least one point
- return;
-
- if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
- return;
-
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
QTouchEvent::TouchPoint p;
- QList<struct TouchPoint>::const_iterator point = points.constBegin();
- QList<struct TouchPoint>::const_iterator end = points.constEnd();
+ QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
+ QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
p.setId(point->id);
p.setPressure(point->pressure);
@@ -264,11 +257,28 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo
}
// Determine the event type based on the combined point states.
- QEvent::Type type = QEvent::TouchUpdate;
- if (states == Qt::TouchPointPressed)
- type = QEvent::TouchBegin;
- else if (states == Qt::TouchPointReleased)
- type = QEvent::TouchEnd;
+ if (type) {
+ *type = QEvent::TouchUpdate;
+ if (states == Qt::TouchPointPressed)
+ *type = QEvent::TouchBegin;
+ else if (states == Qt::TouchPointReleased)
+ *type = QEvent::TouchEnd;
+ }
+
+ return touchPoints;
+}
+
+void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device,
+ const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
+{
+ if (!points.size()) // Touch events must have at least one point
+ return;
+
+ if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
+ return;
+
+ QEvent::Type type;
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index 886c1d0762..b5614eb38e 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -72,8 +72,9 @@ public:
class WindowSystemEvent {
public:
explicit WindowSystemEvent(EventType t)
- : type(t) { }
+ : type(t), synthetic(false) { }
EventType type;
+ bool synthetic;
};
class CloseEvent : public WindowSystemEvent {
@@ -261,6 +262,8 @@ public:
static void queueWindowSystemEvent(WindowSystemEvent *ev);
static QTime eventTime;
+
+ static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
};
QT_END_HEADER
diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
index cc85c47c58..43767b09b2 100644
--- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm
+++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
@@ -73,8 +73,6 @@ QCocoaTouch::~QCocoaTouch()
void QCocoaTouch::updateTouchData(NSTouch *nstouch, NSTouchPhase phase)
{
_touchPoint.state = toTouchPointState(phase);
- if (_touchCount == 1)
- _touchPoint.flags |= QTouchEvent::TouchPoint::Primary;
// From the normalized position on the trackpad, calculate
// where on screen the touchpoint should be according to the
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 54a16d5013..e491029ea1 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -240,8 +240,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
const TOUCHINPUT &winTouchInput = winTouchInputs[i];
QTouchPoint touchPoint;
touchPoint.pressure = 1.0;
- if ((winTouchInput.dwFlags & TOUCHEVENTF_PRIMARY) != 0)
- touchPoint.flags |= QTouchEvent::TouchPoint::Primary;
touchPoint.id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
if (touchPoint.id == -1) {
touchPoint.id = m_touchInputIDToTouchPointID.size();
diff --git a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp
index 1ac8e771fc..12b3d67b9f 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp
@@ -222,8 +222,6 @@ void QXcbConnection::handleGenericEvent(xcb_ge_event_t *event)
for (int i = 0; i < m_xinputData->xiMaxContacts; ++i) {
QWindowSystemInterface::TouchPoint tp;
tp.id = i;
- if (i == 0)
- tp.flags |= QTouchEvent::TouchPoint::Primary;
tp.state = Qt::TouchPointReleased;
touchPoints << tp;
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index a66ccf8572..531a217b1d 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -8227,40 +8227,7 @@ bool QWidget::event(QEvent *event)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
-#ifndef Q_WS_MAC
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
- if (touchPoint.isPrimary() || touchEvent->device()->type() == QTouchDevice::TouchPad)
- break;
-
- // fake a mouse event!
- QEvent::Type eventType = QEvent::None;
- switch (touchEvent->type()) {
- case QEvent::TouchBegin:
- eventType = QEvent::MouseButtonPress;
- break;
- case QEvent::TouchUpdate:
- eventType = QEvent::MouseMove;
- break;
- case QEvent::TouchEnd:
- eventType = QEvent::MouseButtonRelease;
- break;
- default:
- Q_ASSERT(!true);
- break;
- }
- if (eventType == QEvent::None)
- break;
-
- QMouseEvent mouseEvent(eventType,
- touchPoint.pos(),
- touchPoint.scenePos(),
- touchPoint.screenPos(),
- Qt::LeftButton,
- Qt::LeftButton,
- touchEvent->modifiers());
- (void) QApplication::sendEvent(this, &mouseEvent);
-#endif // Q_WS_MAC
+ event->ignore();
break;
}
#ifndef QT_NO_GESTURES
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 9244c86ca5..77fffef13a 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -54,6 +54,18 @@ private slots:
void positioning();
void isActive();
void testInputEvents();
+ void touchToMouseTranslation();
+ void mouseToTouchTranslation();
+ void mouseToTouchLoop();
+ void initTestCase()
+ {
+ touchDevice = new QTouchDevice;
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+ }
+
+private:
+ QTouchDevice *touchDevice;
};
@@ -234,12 +246,22 @@ public:
keyReleaseCode = event->key();
}
void mousePressEvent(QMouseEvent *event) {
- mousePressButton = event->button();
+ if (ignoreMouse)
+ event->ignore();
+ else
+ mousePressButton = event->button();
}
void mouseReleaseEvent(QMouseEvent *event) {
- mouseReleaseButton = event->button();
+ if (ignoreMouse)
+ event->ignore();
+ else
+ mouseReleaseButton = event->button();
}
void touchEvent(QTouchEvent *event) {
+ if (ignoreTouch) {
+ event->ignore();
+ return;
+ }
QList<QTouchEvent::TouchPoint> points = event->touchPoints();
for (int i = 0; i < points.count(); ++i) {
switch (points.at(i).state()) {
@@ -249,6 +271,8 @@ public:
case Qt::TouchPointReleased:
++touchReleasedCount;
break;
+ default:
+ break;
}
}
}
@@ -257,11 +281,14 @@ public:
keyPressCode = keyReleaseCode = 0;
mousePressButton = mouseReleaseButton = 0;
touchPressedCount = touchReleasedCount = 0;
+ ignoreMouse = ignoreTouch = 0;
}
int keyPressCode, keyReleaseCode;
int mousePressButton, mouseReleaseButton;
int touchPressedCount, touchReleasedCount;
+
+ bool ignoreMouse, ignoreTouch;
};
void tst_QWindow::testInputEvents()
@@ -284,9 +311,32 @@ void tst_QWindow::testInputEvents()
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
- QTouchDevice *device = new QTouchDevice;
- device->setType(QTouchDevice::TouchScreen);
- QWindowSystemInterface::registerTouchDevice(device);
+ QList<QWindowSystemInterface::TouchPoint> points;
+ QWindowSystemInterface::TouchPoint tp1, tp2;
+ tp1.id = 1;
+ tp1.state = Qt::TouchPointPressed;
+ tp1.area = QRect(10, 10, 4, 4);
+ tp2.id = 2;
+ tp2.state = Qt::TouchPointPressed;
+ tp2.area = QRect(20, 20, 4, 4);
+ points << tp1 << tp2;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ points[0].state = Qt::TouchPointReleased;
+ points[1].state = Qt::TouchPointReleased;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ QCoreApplication::processEvents();
+ QTRY_COMPARE(window.touchPressedCount, 2);
+ QTRY_COMPARE(window.touchReleasedCount, 2);
+}
+
+void tst_QWindow::touchToMouseTranslation()
+{
+ InputTestWindow window;
+ window.ignoreTouch = true;
+ window.setGeometry(80, 80, 40, 40);
+ window.show();
+ QTest::qWaitForWindowShown(&window);
+
QList<QWindowSystemInterface::TouchPoint> points;
QWindowSystemInterface::TouchPoint tp1, tp2;
tp1.id = 1;
@@ -294,13 +344,115 @@ void tst_QWindow::testInputEvents()
tp2.id = 2;
tp2.state = Qt::TouchPointPressed;
points << tp1 << tp2;
- QWindowSystemInterface::handleTouchEvent(&window, device, points);
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ points[0].state = Qt::TouchPointReleased;
+ points[1].state = Qt::TouchPointReleased;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton));
+ QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
+
+ window.mousePressButton = 0;
+ window.mouseReleaseButton = 0;
+
+ window.ignoreTouch = false;
+
+ points[0].state = Qt::TouchPointPressed;
+ points[1].state = Qt::TouchPointPressed;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ points[0].state = Qt::TouchPointReleased;
+ points[1].state = Qt::TouchPointReleased;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
+ QCoreApplication::processEvents();
+
+ // no new mouse events should be generated since the input window handles the touch events
+ QTRY_COMPARE(window.mousePressButton, 0);
+ QTRY_COMPARE(window.mouseReleaseButton, 0);
+
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ window.ignoreTouch = true;
+ points[0].state = Qt::TouchPointPressed;
+ points[1].state = Qt::TouchPointPressed;
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[1].state = Qt::TouchPointReleased;
- QWindowSystemInterface::handleTouchEvent(&window, device, points);
+ QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
- QCOMPARE(window.touchPressedCount, 2);
- QCOMPARE(window.touchReleasedCount, 2);
+
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
+
+ // mouse event synthesizing disabled
+ QTRY_COMPARE(window.mousePressButton, 0);
+ QTRY_COMPARE(window.mouseReleaseButton, 0);
+}
+
+void tst_QWindow::mouseToTouchTranslation()
+{
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
+
+ InputTestWindow window;
+ window.ignoreMouse = true;
+ window.setGeometry(80, 80, 40, 40);
+ window.show();
+ QTest::qWaitForWindowShown(&window);
+
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
+ QCoreApplication::processEvents();
+
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
+
+ QTRY_COMPARE(window.touchPressedCount, 1);
+ QTRY_COMPARE(window.touchReleasedCount, 1);
+
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
+
+ window.ignoreMouse = false;
+
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
+ QCoreApplication::processEvents();
+
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
+
+ // no new touch events should be generated since the input window handles the mouse events
+ QTRY_COMPARE(window.touchPressedCount, 1);
+ QTRY_COMPARE(window.touchReleasedCount, 1);
+
+ window.ignoreMouse = true;
+
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
+ QCoreApplication::processEvents();
+
+ // touch event synthesis disabled
+ QTRY_COMPARE(window.touchPressedCount, 1);
+ QTRY_COMPARE(window.touchReleasedCount, 1);
+
+
+}
+
+void tst_QWindow::mouseToTouchLoop()
+{
+ // make sure there's no infinite loop when synthesizing both ways
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
+
+ InputTestWindow window;
+ window.ignoreMouse = true;
+ window.ignoreTouch = true;
+ window.setGeometry(80, 80, 40, 40);
+ window.show();
+ QTest::qWaitForWindowShown(&window);
+
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
+ QCoreApplication::processEvents();
+
+ qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
}
#include <tst_qwindow.moc>