Merge pull request #6258 from fufesou/fix/remove_unused_capturer_on_peer

fix, remove unused capturer when switching display
This commit is contained in:
RustDesk 2023-11-01 20:06:12 +08:00 committed by GitHub
commit faf99ffe14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 42 deletions

View File

@ -1223,8 +1223,9 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
@override
Widget build(BuildContext context) {
final isVirtualDisplay = ffiModel.isVirtualDisplayResolution;
final visible =
ffiModel.keyboard && (isVirtualDisplay || resolutions.length > 1);
final visible = ffiModel.keyboard &&
(isVirtualDisplay || resolutions.length > 1) &&
pi.currentDisplay != kAllDisplayValue;
if (!visible) return Offstage();
final showOriginalBtn =
ffiModel.isOriginalResolutionSet && !ffiModel.isOriginalResolution;

View File

@ -431,15 +431,19 @@ class FfiModel with ChangeNotifier {
handleSwitchDisplay(
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
final curDisplay = int.parse(evt['display']);
final display = int.parse(evt['display']);
if (_pi.currentDisplay != kAllDisplayValue) {
if (bind.peerGetDefaultSessionsCount(id: peerId) > 1) {
if (curDisplay != _pi.currentDisplay) {
if (display != _pi.currentDisplay) {
return;
}
}
_pi.currentDisplay = curDisplay;
if (!_pi.isSupportMultiUiSession) {
_pi.currentDisplay = display;
}
// If `isSupportMultiUiSession` is true, the switch display message should not be used to update current display.
// It is only used to update the display info.
}
var newDisplay = Display();
@ -452,16 +456,24 @@ class FfiModel with ChangeNotifier {
int.tryParse(evt['original_width']) ?? kInvalidResolutionValue;
newDisplay.originalHeight =
int.tryParse(evt['original_height']) ?? kInvalidResolutionValue;
_pi.displays[curDisplay] = newDisplay;
_pi.displays[display] = newDisplay;
updateCurDisplay(sessionId);
try {
CurrentDisplayState.find(peerId).value = curDisplay;
} catch (e) {
//
if (!_pi.isSupportMultiUiSession || _pi.currentDisplay == display) {
updateCurDisplay(sessionId);
}
if (!_pi.isSupportMultiUiSession) {
try {
CurrentDisplayState.find(peerId).value = display;
} catch (e) {
//
}
}
parent.target?.recordingModel.onSwitchDisplay();
handleResolutions(peerId, evt['resolutions']);
if (!_pi.isSupportMultiUiSession || _pi.currentDisplay == display) {
handleResolutions(peerId, evt['resolutions']);
}
notifyListeners();
}

View File

@ -1466,25 +1466,7 @@ pub mod sessions {
if write_lock.is_empty() {
remove_peer_key = Some(peer_key.clone());
} else {
// Set capture displays if some are not used any more.
let mut remains_displays = HashSet::new();
for (_, h) in write_lock.iter() {
remains_displays.extend(
h.renderer
.map_display_sessions
.read()
.unwrap()
.keys()
.cloned(),
);
}
if !remains_displays.is_empty() {
s.capture_displays(
vec![],
vec![],
remains_displays.iter().map(|d| *d as i32).collect(),
);
}
check_remove_unused_displays(None, id, s, &write_lock);
}
break;
}
@ -1494,6 +1476,68 @@ pub mod sessions {
SESSIONS.write().unwrap().remove(&remove_peer_key?)
}
#[cfg(feature = "flutter_texture_render")]
fn check_remove_unused_displays(
current: Option<usize>,
session_id: &SessionID,
session: &FlutterSession,
handlers: &HashMap<SessionID, SessionHandler>,
) {
// Set capture displays if some are not used any more.
let mut remains_displays = HashSet::new();
if let Some(current) = current {
remains_displays.insert(current);
}
for (k, h) in handlers.iter() {
if k == session_id {
continue;
}
remains_displays.extend(
h.renderer
.map_display_sessions
.read()
.unwrap()
.keys()
.cloned(),
);
}
if !remains_displays.is_empty() {
session.capture_displays(
vec![],
vec![],
remains_displays.iter().map(|d| *d as i32).collect(),
);
}
}
pub fn session_switch_display(session_id: SessionID, value: Vec<i32>) {
for s in SESSIONS.read().unwrap().values() {
let read_lock = s.ui_handler.session_handlers.read().unwrap();
if read_lock.contains_key(&session_id) {
if value.len() == 1 {
// Switch display.
// This operation will also cause the peer to send a switch display message.
// The switch display message will contain `SupportedResolutions`, which is useful when changing resolutions.
s.switch_display(value[0]);
// Check if other displays are needed.
if value.len() == 1 {
check_remove_unused_displays(
Some(value[0] as _),
&session_id,
&s,
&read_lock,
);
}
} else {
// Try capture all displays.
s.capture_displays(vec![], vec![], value);
}
break;
}
}
}
#[inline]
pub fn insert_session(session_id: SessionID, conn_type: ConnType, session: FlutterSession) {
SESSIONS

View File

@ -429,13 +429,7 @@ pub fn session_ctrl_alt_del(session_id: SessionID) {
}
pub fn session_switch_display(session_id: SessionID, value: Vec<i32>) {
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
if value.len() == 1 {
session.switch_display(value[0]);
} else {
session.capture_displays(vec![], vec![], value);
}
}
sessions::session_switch_display(session_id, value);
}
pub fn session_handle_flutter_key_event(

View File

@ -2177,8 +2177,9 @@ impl Connection {
}
// Send display changed message.
// For compatibility with old versions ( < 1.2.4 ).
// sciter need it in new version
// 1. For compatibility with old versions ( < 1.2.4 ).
// 2. Sciter version.
// 3. Update `SupportedResolutions`.
if let Some(msg_out) = video_service::make_display_changed_msg(self.display_idx, None) {
self.send(msg_out).await;
}
@ -2194,7 +2195,11 @@ impl Connection {
lock.add_service(Box::new(video_service::new(display_idx)));
}
}
lock.subscribe(&old_service_name, self.inner.clone(), false);
// For versions greater than 1.2.4, a `CaptureDisplays` message will be sent immediately.
// Unnecessary capturers will be removed then.
if !crate::common::is_support_multi_ui_session(&self.lr.version) {
lock.subscribe(&old_service_name, self.inner.clone(), false);
}
lock.subscribe(&new_service_name, self.inner.clone(), true);
self.display_idx = display_idx;
}

View File

@ -349,7 +349,7 @@ pub fn try_get_displays() -> ResultType<Vec<Display>> {
#[cfg(all(windows, feature = "virtual_display_driver"))]
pub fn try_get_displays() -> ResultType<Vec<Display>> {
let mut displays = Display::all()?;
if no_displays(&displays) {
if crate::platform::is_installed() && no_displays(&displays) {
log::debug!("no displays, create virtual display");
if let Err(e) = virtual_display_manager::plug_in_headless() {
log::error!("plug in headless failed {}", e);