mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-11-10 19:00:53 +08:00
fix(macos): turn privacy mode off before locking at session end (#16729)
* fix(macos): turn privacy mode off before locking at session end Most closes call on_close(.., true) from inside the connection loop, which locks the screen before the loop turns privacy mode off. On macOS the lock is a Ctrl+Cmd+Q queued on the main queue, and privacy mode's event tap is torn down on that same queue right after it, so the screen did not lock and the displays came back on unlocked. On macOS a connection that owns privacy mode now turns it off before locking. The macOS lock_screen() also checks that the screen locked (CGSSessionScreenIsLocked) and presses the shortcut once more if not. Fixes #15875 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(macos): check the lock once more after the last wait The retry loop ended its last wait without checking, so a lock that landed in the final 100 ms pressed the shortcut again or logged a false "Failed to lock the screen". Wait in platform::wait_locked(), which also checks at the deadline, and keep the first press as it is on master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refact(macos): keep on_close a one-line hook for the turn-off before locking Move the ownership check and the turn-off into privacy_mode::macos, so the shared Connection::on_close only calls it, and log a failed turn-off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(macos): turn privacy mode off on the main queue The blackout monitor, the display reconfiguration callback and the deferred shutdown lock g_privacyModeMutex on the main thread, while the turn-off held that mutex and waited for the main queue to tear the event tap down, so the two could deadlock. The turn-off now runs before the lock at session end, where a deadlock would also keep the lock from being requested. Called off the main thread with privacy mode on, MacSetPrivacyMode(false) now runs the whole turn-off on the main queue. With privacy mode off it returns as before, without touching the main queue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(macos): leave lock_screen() as on master Review asked to keep this PR to the ordering fix. Drop the second press in lock_screen() and the wait_locked() helper it used, so ordinary macOS lock requests behave as on master again. Privacy mode is still turned off before the lock at session end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
05b9f2d891
commit
95cca3f661
3 files changed
+28
No files matched your search
@@ -802,6 +802,22 @@ static bool TurnOffPrivacyModeInternal() {
|
||||
}
|
||||
|
||||
extern "C" bool MacSetPrivacyMode(bool on) {
|
||||
if (!on && ![NSThread isMainThread]) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_privacyModeMutex);
|
||||
if (!g_privacyModeActive) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The blackout monitor, the reconfiguration callback and the deferred shutdown lock
|
||||
// g_privacyModeMutex on the main thread, so the teardown must not wait for the main
|
||||
// queue while holding the mutex. Turn privacy mode off on the main queue instead.
|
||||
__block bool result = true;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
result = MacSetPrivacyMode(false);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(g_privacyModeMutex);
|
||||
if (on) {
|
||||
// Already in privacy mode
|
||||
|
||||
@@ -79,3 +79,13 @@ impl Drop for PrivacyModeImpl {
|
||||
self.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Most closes lock before the connection loop turns privacy mode off, and a lock shortcut
|
||||
/// injected while the tap and the blackout are torn down can be lost (#15875).
|
||||
pub fn turn_off_before_lock(conn_id: i32) {
|
||||
if super::get_privacy_mode_conn_id() == Some(conn_id) {
|
||||
if let Some(Err(e)) = super::turn_off_privacy(conn_id, None) {
|
||||
hbb_common::log::error!("Failed to turn off privacy mode before locking: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5322,6 +5322,8 @@ impl Connection {
|
||||
&& self.keyboard
|
||||
&& !raii::AuthedConnID::session_reconnected(self.inner.id(), &self.session_key())
|
||||
{
|
||||
#[cfg(target_os = "macos")]
|
||||
privacy_mode::macos::turn_off_before_lock(self.inner.id());
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
lock_screen().await;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user