mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 13:20:27 -06:00
linux: Use D-Bus to inhibit screensaver
This commit is contained in:
204
Source/Core/UICommon/DBusUtils.cpp
Normal file
204
Source/Core/UICommon/DBusUtils.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
// Copyright 2024 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "UICommon/DBusUtils.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
namespace DBusUtils
|
||||
{
|
||||
static bool InhibitFDO();
|
||||
static bool InhibitXfce();
|
||||
static bool InhibitMate();
|
||||
static bool InhibitPortal();
|
||||
static void Uninhibit();
|
||||
|
||||
static constexpr char s_app_id[] = "org.DolphinEmu.dolphin-emu";
|
||||
|
||||
// Cookie for the org.freedesktop.ScreenSaver interface
|
||||
static uint32_t s_fdo_cookie = 0;
|
||||
// Cookie for the org.xfce.ScreenSaver interface
|
||||
static uint32_t s_xfce_cookie = 0;
|
||||
// Cookie for the org.mate.ScreenSaver interface
|
||||
static uint32_t s_mate_cookie = 0;
|
||||
// Return handle for the org.freedesktop.portal.Desktop interface
|
||||
static QString s_portal_handle;
|
||||
|
||||
// Uses D-Bus to inhibit the screensaver
|
||||
// Tries various D-Bus interfaces until it finds one that works
|
||||
void InhibitScreenSaver(bool inhibit)
|
||||
{
|
||||
if (inhibit)
|
||||
{
|
||||
if (s_fdo_cookie || s_xfce_cookie || s_mate_cookie || !s_portal_handle.isEmpty())
|
||||
return;
|
||||
if (!InhibitFDO() && !InhibitXfce() && !InhibitMate() && !InhibitPortal())
|
||||
INFO_LOG_FMT(VIDEO, "Could not inhibit screensaver: No services available");
|
||||
}
|
||||
else
|
||||
Uninhibit();
|
||||
}
|
||||
|
||||
// Inhibits screensaver on Xfce desktop
|
||||
static bool InhibitXfce()
|
||||
{
|
||||
QDBusInterface interface("org.xfce.ScreenSaver", "/", "org.xfce.ScreenSaver");
|
||||
if (!interface.isValid())
|
||||
return false;
|
||||
|
||||
QDBusReply<uint32_t> reply = interface.call("Inhibit", s_app_id, QObject::tr("Playing a game"));
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.xfce.ScreenSaver::Inhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
return false;
|
||||
}
|
||||
INFO_LOG_FMT(VIDEO, "org.xfce.ScreenSaver::Inhibit succeeded");
|
||||
s_xfce_cookie = reply;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inhibits screensaver on the MATE desktop
|
||||
// MATE advertises support for xdg-desktop-portal Inhibit,
|
||||
// but it doesn't work as of Fedora 40
|
||||
static bool InhibitMate()
|
||||
{
|
||||
QDBusInterface interface("org.mate.ScreenSaver", "/org/mate/ScreenSaver", "org.mate.ScreenSaver");
|
||||
if (!interface.isValid())
|
||||
return false;
|
||||
|
||||
QDBusReply<uint32_t> reply = interface.call("Inhibit", s_app_id, QObject::tr("Playing a game"));
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.mate.ScreenSaver::Inhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
return false;
|
||||
}
|
||||
INFO_LOG_FMT(VIDEO, "org.mate.ScreenSaver::Inhibit succeeded");
|
||||
s_mate_cookie = reply;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inhibits screensaver on GNOME, KDE and Cinnamon
|
||||
static bool InhibitFDO()
|
||||
{
|
||||
QDBusInterface interface("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver",
|
||||
"org.freedesktop.ScreenSaver");
|
||||
if (!interface.isValid())
|
||||
return false;
|
||||
|
||||
QDBusReply<uint32_t> reply = interface.call("Inhibit", s_app_id, QObject::tr("Playing a game"));
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.freedesktop.ScreenSaver::Inhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
return false;
|
||||
}
|
||||
INFO_LOG_FMT(VIDEO, "org.freedesktop.ScreenSaver::Inhibit succeeded");
|
||||
s_fdo_cookie = reply;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inhibits screensaver when sandboxed through Flatpak
|
||||
// Does not work on KDE Plasma versions before 6.1.5
|
||||
static bool InhibitPortal()
|
||||
{
|
||||
QDBusInterface interface("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Inhibit");
|
||||
if (!interface.isValid())
|
||||
return false;
|
||||
|
||||
QHash<QString, QVariant> options;
|
||||
options["handle_token"] = "dolphin_" + QString::number(std::rand(), 0x10);
|
||||
options["reason"] = QObject::tr("Playing a game");
|
||||
uint32_t flags = 9; // logout | idle
|
||||
QDBusReply<QDBusObjectPath> reply = interface.call("Inhibit", "", flags, options);
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.freedesktop.portal.Desktop::Inhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
return false;
|
||||
}
|
||||
INFO_LOG_FMT(VIDEO, "org.freedesktop.portal.Desktop::Inhibit succeeded");
|
||||
s_portal_handle = reply.value().path();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Uninhibit()
|
||||
{
|
||||
if (s_fdo_cookie)
|
||||
{
|
||||
QDBusInterface interface("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver",
|
||||
"org.freedesktop.ScreenSaver");
|
||||
interface.call("UnInhibit", s_fdo_cookie);
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.freedesktop.ScreenSaver::UnInhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "org.freedesktop.ScreenSaver::UnInhibit succeeded");
|
||||
}
|
||||
s_fdo_cookie = 0;
|
||||
}
|
||||
|
||||
if (s_xfce_cookie)
|
||||
{
|
||||
QDBusInterface interface("org.xfce.ScreenSaver", "/org/xfce/ScreenSaver",
|
||||
"org.xfce.ScreenSaver");
|
||||
interface.call("UnInhibit", s_xfce_cookie);
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.xfce.ScreenSaver::UnInhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "org.xfce.ScreenSaver::UnInhibit succeeded");
|
||||
}
|
||||
s_xfce_cookie = 0;
|
||||
}
|
||||
|
||||
if (s_mate_cookie)
|
||||
{
|
||||
QDBusInterface interface("org.mate.ScreenSaver", "/", "org.mate.ScreenSaver");
|
||||
interface.call("UnInhibit", s_mate_cookie);
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.mate.ScreenSaver::UnInhibit failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "org.mate.ScreenSaver::UnInhibit succeeded");
|
||||
}
|
||||
s_mate_cookie = 0;
|
||||
}
|
||||
|
||||
if (!s_portal_handle.isEmpty())
|
||||
{
|
||||
QDBusInterface interface("org.freedesktop.portal.Desktop", s_portal_handle,
|
||||
"org.freedesktop.portal.Request");
|
||||
interface.call("Close");
|
||||
if (interface.lastError().isValid())
|
||||
{
|
||||
WARN_LOG_FMT(VIDEO, "org.freedesktop.portal.Request::Close failed: {}",
|
||||
interface.lastError().message().toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "org.freedesktop.portal.Request::Close succeeded");
|
||||
}
|
||||
s_portal_handle = QString();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DBusUtils
|
Reference in New Issue
Block a user