From 3835b957bde169d14e3036a31fed9e0b16e169e2 Mon Sep 17 00:00:00 2001 From: Eneji Victor Date: Fri, 10 Oct 2025 14:58:59 +0100 Subject: [PATCH 1/7] saving the hash generator for to modify it for a new one --- crates/tools/Cargo.toml | 15 +++++ crates/tools/cursor_hash_collector.rs | 92 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 crates/tools/Cargo.toml create mode 100644 crates/tools/cursor_hash_collector.rs diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml new file mode 100644 index 000000000..8bb470f25 --- /dev/null +++ b/crates/tools/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cursor_hash_collector" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "cursor_hash_collector" +path = "cursor_hash_collector.rs" + +[dependencies] +objc2 = "0.6" +objc2-app-kit = { version = "0.3.1", features = ["NSCursor", "NSApplication", "NSImage", "NSBitmapImageRep"] } +objc2-foundation = "0.3.1" +sha2 = "0.10.6" +hex = "0.4.3" diff --git a/crates/tools/cursor_hash_collector.rs b/crates/tools/cursor_hash_collector.rs new file mode 100644 index 000000000..aab9b98a6 --- /dev/null +++ b/crates/tools/cursor_hash_collector.rs @@ -0,0 +1,92 @@ +use objc2_app_kit::{NSCursor, NSImage, NSApplication}; +use objc2_foundation::NSAutoreleasePool; +use objc2::rc::Retained; +use objc2::MainThreadMarker; +use sha2::{Digest, Sha256}; +use std::collections::HashMap; + +fn main() { + println!("macOS Tahoe Cursor Hash Collector"); + println!("================================="); + println!("Automatically capturing all available cursor types..."); + println!(); + + let mut cursor_hashes: HashMap = HashMap::new(); + + unsafe { + // Create autorelease pool + let _pool = NSAutoreleasePool::new(); + + // Initialize application + let mtm = MainThreadMarker::new().unwrap(); + let app = NSApplication::sharedApplication(mtm); + + // Capture all standard cursor types + capture_cursor(&mut cursor_hashes, "Arrow testing", NSCursor::arrowCursor()); + capture_cursor(&mut cursor_hashes, "IBeam testing", NSCursor::IBeamCursor()); + capture_cursor(&mut cursor_hashes, "CrossHair testing", NSCursor::crosshairCursor()); + capture_cursor(&mut cursor_hashes, "ClosedHand testing", NSCursor::closedHandCursor()); + capture_cursor(&mut cursor_hashes, "OpenHand", NSCursor::openHandCursor()); + capture_cursor(&mut cursor_hashes, "PointingHand", NSCursor::pointingHandCursor()); + capture_cursor(&mut cursor_hashes, "ResizeLeft", NSCursor::resizeLeftCursor()); + capture_cursor(&mut cursor_hashes, "ResizeRight", NSCursor::resizeRightCursor()); + capture_cursor(&mut cursor_hashes, "ResizeLeftRight", NSCursor::resizeLeftRightCursor()); + capture_cursor(&mut cursor_hashes, "ResizeUp", NSCursor::resizeUpCursor()); + capture_cursor(&mut cursor_hashes, "ResizeDown", NSCursor::resizeDownCursor()); + capture_cursor(&mut cursor_hashes, "ResizeUpDown", NSCursor::resizeUpDownCursor()); + capture_cursor(&mut cursor_hashes, "DisappearingItem", NSCursor::disappearingItemCursor()); + capture_cursor(&mut cursor_hashes, "IBeamVerticalForVerticalLayout", NSCursor::IBeamCursorForVerticalLayout()); + capture_cursor(&mut cursor_hashes, "OperationNotAllowed", NSCursor::operationNotAllowedCursor()); + capture_cursor(&mut cursor_hashes, "DragLink", NSCursor::dragLinkCursor()); + capture_cursor(&mut cursor_hashes, "DragCopy", NSCursor::dragCopyCursor()); + capture_cursor(&mut cursor_hashes, "ContextualMenu", NSCursor::contextualMenuCursor()); + + // Try to access current system cursor as well + if let Some(current) = NSCursor::currentSystemCursor() { + capture_cursor(&mut cursor_hashes, "CurrentSystem", current); + } + + // Also get current cursor + capture_cursor(&mut cursor_hashes, "Current", NSCursor::currentCursor()); + } + + // Print results in a format ready for insertion into from_hash function + println!("Hash mappings for use in from_hash function:"); + println!("-------------------------------------------"); + + for (name, (hash, hotspot)) in cursor_hashes { + println!("\"{hash}\" => Self::{}, // {name}, hotspot: {hotspot:?}", + if name.starts_with("Current") { "TahoeDefault" } else { &name }); + } +} + +/// Captures a cursor and adds its hash to the collection if it's new +unsafe fn capture_cursor( + hashes: &mut HashMap, + name: &str, + cursor: Retained, +) { + let image = cursor.image(); + + let size = image.size(); + let hotspot = cursor.hotSpot(); + + if let Some(image_data) = image.TIFFRepresentation() { + let image_bytes = image_data.as_bytes_unchecked().to_vec(); + let hash = hex::encode(Sha256::digest(&image_bytes)); + + let hotspot_normalized = (hotspot.x / size.width, hotspot.y / size.height); + + // Only add if we haven't seen this hash before + if !hashes.contains_key(name) { + println!("Captured cursor: {}", name); + println!(" Hash: {}", hash); + println!(" Hotspot: {:?}", hotspot_normalized); + println!(); + + hashes.insert(name.to_string(), (hash, hotspot_normalized)); + } + } else { + println!("Failed to get TIFF representation for cursor: {}", name); + } +} From 187579bd09545b7b5760fda29641b9d2641bfec1 Mon Sep 17 00:00:00 2001 From: Eneji Victor Date: Sat, 11 Oct 2025 10:36:42 +0100 Subject: [PATCH 2/7] Cleanup: remove unused SVG files, scripts, and tools directory. Code and asset cleanup. --- .../assets/mac/tahoe/context-menu.svg | 17 +++ .../assets/mac/tahoe/crosshair.svg | 4 + .../cursor-info/assets/mac/tahoe/default.svg | 4 + crates/cursor-info/assets/mac/tahoe/grab.svg | 4 + .../cursor-info/assets/mac/tahoe/grabbing.svg | 4 + .../cursor-info/assets/mac/tahoe/pointer.svg | 4 + .../cursor-info/assets/mac/tahoe/resize-e.svg | 4 + .../assets/mac/tahoe/resize-ew.svg | 4 + .../cursor-info/assets/mac/tahoe/resize-n.svg | 4 + .../assets/mac/tahoe/resize-ns.svg | 4 + .../cursor-info/assets/mac/tahoe/resize-s.svg | 4 + .../cursor-info/assets/mac/tahoe/resize-w.svg | 4 + crates/cursor-info/assets/mac/tahoe/text.svg | 4 + .../cursor-info/assets/mac/tahoe/zoom-in.svg | 7 + .../cursor-info/assets/mac/tahoe/zoom-out.svg | 5 + crates/cursor-info/src/macos.rs | 133 +++++++++++++++++- crates/tools/Cargo.toml | 15 -- crates/tools/cursor_hash_collector.rs | 92 ------------ 18 files changed, 207 insertions(+), 110 deletions(-) create mode 100644 crates/cursor-info/assets/mac/tahoe/context-menu.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/crosshair.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/default.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/grab.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/grabbing.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/pointer.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-e.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-ew.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-n.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-ns.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-s.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/resize-w.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/text.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/zoom-in.svg create mode 100644 crates/cursor-info/assets/mac/tahoe/zoom-out.svg delete mode 100644 crates/tools/Cargo.toml delete mode 100644 crates/tools/cursor_hash_collector.rs diff --git a/crates/cursor-info/assets/mac/tahoe/context-menu.svg b/crates/cursor-info/assets/mac/tahoe/context-menu.svg new file mode 100644 index 000000000..47bc6bb6d --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/context-menu.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/crosshair.svg b/crates/cursor-info/assets/mac/tahoe/crosshair.svg new file mode 100644 index 000000000..803171ea1 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/crosshair.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/default.svg b/crates/cursor-info/assets/mac/tahoe/default.svg new file mode 100644 index 000000000..18b29be70 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/default.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/grab.svg b/crates/cursor-info/assets/mac/tahoe/grab.svg new file mode 100644 index 000000000..ea0a83ab6 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/grab.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/grabbing.svg b/crates/cursor-info/assets/mac/tahoe/grabbing.svg new file mode 100644 index 000000000..4b76948b1 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/grabbing.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/pointer.svg b/crates/cursor-info/assets/mac/tahoe/pointer.svg new file mode 100644 index 000000000..a8000ee15 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/pointer.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-e.svg b/crates/cursor-info/assets/mac/tahoe/resize-e.svg new file mode 100644 index 000000000..54dd100d5 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-e.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-ew.svg b/crates/cursor-info/assets/mac/tahoe/resize-ew.svg new file mode 100644 index 000000000..2e0371f9b --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-ew.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-n.svg b/crates/cursor-info/assets/mac/tahoe/resize-n.svg new file mode 100644 index 000000000..22bb9583a --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-n.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-ns.svg b/crates/cursor-info/assets/mac/tahoe/resize-ns.svg new file mode 100644 index 000000000..539e6b8c1 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-ns.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-s.svg b/crates/cursor-info/assets/mac/tahoe/resize-s.svg new file mode 100644 index 000000000..ebb5a054a --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-s.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/resize-w.svg b/crates/cursor-info/assets/mac/tahoe/resize-w.svg new file mode 100644 index 000000000..d5c6a82c9 --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/resize-w.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/text.svg b/crates/cursor-info/assets/mac/tahoe/text.svg new file mode 100644 index 000000000..ade24f4cc --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/zoom-in.svg b/crates/cursor-info/assets/mac/tahoe/zoom-in.svg new file mode 100644 index 000000000..a75efedda --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/zoom-in.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/crates/cursor-info/assets/mac/tahoe/zoom-out.svg b/crates/cursor-info/assets/mac/tahoe/zoom-out.svg new file mode 100644 index 000000000..6734f42dd --- /dev/null +++ b/crates/cursor-info/assets/mac/tahoe/zoom-out.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index a45c2cfbd..7641fb2cb 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -42,6 +42,28 @@ pub enum CursorShapeMacOS { ResizeUpDown, /// https://developer.apple.com/documentation/appkit/nscursor/ibeamcursorforverticallayout IBeamVerticalForVerticalLayout, + + // macOS Tahoe Cursors + TahoeArrow, + TahoeContextualMenu, + TahoeClosedHand, + TahoeCrosshair, + TahoeDisappearingItem, + TahoeDragCopy, + TahoeDragLink, + TahoeIBeam, + TahoeOpenHand, + TahoeOperationNotAllowed, + TahoePointingHand, + TahoeResizeDown, + TahoeResizeLeft, + TahoeResizeLeftRight, + TahoeResizeRight, + TahoeResizeUp, + TahoeResizeUpDown, + TahoeIBeamVerticalForVerticalLayout, + TahoeZoomOut, + TahoeZoomIn } impl CursorShapeMacOS { @@ -116,14 +138,97 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/ibeam_vertical.svg"), hotspot: (0.51, 0.49), }, + + // Tahoe cursor variants + Self::TahoeArrow => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/default.svg"), + hotspot: (0.347, 0.33), + }, + Self::TahoeContextualMenu => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/context-menu.svg"), + hotspot: (0.278, 0.295), + }, + Self::TahoeClosedHand => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/grabbing.svg"), + hotspot: (0.5, 0.5), + }, + Self::TahoeCrosshair => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/crosshair.svg"), + hotspot: (0.52, 0.51), + }, + Self::TahoeDisappearingItem => return None, + Self::TahoeDragCopy => ResolvedCursor { + raw: include_str!("../assets/mac/drag_copy.svg"), + hotspot: (0.255, 0.1), + }, + Self::TahoeDragLink => ResolvedCursor { + raw: include_str!("../assets/mac/drag_link.svg"), + hotspot: (0.621, 0.309), + }, + + Self::TahoeIBeam => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/text.svg"), + hotspot: (0.525, 0.52), + }, + Self::TahoeOpenHand => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/grab.svg"), + hotspot: (0.5, 0.5), + }, + Self::TahoeOperationNotAllowed => ResolvedCursor { + raw: include_str!("../assets/mac/operation_not_allowed.svg"), + hotspot: (0.24, 0.1), + }, + Self::TahoePointingHand => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/pointer.svg"), + hotspot: (0.5, 0.4), + }, + Self::TahoeResizeDown => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-s.svg"), + hotspot: (0.5, 0.5), + }, + Self::TahoeResizeLeft => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-w.svg"), + hotspot: (0.5, 0.5), + }, + + Self::TahoeResizeLeftRight => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-ew.svg"), + hotspot: (0.5, 0.5), + }, + + Self::TahoeResizeRight => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-e.svg"), + hotspot: (0.5, 0.5), + }, + + Self::TahoeResizeUpDown => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-ns.svg"), + hotspot: (0.5, 0.5), + }, + + Self::TahoeResizeUp => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/resize-n.svg"), + hotspot: (0.5, 0.5), + }, + Self::TahoeIBeamVerticalForVerticalLayout => ResolvedCursor { + raw: include_str!("../assets/mac/ibeam_vertical.svg"), + hotspot: (0.51, 0.49), + }, + Self::TahoeZoomIn => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/zoom-in.svg"), + hotspot: (0.51, 0.49), + }, + Self::TahoeZoomOut => ResolvedCursor { + raw: include_str!("../assets/mac/tahoe/zoom-out.svg"), + hotspot: (0.51, 0.49), + }, + }) } - /// Derive the cursor type from a hash - /// macOS doesn't allow comparing `NSCursor` instances directly so we hash the image data. - /// macOS cursor are also resolution-independent so this works. pub fn from_hash(hash: &str) -> Option { Some(match hash { + // Regular macOS cursor hashes "de2d1f4a81e520b65fd1317b845b00a1c51a4d1f71cca3cd4ccdab52b98d1ac9" => Self::Arrow, "ab26ca862492d41355b711c58544687a799dd7ae14cf161959ca524bbc97c322" => { Self::ContextualMenu @@ -156,6 +261,28 @@ impl CursorShapeMacOS { "024e1d486a7f16368669d419e69c9a326e464ec1b8ed39645e5c89cb183e03c5" => { Self::IBeamVerticalForVerticalLayout } + + //Hash values obtained from a macOS Tahoe system. + "57a1d610df3e421ebef670ba58c97319d2ab6990d64dca34d28140e4527fd54d" => Self::TahoeArrow, + "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c" => Self::TahoeContextualMenu, + "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae" => Self::TahoeClosedHand, + "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => Self::TahoeCrosshair, + "f44a524d6fcfe5a1b1bebf23fcb12fbfeaea0ecf92beb7f69fdf586c319dd8ab" => Self::TahoeDisappearingItem, + "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => Self::TahoeDragCopy, + "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351" => Self::TahoeDragLink, + "3de4a52b22f76f28db5206dc4c2219dff28a6ee5abfb9c5656a469f2140f7eaa" => Self::TahoeIBeam, + "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5" => Self::TahoeOpenHand, + "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320" => Self::TahoeOperationNotAllowed, + "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f" => Self::TahoePointingHand, + "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35" => Self::TahoeResizeDown, + "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf" => Self::TahoeResizeLeft, + "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e" => Self::TahoeResizeLeftRight, + "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb" => Self::TahoeResizeRight, + "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b" => Self::TahoeResizeUp, + "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451" => Self::TahoeResizeUpDown, + "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a" => Self::TahoeIBeamVerticalForVerticalLayout, + "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177" => Self::TahoeZoomIn, + "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049" => Self::TahoeZoomOut, _ => return None, }) } diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml deleted file mode 100644 index 8bb470f25..000000000 --- a/crates/tools/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "cursor_hash_collector" -version = "0.1.0" -edition = "2021" - -[[bin]] -name = "cursor_hash_collector" -path = "cursor_hash_collector.rs" - -[dependencies] -objc2 = "0.6" -objc2-app-kit = { version = "0.3.1", features = ["NSCursor", "NSApplication", "NSImage", "NSBitmapImageRep"] } -objc2-foundation = "0.3.1" -sha2 = "0.10.6" -hex = "0.4.3" diff --git a/crates/tools/cursor_hash_collector.rs b/crates/tools/cursor_hash_collector.rs deleted file mode 100644 index aab9b98a6..000000000 --- a/crates/tools/cursor_hash_collector.rs +++ /dev/null @@ -1,92 +0,0 @@ -use objc2_app_kit::{NSCursor, NSImage, NSApplication}; -use objc2_foundation::NSAutoreleasePool; -use objc2::rc::Retained; -use objc2::MainThreadMarker; -use sha2::{Digest, Sha256}; -use std::collections::HashMap; - -fn main() { - println!("macOS Tahoe Cursor Hash Collector"); - println!("================================="); - println!("Automatically capturing all available cursor types..."); - println!(); - - let mut cursor_hashes: HashMap = HashMap::new(); - - unsafe { - // Create autorelease pool - let _pool = NSAutoreleasePool::new(); - - // Initialize application - let mtm = MainThreadMarker::new().unwrap(); - let app = NSApplication::sharedApplication(mtm); - - // Capture all standard cursor types - capture_cursor(&mut cursor_hashes, "Arrow testing", NSCursor::arrowCursor()); - capture_cursor(&mut cursor_hashes, "IBeam testing", NSCursor::IBeamCursor()); - capture_cursor(&mut cursor_hashes, "CrossHair testing", NSCursor::crosshairCursor()); - capture_cursor(&mut cursor_hashes, "ClosedHand testing", NSCursor::closedHandCursor()); - capture_cursor(&mut cursor_hashes, "OpenHand", NSCursor::openHandCursor()); - capture_cursor(&mut cursor_hashes, "PointingHand", NSCursor::pointingHandCursor()); - capture_cursor(&mut cursor_hashes, "ResizeLeft", NSCursor::resizeLeftCursor()); - capture_cursor(&mut cursor_hashes, "ResizeRight", NSCursor::resizeRightCursor()); - capture_cursor(&mut cursor_hashes, "ResizeLeftRight", NSCursor::resizeLeftRightCursor()); - capture_cursor(&mut cursor_hashes, "ResizeUp", NSCursor::resizeUpCursor()); - capture_cursor(&mut cursor_hashes, "ResizeDown", NSCursor::resizeDownCursor()); - capture_cursor(&mut cursor_hashes, "ResizeUpDown", NSCursor::resizeUpDownCursor()); - capture_cursor(&mut cursor_hashes, "DisappearingItem", NSCursor::disappearingItemCursor()); - capture_cursor(&mut cursor_hashes, "IBeamVerticalForVerticalLayout", NSCursor::IBeamCursorForVerticalLayout()); - capture_cursor(&mut cursor_hashes, "OperationNotAllowed", NSCursor::operationNotAllowedCursor()); - capture_cursor(&mut cursor_hashes, "DragLink", NSCursor::dragLinkCursor()); - capture_cursor(&mut cursor_hashes, "DragCopy", NSCursor::dragCopyCursor()); - capture_cursor(&mut cursor_hashes, "ContextualMenu", NSCursor::contextualMenuCursor()); - - // Try to access current system cursor as well - if let Some(current) = NSCursor::currentSystemCursor() { - capture_cursor(&mut cursor_hashes, "CurrentSystem", current); - } - - // Also get current cursor - capture_cursor(&mut cursor_hashes, "Current", NSCursor::currentCursor()); - } - - // Print results in a format ready for insertion into from_hash function - println!("Hash mappings for use in from_hash function:"); - println!("-------------------------------------------"); - - for (name, (hash, hotspot)) in cursor_hashes { - println!("\"{hash}\" => Self::{}, // {name}, hotspot: {hotspot:?}", - if name.starts_with("Current") { "TahoeDefault" } else { &name }); - } -} - -/// Captures a cursor and adds its hash to the collection if it's new -unsafe fn capture_cursor( - hashes: &mut HashMap, - name: &str, - cursor: Retained, -) { - let image = cursor.image(); - - let size = image.size(); - let hotspot = cursor.hotSpot(); - - if let Some(image_data) = image.TIFFRepresentation() { - let image_bytes = image_data.as_bytes_unchecked().to_vec(); - let hash = hex::encode(Sha256::digest(&image_bytes)); - - let hotspot_normalized = (hotspot.x / size.width, hotspot.y / size.height); - - // Only add if we haven't seen this hash before - if !hashes.contains_key(name) { - println!("Captured cursor: {}", name); - println!(" Hash: {}", hash); - println!(" Hotspot: {:?}", hotspot_normalized); - println!(); - - hashes.insert(name.to_string(), (hash, hotspot_normalized)); - } - } else { - println!("Failed to get TIFF representation for cursor: {}", name); - } -} From b28d28eb687fc0bd56e0cfe7bfc0146ef22ff954 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Wed, 15 Oct 2025 15:26:59 +0800 Subject: [PATCH 3/7] format + bring back comment --- .../(window-chrome)/settings/general.tsx | 2 +- crates/cursor-info/src/macos.rs | 82 +++++++++++++------ 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/apps/desktop/src/routes/(window-chrome)/settings/general.tsx b/apps/desktop/src/routes/(window-chrome)/settings/general.tsx index 7c9c1d77c..39a3dd055 100644 --- a/apps/desktop/src/routes/(window-chrome)/settings/general.tsx +++ b/apps/desktop/src/routes/(window-chrome)/settings/general.tsx @@ -14,7 +14,7 @@ import { createMemo, createResource, For, - ParentProps, + type ParentProps, Show, } from "solid-js"; import { createStore, reconcile } from "solid-js/store"; diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index 7641fb2cb..7ebdff06a 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -42,7 +42,7 @@ pub enum CursorShapeMacOS { ResizeUpDown, /// https://developer.apple.com/documentation/appkit/nscursor/ibeamcursorforverticallayout IBeamVerticalForVerticalLayout, - + // macOS Tahoe Cursors TahoeArrow, TahoeContextualMenu, @@ -63,7 +63,7 @@ pub enum CursorShapeMacOS { TahoeResizeUpDown, TahoeIBeamVerticalForVerticalLayout, TahoeZoomOut, - TahoeZoomIn + TahoeZoomIn, } impl CursorShapeMacOS { @@ -138,7 +138,7 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/ibeam_vertical.svg"), hotspot: (0.51, 0.49), }, - + // Tahoe cursor variants Self::TahoeArrow => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/default.svg"), @@ -205,7 +205,7 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/tahoe/resize-ns.svg"), hotspot: (0.5, 0.5), }, - + Self::TahoeResizeUp => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/resize-n.svg"), hotspot: (0.5, 0.5), @@ -222,10 +222,12 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/tahoe/zoom-out.svg"), hotspot: (0.51, 0.49), }, - }) } + /// Derive the cursor type from a hash + /// macOS doesn't allow comparing `NSCursor` instances directly so we hash the image data. + /// macOS cursor are also resolution-independent so this works. pub fn from_hash(hash: &str) -> Option { Some(match hash { // Regular macOS cursor hashes @@ -261,28 +263,62 @@ impl CursorShapeMacOS { "024e1d486a7f16368669d419e69c9a326e464ec1b8ed39645e5c89cb183e03c5" => { Self::IBeamVerticalForVerticalLayout } - + //Hash values obtained from a macOS Tahoe system. "57a1d610df3e421ebef670ba58c97319d2ab6990d64dca34d28140e4527fd54d" => Self::TahoeArrow, - "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c" => Self::TahoeContextualMenu, - "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae" => Self::TahoeClosedHand, - "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => Self::TahoeCrosshair, - "f44a524d6fcfe5a1b1bebf23fcb12fbfeaea0ecf92beb7f69fdf586c319dd8ab" => Self::TahoeDisappearingItem, - "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => Self::TahoeDragCopy, - "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351" => Self::TahoeDragLink, + "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c" => { + Self::TahoeContextualMenu + } + "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae" => { + Self::TahoeClosedHand + } + "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => { + Self::TahoeCrosshair + } + "f44a524d6fcfe5a1b1bebf23fcb12fbfeaea0ecf92beb7f69fdf586c319dd8ab" => { + Self::TahoeDisappearingItem + } + "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => { + Self::TahoeDragCopy + } + "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351" => { + Self::TahoeDragLink + } "3de4a52b22f76f28db5206dc4c2219dff28a6ee5abfb9c5656a469f2140f7eaa" => Self::TahoeIBeam, - "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5" => Self::TahoeOpenHand, - "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320" => Self::TahoeOperationNotAllowed, - "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f" => Self::TahoePointingHand, - "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35" => Self::TahoeResizeDown, - "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf" => Self::TahoeResizeLeft, - "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e" => Self::TahoeResizeLeftRight, - "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb" => Self::TahoeResizeRight, - "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b" => Self::TahoeResizeUp, - "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451" => Self::TahoeResizeUpDown, - "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a" => Self::TahoeIBeamVerticalForVerticalLayout, + "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5" => { + Self::TahoeOpenHand + } + "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320" => { + Self::TahoeOperationNotAllowed + } + "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f" => { + Self::TahoePointingHand + } + "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35" => { + Self::TahoeResizeDown + } + "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf" => { + Self::TahoeResizeLeft + } + "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e" => { + Self::TahoeResizeLeftRight + } + "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb" => { + Self::TahoeResizeRight + } + "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b" => { + Self::TahoeResizeUp + } + "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451" => { + Self::TahoeResizeUpDown + } + "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a" => { + Self::TahoeIBeamVerticalForVerticalLayout + } "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177" => Self::TahoeZoomIn, - "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049" => Self::TahoeZoomOut, + "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049" => { + Self::TahoeZoomOut + } _ => return None, }) } From 06025432cfe4f5efb5df4ec010f8103a09b280fc Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 17 Oct 2025 17:54:18 +0800 Subject: [PATCH 4/7] fixup hotspots --- crates/cursor-info/cursors.html | 159 ++++++++++++++++++++++++++++---- crates/cursor-info/src/macos.rs | 86 +++++++++++------ 2 files changed, 199 insertions(+), 46 deletions(-) diff --git a/crates/cursor-info/cursors.html b/crates/cursor-info/cursors.html index c88e7158b..026102cfe 100644 --- a/crates/cursor-info/cursors.html +++ b/crates/cursor-info/cursors.html @@ -1,4 +1,4 @@ - + @@ -50,25 +50,31 @@ display: inline-block; border: 2px solid #ddd; border-radius: 4px; - background: linear-gradient(45deg, #ccc 25%, transparent 25%), + background: + linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%); background-size: 10px 10px; - background-position: 0 0, 0 5px, 5px -5px, -5px 0px; + background-position: + 0 0, + 0 5px, + 5px -5px, + -5px 0px; cursor: crosshair; } .cursor-svg { display: block; - max-width: 200px; - max-height: 200px; + width: 200px; + height: 200px; pointer-events: none; + object-fit: contain; } .cursor-svg.macos { - max-width: 250px; - max-height: 250px; + width: 200px; + height: 200px; } .hotspot { @@ -135,8 +141,8 @@

Cursor Hotspot Viewer

- Hover over cursors to see mouse coordinates, click to copy hotspot - values + Hover over cursors to see mouse coordinates, click to copy + hotspot values

@@ -255,6 +261,120 @@

Windows Cursors

svg: "assets/mac/ibeam_vertical.svg", hotspot: [0.51, 0.49], }, + { + name: "tahoe_arrow", + hash: "57a1d610df3e421ebef670ba58c97319d2ab6990d64dca34d28140e4527fd54d", + svg: "assets/mac/tahoe/default.svg", + hotspot: [0.495, 0.463], + }, + { + name: "tahoe_contextual_menu", + hash: "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c", + svg: "assets/mac/tahoe/context-menu.svg", + hotspot: [0.495, 0.352], + }, + { + name: "tahoe_closed_hand", + hash: "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae", + svg: "assets/mac/tahoe/grabbing.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_crosshair", + hash: "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46", + svg: "assets/mac/tahoe/crosshair.svg", + hotspot: [0.52, 0.51], + }, + { + name: "tahoe_drag_copy", + hash: "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960", + svg: "assets/mac/drag_copy.svg", + hotspot: [0.255, 0.1], + }, + { + name: "tahoe_drag_link", + hash: "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351", + svg: "assets/mac/drag_link.svg", + hotspot: [0.621, 0.309], + }, + { + name: "tahoe_ibeam", + hash: "3de4a52b22f76f28db5206dc4c2219dff28a6ee5abfb9c5656a469f2140f7eaa", + svg: "assets/mac/tahoe/text.svg", + hotspot: [0.525, 0.52], + }, + { + name: "tahoe_open_hand", + hash: "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5", + svg: "assets/mac/tahoe/grab.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_operation_not_allowed", + hash: "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320", + svg: "assets/mac/operation_not_allowed.svg", + hotspot: [0.24, 0.1], + }, + { + name: "tahoe_pointing_hand", + hash: "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f", + svg: "assets/mac/tahoe/pointer.svg", + hotspot: [0.5, 0.4], + }, + { + name: "tahoe_resize_down", + hash: "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35", + svg: "assets/mac/tahoe/resize-s.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_resize_left", + hash: "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf", + svg: "assets/mac/tahoe/resize-w.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_resize_left_right", + hash: "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e", + svg: "assets/mac/tahoe/resize-ew.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_resize_right", + hash: "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb", + svg: "assets/mac/tahoe/resize-e.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_resize_up", + hash: "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b", + svg: "assets/mac/tahoe/resize-n.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_resize_up_down", + hash: "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451", + svg: "assets/mac/tahoe/resize-ns.svg", + hotspot: [0.5, 0.5], + }, + { + name: "tahoe_ibeam_vertical", + hash: "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a", + svg: "assets/mac/ibeam_vertical.svg", + hotspot: [0.51, 0.49], + }, + { + name: "tahoe_zoom_in", + hash: "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177", + svg: "assets/mac/tahoe/zoom-in.svg", + hotspot: [0.51, 0.49], + }, + { + name: "tahoe_zoom_out", + hash: "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049", + svg: "assets/mac/tahoe/zoom-out.svg", + hotspot: [0.51, 0.49], + }, ], windows: [ { @@ -398,7 +518,7 @@

Windows Cursors

if (cursor.hotspot) { hotspotInfo.textContent = `Hotspot: (${cursor.hotspot[0].toFixed( - 3 + 3, )}, ${cursor.hotspot[1].toFixed(3)})`; } else { hotspotInfo.innerHTML = @@ -418,7 +538,7 @@

Windows Cursors

const y = (e.clientY - rect.top) / rect.height; currentMousePos = [x, y]; mousePosition.textContent = `Mouse: (${x.toFixed(3)}, ${y.toFixed( - 3 + 3, )})`; }); @@ -431,14 +551,14 @@

Windows Cursors

// If mouse is over the container, use current mouse position if (currentMousePos) { const hotspotText = `(${currentMousePos[0].toFixed( - 3 + 3, )}, ${currentMousePos[1].toFixed(3)})`; navigator.clipboard.writeText(hotspotText).then(() => { mousePosition.textContent = "Copied!"; setTimeout(() => { if (currentMousePos) { mousePosition.textContent = `Mouse: (${currentMousePos[0].toFixed( - 3 + 3, )}, ${currentMousePos[1].toFixed(3)})`; } else { mousePosition.textContent = ""; @@ -448,7 +568,7 @@

Windows Cursors

} else if (cursor.hotspot) { // Fallback to defined hotspot if no current mouse position const hotspotText = `(${cursor.hotspot[0].toFixed( - 3 + 3, )}, ${cursor.hotspot[1].toFixed(3)})`; navigator.clipboard.writeText(hotspotText).then(() => { mousePosition.textContent = "Copied!"; @@ -479,14 +599,19 @@

Windows Cursors

function initializeCursors() { const macosContainer = document.getElementById("macos-cursors"); - const windowsContainer = document.getElementById("windows-cursors"); + const windowsContainer = + document.getElementById("windows-cursors"); cursors.macos.forEach((cursor) => { - macosContainer.appendChild(createCursorElement(cursor, "macos")); + macosContainer.appendChild( + createCursorElement(cursor, "macos"), + ); }); cursors.windows.forEach((cursor) => { - windowsContainer.appendChild(createCursorElement(cursor, "windows")); + windowsContainer.appendChild( + createCursorElement(cursor, "windows"), + ); }); } diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index 7641fb2cb..f4bd3ea24 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -42,13 +42,12 @@ pub enum CursorShapeMacOS { ResizeUpDown, /// https://developer.apple.com/documentation/appkit/nscursor/ibeamcursorforverticallayout IBeamVerticalForVerticalLayout, - + // macOS Tahoe Cursors TahoeArrow, TahoeContextualMenu, TahoeClosedHand, TahoeCrosshair, - TahoeDisappearingItem, TahoeDragCopy, TahoeDragLink, TahoeIBeam, @@ -63,7 +62,7 @@ pub enum CursorShapeMacOS { TahoeResizeUpDown, TahoeIBeamVerticalForVerticalLayout, TahoeZoomOut, - TahoeZoomIn + TahoeZoomIn, } impl CursorShapeMacOS { @@ -138,15 +137,15 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/ibeam_vertical.svg"), hotspot: (0.51, 0.49), }, - + // Tahoe cursor variants Self::TahoeArrow => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/default.svg"), - hotspot: (0.347, 0.33), + hotspot: (0.495, 0.463), }, Self::TahoeContextualMenu => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/context-menu.svg"), - hotspot: (0.278, 0.295), + hotspot: (0.495, 0.352), }, Self::TahoeClosedHand => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/grabbing.svg"), @@ -156,7 +155,6 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/tahoe/crosshair.svg"), hotspot: (0.52, 0.51), }, - Self::TahoeDisappearingItem => return None, Self::TahoeDragCopy => ResolvedCursor { raw: include_str!("../assets/mac/drag_copy.svg"), hotspot: (0.255, 0.1), @@ -205,7 +203,7 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/tahoe/resize-ns.svg"), hotspot: (0.5, 0.5), }, - + Self::TahoeResizeUp => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/resize-n.svg"), hotspot: (0.5, 0.5), @@ -216,13 +214,12 @@ impl CursorShapeMacOS { }, Self::TahoeZoomIn => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/zoom-in.svg"), - hotspot: (0.51, 0.49), + hotspot: (0.548, 0.544), }, Self::TahoeZoomOut => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/zoom-out.svg"), - hotspot: (0.51, 0.49), + hotspot: (0.551, 0.544), }, - }) } @@ -261,28 +258,59 @@ impl CursorShapeMacOS { "024e1d486a7f16368669d419e69c9a326e464ec1b8ed39645e5c89cb183e03c5" => { Self::IBeamVerticalForVerticalLayout } - + //Hash values obtained from a macOS Tahoe system. "57a1d610df3e421ebef670ba58c97319d2ab6990d64dca34d28140e4527fd54d" => Self::TahoeArrow, - "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c" => Self::TahoeContextualMenu, - "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae" => Self::TahoeClosedHand, - "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => Self::TahoeCrosshair, - "f44a524d6fcfe5a1b1bebf23fcb12fbfeaea0ecf92beb7f69fdf586c319dd8ab" => Self::TahoeDisappearingItem, - "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => Self::TahoeDragCopy, - "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351" => Self::TahoeDragLink, + "877e1c153d942d18ddfe88e72e2f34ad4435a6839fc447c1a32a71e6bbe1104c" => { + Self::TahoeContextualMenu + } + "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae" => { + Self::TahoeClosedHand + } + "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => { + Self::TahoeCrosshair + } + "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => { + Self::TahoeDragCopy + } + "00cdb9c59246bf98172a027a94b323498bf8d82c701c4d0d85c6e452549fa351" => { + Self::TahoeDragLink + } "3de4a52b22f76f28db5206dc4c2219dff28a6ee5abfb9c5656a469f2140f7eaa" => Self::TahoeIBeam, - "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5" => Self::TahoeOpenHand, - "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320" => Self::TahoeOperationNotAllowed, - "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f" => Self::TahoePointingHand, - "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35" => Self::TahoeResizeDown, - "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf" => Self::TahoeResizeLeft, - "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e" => Self::TahoeResizeLeftRight, - "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb" => Self::TahoeResizeRight, - "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b" => Self::TahoeResizeUp, - "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451" => Self::TahoeResizeUpDown, - "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a" => Self::TahoeIBeamVerticalForVerticalLayout, + "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5" => { + Self::TahoeOpenHand + } + "48941d14eefe97e53fe38531c0f927d71fbd3e63b32e1e10e0a4ff729d64e320" => { + Self::TahoeOperationNotAllowed + } + "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f" => { + Self::TahoePointingHand + } + "825236ff95d98fd49868da5a588ad7077ea507e15ad0a4924495511d05c1bc35" => { + Self::TahoeResizeDown + } + "8a8608a42590e7c518f410aa0750894d2296c7a72e74e3a9dcceb72bc3bc2daf" => { + Self::TahoeResizeLeft + } + "1db16810eb4c14a9c86807b15633d891298e4decd22ed650d8d5d2375f94d27e" => { + Self::TahoeResizeLeftRight + } + "426e4d72be3d8b97fadca5e1067c5a5c2c939e0bbe9c686947c60e3350f386cb" => { + Self::TahoeResizeRight + } + "95b05d0dd57d3a5c7198c7e8fbcf001c316530dd65de9ec26dde42ba9922e11b" => { + Self::TahoeResizeUp + } + "f919de8ef1e36cd95ec8805f6731e831cb5996a4e4403f7c62b6ff994d429451" => { + Self::TahoeResizeUpDown + } + "5113d2b572347a56228457ca3e96102934eb394c7d26c3d985d4ee146959d34a" => { + Self::TahoeIBeamVerticalForVerticalLayout + } "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177" => Self::TahoeZoomIn, - "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049" => Self::TahoeZoomOut, + "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049" => { + Self::TahoeZoomOut + } _ => return None, }) } From 85b063c731e97233793a802e46a880ab1f52adac Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 17 Oct 2025 18:07:39 +0800 Subject: [PATCH 5/7] put back DisappearingItem --- crates/cursor-info/src/macos.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index d1c7882d1..5c824d7d3 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -48,6 +48,7 @@ pub enum CursorShapeMacOS { TahoeContextualMenu, TahoeClosedHand, TahoeCrosshair, + TahoeDisappearingItem, TahoeDragCopy, TahoeDragLink, TahoeIBeam, @@ -273,6 +274,9 @@ impl CursorShapeMacOS { "0aa0d950a742ed4802ed44095cbf5834de3eea84bf78026cacb8e2c37d244f46" => { Self::TahoeCrosshair } + "f44a524d6fcfe5a1b1bebf23fcb12fbfeaea0ecf92beb7f69fdf586c319dd8ab" => { + Self::TahoeDisappearingItem + } "93d05bf80e702fdf5d6924447c91a0ab5fb196251d5758e98c5b6a5f08f0e960" => { Self::TahoeDragCopy } From bf76f23e6c412f007bc8126f15a27c7a811efd95 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 17 Oct 2025 18:12:00 +0800 Subject: [PATCH 6/7] ready to go --- crates/cursor-info/cursors.html | 4 ++-- crates/cursor-info/src/macos.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/cursor-info/cursors.html b/crates/cursor-info/cursors.html index 026102cfe..596b15856 100644 --- a/crates/cursor-info/cursors.html +++ b/crates/cursor-info/cursors.html @@ -367,13 +367,13 @@

Windows Cursors

name: "tahoe_zoom_in", hash: "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177", svg: "assets/mac/tahoe/zoom-in.svg", - hotspot: [0.51, 0.49], + hotspot: [0.548, 0.544], }, { name: "tahoe_zoom_out", hash: "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049", svg: "assets/mac/tahoe/zoom-out.svg", - hotspot: [0.51, 0.49], + hotspot: [0.551, 0.544], }, ], windows: [ diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index 5c824d7d3..9f49aeeed 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -156,6 +156,7 @@ impl CursorShapeMacOS { raw: include_str!("../assets/mac/tahoe/crosshair.svg"), hotspot: (0.52, 0.51), }, + Self::TahoeDisappearingItem => return None, Self::TahoeDragCopy => ResolvedCursor { raw: include_str!("../assets/mac/drag_copy.svg"), hotspot: (0.255, 0.1), From 0381ec4693ddc413917450a90b5f3babcd7ac3bc Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Fri, 17 Oct 2025 18:21:18 +0800 Subject: [PATCH 7/7] hotspots --- crates/cursor-info/cursors.html | 12 ++++++------ crates/cursor-info/src/macos.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/cursor-info/cursors.html b/crates/cursor-info/cursors.html index 596b15856..599d7061a 100644 --- a/crates/cursor-info/cursors.html +++ b/crates/cursor-info/cursors.html @@ -217,7 +217,7 @@

Windows Cursors

name: "pointing_hand", hash: "b0443e9f72e724cb6d94b879bf29c6cb18376d0357c6233e5a7561cf8a9943c6", svg: "assets/mac/pointing_hand.svg", - hotspot: [0.406, 0.25], + hotspot: [0.516, 0.461], }, { name: "resize_down", @@ -277,7 +277,7 @@

Windows Cursors

name: "tahoe_closed_hand", hash: "bc1a01ced20ea38eda8f0eb1976bfe74ac39150ed9a044d3df918faf3dff15ae", svg: "assets/mac/tahoe/grabbing.svg", - hotspot: [0.5, 0.5], + hotspot: [0.539, 0.498], }, { name: "tahoe_crosshair", @@ -307,7 +307,7 @@

Windows Cursors

name: "tahoe_open_hand", hash: "a6f87e2749a5a6799c04ca8e1782194b770a2b5f966e70b79c7c245222176ec5", svg: "assets/mac/tahoe/grab.svg", - hotspot: [0.5, 0.5], + hotspot: [0.543, 0.515], }, { name: "tahoe_operation_not_allowed", @@ -319,7 +319,7 @@

Windows Cursors

name: "tahoe_pointing_hand", hash: "cb0277925fa3ecca8bc54bc98b3ef1d5c08cfd4c6086733f4d849c675f68bf6f", svg: "assets/mac/tahoe/pointer.svg", - hotspot: [0.5, 0.4], + hotspot: [0.516, 0.459], }, { name: "tahoe_resize_down", @@ -367,13 +367,13 @@

Windows Cursors

name: "tahoe_zoom_in", hash: "e539c32a13a6b2caf0e0a991a21d31f8d16cb9feee61fb4efc27a21d6dd6a177", svg: "assets/mac/tahoe/zoom-in.svg", - hotspot: [0.548, 0.544], + hotspot: [0.549, 0.550], }, { name: "tahoe_zoom_out", hash: "d2324ade560f68ce638bb2fd98e9ba2f08d219593afab6b94fb647b1c243d049", svg: "assets/mac/tahoe/zoom-out.svg", - hotspot: [0.551, 0.544], + hotspot: [0.551, 0.552], }, ], windows: [ diff --git a/crates/cursor-info/src/macos.rs b/crates/cursor-info/src/macos.rs index 9f49aeeed..432d1333c 100644 --- a/crates/cursor-info/src/macos.rs +++ b/crates/cursor-info/src/macos.rs @@ -108,7 +108,7 @@ impl CursorShapeMacOS { }, Self::PointingHand => ResolvedCursor { raw: include_str!("../assets/mac/pointing_hand.svg"), - hotspot: (0.406, 0.25), + hotspot: (0.516, 0.461), }, Self::ResizeDown => ResolvedCursor { raw: include_str!("../assets/mac/resize_down.svg"), @@ -150,7 +150,7 @@ impl CursorShapeMacOS { }, Self::TahoeClosedHand => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/grabbing.svg"), - hotspot: (0.5, 0.5), + hotspot: (0.539, 0.498), }, Self::TahoeCrosshair => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/crosshair.svg"), @@ -172,7 +172,7 @@ impl CursorShapeMacOS { }, Self::TahoeOpenHand => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/grab.svg"), - hotspot: (0.5, 0.5), + hotspot: (0.543, 0.515), }, Self::TahoeOperationNotAllowed => ResolvedCursor { raw: include_str!("../assets/mac/operation_not_allowed.svg"), @@ -180,7 +180,7 @@ impl CursorShapeMacOS { }, Self::TahoePointingHand => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/pointer.svg"), - hotspot: (0.5, 0.4), + hotspot: (0.516, 0.459), }, Self::TahoeResizeDown => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/resize-s.svg"), @@ -216,11 +216,11 @@ impl CursorShapeMacOS { }, Self::TahoeZoomIn => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/zoom-in.svg"), - hotspot: (0.548, 0.544), + hotspot: (0.549, 0.550), }, Self::TahoeZoomOut => ResolvedCursor { raw: include_str!("../assets/mac/tahoe/zoom-out.svg"), - hotspot: (0.551, 0.544), + hotspot: (0.551, 0.552), }, }) }