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 <Friedemann.Kleint@nokia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>bb10
parent
ce7b3c9720
commit
b551d5e4f7
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue