diff --git a/src/device_controller/device_controller.h b/src/device_controller/device_controller.h index a17be22..80cae5d 100644 --- a/src/device_controller/device_controller.h +++ b/src/device_controller/device_controller.h @@ -74,7 +74,7 @@ typedef struct { // Keep these values aligned with Slint's MouseCursor enum. The wire protocol // intentionally carries a semantic cursor instead of a platform handle so a // Windows, macOS or Linux host can control a different desktop platform. -enum class CursorShape : uint8_t { +enum class RemoteCursorShape : uint8_t { default_cursor = 0, none, help, @@ -109,7 +109,7 @@ enum class CursorShape : uint8_t { typedef struct { uint32_t seq; bool visible; - CursorShape shape; + RemoteCursorShape shape; } CursorState; typedef struct { @@ -270,13 +270,13 @@ struct RemoteAction { case ControlType::cursor_state: { const auto& cursor_state_json = j.at("cursor_state"); const int shape = cursor_state_json.at("shape").get(); - if (shape < static_cast(CursorShape::default_cursor) || - shape > static_cast(CursorShape::nwse_resize)) { + if (shape < static_cast(RemoteCursorShape::default_cursor) || + shape > static_cast(RemoteCursorShape::nwse_resize)) { return false; } out.cs.seq = cursor_state_json.at("seq").get(); out.cs.visible = cursor_state_json.at("visible").get(); - out.cs.shape = static_cast(shape); + out.cs.shape = static_cast(shape); break; } case ControlType::audio_capture: diff --git a/src/gui/application/gui_application.cpp b/src/gui/application/gui_application.cpp index 904aa8e..d05a840 100644 --- a/src/gui/application/gui_application.cpp +++ b/src/gui/application/gui_application.cpp @@ -2418,7 +2418,7 @@ void GuiApplication::SyncStreamWindow() { : std::string{})); (*ui_->stream)->set_mouse_control_enabled(props->control_mouse_); int remote_cursor_shape = - static_cast(CursorShape::default_cursor); + static_cast(RemoteCursorShape::default_cursor); bool remote_cursor_active = false; { std::lock_guard lock(props->remote_cursor_state_mutex_); @@ -2429,7 +2429,7 @@ void GuiApplication::SyncStreamWindow() { remote_cursor_shape = static_cast( props->remote_cursor_state_.visible ? props->remote_cursor_state_.shape - : CursorShape::none); + : RemoteCursorShape::none); } } (*ui_->stream)->set_remote_cursor_active(remote_cursor_active); diff --git a/src/gui/runtime/cursor_state_provider.cpp b/src/gui/runtime/cursor_state_provider.cpp index aaeb2bd..4f06e3b 100644 --- a/src/gui/runtime/cursor_state_provider.cpp +++ b/src/gui/runtime/cursor_state_provider.cpp @@ -11,21 +11,25 @@ bool IsSystemCursor(HCURSOR cursor, LPCWSTR resource) { return cursor != nullptr && cursor == LoadCursorW(nullptr, resource); } -CursorShape ShapeFromWindowsCursor(HCURSOR cursor) { - if (IsSystemCursor(cursor, IDC_HELP)) return CursorShape::help; - if (IsSystemCursor(cursor, IDC_HAND)) return CursorShape::pointer; - if (IsSystemCursor(cursor, IDC_APPSTARTING)) return CursorShape::progress; - if (IsSystemCursor(cursor, IDC_WAIT)) return CursorShape::wait; - if (IsSystemCursor(cursor, IDC_CROSS)) return CursorShape::crosshair; - if (IsSystemCursor(cursor, IDC_IBEAM)) return CursorShape::text; - if (IsSystemCursor(cursor, IDC_NO)) return CursorShape::not_allowed; - if (IsSystemCursor(cursor, IDC_SIZEALL)) return CursorShape::move; - if (IsSystemCursor(cursor, IDC_SIZEWE)) return CursorShape::ew_resize; - if (IsSystemCursor(cursor, IDC_SIZENS)) return CursorShape::ns_resize; - if (IsSystemCursor(cursor, IDC_SIZENESW)) return CursorShape::nesw_resize; - if (IsSystemCursor(cursor, IDC_SIZENWSE)) return CursorShape::nwse_resize; - if (IsSystemCursor(cursor, IDC_UPARROW)) return CursorShape::n_resize; - return CursorShape::default_cursor; +RemoteCursorShape ShapeFromWindowsCursor(HCURSOR cursor) { + if (IsSystemCursor(cursor, IDC_HELP)) return RemoteCursorShape::help; + if (IsSystemCursor(cursor, IDC_HAND)) return RemoteCursorShape::pointer; + if (IsSystemCursor(cursor, IDC_APPSTARTING)) + return RemoteCursorShape::progress; + if (IsSystemCursor(cursor, IDC_WAIT)) return RemoteCursorShape::wait; + if (IsSystemCursor(cursor, IDC_CROSS)) return RemoteCursorShape::crosshair; + if (IsSystemCursor(cursor, IDC_IBEAM)) return RemoteCursorShape::text; + if (IsSystemCursor(cursor, IDC_NO)) + return RemoteCursorShape::not_allowed; + if (IsSystemCursor(cursor, IDC_SIZEALL)) return RemoteCursorShape::move; + if (IsSystemCursor(cursor, IDC_SIZEWE)) return RemoteCursorShape::ew_resize; + if (IsSystemCursor(cursor, IDC_SIZENS)) return RemoteCursorShape::ns_resize; + if (IsSystemCursor(cursor, IDC_SIZENESW)) + return RemoteCursorShape::nesw_resize; + if (IsSystemCursor(cursor, IDC_SIZENWSE)) + return RemoteCursorShape::nwse_resize; + if (IsSystemCursor(cursor, IDC_UPARROW)) return RemoteCursorShape::n_resize; + return RemoteCursorShape::default_cursor; } } // namespace @@ -45,7 +49,7 @@ bool CursorStateProvider::Sample(CursorState* state) { state->seq = 0; state->visible = (info.flags & CURSOR_SHOWING) != 0; state->shape = state->visible ? ShapeFromWindowsCursor(info.hCursor) - : CursorShape::none; + : RemoteCursorShape::none; return true; } @@ -56,12 +60,6 @@ bool CursorStateProvider::Sample(CursorState* state) { #include #include -// X11/X.h defines CursorShape as a protocol request opcode, which conflicts -// with CrossDesk's CursorShape enum. -#ifdef CursorShape -#undef CursorShape -#endif - #include #include #include @@ -79,64 +77,64 @@ bool Contains(const std::string& value, const char* token) { return value.find(token) != std::string::npos; } -CursorShape ShapeFromXCursorName(const std::string& raw_name) { +RemoteCursorShape ShapeFromXCursorName(const std::string& raw_name) { const std::string name = Lowercase(raw_name); if (Contains(name, "left_ptr_watch") || Contains(name, "progress")) - return CursorShape::progress; + return RemoteCursorShape::progress; if (Contains(name, "watch") || Contains(name, "wait")) - return CursorShape::wait; + return RemoteCursorShape::wait; if (Contains(name, "question") || Contains(name, "help")) - return CursorShape::help; + return RemoteCursorShape::help; if (Contains(name, "xterm") || Contains(name, "vertical-text") || name == "text") - return CursorShape::text; + return RemoteCursorShape::text; if (Contains(name, "crosshair") || name == "cross" || name == "tcross") - return CursorShape::crosshair; + return RemoteCursorShape::crosshair; if (Contains(name, "closedhand") || Contains(name, "grabbing")) - return CursorShape::grabbing; + return RemoteCursorShape::grabbing; if (Contains(name, "openhand") || Contains(name, "grab")) - return CursorShape::grab; + return RemoteCursorShape::grab; if (Contains(name, "dnd-link") || name == "alias") - return CursorShape::alias; + return RemoteCursorShape::alias; if (Contains(name, "hand") || Contains(name, "pointer") || Contains(name, "link")) - return CursorShape::pointer; + return RemoteCursorShape::pointer; if (Contains(name, "dnd-copy") || name == "copy") - return CursorShape::copy; - if (Contains(name, "no-drop")) return CursorShape::no_drop; + return RemoteCursorShape::copy; + if (Contains(name, "no-drop")) return RemoteCursorShape::no_drop; if (Contains(name, "not-allowed") || Contains(name, "crossed_circle")) - return CursorShape::not_allowed; + return RemoteCursorShape::not_allowed; if (name == "fleur" || Contains(name, "size_all") || name == "move") - return CursorShape::move; + return RemoteCursorShape::move; if (Contains(name, "top_left_corner") || Contains(name, "bottom_right_corner") || Contains(name, "nwse-resize") || Contains(name, "size_fdiag")) - return CursorShape::nwse_resize; + return RemoteCursorShape::nwse_resize; if (Contains(name, "top_right_corner") || Contains(name, "bottom_left_corner") || Contains(name, "nesw-resize") || Contains(name, "size_bdiag")) - return CursorShape::nesw_resize; + return RemoteCursorShape::nesw_resize; if (Contains(name, "sb_h_double_arrow") || Contains(name, "ew-resize") || Contains(name, "size_hor")) - return CursorShape::ew_resize; + return RemoteCursorShape::ew_resize; if (Contains(name, "sb_v_double_arrow") || Contains(name, "ns-resize") || Contains(name, "size_ver")) - return CursorShape::ns_resize; - if (Contains(name, "col-resize")) return CursorShape::col_resize; - if (Contains(name, "row-resize")) return CursorShape::row_resize; - if (Contains(name, "ne-resize")) return CursorShape::ne_resize; - if (Contains(name, "nw-resize")) return CursorShape::nw_resize; - if (Contains(name, "se-resize")) return CursorShape::se_resize; - if (Contains(name, "sw-resize")) return CursorShape::sw_resize; + return RemoteCursorShape::ns_resize; + if (Contains(name, "col-resize")) return RemoteCursorShape::col_resize; + if (Contains(name, "row-resize")) return RemoteCursorShape::row_resize; + if (Contains(name, "ne-resize")) return RemoteCursorShape::ne_resize; + if (Contains(name, "nw-resize")) return RemoteCursorShape::nw_resize; + if (Contains(name, "se-resize")) return RemoteCursorShape::se_resize; + if (Contains(name, "sw-resize")) return RemoteCursorShape::sw_resize; if (Contains(name, "top_side") || name == "n-resize") - return CursorShape::n_resize; + return RemoteCursorShape::n_resize; if (Contains(name, "right_side") || name == "e-resize") - return CursorShape::e_resize; + return RemoteCursorShape::e_resize; if (Contains(name, "bottom_side") || name == "s-resize") - return CursorShape::s_resize; + return RemoteCursorShape::s_resize; if (Contains(name, "left_side") || name == "w-resize") - return CursorShape::w_resize; - return CursorShape::default_cursor; + return RemoteCursorShape::w_resize; + return RemoteCursorShape::default_cursor; } bool CursorHasVisiblePixel(const XFixesCursorImage& image) { @@ -172,7 +170,7 @@ bool CursorStateProvider::Sample(CursorState* state) { state->seq = 0; state->visible = CursorHasVisiblePixel(*image); state->shape = state->visible ? ShapeFromXCursorName(name) - : CursorShape::none; + : RemoteCursorShape::none; XFree(image); return true; } diff --git a/src/gui/runtime/cursor_state_provider_mac.mm b/src/gui/runtime/cursor_state_provider_mac.mm index 465183f..0724614 100644 --- a/src/gui/runtime/cursor_state_provider_mac.mm +++ b/src/gui/runtime/cursor_state_provider_mac.mm @@ -22,7 +22,7 @@ struct CursorFingerprint { struct KnownCursor { CursorFingerprint fingerprint; - CursorShape shape = CursorShape::default_cursor; + RemoteCursorShape shape = RemoteCursorShape::default_cursor; }; bool FingerprintCursor(NSCursor* cursor, CursorFingerprint* fingerprint) { @@ -75,7 +75,7 @@ bool SameCursor(const CursorFingerprint& left, } void AddKnownCursor(std::vector* cursors, NSCursor* cursor, - CursorShape shape) { + RemoteCursorShape shape) { CursorFingerprint fingerprint; if (FingerprintCursor(cursor, &fingerprint)) { cursors->push_back({fingerprint, shape}); @@ -88,34 +88,43 @@ std::vector BuildKnownCursors() { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - AddKnownCursor(&cursors, NSCursor.arrowCursor, CursorShape::default_cursor); - AddKnownCursor(&cursors, NSCursor.pointingHandCursor, CursorShape::pointer); - AddKnownCursor(&cursors, NSCursor.crosshairCursor, CursorShape::crosshair); - AddKnownCursor(&cursors, NSCursor.IBeamCursor, CursorShape::text); + AddKnownCursor(&cursors, NSCursor.arrowCursor, + RemoteCursorShape::default_cursor); + AddKnownCursor(&cursors, NSCursor.pointingHandCursor, + RemoteCursorShape::pointer); + AddKnownCursor(&cursors, NSCursor.crosshairCursor, + RemoteCursorShape::crosshair); + AddKnownCursor(&cursors, NSCursor.IBeamCursor, RemoteCursorShape::text); AddKnownCursor(&cursors, NSCursor.IBeamCursorForVerticalLayout, - CursorShape::text); + RemoteCursorShape::text); AddKnownCursor(&cursors, NSCursor.operationNotAllowedCursor, - CursorShape::not_allowed); - AddKnownCursor(&cursors, NSCursor.dragLinkCursor, CursorShape::alias); - AddKnownCursor(&cursors, NSCursor.dragCopyCursor, CursorShape::copy); - AddKnownCursor(&cursors, NSCursor.openHandCursor, CursorShape::grab); - AddKnownCursor(&cursors, NSCursor.closedHandCursor, CursorShape::grabbing); + RemoteCursorShape::not_allowed); + AddKnownCursor(&cursors, NSCursor.dragLinkCursor, RemoteCursorShape::alias); + AddKnownCursor(&cursors, NSCursor.dragCopyCursor, RemoteCursorShape::copy); + AddKnownCursor(&cursors, NSCursor.openHandCursor, RemoteCursorShape::grab); + AddKnownCursor(&cursors, NSCursor.closedHandCursor, + RemoteCursorShape::grabbing); AddKnownCursor(&cursors, NSCursor.resizeLeftRightCursor, - CursorShape::ew_resize); - AddKnownCursor(&cursors, NSCursor.resizeUpDownCursor, CursorShape::ns_resize); - AddKnownCursor(&cursors, NSCursor.resizeUpCursor, CursorShape::n_resize); - AddKnownCursor(&cursors, NSCursor.resizeRightCursor, CursorShape::e_resize); - AddKnownCursor(&cursors, NSCursor.resizeDownCursor, CursorShape::s_resize); - AddKnownCursor(&cursors, NSCursor.resizeLeftCursor, CursorShape::w_resize); + RemoteCursorShape::ew_resize); + AddKnownCursor(&cursors, NSCursor.resizeUpDownCursor, + RemoteCursorShape::ns_resize); + AddKnownCursor(&cursors, NSCursor.resizeUpCursor, + RemoteCursorShape::n_resize); + AddKnownCursor(&cursors, NSCursor.resizeRightCursor, + RemoteCursorShape::e_resize); + AddKnownCursor(&cursors, NSCursor.resizeDownCursor, + RemoteCursorShape::s_resize); + AddKnownCursor(&cursors, NSCursor.resizeLeftCursor, + RemoteCursorShape::w_resize); #pragma clang diagnostic pop return cursors; } -CursorShape ShapeFromMacCursor(NSCursor* cursor) { +RemoteCursorShape ShapeFromMacCursor(NSCursor* cursor) { CursorFingerprint fingerprint; if (!FingerprintCursor(cursor, &fingerprint)) { - return CursorShape::default_cursor; + return RemoteCursorShape::default_cursor; } // Sampling begins from the UI tick, after AppKit has initialized its cursor @@ -125,7 +134,7 @@ CursorShape ShapeFromMacCursor(NSCursor* cursor) { for (const KnownCursor& known : known_cursors) { if (SameCursor(fingerprint, known.fingerprint)) return known.shape; } - return CursorShape::default_cursor; + return RemoteCursorShape::default_cursor; } } // namespace @@ -146,7 +155,8 @@ bool CursorStateProvider::Sample(CursorState* state) { state->seq = 0; state->visible = visible && cursor != nil; - state->shape = state->visible ? ShapeFromMacCursor(cursor) : CursorShape::none; + state->shape = state->visible ? ShapeFromMacCursor(cursor) + : RemoteCursorShape::none; return true; } diff --git a/src/gui/ui/stream_window.slint b/src/gui/ui/stream_window.slint index d5347f4..64bf833 100644 --- a/src/gui/ui/stream_window.slint +++ b/src/gui/ui/stream_window.slint @@ -133,7 +133,7 @@ export component StreamWindow inherits Window { in property <[string]> displays; in-out property selected-display: 0; in property mouse-control-enabled: true; - // Numeric values mirror crossdesk::CursorShape and Slint's MouseCursor. + // Numeric values mirror crossdesk::RemoteCursorShape and Slint's MouseCursor. in property remote-cursor-active: false; in property remote-cursor-shape: 0; in property audio-enabled: true;