diff --git a/libinput/connection.cpp b/libinput/connection.cpp
index ca71e563f9..ac06616cd3 100644
--- a/libinput/connection.cpp
+++ b/libinput/connection.cpp
@@ -20,6 +20,7 @@ along with this program. If not, see .
#include "connection.h"
#include "context.h"
#include "events.h"
+#include "../logind.h"
#include
#include
@@ -85,6 +86,13 @@ void Connection::setup()
Q_ASSERT(!m_notifier);
m_notifier = new QSocketNotifier(m_input->fileDescriptor(), QSocketNotifier::Read, this);
connect(m_notifier, &QSocketNotifier::activated, this, &Connection::handleEvent);
+
+ LogindIntegration *logind = LogindIntegration::self();
+ connect(logind, &LogindIntegration::sessionActiveChanged, this,
+ [this](bool active) {
+ active ? m_input->resume() : m_input->suspend();
+ }
+ );
}
void Connection::handleEvent()
diff --git a/libinput/context.cpp b/libinput/context.cpp
index eda3ab66a2..137ef947a1 100644
--- a/libinput/context.cpp
+++ b/libinput/context.cpp
@@ -45,6 +45,7 @@ Udev::~Udev()
Context::Context(const Udev &udev)
: m_libinput(libinput_udev_create_context(&Context::s_interface, this, udev))
+ , m_suspended(false)
{
libinput_log_set_priority(m_libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
}
@@ -150,5 +151,23 @@ Event *Context::event()
return Event::create(libinput_get_event(m_libinput));
}
+void Context::suspend()
+{
+ if (m_suspended) {
+ return;
+ }
+ libinput_suspend(m_libinput);
+ m_suspended = true;
+}
+
+void Context::resume()
+{
+ if (!m_suspended) {
+ return;
+ }
+ libinput_resume(m_libinput);
+ m_suspended = false;
+}
+
}
}
diff --git a/libinput/context.h b/libinput/context.h
index d0c65f8c56..25b40470f2 100644
--- a/libinput/context.h
+++ b/libinput/context.h
@@ -62,6 +62,8 @@ public:
int fileDescriptor();
void dispatch();
+ void suspend();
+ void resume();
operator libinput*() {
return m_libinput;
@@ -84,6 +86,7 @@ private:
int openRestricted(const char *path, int flags);
void closeRestricted(int fd);
struct libinput *m_libinput;
+ bool m_suspended;
};
}
diff --git a/logind.cpp b/logind.cpp
index 731d912d00..2b9aaca913 100644
--- a/logind.cpp
+++ b/logind.cpp
@@ -37,6 +37,7 @@ const static QString s_login1Service = QStringLiteral("org.freedesktop.login1");
const static QString s_login1Path = QStringLiteral("/org/freedesktop/login1");
const static QString s_login1ManagerInterface = QStringLiteral("org.freedesktop.login1.Manager");
const static QString s_login1SessionInterface = QStringLiteral("org.freedesktop.login1.Session");
+const static QString s_dbusPropertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
LogindIntegration *LogindIntegration::s_self = nullptr;
@@ -56,6 +57,7 @@ LogindIntegration::LogindIntegration(const QDBusConnection &connection, QObject
this))
, m_connected(false)
, m_sessionControl(false)
+ , m_sessionActive(false)
{
connect(m_logindServiceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &LogindIntegration::logindServiceRegistered);
connect(m_logindServiceWatcher, &QDBusServiceWatcher::serviceUnregistered, this,
@@ -120,11 +122,53 @@ void LogindIntegration::logindServiceRegistered()
m_sessionPath = reply.value().path();
qDebug() << "Session path:" << m_sessionPath;
m_connected = true;
+ connectSessionPropertiesChanged();
+ getSessionActive();
+
emit connectedChanged();
}
);
}
+void LogindIntegration::connectSessionPropertiesChanged()
+{
+ m_bus.connect(s_login1Service,
+ m_sessionPath,
+ s_dbusPropertiesInterface,
+ QStringLiteral("PropertiesChanged"),
+ this,
+ SLOT(getSessionActive()));
+}
+
+void LogindIntegration::getSessionActive()
+{
+ if (!m_connected || m_sessionPath.isEmpty()) {
+ return;
+ }
+ QDBusMessage message = QDBusMessage::createMethodCall(s_login1Service,
+ m_sessionPath,
+ s_dbusPropertiesInterface,
+ QStringLiteral("Get"));
+ message.setArguments(QVariantList({s_login1SessionInterface, QStringLiteral("Active")}));
+ QDBusPendingReply reply = m_bus.asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, &QDBusPendingCallWatcher::finished, this,
+ [this](QDBusPendingCallWatcher *self) {
+ QDBusPendingReply reply = *self;
+ self->deleteLater();
+ if (!reply.isValid()) {
+ qDebug() << "Failed to get Active Property of logind session:" << reply.error().message();
+ return;
+ }
+ const bool active = reply.value().toBool();
+ if (m_sessionActive != active) {
+ m_sessionActive = active;
+ emit sessionActiveChanged(m_sessionActive);
+ }
+ }
+ );
+}
+
void LogindIntegration::takeControl()
{
if (!m_connected || m_sessionPath.isEmpty() || m_sessionControl) {
diff --git a/logind.h b/logind.h
index ccb318c264..bc6478af67 100644
--- a/logind.h
+++ b/logind.h
@@ -42,6 +42,9 @@ public:
bool hasSessionControl() const {
return m_sessionControl;
}
+ bool isActiveSession() const {
+ return m_sessionActive;
+ }
void takeControl();
void releaseControl();
@@ -52,6 +55,10 @@ public:
Q_SIGNALS:
void connectedChanged();
void hasSessionControlChanged(bool);
+ void sessionActiveChanged(bool);
+
+private Q_SLOTS:
+ void getSessionActive();
private:
friend class LogindTest;
@@ -63,11 +70,13 @@ private:
**/
explicit LogindIntegration(const QDBusConnection &connection, QObject *parent = nullptr);
void logindServiceRegistered();
+ void connectSessionPropertiesChanged();
QDBusConnection m_bus;
QDBusServiceWatcher *m_logindServiceWatcher;
bool m_connected;
QString m_sessionPath;
bool m_sessionControl;
+ bool m_sessionActive;
KWIN_SINGLETON(LogindIntegration)
};