123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // 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
|