mirror of
https://github.com/theCheeseboard/thedesk.git
synced 2025-01-22 18:32:09 -05:00
176 lines
7.5 KiB
C++
176 lines
7.5 KiB
C++
/****************************************
|
|
*
|
|
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
|
* Copyright (C) 2020 Victor Tran
|
|
*
|
|
* 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
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* *************************************/
|
|
#include "powermanager.h"
|
|
|
|
#include <QApplication>
|
|
#include <QDBusConnection>
|
|
#include <QDBusInterface>
|
|
#include <QDBusMessage>
|
|
#include <QPointer>
|
|
#include <QProcess>
|
|
|
|
#include "keygrab.h"
|
|
#include <QKeySequence>
|
|
#include <Wm/desktopwm.h>
|
|
#include <tnotification.h>
|
|
|
|
#include "onboardingmanager.h"
|
|
#include "statemanager.h"
|
|
|
|
struct PowerManagerPrivate {
|
|
QPointer<QProcess> lockScreenProcess;
|
|
QDBusInterface* logindInterface;
|
|
};
|
|
|
|
PowerManager::PowerManager(QObject* parent) :
|
|
QObject(parent) {
|
|
d = new PowerManagerPrivate();
|
|
|
|
connect(new KeyGrab(QKeySequence(Qt::Key_L | Qt::MetaModifier), "lockScreen"), &KeyGrab::activated, this, [=] {
|
|
this->performPowerOperation(PowerManager::Lock);
|
|
});
|
|
|
|
// Find this session ID
|
|
d->logindInterface = new QDBusInterface("org.freedesktop.login1", "/org/freedesktop/login1/session/self", "org.freedesktop.login1.Session", QDBusConnection::systemBus(), this);
|
|
QString id = d->logindInterface->property("Id").toString();
|
|
if (!id.isEmpty()) {
|
|
QDBusMessage sessionRequest = QDBusMessage::createMethodCall("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "GetSession");
|
|
sessionRequest.setArguments({id});
|
|
QDBusMessage sessionReply = QDBusConnection::systemBus().call(sessionRequest);
|
|
if (sessionReply.type() == QDBusMessage::ReplyMessage) {
|
|
// Register event handlers for logind
|
|
QDBusObjectPath path = sessionReply.arguments().first().value<QDBusObjectPath>();
|
|
QDBusConnection::systemBus().connect("org.freedesktop.login1", path.path(), "org.freedesktop.login1.Session", "Lock", this, SLOT(logindRequestLock()));
|
|
QDBusConnection::systemBus().connect("org.freedesktop.login1", path.path(), "org.freedesktop.login1.Session", "Unlock", this, SLOT(logindRequestUnlock()));
|
|
}
|
|
}
|
|
}
|
|
|
|
PowerManager::~PowerManager() {
|
|
delete d;
|
|
}
|
|
|
|
tPromise<void>* PowerManager::showPowerOffConfirmation(PowerManager::PowerOperation operation, QString message, QStringList flags) {
|
|
return tPromise<void>::runOnSameThread([=](tPromiseFunctions<void>::SuccessFunction res, tPromiseFunctions<void>::FailureFunction rej) {
|
|
Q_UNUSED(rej)
|
|
|
|
emit powerOffConfirmationRequested(operation, message, flags, res);
|
|
});
|
|
}
|
|
|
|
void PowerManager::logindRequestLock() {
|
|
this->performPowerOperation(Lock);
|
|
}
|
|
|
|
void PowerManager::logindRequestUnlock() {
|
|
if (d->lockScreenProcess) d->lockScreenProcess->terminate();
|
|
// Process will be automatically deleted
|
|
}
|
|
|
|
void PowerManager::performPowerOperation(PowerManager::PowerOperation operation, QStringList flags) {
|
|
emit powerOffOperationCommencing(operation);
|
|
|
|
switch (operation) {
|
|
case PowerManager::PowerOff:
|
|
case PowerManager::Reboot:
|
|
case PowerManager::Suspend:
|
|
case PowerManager::Hibernate:
|
|
{
|
|
QMap<PowerManager::PowerOperation, QString> methods = {
|
|
{PowerManager::PowerOff, "PowerOff" },
|
|
{PowerManager::Reboot, "Reboot" },
|
|
{PowerManager::Suspend, "Suspend" },
|
|
{PowerManager::Hibernate, "Hibernate"}
|
|
};
|
|
|
|
if (flags.contains("update")) {
|
|
// Ask PackageKit to prepare for updates
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit.Offline", "Trigger");
|
|
message.setArguments({operation == PowerManager::Reboot ? "reboot" : "shutdown"});
|
|
QDBusMessage msg = QDBusConnection::systemBus().call(message);
|
|
|
|
// Fall through
|
|
}
|
|
|
|
if (flags.contains("setup")) {
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "SetRebootToFirmwareSetup");
|
|
message.setArguments({true});
|
|
QDBusMessage msg = QDBusConnection::systemBus().call(message);
|
|
|
|
// Fall through
|
|
}
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", methods.value(operation));
|
|
message.setArguments({true});
|
|
QDBusConnection::systemBus().call(message);
|
|
break;
|
|
}
|
|
case PowerManager::LogOut:
|
|
// Quit theDesk
|
|
qApp->exit();
|
|
break;
|
|
case PowerManager::Lock:
|
|
// Lock the screen
|
|
if (d->lockScreenProcess) return; // Screen is already locked
|
|
if (StateManager::onboardingManager()->isOnboardingRunning()) return; // Onboarding is currently running
|
|
|
|
d->lockScreenProcess = new QProcess();
|
|
connect(d->lockScreenProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this] {
|
|
// Tell logind that we're not locked
|
|
d->logindInterface->asyncCall("SetLockedHint", false);
|
|
|
|
d->lockScreenProcess->deleteLater();
|
|
});
|
|
connect(d->lockScreenProcess, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
|
|
if (error == QProcess::FailedToStart) {
|
|
// Send a notification
|
|
auto notification = new tNotification();
|
|
notification->setSummary(tr("Unable to lock screen"));
|
|
notification->setText(tr("Sorry, the screen lock was unable to be started."));
|
|
notification->post();
|
|
|
|
// Tell logind that we're not locked
|
|
d->logindInterface->asyncCall("SetLockedHint", false);
|
|
|
|
d->lockScreenProcess->deleteLater();
|
|
}
|
|
});
|
|
|
|
// TODO: Don't hardcode!
|
|
d->lockScreenProcess->start("/usr/lib/td-locker", QStringList()); // Lock Screen
|
|
|
|
// Tell logind that we're locked
|
|
d->logindInterface->asyncCall("SetLockedHint", true);
|
|
break;
|
|
case PowerManager::SwitchUsers:
|
|
{
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DisplayManager", qEnvironmentVariable("XDG_SEAT_PATH"), "org.freedesktop.DisplayManager.Seat", "SwitchToGreeter");
|
|
QDBusConnection::systemBus().call(message);
|
|
break;
|
|
}
|
|
case PowerManager::TurnOffScreen:
|
|
DesktopWm::setScreenOff(true);
|
|
break;
|
|
case PowerManager::All:
|
|
// Doesn't make sense ???
|
|
break;
|
|
}
|
|
}
|