From c1b865d00e95bb63921b42d914b5a8307373785b Mon Sep 17 00:00:00 2001 From: dignow Date: Wed, 18 Oct 2023 09:59:02 +0800 Subject: [PATCH] fix, change_display_resolution, add comments Signed-off-by: dignow --- flutter/lib/models/model.dart | 13 ++++++------- src/server/display_service.rs | 12 ++++++++++++ src/server/video_service.rs | 34 +++++++++++++++++----------------- src/server/wayland.rs | 3 +++ 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index f3d9899e1..ce4cbe523 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -430,14 +430,12 @@ class FfiModel with ChangeNotifier { Map evt, SessionID sessionId, String peerId) { final curDisplay = int.parse(evt['display']); - // The message should be handled by the another UI session. - if (isChooseDisplayToOpenInNewWindow(_pi, sessionId)) { - if (curDisplay != _pi.currentDisplay) { - return; - } - } - if (_pi.currentDisplay != kAllDisplayValue) { + if (bind.peerGetDefaultSessionsCount(id: peerId) > 1) { + if (curDisplay != _pi.currentDisplay) { + return; + } + } _pi.currentDisplay = curDisplay; } @@ -825,6 +823,7 @@ class FfiModel with ChangeNotifier { } _pi.displays = newDisplays; _pi.displaysCount.value = _pi.displays.length; + if (_pi.currentDisplay == kAllDisplayValue) { updateCurDisplay(sessionId); // to-do: What if the displays are changed? diff --git a/src/server/display_service.rs b/src/server/display_service.rs index 878526872..eb9b4272b 100644 --- a/src/server/display_service.rs +++ b/src/server/display_service.rs @@ -59,7 +59,10 @@ impl SyncDisplaysInfo { } } +// This function is really useful, though a duplicate check if display changed. +// Because the video server will send the supported resolutions of the {idx} display to the subscribers. pub(super) fn check_display_changed( + ndisplay: usize, idx: usize, (x, y, w, h): (i32, i32, usize, usize), ) -> Option { @@ -72,7 +75,14 @@ pub(super) fn check_display_changed( } let lock = SYNC_DISPLAYS.lock().unwrap(); + // If plugging out a monitor && lock.displays.get(idx) is None. + // 1. The client version < 1.2.4. The client side has to reconnect. + // 2. The client version > 1.2.4, The client side can handle the case becuase sync peer info message will be sent. + // But it is acceptable to for the user to reconnect manually, becuase the monitor is unplugged. let d = lock.displays.get(idx)?; + if ndisplay != lock.displays.len() { + return Some(d.clone()); + } if !(d.x == x && d.y == y && d.width == w as i32 && d.height == h as i32) { Some(d.clone()) } else { @@ -144,6 +154,8 @@ fn displays_to_msg(displays: Vec) -> Message { ..Default::default() }; pi.displays = displays.clone(); + // current_display should not be used in server. + // It is set to 0 for compatibility with old clients. pi.current_display = 0; let mut msg_out = Message::new(); msg_out.set_peer_info(pi); diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 25b08bb3e..664ca6628 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -297,6 +297,7 @@ pub(super) struct CapturerInfo { pub origin: (i32, i32), pub width: usize, pub height: usize, + pub ndisplay: usize, pub current: usize, pub privacy_mode_id: i32, pub _capturer_privacy_mode_id: i32, @@ -388,6 +389,7 @@ fn get_capturer( origin, width, height, + ndisplay, current, privacy_mode_id, _capturer_privacy_mode_id: capturer_privacy_mode_id, @@ -503,9 +505,11 @@ fn run(vs: VideoService) -> ResultType<()> { let now = time::Instant::now(); if last_check_displays.elapsed().as_millis() > 1000 { last_check_displays = now; - if let Some(display) = - check_display_changed(c.current, (c.origin.0, c.origin.1, c.width, c.height)) - { + if let Some(display) = check_display_changed( + c.ndisplay, + c.current, + (c.origin.0, c.origin.1, c.width, c.height), + ) { log::info!("Display {} changed", display); broadcast_display_changed(display_idx, &sp, &c.name, display); bail!("SWITCH"); @@ -586,6 +590,16 @@ fn run(vs: VideoService) -> ResultType<()> { } } Err(err) => { + if let Some(display) = check_display_changed( + c.ndisplay, + c.current, + (c.origin.0, c.origin.1, c.width, c.height), + ) { + log::info!("Display {} changed", display); + broadcast_display_changed(display_idx, &sp, &c.name, display); + bail!("SWITCH"); + } + #[cfg(windows)] if !c.is_gdi() { c.set_gdi(); @@ -850,20 +864,6 @@ fn broadcast_display_changed( } } -fn get_display_info_simple_meta(display_idx: usize) -> Option<(String, (i32, i32), usize, usize)> { - let displays = display_service::try_get_displays().ok()?; - if let Some(display) = displays.get(display_idx) { - Some(( - display.name(), - display.origin(), - display.width(), - display.height(), - )) - } else { - None - } -} - fn make_display_changed_msg( display_idx: usize, name: &str, diff --git a/src/server/wayland.rs b/src/server/wayland.rs index 2be67bc32..02e83fdc2 100644 --- a/src/server/wayland.rs +++ b/src/server/wayland.rs @@ -84,6 +84,7 @@ impl TraitCapturer for CapturerPtr { struct CapDisplayInfo { rects: Vec<((i32, i32), usize, usize)>, displays: Vec, + num: usize, primary: usize, current: usize, capturer: CapturerPtr, @@ -194,6 +195,7 @@ pub(super) async fn check_init() -> ResultType<()> { let cap_display_info = Box::into_raw(Box::new(CapDisplayInfo { rects, displays, + num, primary, current, capturer, @@ -275,6 +277,7 @@ pub(super) fn get_capturer() -> ResultType { origin: rect.0, width: rect.1, height: rect.2, + ndisplay: cap_display_info.num, current: cap_display_info.current, privacy_mode_id: 0, _capturer_privacy_mode_id: 0,