File indexing completed on 2024-05-12 04:19:46
0001 /* 0002 Gwenview: an image viewer 0003 Copyright 2013 Martin Gräßlin <mgraesslin@kde.org> 0004 Copyright 2018 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "lockscreenwatcher.h" 0022 0023 // lib 0024 #include <screensaverdbusinterface.h> 0025 // Qt 0026 #include <QDBusServiceWatcher> 0027 #include <QFutureWatcher> 0028 #include <QtConcurrentRun> 0029 0030 namespace Gwenview 0031 { 0032 using DBusBoolReplyWatcher = QFutureWatcher<QDBusReply<bool>>; 0033 using DBusStringReplyWatcher = QFutureWatcher<QDBusReply<QString>>; 0034 0035 inline QString screenSaverServiceName() 0036 { 0037 return QStringLiteral("org.freedesktop.ScreenSaver"); 0038 } 0039 0040 LockScreenWatcher::LockScreenWatcher(QObject *parent) 0041 : QObject(parent) 0042 { 0043 auto screenLockServiceWatcher = new QDBusServiceWatcher(this); 0044 connect(screenLockServiceWatcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &LockScreenWatcher::onScreenSaverServiceOwnerChanged); 0045 screenLockServiceWatcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange); 0046 screenLockServiceWatcher->addWatchedService(screenSaverServiceName()); 0047 0048 if (QDBusConnection::sessionBus().interface()) { 0049 auto watcher = new DBusBoolReplyWatcher(this); 0050 connect(watcher, &DBusBoolReplyWatcher::finished, this, &LockScreenWatcher::onServiceRegisteredQueried); 0051 connect(watcher, &DBusBoolReplyWatcher::canceled, watcher, &DBusBoolReplyWatcher::deleteLater); 0052 0053 watcher->setFuture( 0054 QtConcurrent::run(&QDBusConnectionInterface::isServiceRegistered, QDBusConnection::sessionBus().interface(), screenSaverServiceName())); 0055 } 0056 } 0057 0058 LockScreenWatcher::~LockScreenWatcher() = default; 0059 0060 bool LockScreenWatcher::isLocked() const 0061 { 0062 return mLocked; 0063 } 0064 0065 void LockScreenWatcher::onScreenSaverServiceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) 0066 { 0067 Q_UNUSED(oldOwner) 0068 0069 if (serviceName != screenSaverServiceName()) { 0070 return; 0071 } 0072 0073 delete mScreenSaverInterface; 0074 mScreenSaverInterface = nullptr; 0075 0076 if (!newOwner.isEmpty()) { 0077 mScreenSaverInterface = new OrgFreedesktopScreenSaverInterface(newOwner, QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus(), this); 0078 connect(mScreenSaverInterface, &OrgFreedesktopScreenSaverInterface::ActiveChanged, this, &LockScreenWatcher::onScreenSaverActiveChanged); 0079 0080 auto watcher = new QDBusPendingCallWatcher(mScreenSaverInterface->GetActive(), this); 0081 connect(watcher, &QDBusPendingCallWatcher::finished, this, &LockScreenWatcher::onActiveQueried); 0082 } else { 0083 if (mLocked) { 0084 // reset 0085 mLocked = false; 0086 Q_EMIT isLockedChanged(mLocked); 0087 } 0088 } 0089 } 0090 0091 void LockScreenWatcher::onServiceRegisteredQueried() 0092 { 0093 auto watcher = dynamic_cast<DBusBoolReplyWatcher *>(sender()); 0094 if (!watcher) { 0095 return; 0096 } 0097 0098 const QDBusReply<bool> &reply = watcher->result(); 0099 0100 if (reply.isValid() && reply.value()) { 0101 auto ownerWatcher = new DBusStringReplyWatcher(this); 0102 connect(ownerWatcher, &DBusStringReplyWatcher::finished, this, &LockScreenWatcher::onServiceOwnerQueried); 0103 connect(ownerWatcher, &DBusStringReplyWatcher::canceled, ownerWatcher, &DBusStringReplyWatcher::deleteLater); 0104 ownerWatcher->setFuture( 0105 QtConcurrent::run(&QDBusConnectionInterface::serviceOwner, QDBusConnection::sessionBus().interface(), screenSaverServiceName())); 0106 } 0107 0108 watcher->deleteLater(); 0109 } 0110 0111 void LockScreenWatcher::onServiceOwnerQueried() 0112 { 0113 auto watcher = dynamic_cast<DBusStringReplyWatcher *>(sender()); 0114 if (!watcher) { 0115 return; 0116 } 0117 0118 const QDBusReply<QString> reply = watcher->result(); 0119 0120 if (reply.isValid()) { 0121 onScreenSaverServiceOwnerChanged(screenSaverServiceName(), QString(), reply.value()); 0122 } 0123 0124 watcher->deleteLater(); 0125 } 0126 0127 void LockScreenWatcher::onActiveQueried(QDBusPendingCallWatcher *watcher) 0128 { 0129 QDBusPendingReply<bool> reply = *watcher; 0130 if (!reply.isError()) { 0131 onScreenSaverActiveChanged(reply.value()); 0132 } 0133 0134 watcher->deleteLater(); 0135 } 0136 0137 void LockScreenWatcher::onScreenSaverActiveChanged(bool isActive) 0138 { 0139 if (mLocked == isActive) { 0140 return; 0141 } 0142 0143 mLocked = isActive; 0144 0145 Q_EMIT isLockedChanged(mLocked); 0146 } 0147 0148 } 0149 0150 #include "moc_lockscreenwatcher.cpp"