add cross-platform tablet->mouse event synth; enable on Android
It's urgent to fix the issue that on Android, it became impossible to interact with any widget or MouseArea which handles only mouse events but not tablet events, using the stylus, because stylus events are sent only as QTabletEvents. Before 5.6 (change 01d78ba86a631386a4d47b7c12d2a359da28f517) they were sent as touch events, and mouse events were synthesized from those. Whereas on other platforms, every QTabletEvent is followed by a synthesized QMouseEvent. This fix proceeds in the direction that event synthesis should be done in cross-platform code so that platform plugins don't have to repeat it, following the same pattern as for touch->mouse synthesis. Just as in that case, the application can disable it, and the platform plugin can also report that it's unnecessary for Qt to do the synthesis because the platform already does. So QTBUG-51618 is fixed, but QTBUG-47007 requires us to remove the tablet->mouse synthesis from all platform plugins, because the plugin does not know whether the tablet event was accepted or not, so it does not have enough information to decide whether to synthesize a mouse event. Synthesis has been unconditional until now, which contradicts what the documentation says: the mouse event should be sent only if the tablet event is NOT accepted. We can now gradually make this promise come true. [ChangeLog][QtCore][Tablet support] A synthetic mouse event will no longer be sent after every QTabletEvent, only after those which are not accepted (as documented). Task-number: QTBUG-47007 Task-number: QTBUG-51618 Change-Id: I99404e0c2b39bbca4377be6fd48e0c6b20338466 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
parent
e187a16906
commit
f931e5e72d
@ -131,6 +131,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
event->accept();
|
||||
update();
|
||||
}
|
||||
//! [3]
|
||||
|
@ -507,6 +507,7 @@ public:
|
||||
AA_DisableHighDpiScaling = 21,
|
||||
AA_UseStyleSheetPropagationInWidgetStyles = 22, // ### Qt 6: remove me
|
||||
AA_DontUseNativeDialogs = 23,
|
||||
AA_SynthesizeMouseForUnhandledTabletEvents = 24,
|
||||
|
||||
// Add new attributes before this line
|
||||
AA_AttributeCount
|
||||
|
@ -325,7 +325,9 @@ Qt::HANDLE qt_application_thread_id = 0;
|
||||
#endif // QT_NO_QOBJECT
|
||||
|
||||
QCoreApplication *QCoreApplication::self = 0;
|
||||
uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents);
|
||||
uint QCoreApplicationPrivate::attribs =
|
||||
(1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
|
||||
(1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
|
||||
|
||||
struct QCoreApplicationData {
|
||||
QCoreApplicationData() Q_DECL_NOTHROW {
|
||||
|
@ -2300,9 +2300,17 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
|
||||
e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt,
|
||||
e->tangentialPressure, e->rotation, e->z,
|
||||
e->modifiers, e->uid, button, e->buttons);
|
||||
ev.setAccepted(false);
|
||||
ev.setTimestamp(e->timestamp);
|
||||
QGuiApplication::sendSpontaneousEvent(window, &ev);
|
||||
pointData.state = e->buttons;
|
||||
if (!ev.isAccepted() && !QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse
|
||||
&& qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) {
|
||||
QWindowSystemInterfacePrivate::MouseEvent fake(window, e->timestamp, e->local, e->global,
|
||||
e->buttons, e->modifiers, Qt::MouseEventSynthesizedByQt);
|
||||
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
|
||||
processMouseEvent(&fake);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(e)
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
|
||||
bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
|
||||
bool QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse = true;
|
||||
QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed;
|
||||
QMutex QWindowSystemInterfacePrivate::flushEventMutex;
|
||||
QAtomicInt QWindowSystemInterfacePrivate::eventAccepted;
|
||||
@ -945,4 +946,9 @@ QWindowSystemInterfacePrivate::WheelEvent::WheelEvent(QWindow *w, ulong time, co
|
||||
{
|
||||
}
|
||||
|
||||
void QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(bool v)
|
||||
{
|
||||
platformSynthesizesMouse = v;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -352,6 +352,7 @@ public:
|
||||
int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
|
||||
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
|
||||
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
|
||||
static void setPlatformSynthesizesMouse(bool v);
|
||||
|
||||
TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
|
||||
int device, int pointerType, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure,
|
||||
@ -372,6 +373,7 @@ public:
|
||||
qreal rotation;
|
||||
int z;
|
||||
qint64 uid;
|
||||
static bool platformSynthesizesMouse;
|
||||
};
|
||||
|
||||
class TabletEnterProximityEvent : public InputEvent {
|
||||
|
@ -864,6 +864,7 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|
||||
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
|
||||
return -1;
|
||||
}
|
||||
QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
|
||||
|
||||
m_javaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
|
@ -956,6 +956,7 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
|
||||
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
|
||||
ev.setTimestamp(event->timestamp());
|
||||
QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev);
|
||||
event->setAccepted(ev.isAccepted());
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::TabletRelease && event->buttons() == Qt::NoButton)
|
||||
|
Loading…
x
Reference in New Issue
Block a user