diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -483,6 +483,7 @@ libinput/events.cpp libinput/libinput_logging.cpp udev.cpp + touch_hide_cursor_spy.cpp ) include(ECMQtDeclareLoggingCategory) diff --git a/autotests/integration/touch_input_test.cpp b/autotests/integration/touch_input_test.cpp --- a/autotests/integration/touch_input_test.cpp +++ b/autotests/integration/touch_input_test.cpp @@ -45,6 +45,7 @@ void initTestCase(); void init(); void cleanup(); + void testTouchHidesCursor(); void testMultipleTouchPoints_data(); void testMultipleTouchPoints(); void testCancel(); @@ -128,6 +129,30 @@ return c; } +void TouchInputTest::testTouchHidesCursor() +{ + QCOMPARE(kwinApp()->platform()->isCursorHidden(), false); + quint32 timestamp = 1; + kwinApp()->platform()->touchDown(1, QPointF(125, 125), timestamp++); + QCOMPARE(kwinApp()->platform()->isCursorHidden(), true); + kwinApp()->platform()->touchDown(2, QPointF(130, 125), timestamp++); + kwinApp()->platform()->touchUp(2, timestamp++); + kwinApp()->platform()->touchUp(1, timestamp++); + + // now a mouse event should show the cursor again + kwinApp()->platform()->pointerMotion(QPointF(0, 0), timestamp++); + QCOMPARE(kwinApp()->platform()->isCursorHidden(), false); + + // touch should hide again + kwinApp()->platform()->touchDown(1, QPointF(125, 125), timestamp++); + kwinApp()->platform()->touchUp(1, timestamp++); + QCOMPARE(kwinApp()->platform()->isCursorHidden(), true); + + // wheel should also show + kwinApp()->platform()->pointerAxisVertical(1.0, timestamp++); + QCOMPARE(kwinApp()->platform()->isCursorHidden(), false); +} + void TouchInputTest::testMultipleTouchPoints_data() { QTest::addColumn("decorated"); diff --git a/input.cpp b/input.cpp --- a/input.cpp +++ b/input.cpp @@ -23,6 +23,7 @@ #include "keyboard_input.h" #include "pointer_input.h" #include "touch_input.h" +#include "touch_hide_cursor_spy.h" #include "client.h" #include "effects.h" #include "gestures.h" @@ -1656,6 +1657,7 @@ installInputEventFilter(new VirtualTerminalFilter); } if (waylandServer()) { + installInputEventSpy(new TouchHideCursorSpy); installInputEventFilter(new TerminateServerFilter); installInputEventFilter(new DragAndDropInputFilter); installInputEventFilter(new LockScreenFilter); diff --git a/touch_hide_cursor_spy.h b/touch_hide_cursor_spy.h new file mode 100644 --- /dev/null +++ b/touch_hide_cursor_spy.h @@ -0,0 +1,21 @@ +#pragma once +#include "input_event_spy.h" + +namespace KWin +{ + +class TouchHideCursorSpy : public InputEventSpy +{ +public: + void pointerEvent(KWin::MouseEvent *event) override; + void wheelEvent(KWin::WheelEvent *event) override; + void touchDown(quint32 id, const QPointF &pos, quint32 time) override; + +private: + void showCursor(); + void hideCursor(); + + bool m_cursorHidden = false; +}; + +} diff --git a/touch_hide_cursor_spy.cpp b/touch_hide_cursor_spy.cpp new file mode 100644 --- /dev/null +++ b/touch_hide_cursor_spy.cpp @@ -0,0 +1,46 @@ +#include "touch_hide_cursor_spy.h" +#include "main.h" +#include "platform.h" + +namespace KWin +{ + +void TouchHideCursorSpy::pointerEvent(MouseEvent *event) +{ + Q_UNUSED(event) + showCursor(); +} + +void TouchHideCursorSpy::wheelEvent(KWin::WheelEvent *event) +{ + Q_UNUSED(event) + showCursor(); +} + +void TouchHideCursorSpy::touchDown(quint32 id, const QPointF &pos, quint32 time) +{ + Q_UNUSED(id) + Q_UNUSED(pos) + Q_UNUSED(time) + hideCursor(); +} + +void TouchHideCursorSpy::showCursor() +{ + if (!m_cursorHidden) { + return; + } + m_cursorHidden = false; + kwinApp()->platform()->showCursor(); +} + +void TouchHideCursorSpy::hideCursor() +{ + if (m_cursorHidden) { + return; + } + m_cursorHidden = true; + kwinApp()->platform()->hideCursor(); +} + +}