Skip to content

Commit

Permalink
Merge pull request rustdesk#6258 from fufesou/fix/remove_unused_captu…
Browse files Browse the repository at this point in the history
…rer_on_peer

fix, remove unused capturer when switching display
  • Loading branch information
rustdesk authored Nov 1, 2023
2 parents 52a4d41 + 58d073b commit faf99ff
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 42 deletions.
5 changes: 3 additions & 2 deletions flutter/lib/desktop/widgets/remote_toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
32 changes: 22 additions & 10 deletions flutter/lib/models/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
}

Expand Down
82 changes: 63 additions & 19 deletions src/flutter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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
Expand Down
8 changes: 1 addition & 7 deletions src/flutter_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
11 changes: 8 additions & 3 deletions src/server/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/server/display_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit faf99ff

Please sign in to comment.