diff --git a/autotests/libinput/input_event_test.cpp b/autotests/libinput/input_event_test.cpp index 2b517877c5..f588016f9d 100644 --- a/autotests/libinput/input_event_test.cpp +++ b/autotests/libinput/input_event_test.cpp @@ -58,7 +58,7 @@ void InputEventsTest::testInitMouseEvent() QFETCH(QEvent::Type, type); // now create our own event MouseEvent event(type, QPointF(100, 200), Qt::LeftButton, Qt::LeftButton | Qt::RightButton, - Qt::ShiftModifier | Qt::ControlModifier, 300, &d); + Qt::ShiftModifier | Qt::ControlModifier, 300, QSizeF(1, 2), QSizeF(3, 4), quint64(-1), &d); // and verify the contract of QMouseEvent QCOMPARE(event.type(), type); QCOMPARE(event.globalPos(), QPoint(100, 200)); @@ -70,6 +70,9 @@ void InputEventsTest::testInitMouseEvent() QCOMPARE(event.timestamp(), 300ul); // and our custom argument QCOMPARE(event.device(), &d); + QCOMPARE(event.delta(), QSizeF(1, 2)); + QCOMPARE(event.deltaUnaccelerated(), QSizeF(3, 4)); + QCOMPARE(event.timestampMicroseconds(), quint64(-1)); } void InputEventsTest::testInitKeyEvent_data() diff --git a/autotests/libinput/mock_libinput.cpp b/autotests/libinput/mock_libinput.cpp index 86d3fc153d..271081b1dc 100644 --- a/autotests/libinput/mock_libinput.cpp +++ b/autotests/libinput/mock_libinput.cpp @@ -450,11 +450,26 @@ double libinput_event_pointer_get_dy(struct libinput_event_pointer *event) return event->delta.height(); } +double libinput_event_pointer_get_dx_unaccelerated(struct libinput_event_pointer *event) +{ + return event->delta.width(); +} + +double libinput_event_pointer_get_dy_unaccelerated(struct libinput_event_pointer *event) +{ + return event->delta.height(); +} + uint32_t libinput_event_pointer_get_time(struct libinput_event_pointer *event) { return event->time; } +uint64_t libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event) +{ + return quint64(event->time * 1000); +} + uint32_t libinput_event_pointer_get_button(struct libinput_event_pointer *event) { return event->button; diff --git a/autotests/libinput/pointer_event_test.cpp b/autotests/libinput/pointer_event_test.cpp index b86441da49..03af54da07 100644 --- a/autotests/libinput/pointer_event_test.cpp +++ b/autotests/libinput/pointer_event_test.cpp @@ -128,6 +128,7 @@ void TestLibinputPointerEvent::testButton() QTEST(pe->buttonState(), "expectedButtonState"); QCOMPARE(pe->button(), button); QCOMPARE(pe->time(), time); + QCOMPARE(pe->timeMicroseconds(), quint64(time * 1000)); } void TestLibinputPointerEvent::testAxis_data() @@ -183,7 +184,7 @@ void TestLibinputPointerEvent::testMotion() QVERIFY(pe); QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_MOTION); QCOMPARE(pe->time(), 500u); - QCOMPARE(pe->delta(), QPointF(2.1, 4.5)); + QCOMPARE(pe->delta(), QSizeF(2.1, 4.5)); } void TestLibinputPointerEvent::testAbsoluteMotion() diff --git a/debug_console.cpp b/debug_console.cpp index db18569fea..9656754b36 100644 --- a/debug_console.cpp +++ b/debug_console.cpp @@ -68,6 +68,11 @@ static QString timestampRow(quint32 timestamp) return tableRow(i18n("Timestamp"), timestamp); } +static QString timestampRowUsec(quint64 timestamp) +{ + return tableRow(i18n("Timestamp (µsec)"), timestamp); +} + static QString buttonToString(Qt::MouseButton button) { switch (button) { @@ -171,14 +176,27 @@ bool DebugConsoleFilter::pointerEvent(QMouseEvent *event, quint32 nativeButton) text.append(s_tableStart); switch (event->type()) { - case QEvent::MouseMove: + case QEvent::MouseMove: { text.append(tableHeaderRow(i18nc("A mouse pointer motion event", "Pointer Motion"))); + auto e = static_cast(event); #if HAVE_INPUT - text.append(deviceRow(static_cast(event)->device())); + text.append(deviceRow(e->device())); #endif text.append(timestamp); + if (e->timestampMicroseconds() != 0) { + text.append(timestampRowUsec(e->timestampMicroseconds())); + } + if (e->delta() != QSizeF()) { + text.append(tableRow(i18nc("The relative mouse movement", "Delta"), + QStringLiteral("%1/%2").arg(e->delta().width()).arg(e->delta().height()))); + } + if (e->deltaUnaccelerated() != QSizeF()) { + text.append(tableRow(i18nc("The relative mouse movement", "Delta (not accelerated)"), + QStringLiteral("%1/%2").arg(e->deltaUnaccelerated().width()).arg(e->deltaUnaccelerated().height()))); + } text.append(tableRow(i18nc("The global mouse pointer position", "Global Position"), QStringLiteral("%1/%2").arg(event->pos().x()).arg(event->pos().y()))); break; + } case QEvent::MouseButtonPress: text.append(tableHeaderRow(i18nc("A mouse pointer button press event", "Pointer Button Press"))); #if HAVE_INPUT diff --git a/input.cpp b/input.cpp index f9237b58e0..5da10dd44f 100644 --- a/input.cpp +++ b/input.cpp @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "input.h" +#include "input_event.h" #include "keyboard_input.h" #include "pointer_input.h" #include "touch_input.h" @@ -43,6 +44,7 @@ along with this program. If not, see . #include #include #include +#include #include #include //screenlocker @@ -892,13 +894,18 @@ public: auto seat = waylandServer()->seat(); seat->setTimestamp(event->timestamp()); switch (event->type()) { - case QEvent::MouseMove: + case QEvent::MouseMove: { if (event->buttons() == Qt::NoButton) { // update pointer window only if no button is pressed input()->pointer()->update(); } seat->setPointerPos(event->globalPos()); + MouseEvent *e = static_cast(event); + if (e->delta() != QSizeF()) { + seat->relativePointerMotion(e->delta(), e->deltaUnaccelerated(), e->timestampMicroseconds()); + } break; + } case QEvent::MouseButtonPress: seat->pointerButtonPressed(nativeButton); break; @@ -1232,6 +1239,12 @@ void InputRedirection::setupLibInput() LibInput::Connection *conn = LibInput::Connection::create(this); m_libInput = conn; if (conn) { + + if (waylandServer()) { + // create relative pointer manager + waylandServer()->display()->createRelativePointerManager(KWayland::Server::RelativePointerInterfaceVersion::UnstableV1, waylandServer()->display())->create(); + } + conn->setInputConfig(m_inputConfig); conn->setup(); connect(conn, &LibInput::Connection::eventsRead, this, @@ -1251,8 +1264,8 @@ void InputRedirection::setupLibInput() connect(conn, &LibInput::Connection::swipeGestureCancelled, m_pointer, &PointerInputRedirection::processSwipeGestureCancelled); connect(conn, &LibInput::Connection::keyChanged, m_keyboard, &KeyboardInputRedirection::processKey); connect(conn, &LibInput::Connection::pointerMotion, this, - [this] (QPointF delta, uint32_t time, LibInput::Device *device) { - m_pointer->processMotion(m_pointer->pos() + delta, time, device); + [this] (const QSizeF &delta, const QSizeF &deltaNonAccel, uint32_t time, quint64 timeMicroseconds, LibInput::Device *device) { + m_pointer->processMotion(m_pointer->pos() + QPointF(delta.width(), delta.height()), delta, deltaNonAccel, time, timeMicroseconds, device); } ); connect(conn, &LibInput::Connection::pointerMotionAbsolute, this, diff --git a/input_event.cpp b/input_event.cpp index 87fdb41a56..8de4284597 100644 --- a/input_event.cpp +++ b/input_event.cpp @@ -24,8 +24,12 @@ namespace KWin MouseEvent::MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, - quint32 timestamp, LibInput::Device *device) + quint32 timestamp, const QSizeF &delta, const QSizeF &deltaNonAccelerated, + quint64 timestampMicroseconds, LibInput::Device *device) : QMouseEvent(type, pos, pos, button, buttons, modifiers) + , m_delta(delta) + , m_deltaUnccelerated(deltaNonAccelerated) + , m_timestampMicroseconds(timestampMicroseconds) , m_device(device) { setTimestamp(timestamp); diff --git a/input_event.h b/input_event.h index 1203a559aa..bbb845da8b 100644 --- a/input_event.h +++ b/input_event.h @@ -33,13 +33,30 @@ class MouseEvent : public QMouseEvent { public: explicit MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton button, Qt::MouseButtons buttons, - Qt::KeyboardModifiers modifiers, quint32 timestamp, LibInput::Device *device); + Qt::KeyboardModifiers modifiers, quint32 timestamp, + const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 timestampMicroseconds, + LibInput::Device *device); + + QSizeF delta() const { + return m_delta; + } + + QSizeF deltaUnaccelerated() const { + return m_deltaUnccelerated; + } + + quint64 timestampMicroseconds() const { + return m_timestampMicroseconds; + } LibInput::Device *device() const { return m_device; } private: + QSizeF m_delta; + QSizeF m_deltaUnccelerated; + quint64 m_timestampMicroseconds; LibInput::Device *m_device; }; diff --git a/libinput/connection.cpp b/libinput/connection.cpp index 6831736b30..9cda9c1693 100644 --- a/libinput/connection.cpp +++ b/libinput/connection.cpp @@ -328,20 +328,24 @@ void Connection::processEvents() } case LIBINPUT_EVENT_POINTER_MOTION: { PointerEvent *pe = static_cast(event.data()); - QPointF delta = pe->delta(); + auto delta = pe->delta(); + auto deltaNonAccel = pe->deltaUnaccelerated(); quint32 latestTime = pe->time(); + quint64 latestTimeUsec = pe->timeMicroseconds(); auto it = m_eventQueue.begin(); while (it != m_eventQueue.end()) { if ((*it)->type() == LIBINPUT_EVENT_POINTER_MOTION) { QScopedPointer p(static_cast(*it)); delta += p->delta(); + deltaNonAccel += p->deltaUnaccelerated(); latestTime = p->time(); + latestTimeUsec = p->timeMicroseconds(); it = m_eventQueue.erase(it); } else { break; } } - emit pointerMotion(delta, latestTime, pe->device()); + emit pointerMotion(delta, deltaNonAccel, latestTime, latestTimeUsec, pe->device()); break; } case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: { diff --git a/libinput/connection.h b/libinput/connection.h index 03996d3fbf..4ad0f464e2 100644 --- a/libinput/connection.h +++ b/libinput/connection.h @@ -86,7 +86,7 @@ Q_SIGNALS: void keyChanged(quint32 key, KWin::InputRedirection::KeyboardKeyState, quint32 time, KWin::LibInput::Device *device); void pointerButtonChanged(quint32 button, KWin::InputRedirection::PointerButtonState state, quint32 time, KWin::LibInput::Device *device); void pointerMotionAbsolute(QPointF orig, QPointF screen, quint32 time, KWin::LibInput::Device *device); - void pointerMotion(QPointF delta, quint32 time, KWin::LibInput::Device *device); + void pointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint32 time, quint64 timeMicroseconds, KWin::LibInput::Device *device); void pointerAxisChanged(KWin::InputRedirection::PointerAxis axis, qreal delta, quint32 time, KWin::LibInput::Device *device); void touchFrame(KWin::LibInput::Device *device); void touchCanceled(KWin::LibInput::Device *device); diff --git a/libinput/events.cpp b/libinput/events.cpp index 1ebb20359e..d0539c3d2e 100644 --- a/libinput/events.cpp +++ b/libinput/events.cpp @@ -133,10 +133,16 @@ QPointF PointerEvent::absolutePos(const QSize &size) const libinput_event_pointer_get_absolute_y_transformed(m_pointerEvent, size.height())); } -QPointF PointerEvent::delta() const +QSizeF PointerEvent::delta() const { Q_ASSERT(type() == LIBINPUT_EVENT_POINTER_MOTION); - return QPointF(libinput_event_pointer_get_dx(m_pointerEvent), libinput_event_pointer_get_dy(m_pointerEvent)); + return QSizeF(libinput_event_pointer_get_dx(m_pointerEvent), libinput_event_pointer_get_dy(m_pointerEvent)); +} + +QSizeF PointerEvent::deltaUnaccelerated() const +{ + Q_ASSERT(type() == LIBINPUT_EVENT_POINTER_MOTION); + return QSizeF(libinput_event_pointer_get_dx_unaccelerated(m_pointerEvent), libinput_event_pointer_get_dy_unaccelerated(m_pointerEvent)); } uint32_t PointerEvent::time() const @@ -144,6 +150,11 @@ uint32_t PointerEvent::time() const return libinput_event_pointer_get_time(m_pointerEvent); } +quint64 PointerEvent::timeMicroseconds() const +{ + return libinput_event_pointer_get_time_usec(m_pointerEvent); +} + uint32_t PointerEvent::button() const { Q_ASSERT(type() == LIBINPUT_EVENT_POINTER_BUTTON); diff --git a/libinput/events.h b/libinput/events.h index bc8baaa7a1..646844cb7c 100644 --- a/libinput/events.h +++ b/libinput/events.h @@ -89,10 +89,12 @@ public: QPointF absolutePos() const; QPointF absolutePos(const QSize &size) const; - QPointF delta() const; + QSizeF delta() const; + QSizeF deltaUnaccelerated() const; uint32_t button() const; InputRedirection::PointerButtonState buttonState() const; uint32_t time() const; + quint64 timeMicroseconds() const; QVector axis() const; qreal axisValue(InputRedirection::PointerAxis a) const; diff --git a/pointer_input.cpp b/pointer_input.cpp index 7716a4e61e..c8cd4ce2fe 100644 --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -161,13 +161,19 @@ void PointerInputRedirection::init() } void PointerInputRedirection::processMotion(const QPointF &pos, uint32_t time, LibInput::Device *device) +{ + processMotion(pos, QSizeF(), QSizeF(), time, 0, device); +} + +void PointerInputRedirection::processMotion(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device) { if (!m_inited) { return; } updatePosition(pos); MouseEvent event(QEvent::MouseMove, m_pos, Qt::NoButton, m_qtButtons, - m_input->keyboardModifiers(), time, device); + m_input->keyboardModifiers(), time, + delta, deltaNonAccelerated, timeUsec, device); const auto &filters = m_input->filters(); for (auto it = filters.begin(), end = filters.end(); it != end; it++) { @@ -199,7 +205,7 @@ void PointerInputRedirection::processButton(uint32_t button, InputRedirection::P } MouseEvent event(type, m_pos, buttonToQtMouseButton(button), m_qtButtons, - m_input->keyboardModifiers(), time, device); + m_input->keyboardModifiers(), time, QSizeF(), QSizeF(), 0, device); const auto &filters = m_input->filters(); for (auto it = filters.begin(), end = filters.end(); it != end; it++) { diff --git a/pointer_input.h b/pointer_input.h index cd730e9acc..8e40153494 100644 --- a/pointer_input.h +++ b/pointer_input.h @@ -86,6 +86,10 @@ public: * @internal */ void processMotion(const QPointF &pos, uint32_t time, LibInput::Device *device = nullptr); + /** + * @internal + **/ + void processMotion(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device); /** * @internal */ diff --git a/tests/libinputtest.cpp b/tests/libinputtest.cpp index 3446dc7270..349b6280be 100644 --- a/tests/libinputtest.cpp +++ b/tests/libinputtest.cpp @@ -75,8 +75,8 @@ int main(int argc, char **argv) } ); QObject::connect(conn, &Connection::pointerMotion, - [](QPointF delta) { - std::cout << "Got pointer motion: " << delta.x() << "/" << delta.y() << std::endl; + [](const QSizeF &delta) { + std::cout << "Got pointer motion: " << delta.width() << "/" << delta.height() << std::endl; } ); QObject::connect(conn, &Connection::pointerAxisChanged,