mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-25 01:19:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			204 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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
 |