mirror of
https://github.com/rustdesk/rustdesk
synced 2026-04-21 13:27:19 +00:00
fix(client): use window-scoped ID and fix deferred-release re-arming
Address PR review feedback: - Use per-window UUID instead of connection-scoped lc.session_id so two windows viewing the same peer get distinct grab owners - Reset deferred_pending on both idempotent Run refresh and owner handoff, so a subsequent Wait can always spawn a fresh timer - Replace manual Default impl with derive
This commit is contained in:
parent
eb42d87994
commit
a069b1d74c
2 changed files with 20 additions and 8 deletions
|
|
@ -615,11 +615,22 @@ pub fn session_enter_or_leave(_session_id: SessionID, _enter: bool) -> SyncRetur
|
|||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
if let Some(session) = sessions::get_session_by_session_id(&_session_id) {
|
||||
let keyboard_mode = session.get_keyboard_mode();
|
||||
// Use the per-window UUID (not lc.session_id which is per-connection)
|
||||
// so that two windows viewing the same peer get distinct grab owners.
|
||||
let window_id = _session_id.as_u128() as u64;
|
||||
if _enter {
|
||||
set_cur_session_id_(_session_id, &keyboard_mode);
|
||||
session.enter(keyboard_mode);
|
||||
crate::keyboard::client::change_grab_status(
|
||||
crate::common::GrabState::Run,
|
||||
&keyboard_mode,
|
||||
window_id,
|
||||
);
|
||||
} else {
|
||||
session.leave(keyboard_mode);
|
||||
crate::keyboard::client::change_grab_status(
|
||||
crate::common::GrabState::Wait,
|
||||
&keyboard_mode,
|
||||
window_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
SyncReturn(())
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub mod client {
|
|||
/// PointerEnter -> grab -> ... at ~10 Hz. `last_grab` lets us debounce
|
||||
/// spurious `Wait` events that arrive shortly after a `Run` for the same
|
||||
/// session - these are X11 focus feedback, not real user actions.
|
||||
#[derive(Default)]
|
||||
struct GrabOwnerState {
|
||||
owner: Option<u64>,
|
||||
last_grab: Option<std::time::Instant>,
|
||||
|
|
@ -97,12 +98,6 @@ pub mod client {
|
|||
deferred_pending: bool,
|
||||
}
|
||||
|
||||
impl Default for GrabOwnerState {
|
||||
fn default() -> Self {
|
||||
Self { owner: None, last_grab: None, deferred_pending: false }
|
||||
}
|
||||
}
|
||||
|
||||
/// How long after a grab acquisition we suppress Wait from the same session.
|
||||
/// Must exceed one full X11 feedback cycle (~100 ms: 50 ms enable + 50 ms disable).
|
||||
const GRAB_DEBOUNCE_MS: u128 = 300;
|
||||
|
|
@ -141,6 +136,9 @@ pub mod client {
|
|||
// actively focused) and skip the actual grab call.
|
||||
if gs.owner == Some(session_id) {
|
||||
gs.last_grab = Some(std::time::Instant::now());
|
||||
// Reset so the next Wait can spawn a fresh deferred-release
|
||||
// timer with an up-to-date snapshot of last_grab.
|
||||
gs.deferred_pending = false;
|
||||
log::debug!("[grab] Run(0x{:x}): already owner, refresh debounce", session_id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -169,6 +167,9 @@ pub mod client {
|
|||
}
|
||||
gs.owner = Some(session_id);
|
||||
gs.last_grab = Some(std::time::Instant::now());
|
||||
// Invalidate any in-flight deferred release from the previous
|
||||
// owner so it cannot suppress a fresh timer for the new owner.
|
||||
gs.deferred_pending = false;
|
||||
}
|
||||
GrabState::Wait => {
|
||||
// Drop stale `Wait` events that do not correspond to the
|
||||
|
|
|
|||
Loading…
Reference in a new issue