From 7f593a67adbd62cd7f767f41abd8b3bbd50b174d Mon Sep 17 00:00:00 2001 From: Vlad Zagorodniy Date: Tue, 12 Feb 2019 11:14:51 +0200 Subject: [PATCH] Send axis_source, axis_discrete, and axis_stop Summary: So far KWin didn't send axis_source, axis_discrete, and axis_stop. Even though most of those events are optional, clients need them to work as expected. For example, one needs axis_source and axis_stop to implement kinetic scrolling; Xwayland needs axis_discrete to prevent multiple scroll events when the compositor sends axis deltas greater than 10, etc. BUG: 404152 FIXED-IN: 5.17.0 Test Plan: * Content of a webpage in Firefox is moved by one line per each mouse wheel "click"; * Scrolled gedit using 2 fingers on GNOME Shell, sway, and KDE Plasma; in all three cases wayland debug looked the same (except diagonal scroll motions). Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D19000 --- autotests/libinput/CMakeLists.txt | 2 +- autotests/libinput/input_event_test.cpp | 14 ++++++--- autotests/libinput/mock_libinput.cpp | 14 +++++++++ autotests/libinput/mock_libinput.h | 3 ++ autotests/libinput/pointer_event_test.cpp | 29 ++++++++++++++++-- input.cpp | 30 +++++++++++++++---- input.h | 11 ++++++- input_event.cpp | 9 ++++-- input_event.h | 29 ++++++++++++++++-- libinput/connection.cpp | 29 +++--------------- libinput/connection.h | 3 +- libinput/events.cpp | 26 ++++++++++++++++ libinput/events.h | 2 ++ platform.cpp | 9 +++--- platform.h | 11 ++++--- plugins/platforms/wayland/wayland_backend.cpp | 1 + .../x11/windowed/x11windowed_backend.cpp | 4 +-- pointer_input.cpp | 11 ++++--- pointer_input.h | 3 +- 19 files changed, 178 insertions(+), 62 deletions(-) diff --git a/autotests/libinput/CMakeLists.txt b/autotests/libinput/CMakeLists.txt index bc0fff699e..b34db02de2 100644 --- a/autotests/libinput/CMakeLists.txt +++ b/autotests/libinput/CMakeLists.txt @@ -108,6 +108,6 @@ ecm_mark_as_test(testLibinputContext) ######################################################## set( testInputEvents_SRCS input_event_test.cpp mock_libinput.cpp ../../libinput/device.cpp ../../input_event.cpp ) add_executable(testInputEvents ${testInputEvents_SRCS}) -target_link_libraries( testInputEvents Qt5::Test Qt5::DBus Qt5::Gui KF5::ConfigCore) +target_link_libraries( testInputEvents Qt5::Test Qt5::DBus Qt5::Gui Qt5::Widgets KF5::ConfigCore) add_test(NAME kwin-testInputEvents COMMAND testInputEvents) ecm_mark_as_test(testInputEvents) diff --git a/autotests/libinput/input_event_test.cpp b/autotests/libinput/input_event_test.cpp index b1a83aa63b..3414a2cd1e 100644 --- a/autotests/libinput/input_event_test.cpp +++ b/autotests/libinput/input_event_test.cpp @@ -121,10 +121,11 @@ void InputEventsTest::testInitWheelEvent_data() { QTest::addColumn("orientation"); QTest::addColumn("delta"); + QTest::addColumn("discreteDelta"); QTest::addColumn("expectedAngleDelta"); - QTest::newRow("horiz") << Qt::Horizontal << 3.0 << QPoint(3, 0); - QTest::newRow("vert") << Qt::Vertical << 2.0 << QPoint(0, 2); + QTest::newRow("horiz") << Qt::Horizontal << 3.3 << 1 << QPoint(3, 0); + QTest::newRow("vert") << Qt::Vertical << 2.4 << 2 << QPoint(0, 2); } void InputEventsTest::testInitWheelEvent() @@ -138,8 +139,9 @@ void InputEventsTest::testInitWheelEvent() // setup event QFETCH(Qt::Orientation, orientation); QFETCH(qreal, delta); - WheelEvent event(QPointF(100, 200), delta, orientation, Qt::LeftButton | Qt::RightButton, - Qt::ShiftModifier | Qt::ControlModifier, 300, &d); + QFETCH(qint32, discreteDelta); + WheelEvent event(QPointF(100, 200), delta, discreteDelta, orientation, Qt::LeftButton | Qt::RightButton, + Qt::ShiftModifier | Qt::ControlModifier, InputRedirection::PointerAxisSourceWheel, 300, &d); // compare QWheelEvent contract QCOMPARE(event.type(), QEvent::Wheel); QCOMPARE(event.posF(), QPointF(100, 200)); @@ -148,6 +150,10 @@ void InputEventsTest::testInitWheelEvent() QCOMPARE(event.modifiers(), Qt::ShiftModifier | Qt::ControlModifier); QCOMPARE(event.timestamp(), 300ul); QTEST(event.angleDelta(), "expectedAngleDelta"); + QTEST(event.orientation(), "orientation"); + QTEST(event.delta(), "delta"); + QTEST(event.discreteDelta(), "discreteDelta"); + QCOMPARE(event.axisSource(), InputRedirection::PointerAxisSourceWheel); // and our custom argument QCOMPARE(event.device(), &d); diff --git a/autotests/libinput/mock_libinput.cpp b/autotests/libinput/mock_libinput.cpp index 1dd3542616..efc1781a38 100644 --- a/autotests/libinput/mock_libinput.cpp +++ b/autotests/libinput/mock_libinput.cpp @@ -602,6 +602,20 @@ double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *even } } +double libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) +{ + if (axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) { + return event->verticalDiscreteAxisValue; + } else { + return event->horizontalDiscreteAxisValue; + } +} + +enum libinput_pointer_axis_source libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) +{ + return event->axisSource; +} + uint32_t libinput_event_touch_get_time(struct libinput_event_touch *event) { return event->time; diff --git a/autotests/libinput/mock_libinput.h b/autotests/libinput/mock_libinput.h index efbc730aa0..2ee7892975 100644 --- a/autotests/libinput/mock_libinput.h +++ b/autotests/libinput/mock_libinput.h @@ -128,6 +128,9 @@ struct libinput_event_pointer : libinput_event { bool horizontalAxis = false; qreal horizontalAxisValue = 0.0; qreal verticalAxisValue = 0.0; + qreal horizontalDiscreteAxisValue = 0.0; + qreal verticalDiscreteAxisValue = 0.0; + libinput_pointer_axis_source axisSource = {}; QSizeF delta; QPointF absolutePos; }; diff --git a/autotests/libinput/pointer_event_test.cpp b/autotests/libinput/pointer_event_test.cpp index bad852076b..ff4e2e0eb8 100644 --- a/autotests/libinput/pointer_event_test.cpp +++ b/autotests/libinput/pointer_event_test.cpp @@ -27,6 +27,7 @@ along with this program. If not, see . Q_DECLARE_METATYPE(libinput_event_type) Q_DECLARE_METATYPE(libinput_button_state) +Q_DECLARE_METATYPE(libinput_pointer_axis_source) using namespace KWin::LibInput; @@ -136,11 +137,25 @@ void TestLibinputPointerEvent::testAxis_data() QTest::addColumn("horizontal"); QTest::addColumn("vertical"); QTest::addColumn("value"); + QTest::addColumn("discreteValue"); + QTest::addColumn("axisSource"); + QTest::addColumn("expectedAxisSource"); QTest::addColumn("time"); - QTest::newRow("horizontal") << true << false << QPointF(3.0, 0.0) << 100u; - QTest::newRow("vertical") << false << true << QPointF(0.0, 2.5) << 200u; - QTest::newRow("both") << true << true << QPointF(1.1, 4.2) << 300u; + QTest::newRow("wheel/horizontal") << true << false << QPointF(3.0, 0.0) << QPoint(1, 0) << LIBINPUT_POINTER_AXIS_SOURCE_WHEEL << KWin::InputRedirection::PointerAxisSourceWheel << 100u; + QTest::newRow("wheel/vertical") << false << true << QPointF(0.0, 2.5) << QPoint(0, 1) << LIBINPUT_POINTER_AXIS_SOURCE_WHEEL << KWin::InputRedirection::PointerAxisSourceWheel << 200u; + QTest::newRow("wheel/both") << true << true << QPointF(1.1, 4.2) << QPoint(1, 1) << LIBINPUT_POINTER_AXIS_SOURCE_WHEEL << KWin::InputRedirection::PointerAxisSourceWheel << 300u; + + QTest::newRow("finger/horizontal") << true << false << QPointF(3.0, 0.0) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 400u; + QTest::newRow("stop finger/horizontal") << true << false << QPointF(0.0, 0.0) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 500u; + QTest::newRow("finger/vertical") << false << true << QPointF(0.0, 2.5) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 600u; + QTest::newRow("stop finger/vertical") << false << true << QPointF(0.0, 0.0) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 700u; + QTest::newRow("finger/both") << true << true << QPointF(1.1, 4.2) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 800u; + QTest::newRow("stop finger/both") << true << true << QPointF(0.0, 0.0) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_FINGER << KWin::InputRedirection::PointerAxisSourceFinger << 900u; + + QTest::newRow("continuous/horizontal") << true << false << QPointF(3.0, 0.0) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS << KWin::InputRedirection::PointerAxisSourceContinuous << 1000u; + QTest::newRow("continuous/vertical") << false << true << QPointF(0.0, 2.5) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS << KWin::InputRedirection::PointerAxisSourceContinuous << 1100u; + QTest::newRow("continuous/both") << true << true << QPointF(1.1, 4.2) << QPoint(0, 0) << LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS << KWin::InputRedirection::PointerAxisSourceContinuous << 1200u; } void TestLibinputPointerEvent::testAxis() @@ -152,11 +167,16 @@ void TestLibinputPointerEvent::testAxis() QFETCH(bool, horizontal); QFETCH(bool, vertical); QFETCH(QPointF, value); + QFETCH(QPoint, discreteValue); + QFETCH(libinput_pointer_axis_source, axisSource); QFETCH(quint32, time); pointerEvent->horizontalAxis = horizontal; pointerEvent->verticalAxis = vertical; pointerEvent->horizontalAxisValue = value.x(); pointerEvent->verticalAxisValue = value.y(); + pointerEvent->horizontalDiscreteAxisValue = discreteValue.x(); + pointerEvent->verticalDiscreteAxisValue = discreteValue.y(); + pointerEvent->axisSource = axisSource; pointerEvent->time = time; QScopedPointer event(Event::create(pointerEvent)); @@ -167,6 +187,9 @@ void TestLibinputPointerEvent::testAxis() QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisVertical), vertical); QCOMPARE(pe->axisValue(KWin::InputRedirection::PointerAxisHorizontal), value.x()); QCOMPARE(pe->axisValue(KWin::InputRedirection::PointerAxisVertical), value.y()); + QCOMPARE(pe->discreteAxisValue(KWin::InputRedirection::PointerAxisHorizontal), discreteValue.x()); + QCOMPARE(pe->discreteAxisValue(KWin::InputRedirection::PointerAxisVertical), discreteValue.y()); + QTEST(pe->axisSource(), "expectedAxisSource"); QCOMPARE(pe->time(), time); } diff --git a/input.cpp b/input.cpp index 955af932b1..5013cb2869 100644 --- a/input.cpp +++ b/input.cpp @@ -4,6 +4,7 @@ Copyright (C) 2013 Martin Gräßlin Copyright (C) 2018 Roman Gilg +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1331,8 +1332,27 @@ public: bool wheelEvent(QWheelEvent *event) override { auto seat = waylandServer()->seat(); seat->setTimestamp(event->timestamp()); - const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal; - seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y()); + auto _event = static_cast(event); + KWayland::Server::PointerAxisSource source; + switch (_event->axisSource()) { + case KWin::InputRedirection::PointerAxisSourceWheel: + source = KWayland::Server::PointerAxisSource::Wheel; + break; + case KWin::InputRedirection::PointerAxisSourceFinger: + source = KWayland::Server::PointerAxisSource::Finger; + break; + case KWin::InputRedirection::PointerAxisSourceContinuous: + source = KWayland::Server::PointerAxisSource::Continuous; + break; + case KWin::InputRedirection::PointerAxisSourceWheelTilt: + source = KWayland::Server::PointerAxisSource::WheelTilt; + break; + case KWin::InputRedirection::PointerAxisSourceUnknown: + default: + source = KWayland::Server::PointerAxisSource::Unknown; + break; + } + seat->pointerAxisV5(_event->orientation(), _event->delta(), _event->discreteDelta(), source); return true; } bool keyEvent(QKeyEvent *event) override { @@ -1724,7 +1744,7 @@ void InputRedirection::setupWorkspace() break; } // TODO: Fix time - m_pointer->processAxis(axis, delta, 0); + m_pointer->processAxis(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, 0); waylandServer()->simulateUserActivity(); } ); @@ -2018,9 +2038,9 @@ void InputRedirection::processPointerButton(uint32_t button, InputRedirection::P m_pointer->processButton(button, state, time); } -void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qreal delta, uint32_t time) +void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, PointerAxisSource source, uint32_t time) { - m_pointer->processAxis(axis, delta, time); + m_pointer->processAxis(axis, delta, discreteDelta, source, time); } void InputRedirection::processKeyboardKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time) diff --git a/input.h b/input.h index 706850da7a..588674d79e 100644 --- a/input.h +++ b/input.h @@ -4,6 +4,7 @@ Copyright (C) 2013 Martin Gräßlin Copyright (C) 2018 Roman Gilg +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -79,6 +80,13 @@ public: PointerAxisVertical, PointerAxisHorizontal }; + enum PointerAxisSource { + PointerAxisSourceUnknown, + PointerAxisSourceWheel, + PointerAxisSourceFinger, + PointerAxisSourceContinuous, + PointerAxisSourceWheelTilt + }; enum KeyboardKeyState { KeyboardKeyReleased, KeyboardKeyPressed, @@ -122,7 +130,7 @@ public: /** * @internal **/ - void processPointerAxis(PointerAxis axis, qreal delta, uint32_t time); + void processPointerAxis(PointerAxis axis, qreal delta, qint32 discreteDelta, PointerAxisSource source, uint32_t time); /** * @internal **/ @@ -479,5 +487,6 @@ void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *a Q_DECLARE_METATYPE(KWin::InputRedirection::KeyboardKeyState) Q_DECLARE_METATYPE(KWin::InputRedirection::PointerButtonState) Q_DECLARE_METATYPE(KWin::InputRedirection::PointerAxis) +Q_DECLARE_METATYPE(KWin::InputRedirection::PointerAxisSource) #endif // KWIN_INPUT_H diff --git a/input_event.cpp b/input_event.cpp index b8a2d7c97c..a5efeef4d5 100644 --- a/input_event.cpp +++ b/input_event.cpp @@ -35,10 +35,15 @@ MouseEvent::MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton bu setTimestamp(timestamp); } -WheelEvent::WheelEvent(const QPointF &pos, qreal delta, Qt::Orientation orientation, Qt::MouseButtons buttons, - Qt::KeyboardModifiers modifiers, quint32 timestamp, LibInput::Device *device) +WheelEvent::WheelEvent(const QPointF &pos, qreal delta, qint32 discreteDelta, Qt::Orientation orientation, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, InputRedirection::PointerAxisSource source, + quint32 timestamp, LibInput::Device *device) : QWheelEvent(pos, pos, QPoint(), (orientation == Qt::Horizontal) ? QPoint(delta, 0) : QPoint(0, delta), delta, orientation, buttons, modifiers) , m_device(device) + , m_orientation(orientation) + , m_delta(delta) + , m_discreteDelta(discreteDelta) + , m_source(source) { setTimestamp(timestamp); } diff --git a/input_event.h b/input_event.h index 7854a10885..8d2bc26483 100644 --- a/input_event.h +++ b/input_event.h @@ -19,6 +19,9 @@ along with this program. If not, see . *********************************************************************/ #ifndef KWIN_INPUT_EVENT_H #define KWIN_INPUT_EVENT_H + +#include "input.h" + #include namespace KWin @@ -78,11 +81,29 @@ private: quint32 m_nativeButton = 0; }; +// TODO: Don't derive from QWheelEvent, this event is quite domain specific. class WheelEvent : public QWheelEvent { public: - explicit WheelEvent(const QPointF &pos, qreal delta, Qt::Orientation orientation, Qt::MouseButtons buttons, - Qt::KeyboardModifiers modifiers, quint32 timestamp, LibInput::Device *device); + explicit WheelEvent(const QPointF &pos, qreal delta, qint32 discreteDelta, Qt::Orientation orientation, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, InputRedirection::PointerAxisSource source, + quint32 timestamp, LibInput::Device *device); + + Qt::Orientation orientation() const { + return m_orientation; + } + + qreal delta() const { + return m_delta; + } + + qint32 discreteDelta() const { + return m_discreteDelta; + } + + InputRedirection::PointerAxisSource axisSource() const { + return m_source; + } LibInput::Device *device() const { return m_device; @@ -98,6 +119,10 @@ public: private: LibInput::Device *m_device; + Qt::Orientation m_orientation; + qreal m_delta; + qint32 m_discreteDelta; + InputRedirection::PointerAxisSource m_source; Qt::KeyboardModifiers m_modifiersRelevantForShortcuts = Qt::KeyboardModifiers(); }; diff --git a/libinput/connection.cpp b/libinput/connection.cpp index 7664659d63..104847aba0 100644 --- a/libinput/connection.cpp +++ b/libinput/connection.cpp @@ -343,31 +343,10 @@ void Connection::processEvents() } case LIBINPUT_EVENT_POINTER_AXIS: { PointerEvent *pe = static_cast(event.data()); - struct Axis { - qreal delta = 0.0; - quint32 time = 0; - }; - QMap deltas; - auto update = [&deltas] (PointerEvent *pe) { - const auto axis = pe->axis(); - for (auto it = axis.begin(); it != axis.end(); ++it) { - deltas[*it].delta += pe->axisValue(*it); - deltas[*it].time = pe->time(); - } - }; - update(pe); - auto it = m_eventQueue.begin(); - while (it != m_eventQueue.end()) { - if ((*it)->type() == LIBINPUT_EVENT_POINTER_AXIS) { - QScopedPointer p(static_cast(*it)); - update(p.data()); - it = m_eventQueue.erase(it); - } else { - break; - } - } - for (auto it = deltas.constBegin(); it != deltas.constEnd(); ++it) { - emit pointerAxisChanged(it.key(), it.value().delta, it.value().time, pe->device()); + const auto axes = pe->axis(); + for (const InputRedirection::PointerAxis &axis : axes) { + emit pointerAxisChanged(axis, pe->axisValue(axis), pe->discreteAxisValue(axis), + pe->axisSource(), pe->time(), pe->device()); } break; } diff --git a/libinput/connection.h b/libinput/connection.h index b45beecaef..9c701141d0 100644 --- a/libinput/connection.h +++ b/libinput/connection.h @@ -104,7 +104,8 @@ Q_SIGNALS: 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(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 pointerAxisChanged(KWin::InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, + KWin::InputRedirection::PointerAxisSource source, quint32 time, KWin::LibInput::Device *device); void touchFrame(KWin::LibInput::Device *device); void touchCanceled(KWin::LibInput::Device *device); void touchDown(qint32 id, const QPointF &absolutePos, quint32 time, KWin::LibInput::Device *device); diff --git a/libinput/events.cpp b/libinput/events.cpp index 3f79062f5f..4077b8ec8e 100644 --- a/libinput/events.cpp +++ b/libinput/events.cpp @@ -205,6 +205,32 @@ qreal PointerEvent::axisValue(InputRedirection::PointerAxis axis) const return libinput_event_pointer_get_axis_value(m_pointerEvent, a); } +qint32 PointerEvent::discreteAxisValue(InputRedirection::PointerAxis axis) const +{ + Q_ASSERT(type() == LIBINPUT_EVENT_POINTER_AXIS); + const libinput_pointer_axis a = (axis == InputRedirection::PointerAxisHorizontal) + ? LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL + : LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; + return libinput_event_pointer_get_axis_value_discrete(m_pointerEvent, a); +} + +InputRedirection::PointerAxisSource PointerEvent::axisSource() const +{ + Q_ASSERT(type() == LIBINPUT_EVENT_POINTER_AXIS); + switch (libinput_event_pointer_get_axis_source(m_pointerEvent)) { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + return InputRedirection::PointerAxisSourceWheel; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + return InputRedirection::PointerAxisSourceFinger; + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + return InputRedirection::PointerAxisSourceContinuous; + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: + return InputRedirection::PointerAxisSourceWheelTilt; + default: + return InputRedirection::PointerAxisSourceUnknown; + } +} + TouchEvent::TouchEvent(libinput_event *event, libinput_event_type type) : Event(event, type) , m_touchEvent(libinput_event_get_touch_event(event)) diff --git a/libinput/events.h b/libinput/events.h index c16fae2dd6..6f8ab7094c 100644 --- a/libinput/events.h +++ b/libinput/events.h @@ -95,6 +95,8 @@ public: quint64 timeMicroseconds() const; QVector axis() const; qreal axisValue(InputRedirection::PointerAxis a) const; + qint32 discreteAxisValue(InputRedirection::PointerAxis axis) const; + InputRedirection::PointerAxisSource axisSource() const; operator libinput_event_pointer*() { return m_pointerEvent; diff --git a/platform.cpp b/platform.cpp index 899b31c4e6..84a9e10448 100644 --- a/platform.cpp +++ b/platform.cpp @@ -22,7 +22,6 @@ along with this program. If not, see . #include "composite.h" #include "cursor.h" #include "effects.h" -#include "input.h" #include #include "overlaywindow.h" #include "outline.h" @@ -193,20 +192,20 @@ void Platform::keymapChange(int fd, uint32_t size) input()->processKeymapChange(fd, size); } -void Platform::pointerAxisHorizontal(qreal delta, quint32 time) +void Platform::pointerAxisHorizontal(qreal delta, quint32 time, qint32 discreteDelta, InputRedirection::PointerAxisSource source) { if (!input()) { return; } - input()->processPointerAxis(InputRedirection::PointerAxisHorizontal, delta, time); + input()->processPointerAxis(InputRedirection::PointerAxisHorizontal, delta, discreteDelta, source, time); } -void Platform::pointerAxisVertical(qreal delta, quint32 time) +void Platform::pointerAxisVertical(qreal delta, quint32 time, qint32 discreteDelta, InputRedirection::PointerAxisSource source) { if (!input()) { return; } - input()->processPointerAxis(InputRedirection::PointerAxisVertical, delta, time); + input()->processPointerAxis(InputRedirection::PointerAxisVertical, delta, discreteDelta, source, time); } void Platform::pointerButtonPressed(quint32 button, quint32 time) diff --git a/platform.h b/platform.h index e2fdc00cb3..b509a636da 100644 --- a/platform.h +++ b/platform.h @@ -22,9 +22,10 @@ along with this program. If not, see . #include #include #include -#include "fixqopengl.h" - #include +#include "fixqopengl.h" +#include "input.h" + #include #include @@ -453,8 +454,10 @@ public Q_SLOTS: void pointerMotion(const QPointF &position, quint32 time); void pointerButtonPressed(quint32 button, quint32 time); void pointerButtonReleased(quint32 button, quint32 time); - void pointerAxisHorizontal(qreal delta, quint32 time); - void pointerAxisVertical(qreal delta, quint32 time); + void pointerAxisHorizontal(qreal delta, quint32 time, qint32 discreteDelta = 0, + InputRedirection::PointerAxisSource source = InputRedirection::PointerAxisSourceUnknown); + void pointerAxisVertical(qreal delta, quint32 time, qint32 discreteDelta = 0, + InputRedirection::PointerAxisSource source = InputRedirection::PointerAxisSourceUnknown); void keyboardKeyPressed(quint32 key, quint32 time); void keyboardKeyReleased(quint32 key, quint32 time); void keyboardModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group); diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp index c7e4f7ca3f..313eb580d5 100644 --- a/plugins/platforms/wayland/wayland_backend.cpp +++ b/plugins/platforms/wayland/wayland_backend.cpp @@ -285,6 +285,7 @@ WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend) } } ); + // TODO: Send discreteDelta and source as well. connect(m_pointer, &Pointer::axisChanged, this, [this](quint32 time, Pointer::Axis axis, qreal delta) { switch (axis) { diff --git a/plugins/platforms/x11/windowed/x11windowed_backend.cpp b/plugins/platforms/x11/windowed/x11windowed_backend.cpp index 22d47fb3ef..9282c94822 100644 --- a/plugins/platforms/x11/windowed/x11windowed_backend.cpp +++ b/plugins/platforms/x11/windowed/x11windowed_backend.cpp @@ -459,9 +459,9 @@ void X11WindowedBackend::handleButtonPress(xcb_button_press_event_t *event) const int delta = (event->detail == XCB_BUTTON_INDEX_4 || event->detail == 6) ? -1 : 1; static const qreal s_defaultAxisStepDistance = 10.0; if (event->detail > 5) { - pointerAxisHorizontal(delta * s_defaultAxisStepDistance, event->time); + pointerAxisHorizontal(delta * s_defaultAxisStepDistance, event->time, delta); } else { - pointerAxisVertical(delta * s_defaultAxisStepDistance, event->time); + pointerAxisVertical(delta * s_defaultAxisStepDistance, event->time, delta); } return; } diff --git a/pointer_input.cpp b/pointer_input.cpp index 8175e8843d..70bddb2dce 100644 --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -4,6 +4,7 @@ Copyright (C) 2013, 2016 Martin Gräßlin Copyright (C) 2018 Roman Gilg +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -319,18 +320,16 @@ void PointerInputRedirection::processButton(uint32_t button, InputRedirection::P } } -void PointerInputRedirection::processAxis(InputRedirection::PointerAxis axis, qreal delta, uint32_t time, LibInput::Device *device) +void PointerInputRedirection::processAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, + InputRedirection::PointerAxisSource source, uint32_t time, LibInput::Device *device) { - if (delta == 0) { - return; - } update(); emit input()->pointerAxisChanged(axis, delta); - WheelEvent wheelEvent(m_pos, delta, + WheelEvent wheelEvent(m_pos, delta, discreteDelta, (axis == InputRedirection::PointerAxisHorizontal) ? Qt::Horizontal : Qt::Vertical, - m_qtButtons, input()->keyboardModifiers(), time, device); + m_qtButtons, input()->keyboardModifiers(), source, time, device); wheelEvent.setModifiersRelevantForGlobalShortcuts(input()->modifiersRelevantForGlobalShortcuts()); input()->processSpies(std::bind(&InputEventSpy::wheelEvent, std::placeholders::_1, &wheelEvent)); diff --git a/pointer_input.h b/pointer_input.h index 2d2bc9fc7b..e3322762ea 100644 --- a/pointer_input.h +++ b/pointer_input.h @@ -4,6 +4,7 @@ Copyright (C) 2013, 2016 Martin Gräßlin Copyright (C) 2018 Roman Gilg +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -110,7 +111,7 @@ public: /** * @internal **/ - void processAxis(InputRedirection::PointerAxis axis, qreal delta, uint32_t time, LibInput::Device *device = nullptr); + void processAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, InputRedirection::PointerAxisSource source, uint32_t time, LibInput::Device *device = nullptr); /** * @internal **/