Commit a44ad7b4 authored by Matthieu Gallien's avatar Matthieu Gallien 🎵
Browse files

Prevent the host computer to sleep while playing music

Summary:
asks PowerDevil in Plasma to inhibit sleep when playing music

try to get windows to not sleep while playing music in Elisa

BUG: 401601

Test Plan: tested on a Plasma desktop. Untested on Windows

Tags: #elisa

Maniphest Tasks: T10360

Differential Revision: https://phabricator.kde.org/D18351
parent c3cb65b7
......@@ -20,6 +20,7 @@ set(elisaLib_SOURCES
abstractfile/abstractfilelisting.cpp
filescanner.cpp
viewmanager.cpp
powermanagementinterface.cpp
file/filelistener.cpp
file/localfilelisting.cpp
models/datamodel.cpp
......
......@@ -18,6 +18,7 @@
#include "audiowrapper.h"
#include "vlcLogging.h"
#include "powermanagementinterface.h"
#include <QTimer>
#include <QAudio>
......@@ -39,6 +40,8 @@ class AudioWrapperPrivate
public:
PowerManagementInterface mPowerInterface;
AudioWrapper *mParent = nullptr;
libvlc_instance_t *mInstance = nullptr;
......@@ -351,12 +354,15 @@ void AudioWrapper::playerStateSignalChanges(QMediaPlayer::State newState)
{
case QMediaPlayer::StoppedState:
Q_EMIT stopped();
d->mPowerInterface.setPreventSleep(false);
break;
case QMediaPlayer::PlayingState:
Q_EMIT playing();
d->mPowerInterface.setPreventSleep(true);
break;
case QMediaPlayer::PausedState:
Q_EMIT paused();
d->mPowerInterface.setPreventSleep(false);
break;
}
}, Qt::QueuedConnection);
......
/*
* Copyright 2019 Matthieu Gallien <matthieu_gallien@yahoo.fr>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "powermanagementinterface.h"
#include "config-upnp-qt.h"
#include <KLocalizedString>
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCall>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QDBusUnixFileDescriptor>
#endif
#include <QString>
#include <QByteArray>
#include <QCoreApplication>
#include <QDebug>
class PowerManagementInterfacePrivate
{
public:
bool mPreventSleep = false;
bool mInhibitedSleep = false;
uint mInhibitSleepCookie = 0;
QDBusUnixFileDescriptor mInhibitSleepFileDescriptor;
};
PowerManagementInterface::PowerManagementInterface(QObject *parent) : QObject(parent), d(std::make_unique<PowerManagementInterfacePrivate>())
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
auto sessionBus = QDBusConnection::sessionBus();
sessionBus.connect(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("HasInhibitChanged"), this, SLOT(hostSleepInhibitChanged()));
#endif
}
PowerManagementInterface::~PowerManagementInterface() = default;
bool PowerManagementInterface::preventSleep() const
{
return d->mPreventSleep;
}
bool PowerManagementInterface::sleepInhibited() const
{
return d->mInhibitedSleep;
}
void PowerManagementInterface::setPreventSleep(bool value)
{
if (d->mPreventSleep == value) {
return;
}
if (value) {
inhibitSleepPlasmaWorkspace();
inhibitSleepGnomeWorkspace();
d->mPreventSleep = true;
} else {
uninhibitSleepPlasmaWorkspace();
uninhibitSleepGnomeWorkspace();
d->mPreventSleep = false;
}
Q_EMIT preventSleepChanged();
}
void PowerManagementInterface::retryInhibitingSleep()
{
if (d->mPreventSleep && !d->mInhibitedSleep) {
inhibitSleepPlasmaWorkspace();
inhibitSleepGnomeWorkspace();
}
}
void PowerManagementInterface::hostSleepInhibitChanged()
{
}
void PowerManagementInterface::inhibitDBusCallFinishedPlasmaWorkspace(QDBusPendingCallWatcher *aWatcher)
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
QDBusPendingReply<uint> reply = *aWatcher;
if (reply.isError()) {
} else {
d->mInhibitSleepCookie = reply.argumentAt<0>();
d->mInhibitedSleep = true;
Q_EMIT sleepInhibitedChanged();
}
aWatcher->deleteLater();
#endif
}
void PowerManagementInterface::uninhibitDBusCallFinishedPlasmaWorkspace(QDBusPendingCallWatcher *aWatcher)
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
QDBusPendingReply<> reply = *aWatcher;
if (reply.isError()) {
qDebug() << "PowerManagementInterface::uninhibitDBusCallFinished" << reply.error();
} else {
d->mInhibitedSleep = false;
Q_EMIT sleepInhibitedChanged();
}
aWatcher->deleteLater();
#endif
}
void PowerManagementInterface::inhibitDBusCallFinishedGnomeWorkspace(QDBusPendingCallWatcher *aWatcher)
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
QDBusPendingReply<uint> reply = *aWatcher;
if (reply.isError()) {
qDebug() << "PowerManagementInterface::inhibitDBusCallFinishedGnomeWorkspace" << reply.error();
} else {
d->mInhibitSleepCookie = reply.argumentAt<0>();
d->mInhibitedSleep = true;
Q_EMIT sleepInhibitedChanged();
}
aWatcher->deleteLater();
#endif
}
void PowerManagementInterface::uninhibitDBusCallFinishedGnomeWorkspace(QDBusPendingCallWatcher *aWatcher)
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
QDBusPendingReply<> reply = *aWatcher;
if (reply.isError()) {
qDebug() << "PowerManagementInterface::uninhibitDBusCallFinished" << reply.error();
} else {
d->mInhibitedSleep = false;
Q_EMIT sleepInhibitedChanged();
}
aWatcher->deleteLater();
#endif
}
void PowerManagementInterface::inhibitSleepPlasmaWorkspace()
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
auto sessionBus = QDBusConnection::sessionBus();
auto inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("Inhibit"));
inhibitCall.setArguments({{QCoreApplication::applicationName()}, {i18nc("explanation for sleep inhibit during play of music", "Playing Music")}});
auto asyncReply = sessionBus.asyncCall(inhibitCall);
auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished,
this, &PowerManagementInterface::inhibitDBusCallFinishedPlasmaWorkspace);
#endif
}
void PowerManagementInterface::uninhibitSleepPlasmaWorkspace()
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
auto sessionBus = QDBusConnection::sessionBus();
auto uninhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("UnInhibit"));
uninhibitCall.setArguments({{d->mInhibitSleepCookie}});
auto asyncReply = sessionBus.asyncCall(uninhibitCall);
auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished,
this, &PowerManagementInterface::uninhibitDBusCallFinishedPlasmaWorkspace);
#endif
}
void PowerManagementInterface::inhibitSleepGnomeWorkspace()
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
auto sessionBus = QDBusConnection::sessionBus();
auto inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.gnome.SessionManager"),
QStringLiteral("/org/gnome/SessionManager"),
QStringLiteral("org.gnome.SessionManager"),
QStringLiteral("Inhibit"));
inhibitCall.setArguments({{QCoreApplication::applicationName()}, {uint(0)},
{i18nc("explanation for sleep inhibit during play of music", "Playing Music")}, {uint(8)}});
auto asyncReply = sessionBus.asyncCall(inhibitCall);
auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished,
this, &PowerManagementInterface::inhibitDBusCallFinishedGnomeWorkspace);
#endif
}
void PowerManagementInterface::uninhibitSleepGnomeWorkspace()
{
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
auto sessionBus = QDBusConnection::sessionBus();
auto uninhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.gnome.SessionManager"),
QStringLiteral("/org/gnome/SessionManager"),
QStringLiteral("org.gnome.SessionManager"),
QStringLiteral("UnInhibit"));
uninhibitCall.setArguments({{d->mInhibitSleepCookie}});
auto asyncReply = sessionBus.asyncCall(uninhibitCall);
auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished,
this, &PowerManagementInterface::uninhibitDBusCallFinishedGnomeWorkspace);
#endif
}
void PowerManagementInterface::inhibitSleepWindowsWorkspace()
{
#if defined Q_OS_WIN
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
#endif
}
void PowerManagementInterface::uninhibitSleepWindowsWorkspace()
{
#if defined Q_OS_WIN
SetThreadExecutionState(ES_CONTINUOUS);
#endif
}
#include "moc_powermanagementinterface.cpp"
/*
* Copyright 2019 Matthieu Gallien <matthieu_gallien@yahoo.fr>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef POWERMANAGEMENTINTERFACE_H
#define POWERMANAGEMENTINTERFACE_H
#include <QObject>
#include <memory>
class QDBusPendingCallWatcher;
class PowerManagementInterfacePrivate;
class PowerManagementInterface : public QObject
{
Q_OBJECT
Q_PROPERTY(bool preventSleep
READ preventSleep
WRITE setPreventSleep
NOTIFY preventSleepChanged)
Q_PROPERTY(bool sleepInhibited
READ sleepInhibited
NOTIFY sleepInhibitedChanged)
public:
explicit PowerManagementInterface(QObject *parent = nullptr);
~PowerManagementInterface();
bool preventSleep() const;
bool sleepInhibited() const;
Q_SIGNALS:
void preventSleepChanged();
void sleepInhibitedChanged();
public Q_SLOTS:
void setPreventSleep(bool value);
void retryInhibitingSleep();
private Q_SLOTS:
void hostSleepInhibitChanged();
void inhibitDBusCallFinishedPlasmaWorkspace(QDBusPendingCallWatcher *aWatcher);
void uninhibitDBusCallFinishedPlasmaWorkspace(QDBusPendingCallWatcher *aWatcher);
void inhibitDBusCallFinishedGnomeWorkspace(QDBusPendingCallWatcher *aWatcher);
void uninhibitDBusCallFinishedGnomeWorkspace(QDBusPendingCallWatcher *aWatcher);
private:
void inhibitSleepPlasmaWorkspace();
void uninhibitSleepPlasmaWorkspace();
void inhibitSleepGnomeWorkspace();
void uninhibitSleepGnomeWorkspace();
void inhibitSleepWindowsWorkspace();
void uninhibitSleepWindowsWorkspace();
std::unique_ptr<PowerManagementInterfacePrivate> d;
};
#endif // POWERMANAGEMENTINTERFACE_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment