mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-25 22:56:23 +08:00
[fix] scope sleep inhibition to active screen sharing, refs #123
This commit is contained in:
@@ -1225,6 +1225,9 @@ bool GuiApplication::InitializeSDL() {
|
|||||||
"windows while retaining Wayland portal capture and input");
|
"windows while retaining Wayland portal capture and input");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// SDL disables the screensaver by default. A background remote desktop app
|
||||||
|
// should leave automatic display sleep under the user's system settings.
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
|
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
|
||||||
LOG_ERROR("SDL initialization failed: {}", SDL_GetError());
|
LOG_ERROR("SDL initialization failed: {}", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -0,0 +1,245 @@
|
|||||||
|
#include "features/devices/screen_sharing_power.h"
|
||||||
|
|
||||||
|
#include "rd_log.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||||
|
#elif defined(__linux__) && !defined(__OHOS__)
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace crossdesk {
|
||||||
|
|
||||||
|
#if defined(__linux__) && !defined(__OHOS__)
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr const char* kApplication = "CrossDesk";
|
||||||
|
constexpr const char* kReason = "Sharing the desktop with a remote controller";
|
||||||
|
constexpr int kDbusTimeoutMs = 1000;
|
||||||
|
|
||||||
|
struct ConnectionCloser {
|
||||||
|
void operator()(DBusConnection* connection) const {
|
||||||
|
dbus_connection_close(connection);
|
||||||
|
dbus_connection_unref(connection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using BusConnection = std::unique_ptr<DBusConnection, ConnectionCloser>;
|
||||||
|
using BusMessage = std::unique_ptr<DBusMessage, decltype(&dbus_message_unref)>;
|
||||||
|
|
||||||
|
BusConnection OpenBus(DBusBusType type) {
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
BusConnection connection(dbus_bus_get_private(type, &error));
|
||||||
|
if (connection) {
|
||||||
|
dbus_connection_set_exit_on_disconnect(connection.get(), false);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Cannot connect to power management bus: {}",
|
||||||
|
error.message ? error.message : "unknown error");
|
||||||
|
}
|
||||||
|
dbus_error_free(&error);
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
BusMessage Call(DBusConnection* connection, DBusMessage* message) {
|
||||||
|
return BusMessage(dbus_connection_send_with_reply_and_block(
|
||||||
|
connection, message, kDbusTimeoutMs, nullptr),
|
||||||
|
dbus_message_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ScreenSharingPower::Impl {
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE request = INVALID_HANDLE_VALUE;
|
||||||
|
bool display = false;
|
||||||
|
bool system = false;
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
wchar_t reason_text[] = L"CrossDesk is sharing the desktop";
|
||||||
|
REASON_CONTEXT reason{};
|
||||||
|
reason.Version = POWER_REQUEST_CONTEXT_VERSION;
|
||||||
|
reason.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
|
||||||
|
reason.Reason.SimpleReasonString = reason_text;
|
||||||
|
request = PowerCreateRequest(&reason);
|
||||||
|
if (request == INVALID_HANDLE_VALUE) {
|
||||||
|
LOG_WARN("Cannot create screen sharing power request: {}", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle-based requests also work in the unattended host, which has no
|
||||||
|
// SDL video subsystem, and do not depend on the calling thread's lifetime.
|
||||||
|
system = PowerSetRequest(request, PowerRequestSystemRequired) != 0;
|
||||||
|
if (!system)
|
||||||
|
LOG_WARN("Cannot prevent system idle sleep: {}", GetLastError());
|
||||||
|
display = PowerSetRequest(request, PowerRequestDisplayRequired) != 0;
|
||||||
|
if (!display)
|
||||||
|
LOG_WARN("Cannot prevent display idle sleep: {}", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
if (request == INVALID_HANDLE_VALUE) return;
|
||||||
|
if (display) PowerClearRequest(request, PowerRequestDisplayRequired);
|
||||||
|
if (system) PowerClearRequest(request, PowerRequestSystemRequired);
|
||||||
|
CloseHandle(request);
|
||||||
|
request = INVALID_HANDLE_VALUE;
|
||||||
|
display = system = false;
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
IOPMAssertionID display = kIOPMNullAssertionID;
|
||||||
|
IOPMAssertionID system = kIOPMNullAssertionID;
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
const auto reason = CFSTR("CrossDesk is sharing the desktop");
|
||||||
|
auto result = IOPMAssertionCreateWithName(
|
||||||
|
kIOPMAssertionTypePreventUserIdleSystemSleep, kIOPMAssertionLevelOn,
|
||||||
|
reason, &system);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
LOG_WARN("Cannot prevent system idle sleep: {}", result);
|
||||||
|
result = IOPMAssertionCreateWithName(
|
||||||
|
kIOPMAssertionTypePreventUserIdleDisplaySleep, kIOPMAssertionLevelOn,
|
||||||
|
reason, &display);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
LOG_WARN("Cannot prevent display idle sleep: {}", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
if (display != kIOPMNullAssertionID) IOPMAssertionRelease(display);
|
||||||
|
if (system != kIOPMNullAssertionID) IOPMAssertionRelease(system);
|
||||||
|
display = system = kIOPMNullAssertionID;
|
||||||
|
}
|
||||||
|
#elif defined(__linux__) && !defined(__OHOS__)
|
||||||
|
BusConnection session;
|
||||||
|
dbus_uint32_t cookie = 0;
|
||||||
|
bool desktop_inhibited = false;
|
||||||
|
bool gnome = false;
|
||||||
|
int sleep_fd = -1;
|
||||||
|
|
||||||
|
bool InhibitDesktop(bool use_gnome) {
|
||||||
|
const char* service = use_gnome ? "org.gnome.SessionManager"
|
||||||
|
: "org.freedesktop.ScreenSaver";
|
||||||
|
const char* path = use_gnome ? "/org/gnome/SessionManager"
|
||||||
|
: "/org/freedesktop/ScreenSaver";
|
||||||
|
BusMessage message(dbus_message_new_method_call(service, path, service,
|
||||||
|
"Inhibit"),
|
||||||
|
dbus_message_unref);
|
||||||
|
if (!message) return false;
|
||||||
|
dbus_bool_t appended;
|
||||||
|
if (use_gnome) {
|
||||||
|
const dbus_uint32_t window = 0;
|
||||||
|
const dbus_uint32_t flags = 4 | 8; // Suspend and session idle.
|
||||||
|
appended = dbus_message_append_args(
|
||||||
|
message.get(), DBUS_TYPE_STRING, &kApplication, DBUS_TYPE_UINT32,
|
||||||
|
&window, DBUS_TYPE_STRING, &kReason, DBUS_TYPE_UINT32, &flags,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
} else {
|
||||||
|
appended = dbus_message_append_args(
|
||||||
|
message.get(), DBUS_TYPE_STRING, &kApplication, DBUS_TYPE_STRING,
|
||||||
|
&kReason, DBUS_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
if (!appended) return false;
|
||||||
|
auto reply = Call(session.get(), message.get());
|
||||||
|
if (!reply || !dbus_message_get_args(reply.get(), nullptr, DBUS_TYPE_UINT32,
|
||||||
|
&cookie, DBUS_TYPE_INVALID))
|
||||||
|
return false;
|
||||||
|
gnome = use_gnome;
|
||||||
|
desktop_inhibited = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
if (!dbus_threads_init_default()) {
|
||||||
|
LOG_WARN("Cannot initialize D-Bus for screen sharing power management");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// These session APIs work without an SDL window, including native Wayland
|
||||||
|
// and a Slint window hidden in the tray. GNOME's API inhibits both kinds of
|
||||||
|
// idle sleep; other desktops use ScreenSaver plus logind below.
|
||||||
|
session = OpenBus(DBUS_BUS_SESSION);
|
||||||
|
if (session && InhibitDesktop(true)) return;
|
||||||
|
if (!session || !InhibitDesktop(false))
|
||||||
|
LOG_WARN("Cannot inhibit desktop idle while sharing the screen");
|
||||||
|
|
||||||
|
auto system_bus = OpenBus(DBUS_BUS_SYSTEM);
|
||||||
|
if (!system_bus) return;
|
||||||
|
BusMessage message(dbus_message_new_method_call(
|
||||||
|
"org.freedesktop.login1", "/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager", "Inhibit"),
|
||||||
|
dbus_message_unref);
|
||||||
|
const char* what = "sleep:idle";
|
||||||
|
const char* mode = "block";
|
||||||
|
if (!message || !dbus_message_append_args(
|
||||||
|
message.get(), DBUS_TYPE_STRING, &what,
|
||||||
|
DBUS_TYPE_STRING, &kApplication, DBUS_TYPE_STRING,
|
||||||
|
&kReason, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID)) {
|
||||||
|
LOG_WARN("Cannot create system sleep inhibition request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto reply = Call(system_bus.get(), message.get());
|
||||||
|
// get_args duplicates the returned fd with CLOEXEC. Holding this fd keeps
|
||||||
|
// the inhibitor alive independently of the reply or D-Bus connection.
|
||||||
|
if (!reply || !dbus_message_get_args(reply.get(), nullptr, DBUS_TYPE_UNIX_FD,
|
||||||
|
&sleep_fd, DBUS_TYPE_INVALID))
|
||||||
|
LOG_WARN("Cannot inhibit system sleep while sharing the screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
if (sleep_fd >= 0) {
|
||||||
|
close(sleep_fd);
|
||||||
|
sleep_fd = -1;
|
||||||
|
}
|
||||||
|
if (session && desktop_inhibited &&
|
||||||
|
dbus_connection_get_is_connected(session.get())) {
|
||||||
|
const char* service = gnome ? "org.gnome.SessionManager"
|
||||||
|
: "org.freedesktop.ScreenSaver";
|
||||||
|
const char* path = gnome ? "/org/gnome/SessionManager"
|
||||||
|
: "/org/freedesktop/ScreenSaver";
|
||||||
|
BusMessage message(dbus_message_new_method_call(
|
||||||
|
service, path, service,
|
||||||
|
gnome ? "Uninhibit" : "UnInhibit"),
|
||||||
|
dbus_message_unref);
|
||||||
|
if (message && dbus_message_append_args(
|
||||||
|
message.get(), DBUS_TYPE_UINT32, &cookie,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
dbus_message_set_no_reply(message.get(), true);
|
||||||
|
dbus_connection_send(session.get(), message.get(), nullptr);
|
||||||
|
dbus_connection_flush(session.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// A private connection also revokes the desktop inhibitor if UnInhibit
|
||||||
|
// could not be sent. Nothing is retained by unrelated D-Bus clients.
|
||||||
|
session.reset();
|
||||||
|
desktop_inhibited = false;
|
||||||
|
gnome = false;
|
||||||
|
cookie = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void Start() {
|
||||||
|
if (!SDL_DisableScreenSaver())
|
||||||
|
LOG_WARN("Cannot prevent display idle sleep: {}", SDL_GetError());
|
||||||
|
}
|
||||||
|
void Stop() { SDL_EnableScreenSaver(); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
ScreenSharingPower::ScreenSharingPower() : impl_(std::make_unique<Impl>()) {}
|
||||||
|
|
||||||
|
ScreenSharingPower::~ScreenSharingPower() { SetSharing(false); }
|
||||||
|
|
||||||
|
void ScreenSharingPower::SetSharing(bool sharing) {
|
||||||
|
if (sharing_ == sharing) return;
|
||||||
|
sharing_ = sharing;
|
||||||
|
if (sharing) {
|
||||||
|
impl_->Start();
|
||||||
|
LOG_INFO("Requested display and system idle-sleep inhibition for screen sharing");
|
||||||
|
} else {
|
||||||
|
impl_->Stop();
|
||||||
|
LOG_INFO("Released screen sharing power inhibitors");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crossdesk
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2026-10-24
|
||||||
|
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SCREEN_SHARING_POWER_H_
|
||||||
|
#define _SCREEN_SHARING_POWER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace crossdesk {
|
||||||
|
|
||||||
|
// Owns temporary display/system idle-sleep inhibitors for the shared capture
|
||||||
|
// source. Call on the UI thread; repeated updates do not acquire extra requests.
|
||||||
|
class ScreenSharingPower {
|
||||||
|
public:
|
||||||
|
ScreenSharingPower();
|
||||||
|
~ScreenSharingPower();
|
||||||
|
ScreenSharingPower(const ScreenSharingPower&) = delete;
|
||||||
|
ScreenSharingPower& operator=(const ScreenSharingPower&) = delete;
|
||||||
|
|
||||||
|
void SetSharing(bool sharing);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
bool sharing_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace crossdesk
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -298,6 +298,21 @@ bool SessionDeviceManager::ShouldCaptureCursor() const {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SessionDeviceManager::HasConnectedController() const {
|
||||||
|
std::shared_lock lock(owner_.connection_status_mutex_);
|
||||||
|
return std::any_of(owner_.connection_status_.begin(),
|
||||||
|
owner_.connection_status_.end(), [](const auto& entry) {
|
||||||
|
return entry.second == ConnectionStatus::Connected;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionDeviceManager::UpdateScreenSharingPower() {
|
||||||
|
// Wayland keeps capture warm after the last disconnect. Only live viewers
|
||||||
|
// justify keeping the host awake; an outgoing viewing session does not.
|
||||||
|
screen_sharing_power_.SetSharing(owner_.screen_capturer_is_started_ &&
|
||||||
|
HasConnectedController());
|
||||||
|
}
|
||||||
|
|
||||||
int SessionDeviceManager::StartScreenCapturer() {
|
int SessionDeviceManager::StartScreenCapturer() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (!owner_.EnsureMacScreenRecordingPermission()) {
|
if (!owner_.EnsureMacScreenRecordingPermission()) {
|
||||||
@@ -317,8 +332,10 @@ int SessionDeviceManager::StartScreenCapturer() {
|
|||||||
cursor_capture_dirty_.store(false, std::memory_order_relaxed);
|
cursor_capture_dirty_.store(false, std::memory_order_relaxed);
|
||||||
const bool show_cursor = ShouldCaptureCursor();
|
const bool show_cursor = ShouldCaptureCursor();
|
||||||
LOG_INFO("Start screen capturer, show cursor: {}", show_cursor);
|
LOG_INFO("Start screen capturer, show cursor: {}", show_cursor);
|
||||||
|
screen_sharing_power_.SetSharing(HasConnectedController());
|
||||||
const int ret = screen_capturer_->Start(show_cursor);
|
const int ret = screen_capturer_->Start(show_cursor);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
screen_sharing_power_.SetSharing(false);
|
||||||
LOG_ERROR("Start screen capturer failed: {}", ret);
|
LOG_ERROR("Start screen capturer failed: {}", ret);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -329,6 +346,8 @@ int SessionDeviceManager::StopScreenCapturer() {
|
|||||||
LOG_INFO("Stop screen capturer");
|
LOG_INFO("Stop screen capturer");
|
||||||
screen_capturer_->Stop();
|
screen_capturer_->Stop();
|
||||||
}
|
}
|
||||||
|
owner_.screen_capturer_is_started_ = false;
|
||||||
|
screen_sharing_power_.SetSharing(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,6 +666,8 @@ void SessionDeviceManager::PushAudio(const std::string& remote_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SessionDeviceManager::UpdateInteractions() {
|
void SessionDeviceManager::UpdateInteractions() {
|
||||||
|
// Release even when pending remote-input cleanup makes this tick return early.
|
||||||
|
UpdateScreenSharingPower();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (owner_.screen_capturer_is_started_ &&
|
if (owner_.screen_capturer_is_started_ &&
|
||||||
cursor_capture_dirty_.load(std::memory_order_relaxed)) {
|
cursor_capture_dirty_.load(std::memory_order_relaxed)) {
|
||||||
@@ -680,6 +701,8 @@ void SessionDeviceManager::UpdateInteractions() {
|
|||||||
owner_.screen_capturer_is_started_ = false;
|
owner_.screen_capturer_is_started_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateScreenSharingPower();
|
||||||
|
|
||||||
if (owner_.start_mouse_controller_ && !owner_.mouse_controller_is_started_) {
|
if (owner_.start_mouse_controller_ && !owner_.mouse_controller_is_started_) {
|
||||||
if (StartMouseController() == 0) {
|
if (StartMouseController() == 0) {
|
||||||
owner_.mouse_controller_is_started_ = true;
|
owner_.mouse_controller_is_started_ = true;
|
||||||
@@ -823,6 +846,8 @@ std::vector<HostDisplay> SessionDeviceManager::host_display_list() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SessionDeviceManager::DestroyDevices() {
|
void SessionDeviceManager::DestroyDevices() {
|
||||||
|
owner_.screen_capturer_is_started_ = false;
|
||||||
|
screen_sharing_power_.SetSharing(false);
|
||||||
speaker_capture_.Shutdown();
|
speaker_capture_.Shutdown();
|
||||||
StopMouseController(true);
|
StopMouseController(true);
|
||||||
if (screen_capturer_) {
|
if (screen_capturer_) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "display_info.h"
|
#include "display_info.h"
|
||||||
#include "features/input/captured_keyboard_queue.h"
|
#include "features/input/captured_keyboard_queue.h"
|
||||||
#include "features/input/remote_mouse_buttons.h"
|
#include "features/input/remote_mouse_buttons.h"
|
||||||
|
#include "screen_sharing_power.h"
|
||||||
#include "speaker_capture_controller.h"
|
#include "speaker_capture_controller.h"
|
||||||
|
|
||||||
struct SDL_AudioStream;
|
struct SDL_AudioStream;
|
||||||
@@ -105,6 +106,8 @@ private:
|
|||||||
bool ShouldSendCapturedFrame(std::chrono::steady_clock::time_point now,
|
bool ShouldSendCapturedFrame(std::chrono::steady_clock::time_point now,
|
||||||
int fps);
|
int fps);
|
||||||
bool ShouldCaptureCursor() const;
|
bool ShouldCaptureCursor() const;
|
||||||
|
bool HasConnectedController() const;
|
||||||
|
void UpdateScreenSharingPower();
|
||||||
bool SyncDisplayInfo();
|
bool SyncDisplayInfo();
|
||||||
void SetDisplayInfoList(std::vector<DisplayInfo> displays);
|
void SetDisplayInfoList(std::vector<DisplayInfo> displays);
|
||||||
void RecordCaptureCadence(std::chrono::steady_clock::time_point now, int fps,
|
void RecordCaptureCadence(std::chrono::steady_clock::time_point now, int fps,
|
||||||
@@ -115,6 +118,7 @@ private:
|
|||||||
std::unordered_map<std::string, SDL_AudioStream*> output_streams_;
|
std::unordered_map<std::string, SDL_AudioStream*> output_streams_;
|
||||||
ScreenCapturerFactory *screen_capturer_factory_ = nullptr;
|
ScreenCapturerFactory *screen_capturer_factory_ = nullptr;
|
||||||
ScreenCapturer *screen_capturer_ = nullptr;
|
ScreenCapturer *screen_capturer_ = nullptr;
|
||||||
|
ScreenSharingPower screen_sharing_power_;
|
||||||
std::atomic<bool> cursor_capture_dirty_{true};
|
std::atomic<bool> cursor_capture_dirty_{true};
|
||||||
SpeakerCaptureController speaker_capture_;
|
SpeakerCaptureController speaker_capture_;
|
||||||
DeviceControllerFactory *device_controller_factory_ = nullptr;
|
DeviceControllerFactory *device_controller_factory_ = nullptr;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace crossdesk {
|
|||||||
|
|
||||||
int RunSlintRendererProbe() {
|
int RunSlintRendererProbe() {
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||||
|
// Renderer probing should not inhibit automatic display sleep either.
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,16 @@ function setup_platform_settings()
|
|||||||
"/usr/local/include/freetype2"
|
"/usr/local/include/freetype2"
|
||||||
}, {system = true})
|
}, {system = true})
|
||||||
|
|
||||||
|
-- Screen sharing power inhibitors also use D-Bus in X11-only builds.
|
||||||
|
add_links("dbus-1")
|
||||||
|
add_existing_include_dirs({
|
||||||
|
"/usr/include/dbus-1.0",
|
||||||
|
"/usr/local/include/dbus-1.0"
|
||||||
|
}, {system = true})
|
||||||
|
for _, include_dir in ipairs(collect_dbus_arch_include_dirs()) do
|
||||||
|
add_includedirs(include_dir, {system = true})
|
||||||
|
end
|
||||||
|
|
||||||
if is_config("USE_DRM", true) then
|
if is_config("USE_DRM", true) then
|
||||||
add_links("drm")
|
add_links("drm")
|
||||||
add_defines("CROSSDESK_HAS_DRM=1")
|
add_defines("CROSSDESK_HAS_DRM=1")
|
||||||
@@ -69,11 +79,8 @@ function setup_platform_settings()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if is_config("USE_WAYLAND", true) then
|
if is_config("USE_WAYLAND", true) then
|
||||||
add_links("dbus-1")
|
|
||||||
add_defines("CROSSDESK_HAS_WAYLAND_CAPTURER=1")
|
add_defines("CROSSDESK_HAS_WAYLAND_CAPTURER=1")
|
||||||
add_existing_include_dirs({
|
add_existing_include_dirs({
|
||||||
"/usr/include/dbus-1.0",
|
|
||||||
"/usr/local/include/dbus-1.0",
|
|
||||||
"/usr/include/pipewire-0.3",
|
"/usr/include/pipewire-0.3",
|
||||||
"/usr/local/include/pipewire-0.3",
|
"/usr/local/include/pipewire-0.3",
|
||||||
"/usr/include/pipewire",
|
"/usr/include/pipewire",
|
||||||
@@ -85,9 +92,6 @@ function setup_platform_settings()
|
|||||||
"/usr/local/include/spa",
|
"/usr/local/include/spa",
|
||||||
"/opt/crossdesk-pipewire-sdk/include/spa-0.2"
|
"/opt/crossdesk-pipewire-sdk/include/spa-0.2"
|
||||||
}, {system = true})
|
}, {system = true})
|
||||||
for _, include_dir in ipairs(collect_dbus_arch_include_dirs()) do
|
|
||||||
add_includedirs(include_dir, {system = true})
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
add_defines("CROSSDESK_HAS_WAYLAND_CAPTURER=0")
|
add_defines("CROSSDESK_HAS_WAYLAND_CAPTURER=0")
|
||||||
end
|
end
|
||||||
@@ -98,7 +102,7 @@ function setup_platform_settings()
|
|||||||
add_ldflags("-Wl,-ld_classic")
|
add_ldflags("-Wl,-ld_classic")
|
||||||
end
|
end
|
||||||
add_cxflags("-Wno-unused-variable")
|
add_cxflags("-Wno-unused-variable")
|
||||||
add_frameworks("Cocoa", "CoreGraphics", "Metal", "QuartzCore",
|
add_frameworks("Cocoa", "CoreGraphics", "Metal", "QuartzCore", "IOKit",
|
||||||
"IOSurface",
|
"IOSurface",
|
||||||
"ScreenCaptureKit", "AVFoundation", "CoreMedia", "CoreVideo",
|
"ScreenCaptureKit", "AVFoundation", "CoreMedia", "CoreVideo",
|
||||||
"CoreAudio", "AudioToolbox")
|
"CoreAudio", "AudioToolbox")
|
||||||
|
|||||||
Reference in New Issue
Block a user