Suspend/Resume libinput when logind session Active changes
LogindIntegration starts monitoring the Active property on the session and emits a signal when the state changes. The LibInput::Connection connects to this signal during the setup and uses it to suspend/resume the libinput context.
This commit is contained in:
parent
a918591fef
commit
6a032e78b7
5 changed files with 83 additions and 0 deletions
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "connection.h"
|
||||
#include "context.h"
|
||||
#include "events.h"
|
||||
#include "../logind.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSocketNotifier>
|
||||
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
44
logind.cpp
44
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<QVariant> reply = m_bus.asyncCall(message);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this,
|
||||
[this](QDBusPendingCallWatcher *self) {
|
||||
QDBusPendingReply<QVariant> 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) {
|
||||
|
|
9
logind.h
9
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)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue