Compare commits
2 Commits
deef85d10c
...
0d8f558f66
| Author | SHA1 | Date | |
|---|---|---|---|
|
0d8f558f66
|
|||
|
ed28d8b56a
|
@@ -29,6 +29,10 @@ Scope {
|
|||||||
Quickshell.execDetached(action);
|
Quickshell.execDetached(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LidWatcher {
|
||||||
|
onAboutToSleep: root.lock.lock.locked = true
|
||||||
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
model: Config.general.idle.timeouts
|
model: Config.general.idle.timeouts
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import qs.Components
|
|||||||
Scope {
|
Scope {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property var lid
|
|
||||||
property alias lock: lock
|
property alias lock: lock
|
||||||
property int seenOnce: 0
|
property int seenOnce: 0
|
||||||
|
|
||||||
@@ -22,13 +21,6 @@ Scope {
|
|||||||
onRequestLock: lock.locked = true
|
onRequestLock: lock.locked = true
|
||||||
onUnlock: lock.locked = false
|
onUnlock: lock.locked = false
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.lid
|
|
||||||
function onRequestLock(): void {
|
|
||||||
lock.locked = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LockSurface {
|
LockSurface {
|
||||||
id: lockSurface
|
id: lockSurface
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ qml_module(ZShell
|
|||||||
requests.hpp requests.cpp
|
requests.hpp requests.cpp
|
||||||
toaster.hpp toaster.cpp
|
toaster.hpp toaster.cpp
|
||||||
qalculator.hpp qalculator.cpp
|
qalculator.hpp qalculator.cpp
|
||||||
lidwatcher.hpp lidwatcher.cpp
|
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
Qt::Quick
|
Qt::Quick
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ qml_module(ZShell-internal
|
|||||||
sparklineitem.hpp sparklineitem.cpp
|
sparklineitem.hpp sparklineitem.cpp
|
||||||
arcgauge.hpp arcgauge.cpp
|
arcgauge.hpp arcgauge.cpp
|
||||||
wallpaperimage.hpp wallpaperimage.cpp
|
wallpaperimage.hpp wallpaperimage.cpp
|
||||||
|
lidwatcher.hpp lidwatcher.cpp
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
Qt::Quick
|
Qt::Quick
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#include "lidwatcher.hpp"
|
||||||
|
|
||||||
|
#include <QtDBus/qdbusconnection.h>
|
||||||
|
#include <QtDBus/qdbuserror.h>
|
||||||
|
#include <QtDBus/qdbusinterface.h>
|
||||||
|
#include <QtDBus/qdbusreply.h>
|
||||||
|
#include <qloggingcategory.h>
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcLidWatcher, "caelestia.internal.logindmanager", QtInfoMsg)
|
||||||
|
|
||||||
|
namespace ZShell::internal {
|
||||||
|
|
||||||
|
LidWatcher::LidWatcher(QObject* parent) : QObject(parent) {
|
||||||
|
auto bus = QDBusConnection::systemBus();
|
||||||
|
if (!bus.isConnected()) {
|
||||||
|
qCWarning(lcLidWatcher)
|
||||||
|
<< "Failed to connect to system bus:" << bus.lastError().message();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = bus.connect("org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
"PrepareForSleep",
|
||||||
|
this,
|
||||||
|
SLOT(handlePrepareForSleep(bool)));
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
qCWarning(lcLidWatcher)
|
||||||
|
<< "Failed to connect to PrepareForSleep signal:"
|
||||||
|
<< bus.lastError().message();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusInterface login1("org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
bus);
|
||||||
|
const QDBusReply<QDBusObjectPath> reply = login1.call("GetSession", "auto");
|
||||||
|
if (!reply.isValid()) {
|
||||||
|
qCWarning(lcLidWatcher) << "Failed to get session path";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto sessionPath = reply.value().path();
|
||||||
|
|
||||||
|
ok = bus.connect("org.freedesktop.login1",
|
||||||
|
sessionPath,
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
"Lock",
|
||||||
|
this,
|
||||||
|
SLOT(handleLockRequested()));
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
qCWarning(lcLidWatcher)
|
||||||
|
<< "Failed to connect to Lock signal:" << bus.lastError().message();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = bus.connect("org.freedesktop.login1",
|
||||||
|
sessionPath,
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
"Unlock",
|
||||||
|
this,
|
||||||
|
SLOT(handleUnlockRequested()));
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
qCWarning(lcLidWatcher) << "Failed to connect to Unlock signal:"
|
||||||
|
<< bus.lastError().message();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LidWatcher::handlePrepareForSleep(bool sleep) {
|
||||||
|
if (sleep) {
|
||||||
|
emit aboutToSleep();
|
||||||
|
} else {
|
||||||
|
emit resumed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LidWatcher::handleLockRequested() {
|
||||||
|
emit lockRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LidWatcher::handleUnlockRequested() {
|
||||||
|
emit unlockRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZShell::internal
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlintegration.h>
|
||||||
|
|
||||||
|
namespace ZShell::internal {
|
||||||
|
|
||||||
|
class LidWatcher : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LidWatcher(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void aboutToSleep();
|
||||||
|
void resumed();
|
||||||
|
void lockRequested();
|
||||||
|
void unlockRequested();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handlePrepareForSleep(bool sleep);
|
||||||
|
void handleLockRequested();
|
||||||
|
void handleUnlockRequested();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ZShell::internal
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
#include "lidwatcher.hpp"
|
|
||||||
|
|
||||||
#include <QtDBus/QDBusConnection>
|
|
||||||
#include <QtDBus/QDBusMessage>
|
|
||||||
#include <QtDBus/QDBusReply>
|
|
||||||
#include <QtDBus/QDBusServiceWatcher>
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcLidWatcher, "ZShell.lidwatcher", QtInfoMsg)
|
|
||||||
|
|
||||||
namespace ZShell {
|
|
||||||
|
|
||||||
static constexpr auto kLogin1Service = "org.freedesktop.login1";
|
|
||||||
static constexpr auto kLogin1Path = "/org/freedesktop/login1";
|
|
||||||
static constexpr auto kLogin1Interface = "org.freedesktop.login1.Manager";
|
|
||||||
static constexpr auto kDBusPropertiesInterface =
|
|
||||||
"org.freedesktop.DBus.Properties";
|
|
||||||
|
|
||||||
LidWatcher::LidWatcher(QObject* parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_watcher(nullptr)
|
|
||||||
, m_pollTimer(nullptr)
|
|
||||||
, m_available(false)
|
|
||||||
{
|
|
||||||
QDBusConnection bus = QDBusConnection::systemBus();
|
|
||||||
if (!bus.isConnected()) {
|
|
||||||
qCWarning(lcLidWatcher) << "system bus unavailable";
|
|
||||||
emit availableChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pollTimer = new QTimer(this);
|
|
||||||
m_pollTimer->setInterval(5000);
|
|
||||||
connect(m_pollTimer, &QTimer::timeout, this, &LidWatcher::queryLidState);
|
|
||||||
|
|
||||||
m_watcher = new QDBusServiceWatcher(
|
|
||||||
kLogin1Service,
|
|
||||||
bus,
|
|
||||||
QDBusServiceWatcher::WatchForRegistration,
|
|
||||||
this);
|
|
||||||
connect(m_watcher, &QDBusServiceWatcher::serviceRegistered,
|
|
||||||
this, &LidWatcher::tryConnect);
|
|
||||||
|
|
||||||
tryConnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LidWatcher::available() const {
|
|
||||||
return m_available;
|
|
||||||
}
|
|
||||||
|
|
||||||
LidWatcher::LidState LidWatcher::state() const {
|
|
||||||
return m_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LidWatcher::tryConnect() {
|
|
||||||
QDBusConnection bus = QDBusConnection::systemBus();
|
|
||||||
|
|
||||||
const auto connected = bus.connect(
|
|
||||||
QString(),
|
|
||||||
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,
|
|
||||||
kLogin1Path,
|
|
||||||
kDBusPropertiesInterface,
|
|
||||||
"Get");
|
|
||||||
msg << kLogin1Interface << "LidClosed";
|
|
||||||
const QDBusReply<QVariant> reply = QDBusConnection::systemBus().call(msg);
|
|
||||||
if (!reply.isValid()) {
|
|
||||||
qCWarning(lcLidWatcher)
|
|
||||||
<< "cannot query LidClosed:" << reply.error().message();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto newState = reply.value().toBool() ? Closed : Opened;
|
|
||||||
if (m_state != newState) {
|
|
||||||
m_state = newState;
|
|
||||||
emit stateChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LidWatcher::onPropertiesChanged(const QString& interface,
|
|
||||||
const QVariantMap& changed,
|
|
||||||
const QStringList& ) {
|
|
||||||
if (interface != kLogin1Interface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!changed.contains("LidClosed")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto newState = changed.value("LidClosed").toBool() ? Closed : Opened;
|
|
||||||
if (m_state != newState) {
|
|
||||||
m_state = newState;
|
|
||||||
emit stateChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZShell
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QVariantMap>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <qqmlintegration.h>
|
|
||||||
|
|
||||||
class QDBusServiceWatcher;
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace ZShell {
|
|
||||||
|
|
||||||
class LidWatcher : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
QML_SINGLETON
|
|
||||||
|
|
||||||
Q_PROPERTY(bool available READ available NOTIFY availableChanged)
|
|
||||||
Q_PROPERTY(LidState state READ state NOTIFY stateChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum LidState : std::uint8_t{ Opened, Closed };
|
|
||||||
Q_ENUM(LidState)
|
|
||||||
|
|
||||||
explicit LidWatcher(QObject* parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] bool available() const;
|
|
||||||
[[nodiscard]] LidState state() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void tryConnect();
|
|
||||||
void queryLidState();
|
|
||||||
|
|
||||||
QDBusServiceWatcher* m_watcher;
|
|
||||||
QTimer* m_pollTimer;
|
|
||||||
bool m_available;
|
|
||||||
LidState m_state = Opened;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onPropertiesChanged(const QString& interface,
|
|
||||||
const QVariantMap& changed,
|
|
||||||
const QStringList& invalidated);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void availableChanged();
|
|
||||||
void stateChanged();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZShell
|
|
||||||
@@ -35,8 +35,6 @@ ShellRoot {
|
|||||||
|
|
||||||
Lock {
|
Lock {
|
||||||
id: lock
|
id: lock
|
||||||
|
|
||||||
lid: lid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcuts {
|
Shortcuts {
|
||||||
@@ -49,16 +47,6 @@ ShellRoot {
|
|||||||
Polkit {
|
Polkit {
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: lid
|
|
||||||
|
|
||||||
activeAsync: Config.lock.lidWatch && Battery.isLaptop
|
|
||||||
|
|
||||||
component: LidService {
|
|
||||||
onRequestLock: lock.lock.requestLock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
activeAsync: root.laptop
|
activeAsync: root.laptop
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user