wayland: Fix handling of synthetic touch cancel events
In case the compositor wants to cancel a touch sequence, we need to ignore subsequent touch motion and touch up events until a new sequence is initiated by the user. Previously, it was implicitly handled by clearing the mapping table between the touch slots and touch ids generated by kwayland-server.
This commit is contained in:
parent
8f2520e00e
commit
d23dab7be9
4 changed files with 20 additions and 21 deletions
|
@ -275,8 +275,6 @@ void TouchInputTest::testTouchPointCount()
|
|||
kwinApp()->platform()->touchUp(1, timestamp++);
|
||||
QCOMPARE(kwinApp()->platform()->touchPointCount(), 2);
|
||||
|
||||
kwinApp()->platform()->cancelTouchSequence();
|
||||
QCOMPARE(kwinApp()->platform()->touchPointCount(), 1);
|
||||
kwinApp()->platform()->cancelTouchSequence();
|
||||
QCOMPARE(kwinApp()->platform()->touchPointCount(), 0);
|
||||
}
|
||||
|
|
|
@ -2303,7 +2303,7 @@ void InputRedirection::setupLibInput()
|
|||
connect(conn, &LibInput::Connection::touchDown, m_touch, &TouchInputRedirection::processDown);
|
||||
connect(conn, &LibInput::Connection::touchUp, m_touch, &TouchInputRedirection::processUp);
|
||||
connect(conn, &LibInput::Connection::touchMotion, m_touch, &TouchInputRedirection::processMotion);
|
||||
connect(conn, &LibInput::Connection::touchCanceled, m_touch, &TouchInputRedirection::processCancel);
|
||||
connect(conn, &LibInput::Connection::touchCanceled, m_touch, &TouchInputRedirection::cancel);
|
||||
connect(conn, &LibInput::Connection::touchFrame, m_touch, &TouchInputRedirection::frame);
|
||||
auto handleSwitchEvent = [this] (SwitchEvent::State state, quint32 time, quint64 timeMicroseconds, LibInput::Device *device) {
|
||||
SwitchEvent event(state, time, timeMicroseconds, device);
|
||||
|
@ -2496,7 +2496,7 @@ void InputRedirection::processTouchMotion(qint32 id, const QPointF &pos, quint32
|
|||
|
||||
void InputRedirection::cancelTouchSequence()
|
||||
{
|
||||
m_touch->processCancel();
|
||||
m_touch->cancel();
|
||||
}
|
||||
|
||||
void InputRedirection::cancelTouch()
|
||||
|
|
|
@ -66,7 +66,7 @@ bool TouchInputRedirection::focusUpdatesBlocked()
|
|||
if (waylandServer()->seat()->isDragTouch()) {
|
||||
return true;
|
||||
}
|
||||
if (m_touches > 1) {
|
||||
if (m_activeTouchPoints.count() > 1) {
|
||||
// first touch defines focus
|
||||
return true;
|
||||
}
|
||||
|
@ -75,9 +75,8 @@ bool TouchInputRedirection::focusUpdatesBlocked()
|
|||
|
||||
bool TouchInputRedirection::positionValid() const
|
||||
{
|
||||
Q_ASSERT(m_touches >= 0);
|
||||
// we can only determine a position with at least one touch point
|
||||
return m_touches;
|
||||
return !m_activeTouchPoints.isEmpty();
|
||||
}
|
||||
|
||||
void TouchInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow)
|
||||
|
@ -144,8 +143,8 @@ void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 t
|
|||
}
|
||||
m_lastPosition = pos;
|
||||
m_windowUpdatedInCycle = false;
|
||||
m_touches++;
|
||||
if (m_touches == 1) {
|
||||
m_activeTouchPoints.insert(id);
|
||||
if (m_activeTouchPoints.count() == 1) {
|
||||
update();
|
||||
}
|
||||
input()->processSpies(std::bind(&InputEventSpy::touchDown, std::placeholders::_1, id, pos, time));
|
||||
|
@ -159,12 +158,14 @@ void TouchInputRedirection::processUp(qint32 id, quint32 time, LibInput::Device
|
|||
if (!inited()) {
|
||||
return;
|
||||
}
|
||||
if (!m_activeTouchPoints.remove(id)) {
|
||||
return;
|
||||
}
|
||||
m_windowUpdatedInCycle = false;
|
||||
input()->processSpies(std::bind(&InputEventSpy::touchUp, std::placeholders::_1, id, time));
|
||||
input()->processFilters(std::bind(&InputEventFilter::touchUp, std::placeholders::_1, id, time));
|
||||
m_windowUpdatedInCycle = false;
|
||||
m_touches--;
|
||||
if (m_touches == 0) {
|
||||
if (m_activeTouchPoints.count() == 0) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +176,9 @@ void TouchInputRedirection::processMotion(qint32 id, const QPointF &pos, quint32
|
|||
if (!inited()) {
|
||||
return;
|
||||
}
|
||||
if (!m_activeTouchPoints.contains(id)) {
|
||||
return;
|
||||
}
|
||||
m_lastPosition = pos;
|
||||
m_windowUpdatedInCycle = false;
|
||||
input()->processSpies(std::bind(&InputEventSpy::touchMotion, std::placeholders::_1, id, pos, time));
|
||||
|
@ -182,17 +186,16 @@ void TouchInputRedirection::processMotion(qint32 id, const QPointF &pos, quint32
|
|||
m_windowUpdatedInCycle = false;
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processCancel()
|
||||
{
|
||||
m_touches--;
|
||||
cancel();
|
||||
}
|
||||
|
||||
void TouchInputRedirection::cancel()
|
||||
{
|
||||
if (!inited()) {
|
||||
return;
|
||||
}
|
||||
// If the touch sequence is artificially cancelled by the compositor, touch motion and touch
|
||||
// up events will be silently ignored and won't be passed down through the event filter chain.
|
||||
// If the touch sequence is cancelled because we received a TOUCH_CANCEL event from libinput,
|
||||
// the compositor will not receive any TOUCH_MOTION or TOUCH_UP events for that slot.
|
||||
m_activeTouchPoints.clear();
|
||||
waylandServer()->seat()->cancelTouchSequence();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ public:
|
|||
void processDown(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processUp(qint32 id, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processMotion(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processCancel();
|
||||
void cancel();
|
||||
void frame();
|
||||
|
||||
|
@ -68,7 +67,7 @@ public:
|
|||
}
|
||||
|
||||
int touchPointCount() const {
|
||||
return m_touches;
|
||||
return m_activeTouchPoints.count();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -77,14 +76,13 @@ private:
|
|||
|
||||
void focusUpdate(Toplevel *focusOld, Toplevel *focusNow) override;
|
||||
|
||||
QSet<qint32> m_activeTouchPoints;
|
||||
bool m_inited = false;
|
||||
qint32 m_decorationId = -1;
|
||||
qint32 m_internalId = -1;
|
||||
QMetaObject::Connection m_focusGeometryConnection;
|
||||
bool m_windowUpdatedInCycle = false;
|
||||
QPointF m_lastPosition;
|
||||
|
||||
int m_touches = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue