diff --git a/autotests/libinput/input_event_test.cpp b/autotests/libinput/input_event_test.cpp
index f588016f9d..c9373aa3c2 100644
--- a/autotests/libinput/input_event_test.cpp
+++ b/autotests/libinput/input_event_test.cpp
@@ -23,6 +23,8 @@ along with this program. If not, see .
#include
+Q_DECLARE_METATYPE(KWin::SwitchEvent::State);
+
using namespace KWin;
using namespace KWin::LibInput;
@@ -36,6 +38,8 @@ private Q_SLOTS:
void testInitKeyEvent();
void testInitWheelEvent_data();
void testInitWheelEvent();
+ void testInitSwitchEvent_data();
+ void testInitSwitchEvent();
};
void InputEventsTest::testInitMouseEvent_data()
@@ -149,5 +153,32 @@ void InputEventsTest::testInitWheelEvent()
}
+void InputEventsTest::testInitSwitchEvent_data()
+{
+ QTest::addColumn("state");
+ QTest::addColumn("timestamp");
+ QTest::addColumn("micro");
+
+ QTest::newRow("on") << SwitchEvent::State::On << 23u << quint64{23456790};
+ QTest::newRow("off") << SwitchEvent::State::Off << 456892u << quint64{45689235987};
+}
+
+void InputEventsTest::testInitSwitchEvent()
+{
+ // this test verifies that a SwitchEvent is constructed correctly
+ libinput_device device;
+ Device d(&device);
+
+ QFETCH(SwitchEvent::State, state);
+ QFETCH(quint32, timestamp);
+ QFETCH(quint64, micro);
+ SwitchEvent event(state, timestamp, micro, &d);
+
+ QCOMPARE(event.state(), state);
+ QCOMPARE(event.timestamp(), ulong(timestamp));
+ QCOMPARE(event.timestampMicroseconds(), micro);
+ QCOMPARE(event.device(), &d);
+}
+
QTEST_GUILESS_MAIN(InputEventsTest)
#include "input_event_test.moc"
diff --git a/debug_console.cpp b/debug_console.cpp
index bbc8c5a9c8..44aed0f9f0 100644
--- a/debug_console.cpp
+++ b/debug_console.cpp
@@ -459,6 +459,43 @@ void DebugConsoleFilter::swipeGestureCancelled(quint32 time)
m_textEdit->ensureCursorVisible();
}
+void DebugConsoleFilter::switchEvent(SwitchEvent *event)
+{
+ QString text = s_hr;
+ text.append(s_tableStart);
+ text.append(tableHeaderRow(i18nc("A hardware switch (e.g. notebook lid) got toggled", "Switch toggled")));
+ text.append(timestampRow(event->timestamp()));
+ if (event->timestampMicroseconds() != 0) {
+ text.append(timestampRowUsec(event->timestampMicroseconds()));
+ }
+#if HAVE_INPUT
+ text.append(deviceRow(event->device()));
+ QString switchName;
+ if (event->device()->isLidSwitch()) {
+ switchName = i18nc("Name of a hardware switch", "Notebook lid");
+ } else if (event->device()->isTabletModeSwitch()) {
+ switchName = i18nc("Name of a hardware switch", "Tablet mode");
+ }
+ text.append(tableRow(i18nc("A hardware switch", "Switch"), switchName));
+#endif
+ QString switchState;
+ switch (event->state()) {
+ case SwitchEvent::State::Off:
+ switchState = i18nc("The hardware switch got turned off", "Off");
+ break;
+ case SwitchEvent::State::On:
+ switchState = i18nc("The hardware switch got turned on", "On");
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ text.append(tableRow(i18nc("State of a hardware switch (on/off)", "State"), switchState));
+ text.append(s_tableEnd);
+
+ m_textEdit->insertHtml(text);
+ m_textEdit->ensureCursorVisible();
+}
+
DebugConsole::DebugConsole()
: QWidget()
, m_ui(new Ui::DebugConsole)
diff --git a/debug_console.h b/debug_console.h
index e5eeb09f1a..27503d3395 100644
--- a/debug_console.h
+++ b/debug_console.h
@@ -150,6 +150,8 @@ public:
void swipeGestureEnd(quint32 time) override;
void swipeGestureCancelled(quint32 time) override;
+ void switchEvent(SwitchEvent *event) override;
+
private:
QTextEdit *m_textEdit;
};
diff --git a/input.cpp b/input.cpp
index 4778390e99..cd105ecf1e 100644
--- a/input.cpp
+++ b/input.cpp
@@ -167,6 +167,12 @@ bool InputEventFilter::swipeGestureCancelled(quint32 time)
return false;
}
+bool InputEventFilter::switchEvent(SwitchEvent *event)
+{
+ Q_UNUSED(event)
+ return false;
+}
+
void InputEventFilter::passToWaylandServer(QKeyEvent *event)
{
Q_ASSERT(waylandServer());
@@ -1766,6 +1772,15 @@ void InputRedirection::setupLibInput()
connect(conn, &LibInput::Connection::touchMotion, m_touch, &TouchInputRedirection::processMotion);
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);
+ processSpies(std::bind(&InputEventSpy::switchEvent, std::placeholders::_1, &event));
+ processFilters(std::bind(&InputEventFilter::switchEvent, std::placeholders::_1, &event));
+ };
+ connect(conn, &LibInput::Connection::switchToggledOn, this,
+ std::bind(handleSwitchEvent, SwitchEvent::State::On, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ connect(conn, &LibInput::Connection::switchToggledOff, this,
+ std::bind(handleSwitchEvent, SwitchEvent::State::Off, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
if (screens()) {
setupLibInputWithScreens();
} else {
diff --git a/input.h b/input.h
index 9aa8047219..da1ad0028c 100644
--- a/input.h
+++ b/input.h
@@ -47,6 +47,7 @@ class PointerConstraintsFilter;
class PointerInputRedirection;
class TouchInputRedirection;
class WindowSelectorFilter;
+class SwitchEvent;
namespace Decoration
{
@@ -360,6 +361,8 @@ public:
virtual bool swipeGestureEnd(quint32 time);
virtual bool swipeGestureCancelled(quint32 time);
+ virtual bool switchEvent(SwitchEvent *event);
+
protected:
void passToWaylandServer(QKeyEvent *event);
};
diff --git a/input_event.cpp b/input_event.cpp
index 8de4284597..b8a2d7c97c 100644
--- a/input_event.cpp
+++ b/input_event.cpp
@@ -51,4 +51,13 @@ KeyEvent::KeyEvent(QEvent::Type type, Qt::Key key, Qt::KeyboardModifiers modifie
setTimestamp(timestamp);
}
+SwitchEvent::SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, LibInput::Device* device)
+ : QInputEvent(QEvent::User)
+ , m_state(state)
+ , m_timestampMicroseconds(timestampMicroseconds)
+ , m_device(device)
+{
+ setTimestamp(timestamp);
+}
+
}
diff --git a/input_event.h b/input_event.h
index 548fcfd7f2..7854a10885 100644
--- a/input_event.h
+++ b/input_event.h
@@ -124,6 +124,33 @@ private:
Qt::KeyboardModifiers m_modifiersRelevantForShortcuts = Qt::KeyboardModifiers();
};
+class SwitchEvent : public QInputEvent
+{
+public:
+ enum class State {
+ Off,
+ On
+ };
+ explicit SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, LibInput::Device *device);
+
+ State state() const {
+ return m_state;
+ }
+
+ quint64 timestampMicroseconds() const {
+ return m_timestampMicroseconds;
+ }
+
+ LibInput::Device *device() const {
+ return m_device;
+ }
+
+private:
+ State m_state;
+ quint64 m_timestampMicroseconds;
+ LibInput::Device *m_device;
+};
+
}
#endif
diff --git a/input_event_spy.cpp b/input_event_spy.cpp
index a7538ab3b2..bb139c0574 100644
--- a/input_event_spy.cpp
+++ b/input_event_spy.cpp
@@ -116,4 +116,9 @@ void InputEventSpy::swipeGestureCancelled(quint32 time)
Q_UNUSED(time)
}
+void InputEventSpy::switchEvent(SwitchEvent *event)
+{
+ Q_UNUSED(event)
+}
+
}
diff --git a/input_event_spy.h b/input_event_spy.h
index 843e148ffa..32ba36ba32 100644
--- a/input_event_spy.h
+++ b/input_event_spy.h
@@ -31,6 +31,7 @@ namespace KWin
class KeyEvent;
class MouseEvent;
class WheelEvent;
+class SwitchEvent;
/**
@@ -81,6 +82,8 @@ public:
virtual void swipeGestureEnd(quint32 time);
virtual void swipeGestureCancelled(quint32 time);
+ virtual void switchEvent(SwitchEvent *event);
+
};