Ver Fonte

main: fix wake lock in Flatpak ...

... by using the XDP system
liushuyu há 4 anos atrás
pai
commit
fa7abafa5f
4 ficheiros alterados com 64 adições e 1 exclusões
  1. 1 1
      CMakeLists.txt
  2. 3 0
      src/yuzu/CMakeLists.txt
  3. 51 0
      src/yuzu/main.cpp
  4. 9 0
      src/yuzu/main.h

+ 1 - 1
CMakeLists.txt

@@ -249,7 +249,7 @@ if(ENABLE_QT)
     # Check for system Qt on Linux, fallback to bundled Qt
     # Check for system Qt on Linux, fallback to bundled Qt
     if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
     if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
         if (NOT YUZU_USE_BUNDLED_QT)
         if (NOT YUZU_USE_BUNDLED_QT)
-            find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets)
+            find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus)
         endif()
         endif()
         if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT)
         if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT)
             # Check for dependencies, then enable bundled Qt download
             # Check for dependencies, then enable bundled Qt download

+ 3 - 0
src/yuzu/CMakeLists.txt

@@ -251,6 +251,9 @@ target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
 if (NOT WIN32)
 if (NOT WIN32)
     target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
     target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
 endif()
 endif()
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+    target_link_libraries(yuzu PRIVATE Qt5::DBus)
+endif()
 
 
 target_compile_definitions(yuzu PRIVATE
 target_compile_definitions(yuzu PRIVATE
     # Use QStringBuilder for string concatenation to reduce
     # Use QStringBuilder for string concatenation to reduce

+ 51 - 0
src/yuzu/main.cpp

@@ -1236,11 +1236,57 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
     }
     }
 }
 }
 
 
+#ifdef __linux__
+static std::optional<QDBusObjectPath> HoldWakeLockLinux(u32 window_id = 0) {
+    if (!QDBusConnection::sessionBus().isConnected()) {
+        return {};
+    }
+    // reference: https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Inhibit
+    QDBusInterface xdp(QString::fromLatin1("org.freedesktop.portal.Desktop"),
+                       QString::fromLatin1("/org/freedesktop/portal/desktop"),
+                       QString::fromLatin1("org.freedesktop.portal.Inhibit"));
+    if (!xdp.isValid()) {
+        LOG_WARNING(Frontend, "Couldn't connect to XDP D-Bus endpoint");
+        return {};
+    }
+    QVariantMap options = {};
+    //: TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping
+    options.insert(QString::fromLatin1("reason"),
+                   QCoreApplication::translate("GMainWindow", "yuzu is emulating a game"));
+    // 0x4: Suspend lock; 0x8: Idle lock
+    QDBusReply<QDBusObjectPath> reply =
+        xdp.call(QString::fromLatin1("Inhibit"),
+                 QString::fromLatin1("x11:") + QString::number(window_id, 16), 12U, options);
+
+    if (reply.isValid()) {
+        return reply.value();
+    }
+    LOG_WARNING(Frontend, "Couldn't read Inhibit reply from XDP: {}",
+                reply.error().message().toStdString());
+    return {};
+}
+
+static void ReleaseWakeLockLinux(QDBusObjectPath lock) {
+    if (!QDBusConnection::sessionBus().isConnected()) {
+        return;
+    }
+    QDBusInterface unlocker(QString::fromLatin1("org.freedesktop.portal.Desktop"), lock.path(),
+                            QString::fromLatin1("org.freedesktop.portal.Request"));
+    unlocker.call(QString::fromLatin1("Close"));
+}
+#endif // __linux__
+
 void GMainWindow::PreventOSSleep() {
 void GMainWindow::PreventOSSleep() {
 #ifdef _WIN32
 #ifdef _WIN32
     SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
     SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
 #elif defined(HAVE_SDL2)
 #elif defined(HAVE_SDL2)
     SDL_DisableScreenSaver();
     SDL_DisableScreenSaver();
+#ifdef __linux__
+    auto reply = HoldWakeLockLinux(winId());
+    if (reply) {
+        wake_lock = std::move(reply.value());
+    }
+#endif
 #endif
 #endif
 }
 }
 
 
@@ -1249,6 +1295,11 @@ void GMainWindow::AllowOSSleep() {
     SetThreadExecutionState(ES_CONTINUOUS);
     SetThreadExecutionState(ES_CONTINUOUS);
 #elif defined(HAVE_SDL2)
 #elif defined(HAVE_SDL2)
     SDL_EnableScreenSaver();
     SDL_EnableScreenSaver();
+#ifdef __linux__
+    if (!wake_lock.path().isEmpty()) {
+        ReleaseWakeLockLinux(wake_lock);
+    }
+#endif
 #endif
 #endif
 }
 }
 
 

+ 9 - 0
src/yuzu/main.h

@@ -17,6 +17,12 @@
 #include "yuzu/compatibility_list.h"
 #include "yuzu/compatibility_list.h"
 #include "yuzu/hotkeys.h"
 #include "yuzu/hotkeys.h"
 
 
+#ifdef __linux__
+#include <QVariant>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QtDBus>
+#endif
+
 class Config;
 class Config;
 class EmuThread;
 class EmuThread;
 class GameList;
 class GameList;
@@ -394,6 +400,9 @@ private:
 
 
     // Applets
     // Applets
     QtSoftwareKeyboardDialog* software_keyboard = nullptr;
     QtSoftwareKeyboardDialog* software_keyboard = nullptr;
+#ifdef __linux__
+    QDBusObjectPath wake_lock{};
+#endif
 
 
 protected:
 protected:
     void dropEvent(QDropEvent* event) override;
     void dropEvent(QDropEvent* event) override;