[libinput] Add support for gesture events
Summary: Gesture events are swipe or pinch events on a touch pad. This change implements basic support by: * wrapping them in LibInput::Event * processing them in LibInput::Connection and emitting dedicated signals * Forwarding them in InputRedirection to PointerInputRedirection * Support them in the internal input event filter * Printing debug information in DebugConsole Further handling is not yet done. In future the following should be implemented: * activating e.g. zoom and present windows on pinch/swipe gesture * forwarding non global gestures to KWayland Note that forwarding to KWayland is not yet useful as QtWayland does not yet have support for the unstable protocol. No Qt application could make use of it yet. So for the moment just global gestures is the best we can get. Test Plan: Looked at output of DebugConsole when triggering gestures Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2359
This commit is contained in:
parent
50571b7921
commit
8a83a6fef5
14 changed files with 798 additions and 0 deletions
|
@ -51,6 +51,20 @@ target_link_libraries( testLibinputTouchEvent Qt5::Test Qt5::Widgets KF5::Config
|
|||
add_test(kwin-testLibinputTouchEvent testLibinputTouchEvent)
|
||||
ecm_mark_as_test(testLibinputTouchEvent)
|
||||
|
||||
########################################################
|
||||
# Test Gesture Event
|
||||
########################################################
|
||||
set( testLibinputGestureEvent_SRCS
|
||||
gesture_event_test.cpp
|
||||
mock_libinput.cpp
|
||||
../../libinput/device.cpp
|
||||
../../libinput/events.cpp
|
||||
)
|
||||
add_executable(testLibinputGestureEvent ${testLibinputGestureEvent_SRCS})
|
||||
target_link_libraries( testLibinputGestureEvent Qt5::Test Qt5::Widgets KF5::ConfigCore)
|
||||
add_test(kwin-testLibinputGestureEvent testLibinputGestureEvent)
|
||||
ecm_mark_as_test(testLibinputGestureEvent)
|
||||
|
||||
########################################################
|
||||
# Test Context
|
||||
########################################################
|
||||
|
|
214
autotests/libinput/gesture_event_test.cpp
Normal file
214
autotests/libinput/gesture_event_test.cpp
Normal file
|
@ -0,0 +1,214 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "mock_libinput.h"
|
||||
#include "../../libinput/device.h"
|
||||
#include "../../libinput/events.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
Q_DECLARE_METATYPE(libinput_event_type)
|
||||
|
||||
using namespace KWin::LibInput;
|
||||
|
||||
class TestLibinputGestureEvent : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void testType_data();
|
||||
void testType();
|
||||
|
||||
void testStart_data();
|
||||
void testStart();
|
||||
|
||||
void testSwipeUpdate();
|
||||
void testPinchUpdate();
|
||||
|
||||
void testEnd_data();
|
||||
void testEnd();
|
||||
|
||||
private:
|
||||
libinput_device *m_nativeDevice = nullptr;
|
||||
Device *m_device = nullptr;
|
||||
};
|
||||
|
||||
void TestLibinputGestureEvent::init()
|
||||
{
|
||||
m_nativeDevice = new libinput_device;
|
||||
m_nativeDevice->pointer = true;
|
||||
m_nativeDevice->gestureSupported = true;
|
||||
m_nativeDevice->deviceSize = QSizeF(12.5, 13.8);
|
||||
m_device = new Device(m_nativeDevice);
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::cleanup()
|
||||
{
|
||||
delete m_device;
|
||||
m_device = nullptr;
|
||||
|
||||
delete m_nativeDevice;
|
||||
m_nativeDevice = nullptr;
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testType_data()
|
||||
{
|
||||
QTest::addColumn<libinput_event_type>("type");
|
||||
|
||||
QTest::newRow("pinch-start") << LIBINPUT_EVENT_GESTURE_PINCH_BEGIN;
|
||||
QTest::newRow("pinch-update") << LIBINPUT_EVENT_GESTURE_PINCH_UPDATE;
|
||||
QTest::newRow("pinch-end") << LIBINPUT_EVENT_GESTURE_PINCH_END;
|
||||
QTest::newRow("swipe-start") << LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN;
|
||||
QTest::newRow("swipe-update") << LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE;
|
||||
QTest::newRow("swipe-end") << LIBINPUT_EVENT_GESTURE_SWIPE_END;
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testType()
|
||||
{
|
||||
// this test verifies the initialization of a PointerEvent and the parent Event class
|
||||
libinput_event_gesture *gestureEvent = new libinput_event_gesture;
|
||||
QFETCH(libinput_event_type, type);
|
||||
gestureEvent->type = type;
|
||||
gestureEvent->device = m_nativeDevice;
|
||||
|
||||
QScopedPointer<Event> event(Event::create(gestureEvent));
|
||||
// API of event
|
||||
QCOMPARE(event->type(), type);
|
||||
QCOMPARE(event->device(), m_device);
|
||||
QCOMPARE(event->nativeDevice(), m_nativeDevice);
|
||||
QCOMPARE((libinput_event*)(*event.data()), gestureEvent);
|
||||
// verify it's a pointer event
|
||||
QVERIFY(dynamic_cast<GestureEvent*>(event.data()));
|
||||
QCOMPARE((libinput_event_gesture*)(*dynamic_cast<GestureEvent*>(event.data())), gestureEvent);
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testStart_data()
|
||||
{
|
||||
QTest::addColumn<libinput_event_type>("type");
|
||||
|
||||
QTest::newRow("pinch") << LIBINPUT_EVENT_GESTURE_PINCH_BEGIN;
|
||||
QTest::newRow("swipe") << LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN;
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testStart()
|
||||
{
|
||||
libinput_event_gesture *gestureEvent = new libinput_event_gesture;
|
||||
gestureEvent->device = m_nativeDevice;
|
||||
QFETCH(libinput_event_type, type);
|
||||
gestureEvent->type = type;
|
||||
gestureEvent->fingerCount = 3;
|
||||
gestureEvent->time = 100u;
|
||||
|
||||
QScopedPointer<Event> event(Event::create(gestureEvent));
|
||||
auto ge = dynamic_cast<GestureEvent*>(event.data());
|
||||
QVERIFY(ge);
|
||||
QCOMPARE(ge->fingerCount(), gestureEvent->fingerCount);
|
||||
QVERIFY(!ge->isCancelled());
|
||||
QCOMPARE(ge->time(), gestureEvent->time);
|
||||
QCOMPARE(ge->delta(), QSizeF(0, 0));
|
||||
if (ge->type() == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN) {
|
||||
auto pe = dynamic_cast<PinchGestureEvent*>(event.data());
|
||||
QCOMPARE(pe->scale(), 1.0);
|
||||
QCOMPARE(pe->angleDelta(), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testSwipeUpdate()
|
||||
{
|
||||
libinput_event_gesture *gestureEvent = new libinput_event_gesture;
|
||||
gestureEvent->device = m_nativeDevice;
|
||||
gestureEvent->type = LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE;
|
||||
gestureEvent->fingerCount = 2;
|
||||
gestureEvent->time = 200u;
|
||||
gestureEvent->delta = QSizeF(2, 3);
|
||||
|
||||
QScopedPointer<Event> event(Event::create(gestureEvent));
|
||||
auto se = dynamic_cast<SwipeGestureEvent*>(event.data());
|
||||
QVERIFY(se);
|
||||
QCOMPARE(se->fingerCount(), gestureEvent->fingerCount);
|
||||
QVERIFY(!se->isCancelled());
|
||||
QCOMPARE(se->time(), gestureEvent->time);
|
||||
QCOMPARE(se->delta(), QSizeF(2, 3));
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testPinchUpdate()
|
||||
{
|
||||
libinput_event_gesture *gestureEvent = new libinput_event_gesture;
|
||||
gestureEvent->device = m_nativeDevice;
|
||||
gestureEvent->type = LIBINPUT_EVENT_GESTURE_PINCH_UPDATE;
|
||||
gestureEvent->fingerCount = 4;
|
||||
gestureEvent->time = 600u;
|
||||
gestureEvent->delta = QSizeF(5, 4);
|
||||
gestureEvent->scale = 2;
|
||||
gestureEvent->angleDelta = -30;
|
||||
|
||||
QScopedPointer<Event> event(Event::create(gestureEvent));
|
||||
auto pe = dynamic_cast<PinchGestureEvent*>(event.data());
|
||||
QVERIFY(pe);
|
||||
QCOMPARE(pe->fingerCount(), gestureEvent->fingerCount);
|
||||
QVERIFY(!pe->isCancelled());
|
||||
QCOMPARE(pe->time(), gestureEvent->time);
|
||||
QCOMPARE(pe->delta(), QSizeF(5, 4));
|
||||
QCOMPARE(pe->scale(), gestureEvent->scale);
|
||||
QCOMPARE(pe->angleDelta(), gestureEvent->angleDelta);
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testEnd_data()
|
||||
{
|
||||
QTest::addColumn<libinput_event_type>("type");
|
||||
QTest::addColumn<bool>("cancelled");
|
||||
|
||||
QTest::newRow("pinch/not cancelled") << LIBINPUT_EVENT_GESTURE_PINCH_END << false;
|
||||
QTest::newRow("pinch/cancelled") << LIBINPUT_EVENT_GESTURE_PINCH_END << true;
|
||||
QTest::newRow("swipe/not cancelled") << LIBINPUT_EVENT_GESTURE_SWIPE_END << false;
|
||||
QTest::newRow("swipe/cancelled") << LIBINPUT_EVENT_GESTURE_SWIPE_END << true;
|
||||
}
|
||||
|
||||
void TestLibinputGestureEvent::testEnd()
|
||||
{
|
||||
libinput_event_gesture *gestureEvent = new libinput_event_gesture;
|
||||
gestureEvent->device = m_nativeDevice;
|
||||
QFETCH(libinput_event_type, type);
|
||||
gestureEvent->type = type;
|
||||
gestureEvent->fingerCount = 4;
|
||||
QFETCH(bool, cancelled);
|
||||
gestureEvent->cancelled = cancelled;
|
||||
gestureEvent->time = 300u;
|
||||
gestureEvent->scale = 3;
|
||||
|
||||
QScopedPointer<Event> event(Event::create(gestureEvent));
|
||||
auto ge = dynamic_cast<GestureEvent*>(event.data());
|
||||
QVERIFY(ge);
|
||||
QCOMPARE(ge->fingerCount(), gestureEvent->fingerCount);
|
||||
QCOMPARE(ge->isCancelled(), cancelled);
|
||||
QCOMPARE(ge->time(), gestureEvent->time);
|
||||
QCOMPARE(ge->delta(), QSizeF(0, 0));
|
||||
if (ge->type() == LIBINPUT_EVENT_GESTURE_PINCH_END) {
|
||||
auto pe = dynamic_cast<PinchGestureEvent*>(event.data());
|
||||
QCOMPARE(pe->scale(), gestureEvent->scale);
|
||||
QCOMPARE(pe->angleDelta(), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestLibinputGestureEvent)
|
||||
#include "gesture_event_test.moc"
|
|
@ -267,6 +267,74 @@ struct libinput_event_touch *libinput_event_get_touch_event(struct libinput_even
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
struct libinput_event_gesture *libinput_event_get_gesture_event(struct libinput_event *event)
|
||||
{
|
||||
if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN ||
|
||||
event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE ||
|
||||
event->type == LIBINPUT_EVENT_GESTURE_PINCH_END ||
|
||||
event->type == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN ||
|
||||
event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE ||
|
||||
event->type == LIBINPUT_EVENT_GESTURE_SWIPE_END) {
|
||||
return reinterpret_cast<libinput_event_gesture *>(event);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event)
|
||||
{
|
||||
if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_END || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_END) {
|
||||
return event->cancelled;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t libinput_event_gesture_get_time(struct libinput_event_gesture *event)
|
||||
{
|
||||
return event->time;
|
||||
}
|
||||
|
||||
int libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event)
|
||||
{
|
||||
return event->fingerCount;
|
||||
}
|
||||
|
||||
double libinput_event_gesture_get_dx(struct libinput_event_gesture *event)
|
||||
{
|
||||
if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE) {
|
||||
return event->delta.width();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double libinput_event_gesture_get_dy(struct libinput_event_gesture *event)
|
||||
{
|
||||
if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE || event->type == LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE) {
|
||||
return event->delta.height();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double libinput_event_gesture_get_scale(struct libinput_event_gesture *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
||||
return 1.0;
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
||||
return event->scale;
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event)
|
||||
{
|
||||
if (event->type == LIBINPUT_EVENT_GESTURE_PINCH_UPDATE) {
|
||||
return event->angleDelta;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
uint32_t libinput_event_keyboard_get_key(struct libinput_event_keyboard *event)
|
||||
{
|
||||
return event->key;
|
||||
|
|
|
@ -87,6 +87,14 @@ struct libinput_event_touch : libinput_event {
|
|||
QPointF absolutePos;
|
||||
};
|
||||
|
||||
struct libinput_event_gesture : libinput_event {
|
||||
int fingerCount = 0;
|
||||
bool cancelled = false;
|
||||
QSizeF delta = QSizeF(0, 0);
|
||||
qreal scale = 0.0;
|
||||
qreal angleDelta = 0.0;
|
||||
};
|
||||
|
||||
struct libinput {
|
||||
int refCount = 1;
|
||||
QByteArray seat;
|
||||
|
|
|
@ -334,6 +334,118 @@ bool DebugConsoleFilter::touchUp(quint32 id, quint32 time)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::pinchGestureBegin(int fingerCount, quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A pinch gesture is started", "Pinch start")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(tableRow(i18nc("Number of fingers in this pinch gesture", "Finger count"), fingerCount));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A pinch gesture is updated", "Pinch update")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(tableRow(i18nc("Current scale in pinch gesture", "Scale"), scale));
|
||||
text.append(tableRow(i18nc("Current angle in pinch gesture", "Angle delta"), angleDelta));
|
||||
text.append(tableRow(i18nc("Current delta in pinch gesture", "Delta x"), delta.width()));
|
||||
text.append(tableRow(i18nc("Current delta in pinch gesture", "Delta y"), delta.height()));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::pinchGestureEnd(quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A pinch gesture ended", "Pinch end")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::pinchGestureCancelled(quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A pinch gesture got cancelled", "Pinch cancelled")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::swipeGestureBegin(int fingerCount, quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A swipe gesture is started", "Swipe start")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(tableRow(i18nc("Number of fingers in this swipe gesture", "Finger count"), fingerCount));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::swipeGestureUpdate(const QSizeF &delta, quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A swipe gesture is updated", "Swipe update")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(tableRow(i18nc("Current delta in swipe gesture", "Delta x"), delta.width()));
|
||||
text.append(tableRow(i18nc("Current delta in swipe gesture", "Delta y"), delta.height()));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::swipeGestureEnd(quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A swipe gesture ended", "Swipe end")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugConsoleFilter::swipeGestureCancelled(quint32 time)
|
||||
{
|
||||
QString text = s_hr;
|
||||
text.append(s_tableStart);
|
||||
text.append(tableHeaderRow(i18nc("A swipe gesture got cancelled", "Swipe cancelled")));
|
||||
text.append(timestampRow(time));
|
||||
text.append(s_tableEnd);
|
||||
|
||||
m_textEdit->insertHtml(text);
|
||||
m_textEdit->ensureCursorVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugConsole::DebugConsole()
|
||||
: QWidget()
|
||||
, m_ui(new Ui::DebugConsole)
|
||||
|
|
|
@ -133,6 +133,16 @@ public:
|
|||
bool touchMotion(quint32 id, const QPointF &pos, quint32 time) override;
|
||||
bool touchUp(quint32 id, quint32 time) override;
|
||||
|
||||
bool pinchGestureBegin(int fingerCount, quint32 time) override;
|
||||
bool pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time) override;
|
||||
bool pinchGestureEnd(quint32 time) override;
|
||||
bool pinchGestureCancelled(quint32 time) override;
|
||||
|
||||
bool swipeGestureBegin(int fingerCount, quint32 time) override;
|
||||
bool swipeGestureUpdate(const QSizeF &delta, quint32 time) override;
|
||||
bool swipeGestureEnd(quint32 time) override;
|
||||
bool swipeGestureCancelled(quint32 time) override;
|
||||
|
||||
private:
|
||||
QTextEdit *m_textEdit;
|
||||
};
|
||||
|
|
62
input.cpp
62
input.cpp
|
@ -106,6 +106,60 @@ bool InputEventFilter::touchUp(quint32 id, quint32 time)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::pinchGestureBegin(int fingerCount, quint32 time)
|
||||
{
|
||||
Q_UNUSED(fingerCount)
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time)
|
||||
{
|
||||
Q_UNUSED(scale)
|
||||
Q_UNUSED(angleDelta)
|
||||
Q_UNUSED(delta)
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::pinchGestureEnd(quint32 time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::pinchGestureCancelled(quint32 time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::swipeGestureBegin(int fingerCount, quint32 time)
|
||||
{
|
||||
Q_UNUSED(fingerCount)
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::swipeGestureUpdate(const QSizeF &delta, quint32 time)
|
||||
{
|
||||
Q_UNUSED(delta)
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::swipeGestureEnd(quint32 time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::swipeGestureCancelled(quint32 time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if HAVE_INPUT
|
||||
class VirtualTerminalFilter : public InputEventFilter {
|
||||
public:
|
||||
|
@ -1134,6 +1188,14 @@ void InputRedirection::setupLibInput()
|
|||
);
|
||||
connect(conn, &LibInput::Connection::pointerButtonChanged, m_pointer, &PointerInputRedirection::processButton);
|
||||
connect(conn, &LibInput::Connection::pointerAxisChanged, m_pointer, &PointerInputRedirection::processAxis);
|
||||
connect(conn, &LibInput::Connection::pinchGestureBegin, m_pointer, &PointerInputRedirection::processPinchGestureBegin);
|
||||
connect(conn, &LibInput::Connection::pinchGestureUpdate, m_pointer, &PointerInputRedirection::processPinchGestureUpdate);
|
||||
connect(conn, &LibInput::Connection::pinchGestureEnd, m_pointer, &PointerInputRedirection::processPinchGestureEnd);
|
||||
connect(conn, &LibInput::Connection::pinchGestureCancelled, m_pointer, &PointerInputRedirection::processPinchGestureCancelled);
|
||||
connect(conn, &LibInput::Connection::swipeGestureBegin, m_pointer, &PointerInputRedirection::processSwipeGestureBegin);
|
||||
connect(conn, &LibInput::Connection::swipeGestureUpdate, m_pointer, &PointerInputRedirection::processSwipeGestureUpdate);
|
||||
connect(conn, &LibInput::Connection::swipeGestureEnd, m_pointer, &PointerInputRedirection::processSwipeGestureEnd);
|
||||
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) {
|
||||
|
|
10
input.h
10
input.h
|
@ -288,6 +288,16 @@ public:
|
|||
virtual bool touchDown(quint32 id, const QPointF &pos, quint32 time);
|
||||
virtual bool touchMotion(quint32 id, const QPointF &pos, quint32 time);
|
||||
virtual bool touchUp(quint32 id, quint32 time);
|
||||
|
||||
virtual bool pinchGestureBegin(int fingerCount, quint32 time);
|
||||
virtual bool pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time);
|
||||
virtual bool pinchGestureEnd(quint32 time);
|
||||
virtual bool pinchGestureCancelled(quint32 time);
|
||||
|
||||
virtual bool swipeGestureBegin(int fingerCount, quint32 time);
|
||||
virtual bool swipeGestureUpdate(const QSizeF &delta, quint32 time);
|
||||
virtual bool swipeGestureEnd(quint32 time);
|
||||
virtual bool swipeGestureCancelled(quint32 time);
|
||||
};
|
||||
|
||||
class InputDeviceHandler : public QObject
|
||||
|
|
|
@ -369,6 +369,44 @@ void Connection::processEvents()
|
|||
emit touchFrame(event->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
emit pinchGestureBegin(pe->fingerCount(), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
emit pinchGestureUpdate(pe->scale(), pe->angleDelta(), pe->delta(), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_END: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
if (pe->isCancelled()) {
|
||||
emit pinchGestureCancelled(pe->time(), pe->device());
|
||||
} else {
|
||||
emit pinchGestureEnd(pe->time(), pe->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
emit swipeGestureBegin(se->fingerCount(), se->time(), se->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
emit swipeGestureUpdate(se->delta(), se->time(), se->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_END: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
if (se->isCancelled()) {
|
||||
emit swipeGestureCancelled(se->time(), se->device());
|
||||
} else {
|
||||
emit swipeGestureEnd(se->time(), se->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// nothing
|
||||
break;
|
||||
|
|
|
@ -99,6 +99,14 @@ Q_SIGNALS:
|
|||
void hasTouchChanged(bool);
|
||||
void deviceAdded(KWin::LibInput::Device *);
|
||||
void deviceRemoved(KWin::LibInput::Device *);
|
||||
void swipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureEnd(quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureCancelled(quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureEnd(quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureCancelled(quint32 time, KWin::LibInput::Device *device);
|
||||
|
||||
void eventsRead();
|
||||
|
||||
|
|
|
@ -49,6 +49,14 @@ Event *Event::create(libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
return new TouchEvent(event, t);
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
||||
return new SwipeGestureEvent(event, t);
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
||||
return new PinchGestureEvent(event, t);
|
||||
default:
|
||||
return new Event(event, t);
|
||||
}
|
||||
|
@ -209,5 +217,58 @@ qint32 TouchEvent::id() const
|
|||
return libinput_event_touch_get_slot(m_touchEvent);
|
||||
}
|
||||
|
||||
GestureEvent::GestureEvent(libinput_event *event, libinput_event_type type)
|
||||
: Event(event, type)
|
||||
, m_gestureEvent(libinput_event_get_gesture_event(event))
|
||||
{
|
||||
}
|
||||
|
||||
GestureEvent::~GestureEvent() = default;
|
||||
|
||||
quint32 GestureEvent::time() const
|
||||
{
|
||||
return libinput_event_gesture_get_time(m_gestureEvent);
|
||||
}
|
||||
|
||||
int GestureEvent::fingerCount() const
|
||||
{
|
||||
return libinput_event_gesture_get_finger_count(m_gestureEvent);
|
||||
}
|
||||
|
||||
QSizeF GestureEvent::delta() const
|
||||
{
|
||||
return QSizeF(libinput_event_gesture_get_dx(m_gestureEvent),
|
||||
libinput_event_gesture_get_dy(m_gestureEvent));
|
||||
}
|
||||
|
||||
bool GestureEvent::isCancelled() const
|
||||
{
|
||||
return libinput_event_gesture_get_cancelled(m_gestureEvent) != 0;
|
||||
}
|
||||
|
||||
PinchGestureEvent::PinchGestureEvent(libinput_event *event, libinput_event_type type)
|
||||
: GestureEvent(event, type)
|
||||
{
|
||||
}
|
||||
|
||||
PinchGestureEvent::~PinchGestureEvent() = default;
|
||||
|
||||
qreal PinchGestureEvent::scale() const
|
||||
{
|
||||
return libinput_event_gesture_get_scale(m_gestureEvent);
|
||||
}
|
||||
|
||||
qreal PinchGestureEvent::angleDelta() const
|
||||
{
|
||||
return libinput_event_gesture_get_angle_delta(m_gestureEvent);
|
||||
}
|
||||
|
||||
SwipeGestureEvent::SwipeGestureEvent(libinput_event *event, libinput_event_type type)
|
||||
: GestureEvent(event, type)
|
||||
{
|
||||
}
|
||||
|
||||
SwipeGestureEvent::~SwipeGestureEvent() = default;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,47 @@ private:
|
|||
libinput_event_touch *m_touchEvent;
|
||||
};
|
||||
|
||||
class GestureEvent : public Event
|
||||
{
|
||||
public:
|
||||
virtual ~GestureEvent();
|
||||
|
||||
quint32 time() const;
|
||||
int fingerCount() const;
|
||||
|
||||
QSizeF delta() const;
|
||||
|
||||
bool isCancelled() const;
|
||||
|
||||
operator libinput_event_gesture*() {
|
||||
return m_gestureEvent;
|
||||
}
|
||||
operator libinput_event_gesture*() const {
|
||||
return m_gestureEvent;
|
||||
}
|
||||
|
||||
protected:
|
||||
GestureEvent(libinput_event *event, libinput_event_type type);
|
||||
libinput_event_gesture *m_gestureEvent;
|
||||
};
|
||||
|
||||
class PinchGestureEvent : public GestureEvent
|
||||
{
|
||||
public:
|
||||
PinchGestureEvent(libinput_event *event, libinput_event_type type);
|
||||
virtual ~PinchGestureEvent();
|
||||
|
||||
qreal scale() const;
|
||||
qreal angleDelta() const;
|
||||
};
|
||||
|
||||
class SwipeGestureEvent : public GestureEvent
|
||||
{
|
||||
public:
|
||||
SwipeGestureEvent(libinput_event *event, libinput_event_type type);
|
||||
virtual ~SwipeGestureEvent();
|
||||
};
|
||||
|
||||
inline
|
||||
libinput_event_type Event::type() const
|
||||
{
|
||||
|
|
|
@ -231,6 +231,126 @@ void PointerInputRedirection::processAxis(InputRedirection::PointerAxis axis, qr
|
|||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->swipeGestureBegin(fingerCount, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->swipeGestureUpdate(delta, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureEnd(quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->swipeGestureEnd(time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureCancelled(quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->swipeGestureCancelled(time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->pinchGestureBegin(fingerCount, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->pinchGestureUpdate(scale, angleDelta, delta, time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureEnd(quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->pinchGestureEnd(time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureCancelled(quint32 time, KWin::LibInput::Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &filters = m_input->filters();
|
||||
for (auto it = filters.begin(), end = filters.end(); it != end; it++) {
|
||||
if ((*it)->pinchGestureCancelled(time)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerInputRedirection::update()
|
||||
{
|
||||
if (!m_inited) {
|
||||
|
|
|
@ -86,6 +86,38 @@ public:
|
|||
* @internal
|
||||
*/
|
||||
void processAxis(InputRedirection::PointerAxis axis, qreal delta, uint32_t time, LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureEnd(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureCancelled(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureEnd(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureCancelled(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
|
||||
private:
|
||||
void updatePosition(const QPointF &pos);
|
||||
|
|
Loading…
Reference in a new issue