From ea615b421b76668332a3029ad31fa725b5bb9e58 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 26 Nov 2015 19:27:10 +0100 Subject: [PATCH] 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 Reviewed-by: Andy Shaw --- .../platforms/xcb/qxcbconnection_xi2.cpp | 5 +---- src/widgets/kernel/qwidgetwindow.cpp | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index f70c7138b3..e82a19a516 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -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. diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 7295cc36f6..5abce140ce 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -973,22 +973,26 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long void QWidgetWindow::handleTabletEvent(QTabletEvent *event) { static QPointer 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()); }