mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-28 08:42:43 +08:00
[feat] add Linux X11 privacy screen and automatic recovery
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <display_stream_id.h>
|
||||
#include "platform.h"
|
||||
#include "privacy_controller.h"
|
||||
#include "rd_log.h"
|
||||
#if defined(CROSSDESK_HAS_DRM) && CROSSDESK_HAS_DRM
|
||||
#include "screen_capturer_drm.h"
|
||||
@@ -64,6 +65,13 @@ int ScreenCapturerLinux::Init(const int fps, cb_desktop_data cb) {
|
||||
return;
|
||||
}
|
||||
invalid_stream_id_logged_.store(false, std::memory_order_relaxed);
|
||||
{
|
||||
std::lock_guard lock(privacy_mutex_);
|
||||
if (privacy_ && !capture_paused_ && !capture_announced_) {
|
||||
capture_announced_ = true;
|
||||
privacy_->CaptureChanged(true);
|
||||
}
|
||||
}
|
||||
if (callback_orig_) {
|
||||
callback_orig_(data, size, width, height, mapped_stream_id.c_str(),
|
||||
native_frame);
|
||||
@@ -145,6 +153,7 @@ int ScreenCapturerLinux::Init(const int fps, cb_desktop_data cb) {
|
||||
}
|
||||
|
||||
int ScreenCapturerLinux::Destroy() {
|
||||
Stop();
|
||||
if (impl_) {
|
||||
impl_->Destroy();
|
||||
impl_.reset();
|
||||
@@ -169,6 +178,11 @@ int ScreenCapturerLinux::Start(bool show_cursor) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard lock(privacy_mutex_);
|
||||
capture_paused_ = false;
|
||||
}
|
||||
|
||||
// X11 output names, DRM connectors and Wayland stream handles may all change
|
||||
// after an HDMI hotplug, so rebuild the current backend before each session.
|
||||
const int refresh_ret = RefreshCurrentBackend();
|
||||
@@ -226,6 +240,11 @@ int ScreenCapturerLinux::Stop() {
|
||||
return 0;
|
||||
}
|
||||
const int ret = impl_->Stop();
|
||||
{
|
||||
std::lock_guard lock(privacy_mutex_);
|
||||
capture_announced_ = false;
|
||||
if (privacy_) privacy_->CaptureChanged(false);
|
||||
}
|
||||
UpdateAliasesFromBackend(impl_.get());
|
||||
return ret;
|
||||
}
|
||||
@@ -234,13 +253,25 @@ int ScreenCapturerLinux::Pause(int monitor_index) {
|
||||
if (!impl_) {
|
||||
return -1;
|
||||
}
|
||||
return impl_->Pause(monitor_index);
|
||||
const int ret = impl_->Pause(monitor_index);
|
||||
{
|
||||
// An in-flight frame must not announce running again after a pause.
|
||||
std::lock_guard lock(privacy_mutex_);
|
||||
capture_paused_ = true;
|
||||
capture_announced_ = false;
|
||||
if (privacy_) privacy_->CaptureChanged(false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ScreenCapturerLinux::Resume(int monitor_index) {
|
||||
if (!impl_) {
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(privacy_mutex_);
|
||||
capture_paused_ = false;
|
||||
}
|
||||
return impl_->Resume(monitor_index);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class ScreenCapturerLinux : public ScreenCapturer {
|
||||
|
||||
public:
|
||||
int Init(const int fps, cb_desktop_data cb) override;
|
||||
void SetPrivacyController(PrivacyController* privacy) override { privacy_ = privacy; }
|
||||
int Destroy() override;
|
||||
int Start(bool show_cursor) override;
|
||||
int Stop() override;
|
||||
@@ -53,6 +54,10 @@ class ScreenCapturerLinux : public ScreenCapturer {
|
||||
|
||||
private:
|
||||
std::unique_ptr<ScreenCapturer> impl_;
|
||||
PrivacyController* privacy_ = nullptr;
|
||||
std::mutex privacy_mutex_;
|
||||
bool capture_announced_ = false;
|
||||
bool capture_paused_ = false;
|
||||
BackendType backend_ = BackendType::kNone;
|
||||
int fps_ = 60;
|
||||
cb_desktop_data callback_;
|
||||
|
||||
Reference in New Issue
Block a user