diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt
--- a/daemon/CMakeLists.txt
+++ b/daemon/CMakeLists.txt
@@ -59,6 +59,8 @@
actions/bundled/wirelesspowersaving.h PowerDevil::BundledActions::WirelessPowerSaving)
endif()
+qt5_add_dbus_interface(powerdevilcore_SRCS org.freedesktop.ScreenSaver.xml screenlocker_interface)
+
add_library(powerdevilcore SHARED ${powerdevilcore_SRCS} ${powerdevil_bundled_actions_SRCS})
set_target_properties(powerdevilcore PROPERTIES VERSION ${POWERDEVIL_CORE_VERSION_STRING} SOVERSION ${POWERDEVIL_CORE_VERSION_MAJOR})
diff --git a/daemon/org.freedesktop.ScreenSaver.xml b/daemon/org.freedesktop.ScreenSaver.xml
new file mode 100644
--- /dev/null
+++ b/daemon/org.freedesktop.ScreenSaver.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/daemon/powerdevilpolicyagent.h b/daemon/powerdevilpolicyagent.h
--- a/daemon/powerdevilpolicyagent.h
+++ b/daemon/powerdevilpolicyagent.h
@@ -34,6 +34,8 @@
class QDBusServiceWatcher;
class QDBusInterface;
+class OrgFreedesktopScreenSaverInterface;
+
#define SYSTEMD_LOGIN1_SERVICE "org.freedesktop.login1"
#define SYSTEMD_LOGIN1_PATH "/org/freedesktop/login1"
#define SYSTEMD_LOGIN1_MANAGER_IFACE "org.freedesktop.login1.Manager"
@@ -110,6 +112,14 @@
void addInhibitionTypeHelper(uint cookie, RequiredPolicies types);
+ // Screen locker integration
+ void onScreenLockerOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
+ QDBusServiceWatcher *m_screenLockerWatcher;
+
+ void onScreenLockerActiveChanged(bool active);
+ OrgFreedesktopScreenSaverInterface *m_screenLockerInterface = nullptr;
+ bool m_screenLockerActive = false;
+
// This function serves solely for fd.o connector
uint addInhibitionWithExplicitDBusService(uint types, const QString &appName,
const QString &reason, const QString &service);
diff --git a/daemon/powerdevilpolicyagent.cpp b/daemon/powerdevilpolicyagent.cpp
--- a/daemon/powerdevilpolicyagent.cpp
+++ b/daemon/powerdevilpolicyagent.cpp
@@ -1,6 +1,7 @@
/***************************************************************************
* Copyright (C) 2010 by Dario Freddi *
* Copyright (C) 2012 Lukáš Tinkl *
+ * Copyright (C) 2016 Kai Uwe Broulik *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -35,6 +36,8 @@
#include "powerdevilpolicyagent.h"
#include "powerdevil_debug.h"
+#include "screenlocker_interface.h"
+
struct NamedDBusObjectPath
{
QString name;
@@ -66,6 +69,8 @@
namespace PowerDevil
{
+static const QString SCREEN_LOCKER_SERVICE_NAME = QStringLiteral("org.freedesktop.ScreenSaver");
+
class PolicyAgentHelper
{
public:
@@ -89,6 +94,7 @@
PolicyAgent::PolicyAgent(QObject* parent)
: QObject(parent)
+ , m_screenLockerWatcher(new QDBusServiceWatcher(this))
, m_sdAvailable(false)
, m_systemdInhibitFd(-1)
, m_ckAvailable(false)
@@ -148,6 +154,29 @@
connect(m_busWatcher.data(), SIGNAL(serviceUnregistered(QString)),
this, SLOT(onServiceUnregistered(QString)));
+
+ // Setup the screen locker watcher and check whether the screen is currently locked
+ connect(m_screenLockerWatcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &PolicyAgent::onScreenLockerOwnerChanged);
+ m_screenLockerWatcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
+ m_screenLockerWatcher->addWatchedService(SCREEN_LOCKER_SERVICE_NAME);
+
+ // async variant of QDBusConnectionInterface::serviceOwner ...
+ auto msg = QDBusMessage::createMethodCall(
+ QStringLiteral("org.freedesktop.DBus"),
+ QStringLiteral("/"),
+ QStringLiteral("org.freedesktop.DBus"),
+ QStringLiteral("GetNameOwner")
+ );
+ msg.setArguments({SCREEN_LOCKER_SERVICE_NAME});
+
+ auto *watcher = new QDBusPendingCallWatcher(QDBusConnection::sessionBus().asyncCall(msg), this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply reply = *watcher;
+ if (!reply.isError()) {
+ onScreenLockerOwnerChanged(SCREEN_LOCKER_SERVICE_NAME, {}, reply.value());
+ }
+ watcher->deleteLater();
+ });
}
QString PolicyAgent::getNamedPathProperty(const QString &path, const QString &iface, const QString &prop) const
@@ -363,7 +392,8 @@
if (!m_typesToCookie[ChangeProfile].isEmpty()) {
retpolicies |= ChangeProfile;
}
- if (!m_typesToCookie[ChangeScreenSettings].isEmpty()) {
+ // when screen locker is active it makes no sense to keep the screen on
+ if (!m_screenLockerActive && !m_typesToCookie[ChangeScreenSettings].isEmpty()) {
retpolicies |= ChangeScreenSettings;
}
if (!m_typesToCookie[InterruptSession].isEmpty()) {
@@ -430,6 +460,46 @@
m_sessionIsBeingInterrupted = false;
}
+void PolicyAgent::onScreenLockerOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
+{
+ Q_UNUSED(oldOwner);
+ if (serviceName != SCREEN_LOCKER_SERVICE_NAME) {
+ return;
+ }
+
+ delete m_screenLockerInterface;
+ m_screenLockerInterface = nullptr;
+ m_screenLockerActive = false;
+
+ if (!newOwner.isEmpty()) {
+ m_screenLockerInterface = new OrgFreedesktopScreenSaverInterface(newOwner, QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus(), this);
+ connect(m_screenLockerInterface, &OrgFreedesktopScreenSaverInterface::ActiveChanged, this, &PolicyAgent::onScreenLockerActiveChanged);
+
+ auto *activeReplyWatcher = new QDBusPendingCallWatcher(m_screenLockerInterface->GetActive());
+ connect(activeReplyWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply reply = *watcher;
+ if (!reply.isError()) {
+ onScreenLockerActiveChanged(reply.value());
+ }
+ watcher->deleteLater();
+ });
+ }
+}
+
+void PolicyAgent::onScreenLockerActiveChanged(bool active)
+{
+ const auto oldPolicies = unavailablePolicies();
+
+ m_screenLockerActive = active;
+
+ const auto newPolicies = unavailablePolicies();
+
+ if (oldPolicies != newPolicies) {
+ qCDebug(POWERDEVIL) << "Screen saver active" << active << "- we have different inhibition policy now because of that";
+ Q_EMIT unavailablePoliciesChanged(newPolicies);
+ }
+}
+
uint PolicyAgent::addInhibitionWithExplicitDBusService(uint types, const QString &appName,
const QString &reason, const QString &service)
{