diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7d9056aa3..d1ad55c9c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -249,7 +249,7 @@ if(ENABLE_QT)
     # Check for system Qt on Linux, fallback to bundled Qt
     if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
         if (NOT YUZU_USE_BUNDLED_QT)
-            find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets)
+            find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus)
         endif()
         if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT)
             # Check for dependencies, then enable bundled Qt download
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 732e8c276..30902101d 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -251,6 +251,9 @@ target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
 if (NOT WIN32)
     target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
 endif()
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+    target_link_libraries(yuzu PRIVATE Qt5::DBus)
+endif()
 
 target_compile_definitions(yuzu PRIVATE
     # Use QStringBuilder for string concatenation to reduce
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index a7271e075..1e02d715b 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1236,11 +1236,58 @@ 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 running 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() {
 #ifdef _WIN32
     SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
 #elif defined(HAVE_SDL2)
     SDL_DisableScreenSaver();
+#ifdef __linux__
+    auto reply = HoldWakeLockLinux(winId());
+    if (reply) {
+        wake_lock = std::move(reply.value());
+    }
+#endif
 #endif
 }
 
@@ -1249,6 +1296,11 @@ void GMainWindow::AllowOSSleep() {
     SetThreadExecutionState(ES_CONTINUOUS);
 #elif defined(HAVE_SDL2)
     SDL_EnableScreenSaver();
+#ifdef __linux__
+    if (!wake_lock.path().isEmpty()) {
+        ReleaseWakeLockLinux(wake_lock);
+    }
+#endif
 #endif
 }
 
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 0fd41ed4f..7870bb963 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -17,6 +17,12 @@
 #include "yuzu/compatibility_list.h"
 #include "yuzu/hotkeys.h"
 
+#ifdef __linux__
+#include <QVariant>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QtDBus>
+#endif
+
 class Config;
 class EmuThread;
 class GameList;
@@ -394,6 +400,9 @@ private:
 
     // Applets
     QtSoftwareKeyboardDialog* software_keyboard = nullptr;
+#ifdef __linux__
+    QDBusObjectPath wake_lock{};
+#endif
 
 protected:
     void dropEvent(QDropEvent* event) override;