fix: privacy mode 2, restore (#9141)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
parent
529e70910d
commit
fc607d6789
@ -34,7 +34,7 @@ const CONFIG_KEY_REG_RECOVERY: &str = "reg_recovery";
|
|||||||
struct Display {
|
struct Display {
|
||||||
dm: DEVMODEW,
|
dm: DEVMODEW,
|
||||||
name: [WCHAR; 32],
|
name: [WCHAR; 32],
|
||||||
_primary: bool,
|
primary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PrivacyModeImpl {
|
pub struct PrivacyModeImpl {
|
||||||
@ -135,7 +135,7 @@ impl PrivacyModeImpl {
|
|||||||
let display = Display {
|
let display = Display {
|
||||||
dm,
|
dm,
|
||||||
name: dd.DeviceName,
|
name: dd.DeviceName,
|
||||||
_primary: primary,
|
primary,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ds = virtual_display_manager::get_cur_device_string();
|
let ds = virtual_display_manager::get_cur_device_string();
|
||||||
@ -357,6 +357,35 @@ impl PrivacyModeImpl {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn restore(&mut self) {
|
||||||
|
Self::restore_displays(&self.displays);
|
||||||
|
Self::restore_displays(&self.virtual_displays);
|
||||||
|
allow_err!(Self::commit_change_display(0));
|
||||||
|
self.restore_plug_out_monitor();
|
||||||
|
self.displays.clear();
|
||||||
|
self.virtual_displays.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_displays(displays: &[Display]) {
|
||||||
|
for display in displays {
|
||||||
|
unsafe {
|
||||||
|
let mut dm = display.dm.clone();
|
||||||
|
let flags = if display.primary {
|
||||||
|
CDS_NORESET | CDS_UPDATEREGISTRY | CDS_SET_PRIMARY
|
||||||
|
} else {
|
||||||
|
CDS_NORESET | CDS_UPDATEREGISTRY
|
||||||
|
};
|
||||||
|
ChangeDisplaySettingsExW(
|
||||||
|
display.name.as_ptr(),
|
||||||
|
&mut dm,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
flags,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrivacyMode for PrivacyModeImpl {
|
impl PrivacyMode for PrivacyModeImpl {
|
||||||
@ -431,14 +460,9 @@ impl PrivacyMode for PrivacyModeImpl {
|
|||||||
) -> ResultType<()> {
|
) -> ResultType<()> {
|
||||||
self.check_off_conn_id(conn_id)?;
|
self.check_off_conn_id(conn_id)?;
|
||||||
super::win_input::unhook()?;
|
super::win_input::unhook()?;
|
||||||
let virtual_display_added = self.virtual_displays_added.len() > 0;
|
let _tmp_ignore_changed_holder = crate::display_service::temp_ignore_displays_changed();
|
||||||
if virtual_display_added {
|
self.restore();
|
||||||
self.restore_plug_out_monitor();
|
|
||||||
}
|
|
||||||
restore_reg_connectivity(false);
|
restore_reg_connectivity(false);
|
||||||
if !virtual_display_added {
|
|
||||||
Self::commit_change_display(CDS_RESET)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.conn_id != INVALID_PRIVACY_MODE_CONN_ID {
|
if self.conn_id != INVALID_PRIVACY_MODE_CONN_ID {
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::common::SimpleCallOnReturn;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use crate::platform::linux::is_x11;
|
use crate::platform::linux::is_x11;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -7,6 +8,7 @@ use crate::virtual_display_manager;
|
|||||||
use hbb_common::get_version_number;
|
use hbb_common::get_version_number;
|
||||||
use hbb_common::protobuf::MessageField;
|
use hbb_common::protobuf::MessageField;
|
||||||
use scrap::Display;
|
use scrap::Display;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
// https://github.com/rustdesk/rustdesk/discussions/6042, avoiding dbus call
|
// https://github.com/rustdesk/rustdesk/discussions/6042, avoiding dbus call
|
||||||
|
|
||||||
@ -29,6 +31,9 @@ lazy_static::lazy_static! {
|
|||||||
static ref SYNC_DISPLAYS: Arc<Mutex<SyncDisplaysInfo>> = Default::default();
|
static ref SYNC_DISPLAYS: Arc<Mutex<SyncDisplaysInfo>> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rustdesk/rustdesk/pull/8537
|
||||||
|
static TEMP_IGNORE_DISPLAYS_CHANGED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SyncDisplaysInfo {
|
struct SyncDisplaysInfo {
|
||||||
displays: Vec<DisplayInfo>,
|
displays: Vec<DisplayInfo>,
|
||||||
@ -39,13 +44,17 @@ impl SyncDisplaysInfo {
|
|||||||
fn check_changed(&mut self, displays: Vec<DisplayInfo>) {
|
fn check_changed(&mut self, displays: Vec<DisplayInfo>) {
|
||||||
if self.displays.len() != displays.len() {
|
if self.displays.len() != displays.len() {
|
||||||
self.displays = displays;
|
self.displays = displays;
|
||||||
self.is_synced = false;
|
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||||
|
self.is_synced = false;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i, d) in displays.iter().enumerate() {
|
for (i, d) in displays.iter().enumerate() {
|
||||||
if d != &self.displays[i] {
|
if d != &self.displays[i] {
|
||||||
self.displays = displays;
|
self.displays = displays;
|
||||||
self.is_synced = false;
|
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||||
|
self.is_synced = false;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +69,21 @@ impl SyncDisplaysInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn temp_ignore_displays_changed() -> SimpleCallOnReturn {
|
||||||
|
TEMP_IGNORE_DISPLAYS_CHANGED.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
SimpleCallOnReturn {
|
||||||
|
b: true,
|
||||||
|
f: Box::new(move || {
|
||||||
|
// Wait for a while to make sure check_display_changed() is called
|
||||||
|
// after video service has sending its `SwitchDisplay` message(`try_broadcast_display_changed()`).
|
||||||
|
std::thread::sleep(Duration::from_millis(1000));
|
||||||
|
TEMP_IGNORE_DISPLAYS_CHANGED.store(false, Ordering::Relaxed);
|
||||||
|
// Trigger the display changed message.
|
||||||
|
SYNC_DISPLAYS.lock().unwrap().is_synced = false;
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This function is really useful, though a duplicate check if display changed.
|
// This function is really useful, though a duplicate check if display changed.
|
||||||
// The video server will then send the following messages to the client:
|
// The video server will then send the following messages to the client:
|
||||||
// 1. the supported resolutions of the {idx} display
|
// 1. the supported resolutions of the {idx} display
|
||||||
@ -204,9 +228,11 @@ fn get_displays_msg() -> Option<Message> {
|
|||||||
fn run(sp: EmptyExtraFieldService) -> ResultType<()> {
|
fn run(sp: EmptyExtraFieldService) -> ResultType<()> {
|
||||||
while sp.ok() {
|
while sp.ok() {
|
||||||
sp.snapshot(|sps| {
|
sp.snapshot(|sps| {
|
||||||
if sps.has_subscribes() {
|
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||||
SYNC_DISPLAYS.lock().unwrap().is_synced = false;
|
if sps.has_subscribes() {
|
||||||
bail!("new subscriber");
|
SYNC_DISPLAYS.lock().unwrap().is_synced = false;
|
||||||
|
bail!("new subscriber");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user