From 649f547dcfa31f20edc9c6dfb42379143df3debe Mon Sep 17 00:00:00 2001 From: Spruce Cloud <1888686+SpruceCloud@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:03:49 +0200 Subject: [PATCH 1/2] Implement macOS cursor setting and hiding support --- src/platform/macos/cursor.rs | 19 ++++++++++--------- src/platform/macos/view.rs | 5 +++++ src/platform/macos/window.rs | 2 ++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/platform/macos/cursor.rs b/src/platform/macos/cursor.rs index 263cbcb5..46587900 100644 --- a/src/platform/macos/cursor.rs +++ b/src/platform/macos/cursor.rs @@ -9,6 +9,7 @@ use crate::MouseCursor; pub enum Cursor { Native(fn() -> Retained), Undocumented(Sel), + Hidden, } impl From for Cursor { @@ -55,19 +56,18 @@ impl From for Cursor { Cursor::Undocumented(sel!(busyButClickableCursor)) } - _ => Cursor::Native(NSCursor::arrowCursor), - // MouseCursor::Hidden => todo!(), - // MouseCursor::Move => todo!(), - // MouseCursor::AllScroll => todo!(), - // MouseCursor::Cell => todo!(), + MouseCursor::Move => Cursor::Native(NSCursor::arrowCursor), + MouseCursor::AllScroll => Cursor::Native(NSCursor::arrowCursor), + MouseCursor::Cell => Cursor::Native(NSCursor::crosshairCursor), + MouseCursor::Hidden => Cursor::Hidden, } } } impl Cursor { - pub fn load(&self) -> Retained { + pub fn load(&self) -> Option> { match self { - Cursor::Native(loader) => loader(), + Cursor::Native(loader) => Some(loader()), Cursor::Undocumented(sel) => { let class = NSCursor::class(); @@ -75,14 +75,15 @@ impl Cursor { let responds_to: bool = unsafe { msg_send![class, respondsToSelector: *sel] }; if !responds_to { - return NSCursor::arrowCursor(); + return Some(NSCursor::arrowCursor()); } let raw: *mut NSCursor = unsafe { class.send_message(*sel, ()) }; let cursor = unsafe { Retained::retain(raw) }; - cursor.unwrap_or_else(NSCursor::arrowCursor) + Some(cursor.unwrap_or_else(NSCursor::arrowCursor)) } + Cursor::Hidden => None, } } } diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index cf3c5a0e..a731930f 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -274,6 +274,11 @@ impl BaseviewView { impl Drop for BaseviewView { fn drop(&mut self) { self.state.closed.set(true); + if self.state.cursor_hidden.get() { + unsafe { + let _: () = objc2::msg_send![objc2_app_kit::NSCursor::class(), unhide]; + } + } } } diff --git a/src/platform/macos/window.rs b/src/platform/macos/window.rs index 7596efa4..cf128911 100644 --- a/src/platform/macos/window.rs +++ b/src/platform/macos/window.rs @@ -180,6 +180,7 @@ pub(crate) struct WindowSharedState { pub size: Cell>, pub scale_factor: Cell, pub sizing_strategy: SizingStrategy, + pub cursor_hidden: Cell, } impl WindowSharedState { @@ -189,6 +190,7 @@ impl WindowSharedState { size: size.into(), scale_factor: scale_factor.into(), sizing_strategy, + cursor_hidden: false.into(), } } } From 4af1bfbe031059fe26501f1602962163c763ba48 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:01:12 +0200 Subject: [PATCH 2/2] Remove unneeded unsafe --- src/platform/macos/context.rs | 7 ++++++- src/platform/macos/view.rs | 8 +++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/platform/macos/context.rs b/src/platform/macos/context.rs index 652b308e..f7579057 100644 --- a/src/platform/macos/context.rs +++ b/src/platform/macos/context.rs @@ -9,6 +9,7 @@ use dispatch2::MainThreadBound; use objc2::rc::Weak; use objc2::runtime::NSObjectProtocol; use objc2::{MainThreadMarker, Message}; +use objc2_app_kit::NSCursor; use raw_window_handle::DisplayHandle; use std::rc::Rc; @@ -75,7 +76,11 @@ impl WindowContext { pub fn set_mouse_cursor(&self, cursor: MouseCursor) -> Result<()> { let Some(view) = self.view.load() else { return Ok(()) }; let native_cursor = Cursor::from(cursor); - view.addCursorRect_cursor(view.bounds(), &native_cursor.load()); + if let Some(cursor) = native_cursor.load() { + view.addCursorRect_cursor(view.bounds(), &cursor); + } else { + NSCursor::hide() + } Ok(()) } diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index a731930f..909575db 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -19,8 +19,8 @@ use objc2::rc::Weak; use objc2::runtime::{NSObjectProtocol, ProtocolObject}; use objc2::{msg_send, AllocAnyThread, ClassType, MainThreadMarker}; use objc2_app_kit::{ - NSApplication, NSDragOperation, NSDraggingInfo, NSEvent, NSFilenamesPboardType, NSTrackingArea, - NSTrackingAreaOptions, NSView, NSWindow, + NSApplication, NSCursor, NSDragOperation, NSDraggingInfo, NSEvent, NSFilenamesPboardType, + NSTrackingArea, NSTrackingAreaOptions, NSView, NSWindow, }; use objc2_foundation::{NSArray, NSNotification, NSPoint, NSRect, NSSize, NSString}; use std::cell::{Cell, RefCell}; @@ -275,9 +275,7 @@ impl Drop for BaseviewView { fn drop(&mut self) { self.state.closed.set(true); if self.state.cursor_hidden.get() { - unsafe { - let _: () = objc2::msg_send![objc2_app_kit::NSCursor::class(), unhide]; - } + NSCursor::unhide(); } } }