diff --git a/libinput/connection.cpp b/libinput/connection.cpp
index 3b29c4a049..93bf746c10 100644
--- a/libinput/connection.cpp
+++ b/libinput/connection.cpp
@@ -26,7 +26,11 @@ along with this program. If not, see .
#include "libinput_logging.h"
#include
+#include
+#include
+#include
+#include
#include
#include
#include
@@ -83,6 +87,8 @@ Connection *Connection::create(QObject *parent)
return s_self;
}
+static const QString s_touchpadComponent = QStringLiteral("kcm_touchpad");
+
Connection::Connection(Context *input, QObject *parent)
: QObject(parent)
, m_input(input)
@@ -90,6 +96,47 @@ Connection::Connection(Context *input, QObject *parent)
, m_mutex(QMutex::Recursive)
{
Q_ASSERT(m_input);
+
+ // steal touchpad shortcuts
+ QAction *touchpadToggleAction = new QAction(this);
+ QAction *touchpadOnAction = new QAction(this);
+ QAction *touchpadOffAction = new QAction(this);
+
+ touchpadToggleAction->setObjectName(QStringLiteral("Toggle Touchpad"));
+ touchpadToggleAction->setProperty("componentName", s_touchpadComponent);
+ touchpadOnAction->setObjectName(QStringLiteral("Enable Touchpad"));
+ touchpadOnAction->setProperty("componentName", s_touchpadComponent);
+ touchpadOffAction->setObjectName(QStringLiteral("Disable Touchpad"));
+ touchpadOffAction->setProperty("componentName", s_touchpadComponent);
+ KGlobalAccel::self()->setDefaultShortcut(touchpadToggleAction, QList{Qt::Key_TouchpadToggle});
+ KGlobalAccel::self()->setShortcut(touchpadToggleAction, QList{Qt::Key_TouchpadToggle});
+ KGlobalAccel::self()->setDefaultShortcut(touchpadOnAction, QList{Qt::Key_TouchpadOn});
+ KGlobalAccel::self()->setShortcut(touchpadOnAction, QList{Qt::Key_TouchpadOn});
+ KGlobalAccel::self()->setDefaultShortcut(touchpadOffAction, QList{Qt::Key_TouchpadOff});
+ KGlobalAccel::self()->setShortcut(touchpadOffAction, QList{Qt::Key_TouchpadOff});
+#ifndef KWIN_BUILD_TESTING
+ InputRedirection::self()->registerShortcut(Qt::Key_TouchpadToggle, touchpadToggleAction);
+ InputRedirection::self()->registerShortcut(Qt::Key_TouchpadOn, touchpadOnAction);
+ InputRedirection::self()->registerShortcut(Qt::Key_TouchpadOff, touchpadOffAction);
+#endif
+ connect(touchpadToggleAction, &QAction::triggered, this, &Connection::toggleTouchpads);
+ connect(touchpadOnAction, &QAction::triggered, this,
+ [this] {
+ if (m_touchpadsEnabled) {
+ return;
+ }
+ toggleTouchpads();
+ }
+ );
+ connect(touchpadOffAction, &QAction::triggered, this,
+ [this] {
+ if (!m_touchpadsEnabled) {
+ return;
+ }
+ toggleTouchpads();
+ }
+ );
+
// need to connect to KGlobalSettings as the mouse KCM does not emit a dedicated signal
QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KGlobalSettings"), QStringLiteral("org.kde.KGlobalSettings"),
QStringLiteral("notifyChange"), this, SLOT(slotKGlobalSettingsNotifyChange(int,int)));
@@ -371,5 +418,41 @@ void Connection::slotKGlobalSettingsNotifyChange(int type, int arg)
}
}
+void Connection::toggleTouchpads()
+{
+ bool changed = false;
+ m_touchpadsEnabled = !m_touchpadsEnabled;
+ for (auto it = m_devices.constBegin(); it != m_devices.constEnd(); ++it) {
+ auto device = *it;
+ if (!device->isPointer()) {
+ continue;
+ }
+ if (device->isKeyboard() || device->isTouch() || device->isTabletPad() || device->isTabletTool()) {
+ // ignore all combined devices. E.g. a touchpad on a keyboard we don't want to toggle
+ // as that would result in the keyboard going off as well
+ continue;
+ }
+ // is this a touch pad? We don't really know, let's do some assumptions
+ if (device->tapFingerCount() > 0 || device->supportsDisableWhileTyping() || device->supportsDisableEventsOnExternalMouse()) {
+ const bool old = device->isEnabled();
+ device->setEnabled(m_touchpadsEnabled);
+ if (old != device->isEnabled()) {
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ // send OSD message
+ QDBusMessage msg = QDBusMessage::createMethodCall(
+ QStringLiteral("org.kde.plasmashell"),
+ QStringLiteral("/org/kde/osdService"),
+ QStringLiteral("org.kde.osdService"),
+ QStringLiteral("touchpadEnabledChanged")
+ );
+ msg.setArguments({m_touchpadsEnabled});
+ QDBusConnection::sessionBus().asyncCall(msg);
+ }
+}
+
}
}
diff --git a/libinput/connection.h b/libinput/connection.h
index 6dd420c501..1a0921c582 100644
--- a/libinput/connection.h
+++ b/libinput/connection.h
@@ -73,6 +73,8 @@ public:
void processEvents();
+ void toggleTouchpads();
+
QVector devices() const {
return m_devices;
}
@@ -118,6 +120,7 @@ private:
bool wasSuspended = false;
QVector m_devices;
KSharedConfigPtr m_config;
+ bool m_touchpadsEnabled = true;
KWIN_SINGLETON(Connection)
static QThread *s_thread;
diff --git a/libinput/device.cpp b/libinput/device.cpp
index ffc086eecc..f6e6236163 100644
--- a/libinput/device.cpp
+++ b/libinput/device.cpp
@@ -82,6 +82,7 @@ Device::Device(libinput_device *device, QObject *parent)
, m_supportsDisableEventsOnExternalMouse(libinput_device_config_send_events_get_modes(m_device) & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
, m_leftHanded(m_supportsLeftHanded ? libinput_device_config_left_handed_get(m_device) : false)
, m_pointerAcceleration(libinput_device_config_accel_get_speed(m_device))
+ , m_enabled(m_supportsDisableEvents ? libinput_device_config_send_events_get_mode(m_device) == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : true)
{
libinput_device_ref(m_device);
@@ -153,5 +154,18 @@ void Device::setPointerAcceleration(qreal acceleration)
}
}
+void Device::setEnabled(bool enabled)
+{
+ if (!m_supportsDisableEvents) {
+ return;
+ }
+ if (libinput_device_config_send_events_set_mode(m_device, enabled ? LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : LIBINPUT_CONFIG_SEND_EVENTS_DISABLED) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ emit enabledChanged();
+ }
+ }
+}
+
}
}
diff --git a/libinput/device.h b/libinput/device.h
index 1e7830ff0a..1bea2a8de0 100644
--- a/libinput/device.h
+++ b/libinput/device.h
@@ -57,6 +57,7 @@ class Device : public QObject
Q_PROPERTY(bool supportsDisableEventsOnExternalMouse READ supportsDisableEventsOnExternalMouse CONSTANT)
Q_PROPERTY(bool leftHanded READ isLeftHanded WRITE setLeftHanded NOTIFY leftHandedChanged)
Q_PROPERTY(qreal pointerAcceleration READ pointerAcceleration WRITE setPointerAcceleration NOTIFY pointerAccelerationChanged)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
public:
explicit Device(libinput_device *device, QObject *parent = nullptr);
virtual ~Device();
@@ -145,6 +146,11 @@ public:
**/
void setPointerAcceleration(qreal acceleration);
+ bool isEnabled() const {
+ return m_enabled;
+ }
+ void setEnabled(bool enabled);
+
libinput_device *device() const {
return m_device;
}
@@ -152,6 +158,7 @@ public:
Q_SIGNALS:
void leftHandedChanged();
void pointerAccelerationChanged();
+ void enabledChanged();
private:
libinput_device *m_device;
@@ -179,6 +186,7 @@ private:
bool m_supportsDisableEventsOnExternalMouse;
bool m_leftHanded;
qreal m_pointerAcceleration;
+ bool m_enabled;
};
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ae094588e3..353514f9cb 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -30,5 +30,6 @@ if (HAVE_INPUT)
${KWIN_SOURCE_DIR}/udev.cpp
)
add_executable(libinputtest ${libinputtest_SRCS})
- target_link_libraries(libinputtest Qt5::Core Qt5::DBus Libinput::Libinput ${UDEV_LIBS} KF5::ConfigCore KF5::WindowSystem)
+ add_definitions(-DKWIN_BUILD_TESTING)
+ target_link_libraries(libinputtest Qt5::Core Qt5::DBus Libinput::Libinput ${UDEV_LIBS} KF5::ConfigCore KF5::GlobalAccel KF5::WindowSystem)
endif()