summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <[email protected]>2012-05-23 15:07:39 +0300
committerQt by Nokia <[email protected]>2012-05-31 09:13:01 +0200
commitb551d5e4f7d9785baef5c24abb902dafa71350e2 (patch)
tree5ff65dec7dbd3112e7689418fa0def4432f6aebf
parentce7b3c972038636d8026dce949f1bd58e0bdd610 (diff)
QPA tablet event support
Should be sufficient to allow implementing the actual functionality in xcb/cocoa/windows to match the Qt 4 level of tablet event support. Task-number: QTBUG-25864 Change-Id: Iebcca256dfba841d8976b58fda1b76026d3133a3 Reviewed-by: Friedemann Kleint <[email protected]> Reviewed-by: Morten Johan Sørvig <[email protected]>
-rw-r--r--src/gui/kernel/qguiapplication.cpp90
-rw-r--r--src/gui/kernel/qguiapplication_p.h6
-rw-r--r--src/gui/kernel/qwindow.cpp21
-rw-r--r--src/gui/kernel/qwindow.h6
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp48
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h14
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h54
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp58
8 files changed, 296 insertions, 1 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 7bf5a7589fc..05e1274fef6 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -102,6 +102,9 @@ Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
+bool QGuiApplicationPrivate::tabletState = false;
+QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
+
QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0;
@@ -1113,6 +1116,18 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
case QWindowSystemInterfacePrivate::Expose:
QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
break;
+ case QWindowSystemInterfacePrivate::Tablet:
+ QGuiApplicationPrivate::processTabletEvent(
+ static_cast<QWindowSystemInterfacePrivate::TabletEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::TabletEnterProximity:
+ QGuiApplicationPrivate::processTabletEnterProximityEvent(
+ static_cast<QWindowSystemInterfacePrivate::TabletEnterProximityEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::TabletLeaveProximity:
+ QGuiApplicationPrivate::processTabletLeaveProximityEvent(
+ static_cast<QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *>(e));
+ break;
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@@ -1439,6 +1454,81 @@ void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate:
QGuiApplication::sendSpontaneousEvent(qApp, &event);
}
+void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e)
+{
+#ifndef QT_NO_TABLETEVENT
+ QEvent::Type type = QEvent::TabletMove;
+ if (e->down != tabletState) {
+ type = e->down ? QEvent::TabletPress : QEvent::TabletRelease;
+ tabletState = e->down;
+ }
+ QWindow *window = e->window.data();
+ bool localValid = true;
+ // If window is null, pick one based on the global position and make sure all
+ // subsequent events up to the release are delivered to that same window.
+ // If window is given, just send to that.
+ if (type == QEvent::TabletPress) {
+ if (!window) {
+ window = QGuiApplication::topLevelAt(e->global.toPoint());
+ localValid = false;
+ }
+ if (!window)
+ return;
+ tabletPressTarget = window;
+ } else {
+ if (!window) {
+ window = tabletPressTarget;
+ localValid = false;
+ }
+ if (type == QEvent::TabletRelease)
+ tabletPressTarget = 0;
+ if (!window)
+ return;
+ }
+ QPointF local = e->local;
+ if (!localValid) {
+ QPointF delta = e->global - e->global.toPoint();
+ local = window->mapFromGlobal(e->global.toPoint()) + delta;
+ }
+ QTabletEvent ev(type, local, e->global,
+ e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt,
+ e->tangentialPressure, e->rotation, e->z,
+ e->mods, e->uid);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(window, &ev);
+#else
+ Q_UNUSED(e)
+#endif
+}
+
+void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e)
+{
+#ifndef QT_NO_TABLETEVENT
+ QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(),
+ e->device, e->pointerType, 0, 0, 0,
+ 0, 0, 0,
+ Qt::NoModifier, e->uid);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
+#else
+ Q_UNUSED(e)
+#endif
+}
+
+void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e)
+{
+#ifndef QT_NO_TABLETEVENT
+ QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(),
+ e->device, e->pointerType, 0, 0, 0,
+ 0, 0, 0,
+ Qt::NoModifier, e->uid);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
+#else
+ Q_UNUSED(e)
+#endif
+}
+
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k)
{
return qHash(k.device) + k.touchPointId;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 4ea95ee1a9a..8b7977e87ad 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -124,6 +124,10 @@ public:
static void processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e);
+ static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
+ static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
+ static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
+
#ifndef QT_NO_DRAGANDDROP
static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
@@ -167,6 +171,8 @@ public:
static int mousePressY;
static int mouse_double_click_distance;
static QPointF lastCursorPosition;
+ static bool tabletState;
+ static QWindow *tabletPressTarget;
#ifndef QT_NO_CLIPBOARD
static QClipboard *qt_clipboard;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index c9a49bf69bf..8fe62bb7fde 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1522,6 +1522,14 @@ bool QWindow::event(QEvent *ev)
hideEvent(static_cast<QHideEvent *>(ev));
break;
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ tabletEvent(static_cast<QTabletEvent *>(ev));
+ break;
+#endif
+
default:
return QObject::event(ev);
}
@@ -1628,6 +1636,19 @@ void QWindow::touchEvent(QTouchEvent *ev)
ev->ignore();
}
+#ifndef QT_NO_TABLETEVENT
+/*!
+ Override this to handle tablet press, move, and release events.
+
+ Proximity enter and leave events are not sent to windows, they are
+ delivered to the application instance.
+*/
+void QWindow::tabletEvent(QTabletEvent *ev)
+{
+ ev->ignore();
+}
+#endif
+
/*!
Override this to handle platform dependent events.
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 9c70395d086..fab9e4658b8 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -78,6 +78,9 @@ class QMouseEvent;
class QWheelEvent;
#endif
class QTouchEvent;
+#ifndef QT_NO_TABLETEVENT
+class QTabletEvent;
+#endif
class QPlatformSurface;
class QPlatformWindow;
@@ -302,6 +305,9 @@ protected:
virtual void wheelEvent(QWheelEvent *);
#endif
virtual void touchEvent(QTouchEvent *);
+#ifndef QT_NO_TABLETEVENT
+ virtual void tabletEvent(QTabletEvent *);
+#endif
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
QWindow(QWindowPrivate &dd, QWindow *parent);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index 3054b9610dc..c707d4eea23 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -528,4 +528,52 @@ void QWindowSystemInterface::handleFileOpenEvent(const QString& fileName)
QGuiApplicationPrivate::processWindowSystemEvent(&e);
}
+void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers)
+{
+ QWindowSystemInterfacePrivate::TabletEvent *e =
+ new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, down, local, global, device, pointerType, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers)
+{
+ ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleTabletEvent(w, time, down, local, global, device, pointerType, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+}
+
+void QWindowSystemInterface::handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
+{
+ QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e =
+ new QWindowSystemInterfacePrivate::TabletEnterProximityEvent(timestamp, device, pointerType, uid);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid)
+{
+ ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleTabletEnterProximityEvent(time, device, pointerType, uid);
+}
+
+void QWindowSystemInterface::handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
+{
+ QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e =
+ new QWindowSystemInterfacePrivate::TabletLeaveProximityEvent(timestamp, device, pointerType, uid);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid)
+{
+ ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleTabletLeaveProximityEvent(time, device, pointerType, uid);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 41e5a599c73..34587f67d85 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -152,6 +152,20 @@ public:
static void handleFileOpenEvent(const QString& fileName);
+ static void handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ static void handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
+ static void handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid);
+ static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
+ static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
+
+
// For event dispatcher implementations
static bool sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags);
static int windowSystemEventsQueued();
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index f026f1ca331..3eebaf2dfc4 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -69,7 +69,10 @@ public:
ScreenRefreshRate,
ThemeChange,
Expose,
- FileOpen
+ FileOpen,
+ Tablet,
+ TabletEnterProximity,
+ TabletLeaveProximity
};
class WindowSystemEvent {
@@ -266,6 +269,55 @@ public:
QString fileName;
};
+ class TabletEvent : public InputEvent {
+ public:
+ static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+
+ TabletEvent(QWindow *w, ulong time, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tpressure,
+ qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers mods)
+ : InputEvent(w, time, Tablet, Qt::NoModifier),
+ down(down), local(local), global(global), device(device), pointerType(pointerType),
+ pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
+ rotation(rotation), z(z), uid(uid), mods(mods) { }
+ bool down;
+ QPointF local;
+ QPointF global;
+ int device;
+ int pointerType;
+ qreal pressure;
+ int xTilt;
+ int yTilt;
+ qreal tangentialPressure;
+ qreal rotation;
+ int z;
+ qint64 uid;
+ Qt::KeyboardModifiers mods;
+ };
+
+ class TabletEnterProximityEvent : public InputEvent {
+ public:
+ TabletEnterProximityEvent(ulong time, int device, int pointerType, qint64 uid)
+ : InputEvent(0, time, TabletEnterProximity, Qt::NoModifier),
+ device(device), pointerType(pointerType), uid(uid) { }
+ int device;
+ int pointerType;
+ qint64 uid;
+ };
+
+ class TabletLeaveProximityEvent : public InputEvent {
+ public:
+ TabletLeaveProximityEvent(ulong time, int device, int pointerType, qint64 uid)
+ : InputEvent(0, time, TabletLeaveProximity, Qt::NoModifier),
+ device(device), pointerType(pointerType), uid(uid) { }
+ int device;
+ int pointerType;
+ qint64 uid;
+ };
+
static QList<WindowSystemEvent *> windowSystemEventQueue;
static QMutex queueMutex;
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 6e6db12268b..55a9a398825 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -71,6 +71,7 @@ private slots:
void mouseEventSequence();
void windowModality();
void inputReentrancy();
+ void tabletEvents();
void initTestCase()
{
@@ -925,5 +926,62 @@ void tst_QWindow::inputReentrancy()
QCOMPARE(window.touchReleasedCount, 1);
}
+#ifndef QT_NO_TABLETEVENT
+class TabletTestWindow : public QWindow
+{
+public:
+ TabletTestWindow() : eventType(0) { }
+ void tabletEvent(QTabletEvent *ev) {
+ eventType = ev->type();
+ eventGlobal = ev->globalPosF();
+ eventLocal = ev->posF();
+ eventDevice = ev->device();
+ }
+ int eventType;
+ QPointF eventGlobal, eventLocal;
+ int eventDevice;
+ bool eventFilter(QObject *obj, QEvent *ev) {
+ if (ev->type() == QEvent::TabletEnterProximity
+ || ev->type() == QEvent::TabletLeaveProximity) {
+ eventType = ev->type();
+ QTabletEvent *te = static_cast<QTabletEvent *>(ev);
+ eventDevice = te->device();
+ }
+ return QWindow::eventFilter(obj, ev);
+ }
+};
+#endif
+
+void tst_QWindow::tabletEvents()
+{
+#ifndef QT_NO_TABLETEVENT
+ TabletTestWindow window;
+ window.setGeometry(10, 10, 100, 100);
+ qGuiApp->installEventFilter(&window);
+
+ QPoint local(10, 10);
+ QPoint global = window.mapToGlobal(local);
+ QWindowSystemInterface::handleTabletEvent(&window, true, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ QCoreApplication::processEvents();
+ QTRY_VERIFY(window.eventType == QEvent::TabletPress);
+ QTRY_COMPARE(window.eventGlobal.toPoint(), global);
+ QTRY_COMPARE(window.eventLocal.toPoint(), local);
+ QWindowSystemInterface::handleTabletEvent(&window, false, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ QCoreApplication::processEvents();
+ QTRY_VERIFY(window.eventType == QEvent::TabletRelease);
+
+ QWindowSystemInterface::handleTabletEnterProximityEvent(1, 2, 3);
+ QCoreApplication::processEvents();
+ QTRY_VERIFY(window.eventType == QEvent::TabletEnterProximity);
+ QTRY_COMPARE(window.eventDevice, 1);
+
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(1, 2, 3);
+ QCoreApplication::processEvents();
+ QTRY_VERIFY(window.eventType == QEvent::TabletLeaveProximity);
+ QTRY_COMPARE(window.eventDevice, 1);
+
+#endif
+}
+
#include <tst_qwindow.moc>
QTEST_MAIN(tst_QWindow)