lid behavior watcher to lock session #115
@@ -3,7 +3,9 @@
|
|||||||
#include <QtDBus/QDBusConnection>
|
#include <QtDBus/QDBusConnection>
|
||||||
#include <QtDBus/QDBusMessage>
|
#include <QtDBus/QDBusMessage>
|
||||||
#include <QtDBus/QDBusReply>
|
#include <QtDBus/QDBusReply>
|
||||||
|
#include <QtDBus/QDBusServiceWatcher>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcLidWatcher, "ZShell.lidwatcher", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcLidWatcher, "ZShell.lidwatcher", QtInfoMsg)
|
||||||
|
|
||||||
@@ -15,32 +17,32 @@ static constexpr auto kLogin1Interface = "org.freedesktop.login1.Manager";
|
|||||||
static constexpr auto kDBusPropertiesInterface =
|
static constexpr auto kDBusPropertiesInterface =
|
||||||
"org.freedesktop.DBus.Properties";
|
"org.freedesktop.DBus.Properties";
|
||||||
|
|
||||||
LidWatcher::LidWatcher(QObject* parent) : QObject(parent), m_available(false) {
|
LidWatcher::LidWatcher(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_watcher(nullptr)
|
||||||
|
, m_pollTimer(nullptr)
|
||||||
|
, m_available(false)
|
||||||
|
{
|
||||||
QDBusConnection bus = QDBusConnection::systemBus();
|
QDBusConnection bus = QDBusConnection::systemBus();
|
||||||
m_available = bus.isConnected();
|
if (!bus.isConnected()) {
|
||||||
|
|
||||||
if (!m_available) {
|
|
||||||
qCWarning(lcLidWatcher) << "system bus unavailable";
|
qCWarning(lcLidWatcher) << "system bus unavailable";
|
||||||
emit availableChanged();
|
emit availableChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ok = bus.connect(
|
m_pollTimer = new QTimer(this);
|
||||||
|
m_pollTimer->setInterval(5000);
|
||||||
|
connect(m_pollTimer, &QTimer::timeout, this, &LidWatcher::queryLidState);
|
||||||
|
|
||||||
|
m_watcher = new QDBusServiceWatcher(
|
||||||
kLogin1Service,
|
kLogin1Service,
|
||||||
kLogin1Path,
|
bus,
|
||||||
kDBusPropertiesInterface,
|
QDBusServiceWatcher::WatchForRegistration,
|
||||||
"PropertiesChanged",
|
this);
|
||||||
|
AramJonghu marked this conversation as resolved
Outdated
|
|||||||
this,
|
connect(m_watcher, &QDBusServiceWatcher::serviceRegistered,
|
||||||
SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
|
this, &LidWatcher::tryConnect);
|
||||||
|
|
||||||
m_available = ok;
|
tryConnect();
|
||||||
emit availableChanged();
|
|
||||||
if (!m_available) {
|
|
||||||
qCWarning(lcLidWatcher) << "login1 properties signal unavailable";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryInitialState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LidWatcher::available() const {
|
bool LidWatcher::available() const {
|
||||||
@@ -51,7 +53,37 @@ LidWatcher::LidState LidWatcher::state() const {
|
|||||||
return m_state;
|
return m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LidWatcher::queryInitialState() {
|
void LidWatcher::tryConnect() {
|
||||||
|
QDBusConnection bus = QDBusConnection::systemBus();
|
||||||
|
|
||||||
|
const auto connected = bus.connect(
|
||||||
|
kLogin1Service,
|
||||||
|
kLogin1Path,
|
||||||
|
kDBusPropertiesInterface,
|
||||||
|
"PropertiesChanged",
|
||||||
|
this,
|
||||||
|
SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
|
||||||
|
|
||||||
|
queryLidState();
|
||||||
|
|
||||||
|
if (connected) {
|
||||||
|
m_pollTimer->stop();
|
||||||
|
qCInfo(lcLidWatcher) << "login1 PropertiesChanged connected";
|
||||||
|
} else {
|
||||||
|
qCWarning(lcLidWatcher)
|
||||||
|
<< "login1 PropertiesChanged unavailable, polling";
|
||||||
|
if (!m_pollTimer->isActive()) {
|
||||||
|
m_pollTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_available) {
|
||||||
|
m_available = true;
|
||||||
|
emit availableChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LidWatcher::queryLidState() {
|
||||||
auto msg = QDBusMessage::createMethodCall(kLogin1Service,
|
auto msg = QDBusMessage::createMethodCall(kLogin1Service,
|
||||||
kLogin1Path,
|
kLogin1Path,
|
||||||
kDBusPropertiesInterface,
|
kDBusPropertiesInterface,
|
||||||
@@ -63,8 +95,11 @@ void LidWatcher::queryInitialState() {
|
|||||||
<< "cannot query LidClosed:" << reply.error().message();
|
<< "cannot query LidClosed:" << reply.error().message();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_state = reply.value().toBool() ? Closed : Opened;
|
const auto newState = reply.value().toBool() ? Closed : Opened;
|
||||||
emit stateChanged();
|
if (m_state != newState) {
|
||||||
|
m_state = newState;
|
||||||
|
emit stateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LidWatcher::onPropertiesChanged(const QString& interface,
|
void LidWatcher::onPropertiesChanged(const QString& interface,
|
||||||
@@ -76,8 +111,11 @@ void LidWatcher::onPropertiesChanged(const QString& interface,
|
|||||||
if (!changed.contains("LidClosed")) {
|
if (!changed.contains("LidClosed")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_state = changed.value("LidClosed").toBool() ? Closed : Opened;
|
const auto newState = changed.value("LidClosed").toBool() ? Closed : Opened;
|
||||||
emit stateChanged();
|
if (m_state != newState) {
|
||||||
|
m_state = newState;
|
||||||
|
emit stateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ZShell
|
} // namespace ZShell
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
|
|
||||||
|
class QDBusServiceWatcher;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
namespace ZShell {
|
namespace ZShell {
|
||||||
|
|
||||||
class LidWatcher : public QObject {
|
class LidWatcher : public QObject {
|
||||||
@@ -26,16 +29,17 @@ class LidWatcher : public QObject {
|
|||||||
[[nodiscard]] LidState state() const;
|
[[nodiscard]] LidState state() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void queryInitialState();
|
void tryConnect();
|
||||||
|
void queryLidState();
|
||||||
bool m_available;
|
|
||||||
LidState m_state = Opened;
|
|
||||||
|
|
||||||
|
|
||||||
void onPropertiesChanged(const QString& interface,
|
void onPropertiesChanged(const QString& interface,
|
||||||
const QVariantMap& changed,
|
const QVariantMap& changed,
|
||||||
|
AramJonghu marked this conversation as resolved
Outdated
zach
commented
`extracted()` is declared but never implemented in the `.cpp` file.
|
|||||||
const QStringList& invalidated);
|
const QStringList& invalidated);
|
||||||
|
|
||||||
|
QDBusServiceWatcher* m_watcher;
|
||||||
|
QTimer* m_pollTimer;
|
||||||
|
bool m_available;
|
||||||
|
LidState m_state = Opened;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void availableChanged();
|
void availableChanged();
|
||||||
void stateChanged();
|
void stateChanged();
|
||||||
|
|||||||
Reference in New Issue
Block a user
Doesn't this trigger only when the system is about to suspend/hibernate? There should be a way to query the lid state directly.
Correct. And in retrospect, not every distro has defaults where the system suspends when laptop is on AC. The idea was that it should only trigger when the system suspends or hibernates to cover it more broadly for desktops (if wished). Could be a separate plugin or addition to current implementation if that is a wish separate from laptop lid behavior.