mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-24 13:48:51 +08:00
[fix] preserve remote cursors when macOS hides the pointer, refs #116
This commit is contained in:
@@ -3112,8 +3112,10 @@ void GuiApplication::SyncStreamWindow() {
|
|||||||
}
|
}
|
||||||
const ConnectionStatus status = props->connection_status_.load();
|
const ConnectionStatus status = props->connection_status_.load();
|
||||||
bool remote_update_available = false;
|
bool remote_update_available = false;
|
||||||
|
HostPlatform remote_platform = HostPlatform::Unknown;
|
||||||
if (status == ConnectionStatus::Connected) {
|
if (status == ConnectionStatus::Connected) {
|
||||||
std::lock_guard lock(props->remote_version_mutex_);
|
std::lock_guard lock(props->remote_version_mutex_);
|
||||||
|
remote_platform = props->remote_platform_;
|
||||||
// Wait for host_info: a version still in transit is not a legacy peer.
|
// Wait for host_info: a version still in transit is not a legacy peer.
|
||||||
if (props->remote_host_info_received_ && !props->remote_update_dismissed_) {
|
if (props->remote_host_info_received_ && !props->remote_update_dismissed_) {
|
||||||
remote_update_available = props->remote_app_version_.empty() ||
|
remote_update_available = props->remote_app_version_.empty() ||
|
||||||
@@ -3176,7 +3178,7 @@ void GuiApplication::SyncStreamWindow() {
|
|||||||
props->remote_cursor_state_received_;
|
props->remote_cursor_state_received_;
|
||||||
if (remote_cursor_active) {
|
if (remote_cursor_active) {
|
||||||
remote_cursor_shape = static_cast<int>(
|
remote_cursor_shape = static_cast<int>(
|
||||||
props->cursor_presentation_.Resolve(SDL_GetTicks()));
|
props->cursor_presentation_.Resolve(SDL_GetTicks(), remote_platform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*ui_->stream)->set_remote_cursor_active(remote_cursor_active);
|
(*ui_->stream)->set_remote_cursor_active(remote_cursor_active);
|
||||||
|
|||||||
@@ -33,6 +33,15 @@ class CursorPresentation {
|
|||||||
const bool separate =
|
const bool separate =
|
||||||
state.render_mode == CursorRenderMode::separate ||
|
state.render_mode == CursorRenderMode::separate ||
|
||||||
(state.render_mode == CursorRenderMode::legacy && state.visible);
|
(state.render_mode == CursorRenderMode::legacy && state.visible);
|
||||||
|
system_hidden_ = state.render_mode == CursorRenderMode::hidden &&
|
||||||
|
state.hidden_reason == CursorHiddenReason::system_hidden;
|
||||||
|
if (separate) {
|
||||||
|
mac_locator_allowed_ = state.shape != RemoteCursorShape::none;
|
||||||
|
} else if (!system_hidden_) {
|
||||||
|
// Embedded cursors and other hiding policies end the separate-cursor
|
||||||
|
// history. A later system_hidden sample must not revive that overlay.
|
||||||
|
mac_locator_allowed_ = false;
|
||||||
|
}
|
||||||
// Old senders cannot distinguish embedded from hidden. Only explicit
|
// Old senders cannot distinguish embedded from hidden. Only explicit
|
||||||
// metadata from a new sender can establish the no-device compatibility
|
// metadata from a new sender can establish the no-device compatibility
|
||||||
// case.
|
// case.
|
||||||
@@ -47,9 +56,21 @@ class CursorPresentation {
|
|||||||
|
|
||||||
void NoteInput(uint64_t now) { last_input_ = now; }
|
void NoteInput(uint64_t now) { last_input_ = now; }
|
||||||
|
|
||||||
RemoteCursorShape Resolve(uint64_t now) {
|
RemoteCursorShape Resolve(uint64_t now, HostPlatform remote_platform) {
|
||||||
if (!stale_at_) return RemoteCursorShape::default_cursor;
|
if (!stale_at_) return RemoteCursorShape::default_cursor;
|
||||||
|
|
||||||
|
// macOS can keep its system cursor hidden after typing even while remote
|
||||||
|
// mouse events move it. Keep a previously separate desktop locator across
|
||||||
|
// those heartbeats; the video has no pointer to fall back to. On a new
|
||||||
|
// connection, use an arrow until the first visible shape arrives. The
|
||||||
|
// protocol cannot distinguish typing from other system_hidden cases;
|
||||||
|
// restrict this policy to identified Mac hosts and stop on any explicit
|
||||||
|
// embedded cursor or other hiding policy.
|
||||||
|
if (remote_platform == HostPlatform::MacOS && system_hidden_ &&
|
||||||
|
mac_locator_allowed_) {
|
||||||
|
return last_visible_shape_;
|
||||||
|
}
|
||||||
|
|
||||||
const bool recent_input =
|
const bool recent_input =
|
||||||
last_input_ && now - *last_input_ < kInputActivityMs;
|
last_input_ && now - *last_input_ < kInputActivityMs;
|
||||||
const bool can_recover =
|
const bool can_recover =
|
||||||
@@ -64,6 +85,8 @@ class CursorPresentation {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool sample_unavailable_ = false;
|
bool sample_unavailable_ = false;
|
||||||
|
bool system_hidden_ = false;
|
||||||
|
bool mac_locator_allowed_ = true;
|
||||||
bool no_device_ = false;
|
bool no_device_ = false;
|
||||||
bool fallback_engaged_ = false;
|
bool fallback_engaged_ = false;
|
||||||
std::optional<uint64_t> stale_at_;
|
std::optional<uint64_t> stale_at_;
|
||||||
|
|||||||
Reference in New Issue
Block a user