handle TabletMove events during stylus hover

The main reason for this is to get feedback about the stylus orientation
(angles and rotation) before the user presses it.  For example an application
might provide an image of the brush which rotates along with the stylus.  As
with mouse events, applications can distinguish hovering by the fact that no
buttons are pressed.

On the xcb platform we need to stop blocking the hover events, and in
QWidgetWindow we need to send the event to the widget being hovered, while
keeping the existing "grab" behavior: after pressing the stylus (or any button
on the stylus or on the tablet), keep sending the events to the same widget
until release.

Task-number: QTBUG-26116
Change-Id: Iaed8b3b94961290dbb29b5fd2ea892fed7221685
Reviewed-by: Dmitry Kazakov <dimula73@gmail.com>
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Shawn Rutledge 2015-11-26 19:27:10 +01:00
parent 35fa30e65d
commit ea615b421b
2 changed files with 13 additions and 12 deletions

View File

@ -1084,10 +1084,7 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
break;
}
case XI_Motion:
// Report TabletMove only when the stylus is touching the tablet or any button is pressed.
// TODO: report proximity (hover) motion (no suitable Qt event exists yet).
if (tabletData->buttons != Qt::NoButton)
xi2ReportTabletEvent(xiEvent, tabletData);
xi2ReportTabletEvent(xiEvent, tabletData);
break;
case XI_PropertyEvent: {
// This is the wacom driver's way of reporting tool proximity.

View File

@ -973,22 +973,26 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long
void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
{
static QPointer<QWidget> qt_tablet_target = 0;
if (event->type() == QEvent::TabletPress) {
QWidget *widget = m_widget->childAt(event->pos());
if (!widget)
widget = m_widget;
qt_tablet_target = widget;
QWidget *widget = qt_tablet_target;
if (!widget) {
widget = m_widget->childAt(event->pos());
if (event->type() == QEvent::TabletPress) {
if (!widget)
widget = m_widget;
qt_tablet_target = widget;
}
}
if (qt_tablet_target) {
if (widget) {
QPointF delta = event->globalPosF() - event->globalPos();
QPointF mapped = qt_tablet_target->mapFromGlobal(event->globalPos()) + delta;
QPointF mapped = widget->mapFromGlobal(event->globalPos()) + delta;
QTabletEvent ev(event->type(), mapped, event->globalPosF(), event->device(), event->pointerType(),
event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(),
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
ev.setTimestamp(event->timestamp());
QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev);
QGuiApplication::sendSpontaneousEvent(widget, &ev);
event->setAccepted(ev.isAccepted());
}