-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
linux: Use D-Bus to inhibit screensaver
- Loading branch information
Showing
9 changed files
with
229 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright 2024 Dolphin Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
namespace DBusUtils | ||
{ | ||
|
||
void InhibitScreenSaver(bool inhibit); | ||
|
||
} // namespace DBusUtils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters