diff --git a/Daemons/LidService.qml b/Daemons/LidService.qml index d015f6e..0a8fe79 100644 --- a/Daemons/LidService.qml +++ b/Daemons/LidService.qml @@ -5,11 +5,12 @@ import QtQuick Scope { id: root - required property var lock + signal requestLock Connections { - function onLidClosing(): void { - root.lock.lock.locked = true; + function onStateChanged(): void { + if (LidWatcher.state === LidWatcher.Closed) + root.requestLock(); } target: LidWatcher diff --git a/Modules/Lock/Lock.qml b/Modules/Lock/Lock.qml index 9c6f8df..68d8a46 100644 --- a/Modules/Lock/Lock.qml +++ b/Modules/Lock/Lock.qml @@ -18,6 +18,9 @@ Scope { signal requestLock signal unlock + onRequestLock: lock.locked = true + onUnlock: lock.locked = false + LockSurface { id: lockSurface diff --git a/Plugins/ZShell/lidwatcher.cpp b/Plugins/ZShell/lidwatcher.cpp index 49386a2..f1f0c43 100644 --- a/Plugins/ZShell/lidwatcher.cpp +++ b/Plugins/ZShell/lidwatcher.cpp @@ -1,6 +1,8 @@ #include "lidwatcher.hpp" #include +#include +#include #include Q_LOGGING_CATEGORY(lcLidWatcher, "ZShell.lidwatcher", QtInfoMsg) @@ -10,11 +12,12 @@ 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 kPrepareForSleep = "PrepareForSleep"; +static constexpr auto kDBusPropertiesInterface = "org.freedesktop.DBus.Properties"; LidWatcher::LidWatcher(QObject* parent) : QObject(parent) - , m_available(false) { + , m_available(false) + , m_state(Opened) { QDBusConnection bus = QDBusConnection::systemBus(); m_available = bus.isConnected(); @@ -24,26 +27,48 @@ LidWatcher::LidWatcher(QObject* parent) return; } - const auto ok = bus.connect(kLogin1Service, kLogin1Path, kLogin1Interface, kPrepareForSleep, this, - SLOT(onPrepareForSleep(bool))); + const auto ok = bus.connect(kLogin1Service, kLogin1Path, kDBusPropertiesInterface, "PropertiesChanged", + this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList))); m_available = ok; emit availableChanged(); if (!m_available) { - qCWarning(lcLidWatcher) << "login1 lid signal unavailable"; + qCWarning(lcLidWatcher) << "login1 properties signal unavailable"; + return; } + + queryInitialState(); } bool LidWatcher::available() const { return m_available; } -void LidWatcher::onPrepareForSleep(bool goingDown) { - if (goingDown) { - emit lidClosing(); - } else { - emit lidOpened(); +LidWatcher::LidState LidWatcher::state() const { + return m_state; +} + +void LidWatcher::queryInitialState() { + const auto msg = QDBusMessage::createMethodCall( + kLogin1Service, kLogin1Path, + kDBusPropertiesInterface, "Get"); + msg << kLogin1Interface << "LidClosed"; + const QDBusReply reply = QDBusConnection::systemBus().call(msg); + if (!reply.isValid()) { + qCWarning(lcLidWatcher) << "cannot query LidClosed:" << reply.error().message(); + return; } + m_state = reply.value().toBool() ? Closed : Opened; + emit stateChanged(); +} + +void LidWatcher::onPropertiesChanged(const QString& interface, const QVariantMap& changed, const QStringList& /*invalidated*/) { + if (interface != kLogin1Interface) + return; + if (!changed.contains("LidClosed")) + return; + m_state = changed.value("LidClosed").toBool() ? Closed : Opened; + emit stateChanged(); } } // namespace ZShell diff --git a/Plugins/ZShell/lidwatcher.hpp b/Plugins/ZShell/lidwatcher.hpp index c2e1d08..7486f6a 100644 --- a/Plugins/ZShell/lidwatcher.hpp +++ b/Plugins/ZShell/lidwatcher.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include namespace ZShell { @@ -11,22 +13,32 @@ class LidWatcher : public QObject { QML_SINGLETON Q_PROPERTY(bool available READ available NOTIFY availableChanged) + Q_PROPERTY(LidState state READ state NOTIFY stateChanged) public: + enum LidState { + Opened, + Closed + }; + Q_ENUM(LidState) + explicit LidWatcher(QObject* parent = nullptr); [[nodiscard]] bool available() const; + [[nodiscard]] LidState state() const; + +private: + void queryInitialState(); + + bool m_available; + LidState m_state = Opened; private Q_SLOTS: - void onPrepareForSleep(bool goingDown); + void onPropertiesChanged(const QString& interface, const QVariantMap& changed, const QStringList& invalidated); Q_SIGNALS: void availableChanged(); - void lidClosing(); - void lidOpened(); - -private: - bool m_available; + void stateChanged(); }; } // namespace ZShell diff --git a/scripts/SettingsIndex.mjs b/scripts/SettingsIndex.mjs index 902467b..9d2c870 100644 --- a/scripts/SettingsIndex.mjs +++ b/scripts/SettingsIndex.mjs @@ -331,7 +331,7 @@ export const settingsIndex = [ category: "lockscreen", categoryName: "Lockscreen", section: "Lockscreen", - keywords: ["lid", "lcck", "watch", "session", "laptop"], + keywords: ["lid", "lock", "watch", "session", "laptop"], }, { name: "Blur amount", diff --git a/shell.qml b/shell.qml index 39c550a..3889720 100644 --- a/shell.qml +++ b/shell.qml @@ -47,12 +47,12 @@ ShellRoot { Polkit { } - LazyLoader { - activeAsync: Config.lock.lidWatch && Battery.isLaptop - component: LidService { - lock: lock - } - } + LazyLoader { + activeAsync: Config.lock.lidWatch && Battery.isLaptop + component: LidService { + onRequestLock: lock.requestLock() + } + } LazyLoader { activeAsync: root.laptop