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 {
|
||||
dm: DEVMODEW,
|
||||
name: [WCHAR; 32],
|
||||
_primary: bool,
|
||||
primary: bool,
|
||||
}
|
||||
|
||||
pub struct PrivacyModeImpl {
|
||||
@ -135,7 +135,7 @@ impl PrivacyModeImpl {
|
||||
let display = Display {
|
||||
dm,
|
||||
name: dd.DeviceName,
|
||||
_primary: primary,
|
||||
primary,
|
||||
};
|
||||
|
||||
let ds = virtual_display_manager::get_cur_device_string();
|
||||
@ -357,6 +357,35 @@ impl PrivacyModeImpl {
|
||||
}
|
||||
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 {
|
||||
@ -431,14 +460,9 @@ impl PrivacyMode for PrivacyModeImpl {
|
||||
) -> ResultType<()> {
|
||||
self.check_off_conn_id(conn_id)?;
|
||||
super::win_input::unhook()?;
|
||||
let virtual_display_added = self.virtual_displays_added.len() > 0;
|
||||
if virtual_display_added {
|
||||
self.restore_plug_out_monitor();
|
||||
}
|
||||
let _tmp_ignore_changed_holder = crate::display_service::temp_ignore_displays_changed();
|
||||
self.restore();
|
||||
restore_reg_connectivity(false);
|
||||
if !virtual_display_added {
|
||||
Self::commit_change_display(CDS_RESET)?;
|
||||
}
|
||||
|
||||
if self.conn_id != INVALID_PRIVACY_MODE_CONN_ID {
|
||||
if let Some(state) = state {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use crate::common::SimpleCallOnReturn;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::platform::linux::is_x11;
|
||||
#[cfg(windows)]
|
||||
@ -7,6 +8,7 @@ use crate::virtual_display_manager;
|
||||
use hbb_common::get_version_number;
|
||||
use hbb_common::protobuf::MessageField;
|
||||
use scrap::Display;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// https://github.com/rustdesk/rustdesk/pull/8537
|
||||
static TEMP_IGNORE_DISPLAYS_CHANGED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[derive(Default)]
|
||||
struct SyncDisplaysInfo {
|
||||
displays: Vec<DisplayInfo>,
|
||||
@ -39,13 +44,17 @@ impl SyncDisplaysInfo {
|
||||
fn check_changed(&mut self, displays: Vec<DisplayInfo>) {
|
||||
if self.displays.len() != displays.len() {
|
||||
self.displays = displays;
|
||||
self.is_synced = false;
|
||||
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||
self.is_synced = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i, d) in displays.iter().enumerate() {
|
||||
if d != &self.displays[i] {
|
||||
self.displays = displays;
|
||||
self.is_synced = false;
|
||||
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||
self.is_synced = false;
|
||||
}
|
||||
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.
|
||||
// The video server will then send the following messages to the client:
|
||||
// 1. the supported resolutions of the {idx} display
|
||||
@ -204,9 +228,11 @@ fn get_displays_msg() -> Option<Message> {
|
||||
fn run(sp: EmptyExtraFieldService) -> ResultType<()> {
|
||||
while sp.ok() {
|
||||
sp.snapshot(|sps| {
|
||||
if sps.has_subscribes() {
|
||||
SYNC_DISPLAYS.lock().unwrap().is_synced = false;
|
||||
bail!("new subscriber");
|
||||
if !TEMP_IGNORE_DISPLAYS_CHANGED.load(Ordering::Relaxed) {
|
||||
if sps.has_subscribes() {
|
||||
SYNC_DISPLAYS.lock().unwrap().is_synced = false;
|
||||
bail!("new subscriber");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
Loading…
x
Reference in New Issue
Block a user