mirror of
https://github.com/stenzek/duckstation.git
synced 2026-01-31 02:05:18 +01:00
Host: Move screensaver inhibit to host
Removes direct dependency on DBus, uses Qt DBus instead.
This commit is contained in:
@@ -76,7 +76,11 @@ if(BUILD_QT_FRONTEND)
|
||||
# All our builds include Qt, so this is not a problem.
|
||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||
|
||||
find_package(Qt6 6.10.1 COMPONENTS Core Gui GuiPrivate Widgets LinguistTools REQUIRED)
|
||||
if(LINUX)
|
||||
find_package(Qt6 6.10.1 COMPONENTS Core Gui GuiPrivate Widgets LinguistTools DBus REQUIRED)
|
||||
else()
|
||||
find_package(Qt6 6.10.1 COMPONENTS Core Gui GuiPrivate Widgets LinguistTools REQUIRED)
|
||||
endif()
|
||||
|
||||
# Have to verify it down here, don't want users using unpatched Qt.
|
||||
if(NOT Qt6_DIR MATCHES "^${CMAKE_PREFIX_PATH}")
|
||||
|
||||
@@ -132,4 +132,7 @@ bool CanChangeFullscreenMode(bool new_fullscreen_state);
|
||||
/// Called when the pause state changes, or fullscreen UI opens.
|
||||
void OnGPUThreadRunIdleChanged(bool is_active);
|
||||
|
||||
/// Changes the screensaver inhibit state.
|
||||
bool SetScreensaverInhibit(bool inhibit, Error* error);
|
||||
|
||||
} // namespace Host
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include "util/input_manager.h"
|
||||
#include "util/iso_reader.h"
|
||||
#include "util/media_capture.h"
|
||||
#include "util/platform_misc.h"
|
||||
#include "util/postprocessing.h"
|
||||
#include "util/sockets.h"
|
||||
#include "util/state_wrapper.h"
|
||||
@@ -197,6 +196,7 @@ static void ResetThrottler();
|
||||
static void Throttle(Timer::Value current_time, Timer::Value sleep_until);
|
||||
static void AccumulatePreFrameSleepTime(Timer::Value current_time);
|
||||
static void UpdateDisplayVSync();
|
||||
static void InhibitScreensaver(bool inhibit);
|
||||
|
||||
static bool UpdateGameSettingsLayer();
|
||||
static void UpdateInputSettingsLayer(std::string input_profile_name, std::unique_lock<std::mutex>& lock);
|
||||
@@ -1688,7 +1688,7 @@ void System::PauseSystem(bool paused)
|
||||
InputManager::UpdateHostMouseMode();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
InhibitScreensaver(false);
|
||||
|
||||
#ifdef ENABLE_GDB_SERVER
|
||||
GDBServer::OnSystemPaused();
|
||||
@@ -1705,7 +1705,7 @@ void System::PauseSystem(bool paused)
|
||||
InputManager::UpdateHostMouseMode();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
InhibitScreensaver(true);
|
||||
|
||||
#ifdef ENABLE_GDB_SERVER
|
||||
GDBServer::OnSystemResumed();
|
||||
@@ -1968,7 +1968,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
|
||||
InputManager::SynchronizeBindingHandlerState();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
InhibitScreensaver(true);
|
||||
|
||||
#ifdef ENABLE_GDB_SERVER
|
||||
if (g_settings.enable_gdb_server)
|
||||
@@ -2102,7 +2102,7 @@ void System::DestroySystem()
|
||||
InputManager::UpdateHostMouseMode();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
InhibitScreensaver(false);
|
||||
|
||||
FreeMemoryStateStorage(true, true, false);
|
||||
|
||||
@@ -3846,6 +3846,22 @@ bool System::ShouldAllowPresentThrottle()
|
||||
return !valid_vm || IsRunningAtNonStandardSpeed();
|
||||
}
|
||||
|
||||
void System::InhibitScreensaver(bool inhibit)
|
||||
{
|
||||
Error error;
|
||||
if (!Host::SetScreensaverInhibit(inhibit, &error))
|
||||
{
|
||||
ERROR_LOG("Set screensaver {} failed: {}", inhibit ? "inhibit" : "allow", error.GetDescription());
|
||||
if (IsValid())
|
||||
{
|
||||
Host::AddIconOSDMessage(OSDMessageType::Error, "ScreensaverInhibit", ICON_EMOJI_WARNING,
|
||||
inhibit ? TRANSLATE_STR("System", "Failed to inhibit screensaver") :
|
||||
TRANSLATE_STR("System", "Failed to allow screensaver"),
|
||||
error.TakeDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool System::IsFastForwardEnabled()
|
||||
{
|
||||
return s_state.fast_forward_enabled;
|
||||
@@ -4839,12 +4855,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||
}
|
||||
|
||||
if (g_settings.inhibit_screensaver != old_settings.inhibit_screensaver)
|
||||
{
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
else
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
}
|
||||
InhibitScreensaver(g_settings.inhibit_screensaver);
|
||||
|
||||
#ifdef ENABLE_GDB_SERVER
|
||||
if (g_settings.enable_gdb_server != old_settings.enable_gdb_server ||
|
||||
|
||||
@@ -1082,6 +1082,30 @@ void Host::OnGPUThreadRunIdleChanged(bool is_active)
|
||||
{
|
||||
}
|
||||
|
||||
bool Host::SetScreensaverInhibit(bool inhibit, Error* error)
|
||||
{
|
||||
if (inhibit)
|
||||
{
|
||||
if (SDL_DisableScreenSaver())
|
||||
{
|
||||
Error::SetStringFmt(error, "SDL_DisableScreenSaver() failed: {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDL_EnableScreenSaver())
|
||||
{
|
||||
Error::SetStringFmt(error, "SDL_EnableScreenSaver() failed: {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Host::FrameDoneOnGPUThread(GPUBackend* gpu_backend, u32 frame_number)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -182,6 +182,10 @@ target_precompile_headers(duckstation-qt PRIVATE "pch.h")
|
||||
target_include_directories(duckstation-qt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(duckstation-qt PRIVATE core common imgui minizip scmversion Qt6::Core Qt6::Gui Qt6::GuiPrivate Qt6::Widgets)
|
||||
|
||||
if(LINUX)
|
||||
target_link_libraries(duckstation-qt PRIVATE Qt6::DBus)
|
||||
endif()
|
||||
|
||||
# Our Qt builds may have exceptions on, so force them off.
|
||||
target_compile_definitions(duckstation-qt PRIVATE QT_NO_EXCEPTIONS QT_NO_SIGNALS_SLOTS_KEYWORDS)
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
|
||||
|
||||
#include "qtwindowinfo.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/gpu_thread.h"
|
||||
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/log.h"
|
||||
@@ -16,15 +18,50 @@
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "common/windows_headers.h"
|
||||
#include <dwmapi.h>
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include "common/cocoa_tools.h"
|
||||
#else
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
#include <QtDBus/QDBusConnection>
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#include <QtDBus/QDBusMessage>
|
||||
#include <QtDBus/QDBusReply>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#endif
|
||||
|
||||
LOG_CHANNEL(Host);
|
||||
|
||||
namespace {
|
||||
|
||||
struct WindowInfoLocals
|
||||
{
|
||||
bool screensaver_inhibited;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
IOPMAssertionID screensaver_inhibit_assertion;
|
||||
#elif defined(__linux__)
|
||||
u32 screensaver_inhibit_cookie;
|
||||
std::optional<QDBusInterface> screensaver_inhibit_interface;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static WindowInfoLocals s_window_info_locals;
|
||||
|
||||
WindowInfoType QtUtils::GetWindowInfoType()
|
||||
{
|
||||
// Windows and Apple are easy here since there's no display connection.
|
||||
@@ -159,3 +196,117 @@ void QtUtils::UpdateSurfaceSize(QWidget* widget, WindowInfo* wi)
|
||||
wi->surface_height = static_cast<u16>(scaled_size.height());
|
||||
wi->surface_scale = static_cast<float>(device_pixel_ratio);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static void FormatQDBusReplyError(Error* error, const char* prefix, const QDBusError& qerror)
|
||||
{
|
||||
Error::SetStringFmt(error, "{}{}: {}", prefix, qerror.name().toStdString(), qerror.message().toStdString());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool Host::SetScreensaverInhibit(bool inhibit, Error* error)
|
||||
{
|
||||
if (s_window_info_locals.screensaver_inhibited == inhibit)
|
||||
return true;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
if (SetThreadExecutionState(ES_CONTINUOUS | (inhibit ? (ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED) : 0)) == NULL)
|
||||
{
|
||||
Error::SetWin32(error, "SetThreadExecutionState() failed: ", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibited = inhibit;
|
||||
return true;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
if (inhibit)
|
||||
{
|
||||
const CFStringRef reason = CFSTR("DuckStation VM is running.");
|
||||
const IOReturn ret =
|
||||
IOPMAssertionCreateWithName(kIOPMAssertionTypePreventUserIdleDisplaySleep, kIOPMAssertionLevelOn, reason,
|
||||
&s_window_info_locals.screensaver_inhibit_assertion);
|
||||
if (ret != kIOReturnSuccess)
|
||||
{
|
||||
Error::SetStringFmt(error, "IOPMAssertionCreateWithName() failed: {}", static_cast<s32>(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibited = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const IOReturn ret = IOPMAssertionRelease(s_window_info_locals.screensaver_inhibit_assertion);
|
||||
if (ret != kIOReturnSuccess)
|
||||
{
|
||||
Error::SetStringFmt(error, "IOPMAssertionRelease() failed: {}", static_cast<s32>(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibit_assertion = kIOPMNullAssertionID;
|
||||
s_window_info_locals.screensaver_inhibited = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
if (!s_window_info_locals.screensaver_inhibit_interface.has_value())
|
||||
{
|
||||
const QDBusConnection connection = QDBusConnection::sessionBus();
|
||||
if (!connection.isConnected())
|
||||
{
|
||||
Error::SetStringView(error, "Failed to connect to the D-Bus session bus");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibit_interface.emplace(
|
||||
"org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", connection);
|
||||
if (!s_window_info_locals.screensaver_inhibit_interface->isValid())
|
||||
{
|
||||
s_window_info_locals.screensaver_inhibit_interface.reset();
|
||||
Error::SetStringView(error, "org.freedesktop.ScreenSaver interface is invalid");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (inhibit)
|
||||
{
|
||||
const QDBusReply<quint32> msg = s_window_info_locals.screensaver_inhibit_interface->call(
|
||||
"Inhibit", QStringLiteral("DuckStation"), QStringLiteral("DuckStation VM is running."));
|
||||
if (!msg.isValid())
|
||||
{
|
||||
FormatQDBusReplyError(error, "Inhibit message call failed: ", msg.error());
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibit_cookie = msg.value();
|
||||
s_window_info_locals.screensaver_inhibited = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QDBusReply<void> msg = s_window_info_locals.screensaver_inhibit_interface->call(
|
||||
"UnInhibit", s_window_info_locals.screensaver_inhibit_cookie);
|
||||
if (!msg.isValid())
|
||||
{
|
||||
FormatQDBusReplyError(error, "UnInhibit message call failed: ", msg.error());
|
||||
return false;
|
||||
}
|
||||
|
||||
s_window_info_locals.screensaver_inhibit_cookie = 0;
|
||||
s_window_info_locals.screensaver_inhibited = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Error::SetStringView(error, "Not implemented.");
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -23,4 +23,7 @@ std::optional<WindowInfo> GetWindowInfoForWidget(QWidget* widget, RenderAPI rend
|
||||
/// Also sets the "real" DPR scale for the widget, ignoring any operating-system level downsampling.
|
||||
void UpdateSurfaceSize(QWidget* widget, WindowInfo* wi);
|
||||
|
||||
/// Changes the screensaver inhibit state.
|
||||
bool SetScreensaverInhibit(bool inhibit, Error* error);
|
||||
|
||||
} // namespace QtUtils
|
||||
|
||||
@@ -323,6 +323,12 @@ void Host::OnGPUThreadRunIdleChanged(bool is_active)
|
||||
//
|
||||
}
|
||||
|
||||
bool Host::SetScreensaverInhibit(bool inhibit, Error* error)
|
||||
{
|
||||
Error::SetStringView(error, "Not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
void Host::OnPerformanceCountersUpdated(const GPUBackend* gpu_backend)
|
||||
{
|
||||
//
|
||||
|
||||
@@ -283,8 +283,6 @@ elseif(NOT ANDROID)
|
||||
target_sources(util PRIVATE
|
||||
platform_misc_unix.cpp
|
||||
)
|
||||
pkg_check_modules(DBUS REQUIRED dbus-1)
|
||||
target_include_directories(util PRIVATE ${DBUS_INCLUDE_DIRS})
|
||||
|
||||
if(LINUX)
|
||||
target_link_libraries(util PRIVATE UDEV::UDEV)
|
||||
|
||||
@@ -11,9 +11,6 @@ namespace PlatformMisc {
|
||||
|
||||
bool InitializeSocketSupport(Error* error);
|
||||
|
||||
void SuspendScreensaver();
|
||||
void ResumeScreensaver();
|
||||
|
||||
/// Sets the rounded corner state for a window.
|
||||
/// Currently only supported on Windows.
|
||||
bool SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error = nullptr);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
// Normally, system includes come last. But apparently some of our macro names are redefined...
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include <cinttypes>
|
||||
#include <optional>
|
||||
@@ -23,62 +22,11 @@ LOG_CHANNEL(PlatformMisc);
|
||||
#error ARC should not be enabled.
|
||||
#endif
|
||||
|
||||
static IOPMAssertionID s_prevent_idle_assertion = kIOPMNullAssertionID;
|
||||
|
||||
bool PlatformMisc::InitializeSocketSupport(Error* error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SetScreensaverInhibitMacOS(bool inhibit)
|
||||
{
|
||||
if (inhibit)
|
||||
{
|
||||
const CFStringRef reason = CFSTR("DuckStation System Running");
|
||||
if (IOPMAssertionCreateWithName(kIOPMAssertionTypePreventUserIdleDisplaySleep, kIOPMAssertionLevelOn, reason,
|
||||
&s_prevent_idle_assertion) != kIOReturnSuccess)
|
||||
{
|
||||
ERROR_LOG("IOPMAssertionCreateWithName() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IOPMAssertionRelease(s_prevent_idle_assertion);
|
||||
s_prevent_idle_assertion = kIOPMNullAssertionID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s_screensaver_suspended = false;
|
||||
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibitMacOS(true))
|
||||
{
|
||||
ERROR_LOG("Failed to suspend screensaver.");
|
||||
return;
|
||||
}
|
||||
|
||||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibitMacOS(false))
|
||||
ERROR_LOG("Failed to resume screensaver.");
|
||||
|
||||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error /* = nullptr */)
|
||||
{
|
||||
Error::SetStringView(error, "Unsupported on this platform.");
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "common/small_string.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <dbus/dbus.h>
|
||||
#include <mutex>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
@@ -31,171 +30,6 @@ bool PlatformMisc::InitializeSocketSupport(Error* error)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SetScreensaverInhibitDBus(const bool inhibit_requested, const char* program_name, const char* reason)
|
||||
{
|
||||
#define DBUS_FUNCS(X) \
|
||||
X(dbus_error_is_set) \
|
||||
X(dbus_error_free) \
|
||||
X(dbus_message_unref) \
|
||||
X(dbus_error_init) \
|
||||
X(dbus_bus_get) \
|
||||
X(dbus_connection_set_exit_on_disconnect) \
|
||||
X(dbus_message_new_method_call) \
|
||||
X(dbus_message_iter_init_append) \
|
||||
X(dbus_message_iter_append_basic) \
|
||||
X(dbus_connection_send_with_reply_and_block) \
|
||||
X(dbus_message_get_args)
|
||||
|
||||
static std::mutex s_screensaver_inhibit_dbus_mutex;
|
||||
static DynamicLibrary s_dbus_library;
|
||||
static bool s_dbus_library_loaded;
|
||||
static dbus_uint32_t s_cookie;
|
||||
static DBusConnection* s_comparison_connection;
|
||||
|
||||
#define DEFINE_FUNC(F) static decltype(&::F) x##F;
|
||||
DBUS_FUNCS(DEFINE_FUNC)
|
||||
#undef DEFINE_FUNC
|
||||
|
||||
const char* bus_method = (inhibit_requested) ? "Inhibit" : "UnInhibit";
|
||||
DBusError error;
|
||||
DBusConnection* connection = nullptr;
|
||||
DBusMessage* message = nullptr;
|
||||
DBusMessage* response = nullptr;
|
||||
DBusMessageIter message_itr;
|
||||
|
||||
std::unique_lock lock(s_screensaver_inhibit_dbus_mutex);
|
||||
if (!s_dbus_library_loaded)
|
||||
{
|
||||
Error lerror;
|
||||
s_dbus_library_loaded = true;
|
||||
|
||||
if (!s_dbus_library.Open(DynamicLibrary::GetVersionedFilename("dbus-1", 3).c_str(), &lerror))
|
||||
{
|
||||
ERROR_LOG("Failed to open libdbus: {}", lerror.GetDescription());
|
||||
return false;
|
||||
}
|
||||
|
||||
#define LOAD_FUNC(F) \
|
||||
if (!s_dbus_library.GetSymbol(#F, &x##F)) \
|
||||
{ \
|
||||
ERROR_LOG("Failed to find function {}", #F); \
|
||||
s_dbus_library.Close(); \
|
||||
return false; \
|
||||
}
|
||||
DBUS_FUNCS(LOAD_FUNC)
|
||||
#undef LOAD_FUNC
|
||||
}
|
||||
|
||||
if (!s_dbus_library.IsOpen())
|
||||
return false;
|
||||
|
||||
ScopedGuard cleanup = [&]() {
|
||||
if (xdbus_error_is_set(&error))
|
||||
{
|
||||
ERROR_LOG("SetScreensaverInhibitDBus error: {}", error.message);
|
||||
xdbus_error_free(&error);
|
||||
}
|
||||
if (message)
|
||||
xdbus_message_unref(message);
|
||||
if (response)
|
||||
xdbus_message_unref(response);
|
||||
};
|
||||
|
||||
xdbus_error_init(&error);
|
||||
|
||||
// Calling dbus_bus_get() after the first time returns a pointer to the existing connection.
|
||||
connection = xdbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
if (!connection || (xdbus_error_is_set(&error)))
|
||||
return false;
|
||||
|
||||
if (s_comparison_connection != connection)
|
||||
{
|
||||
xdbus_connection_set_exit_on_disconnect(connection, false);
|
||||
s_cookie = 0;
|
||||
s_comparison_connection = connection;
|
||||
}
|
||||
|
||||
message = xdbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver",
|
||||
"org.freedesktop.ScreenSaver", bus_method);
|
||||
if (!message)
|
||||
return false;
|
||||
|
||||
// Initialize an append iterator for the message, gets freed with the message.
|
||||
xdbus_message_iter_init_append(message, &message_itr);
|
||||
if (inhibit_requested)
|
||||
{
|
||||
// Guard against repeat inhibitions which would add extra inhibitors each generating a different cookie.
|
||||
if (s_cookie)
|
||||
return false;
|
||||
|
||||
// Append process/window name.
|
||||
if (!xdbus_message_iter_append_basic(&message_itr, DBUS_TYPE_STRING, &program_name))
|
||||
return false;
|
||||
|
||||
// Append reason for inhibiting the screensaver.
|
||||
if (!xdbus_message_iter_append_basic(&message_itr, DBUS_TYPE_STRING, &reason))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only Append the cookie.
|
||||
if (!xdbus_message_iter_append_basic(&message_itr, DBUS_TYPE_UINT32, &s_cookie))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send message and get response.
|
||||
response = xdbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error);
|
||||
if (!response || xdbus_error_is_set(&error))
|
||||
return false;
|
||||
|
||||
s_cookie = 0;
|
||||
if (inhibit_requested)
|
||||
{
|
||||
// Get the cookie from the response message.
|
||||
if (!xdbus_message_get_args(response, &error, DBUS_TYPE_UINT32, &s_cookie, DBUS_TYPE_INVALID) ||
|
||||
xdbus_error_is_set(&error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
#undef DBUS_FUNCS
|
||||
}
|
||||
|
||||
static bool SetScreensaverInhibit(bool inhibit)
|
||||
{
|
||||
return SetScreensaverInhibitDBus(inhibit, "DuckStation", "DuckStation VM is running.");
|
||||
}
|
||||
|
||||
static bool s_screensaver_suspended = false;
|
||||
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibit(true))
|
||||
{
|
||||
ERROR_LOG("Failed to suspend screensaver.");
|
||||
return;
|
||||
}
|
||||
|
||||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibit(false))
|
||||
ERROR_LOG("Failed to resume screensaver.");
|
||||
|
||||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error /* = nullptr */)
|
||||
{
|
||||
Error::SetStringView(error, "Unsupported on this platform.");
|
||||
|
||||
@@ -45,42 +45,6 @@ bool PlatformMisc::InitializeSocketSupport(Error* error)
|
||||
return s_winsock_initialized;
|
||||
}
|
||||
|
||||
static bool SetScreensaverInhibitWin32(bool inhibit)
|
||||
{
|
||||
if (SetThreadExecutionState(ES_CONTINUOUS | (inhibit ? (ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED) : 0)) == NULL)
|
||||
{
|
||||
ERROR_LOG("SetThreadExecutionState() failed: {}", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibitWin32(true))
|
||||
{
|
||||
ERROR_LOG("Failed to suspend screensaver.");
|
||||
return;
|
||||
}
|
||||
|
||||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
||||
if (!SetScreensaverInhibitWin32(false))
|
||||
ERROR_LOG("Failed to resume screensaver.");
|
||||
|
||||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error)
|
||||
{
|
||||
const DWM_WINDOW_CORNER_PREFERENCE value = enabled ? DWMWCP_DEFAULT : DWMWCP_DONOTROUND;
|
||||
|
||||
@@ -35,6 +35,7 @@ using nfds_t = ULONG;
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
Reference in New Issue
Block a user