diff --git a/winit-appkit/src/cursor.rs b/winit-appkit/src/cursor.rs index 9c86c55db7..e6e3337fff 100644 --- a/winit-appkit/src/cursor.rs +++ b/winit-appkit/src/cursor.rs @@ -5,7 +5,10 @@ use std::sync::OnceLock; use objc2::rc::Retained; use objc2::runtime::Sel; use objc2::{AllocAnyThread, ClassType, available, msg_send, sel}; -use objc2_app_kit::{NSBitmapImageRep, NSCursor, NSDeviceRGBColorSpace, NSImage}; +use objc2_app_kit::{ + NSBitmapImageRep, NSCursor, NSCursorFrameResizeDirections, NSCursorFrameResizePosition, + NSDeviceRGBColorSpace, NSImage, +}; use objc2_foundation::{ NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSSize, NSString, ns_string, }; @@ -204,23 +207,155 @@ pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Retained { CursorIcon::NotAllowed | CursorIcon::NoDrop => NSCursor::operationNotAllowedCursor(), CursorIcon::ContextMenu => NSCursor::contextualMenuCursor(), CursorIcon::Crosshair => NSCursor::crosshairCursor(), - CursorIcon::EResize => NSCursor::resizeRightCursor(), - CursorIcon::NResize => NSCursor::resizeUpCursor(), - CursorIcon::WResize => NSCursor::resizeLeftCursor(), - CursorIcon::SResize => NSCursor::resizeDownCursor(), - CursorIcon::EwResize | CursorIcon::ColResize => NSCursor::resizeLeftRightCursor(), - CursorIcon::NsResize | CursorIcon::RowResize => NSCursor::resizeUpDownCursor(), + CursorIcon::EResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Right, + NSCursorFrameResizeDirections::Outward, + ) + } else { + NSCursor::resizeRightCursor() + } + }, + CursorIcon::NResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Top, + NSCursorFrameResizeDirections::Outward, + ) + } else { + NSCursor::resizeUpCursor() + } + }, + CursorIcon::WResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Left, + NSCursorFrameResizeDirections::Outward, + ) + } else { + NSCursor::resizeLeftCursor() + } + }, + CursorIcon::SResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Bottom, + NSCursorFrameResizeDirections::Outward, + ) + } else { + NSCursor::resizeDownCursor() + } + }, + CursorIcon::EwResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Right, + NSCursorFrameResizeDirections::All, + ) + } else { + NSCursor::resizeLeftRightCursor() + } + }, + CursorIcon::NsResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::Top, + NSCursorFrameResizeDirections::All, + ) + } else { + NSCursor::resizeUpDownCursor() + } + }, + CursorIcon::NeResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::TopRight, + NSCursorFrameResizeDirections::Outward, + ) + } else { + _windowResizeNorthEastCursor() + } + }, + CursorIcon::NwResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::TopLeft, + NSCursorFrameResizeDirections::Outward, + ) + } else { + _windowResizeNorthWestCursor() + } + }, + CursorIcon::SeResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::BottomRight, + NSCursorFrameResizeDirections::Outward, + ) + } else { + _windowResizeSouthEastCursor() + } + }, + CursorIcon::SwResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::BottomLeft, + NSCursorFrameResizeDirections::Outward, + ) + } else { + _windowResizeSouthWestCursor() + } + }, + CursorIcon::NeswResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::TopRight, + NSCursorFrameResizeDirections::All, + ) + } else { + _windowResizeNorthEastSouthWestCursor() + } + }, + CursorIcon::NwseResize => { + if available!(macos = 15.0) { + NSCursor::frameResizeCursorFromPosition_inDirections( + NSCursorFrameResizePosition::TopLeft, + NSCursorFrameResizeDirections::All, + ) + } else { + _windowResizeNorthWestSouthEastCursor() + } + }, + CursorIcon::ColResize => { + if available!(macos = 15.0) { + NSCursor::columnResizeCursor() + } else { + NSCursor::resizeLeftRightCursor() + } + }, + CursorIcon::RowResize => { + if available!(macos = 15.0) { + NSCursor::rowResizeCursor() + } else { + NSCursor::resizeUpDownCursor() + } + }, + CursorIcon::ZoomIn => { + if available!(macos = 15.0) { + NSCursor::zoomInCursor() + } else { + _zoomInCursor() + } + }, + CursorIcon::ZoomOut => { + if available!(macos = 15.0) { + NSCursor::zoomOutCursor() + } else { + _zoomOutCursor() + } + }, CursorIcon::Help => _helpCursor(), - CursorIcon::ZoomIn if available!(macos = 15.0) => NSCursor::zoomInCursor(), - CursorIcon::ZoomIn => _zoomInCursor(), - CursorIcon::ZoomOut if available!(macos = 15.0) => NSCursor::zoomOutCursor(), - CursorIcon::ZoomOut => _zoomOutCursor(), - CursorIcon::NeResize => _windowResizeNorthEastCursor(), - CursorIcon::NwResize => _windowResizeNorthWestCursor(), - CursorIcon::SeResize => _windowResizeSouthEastCursor(), - CursorIcon::SwResize => _windowResizeSouthWestCursor(), - CursorIcon::NeswResize => _windowResizeNorthEastSouthWestCursor(), - CursorIcon::NwseResize => _windowResizeNorthWestSouthEastCursor(), // This is the wrong semantics for `Wait`, but it's the same as // what's used in Safari and Chrome. CursorIcon::Wait | CursorIcon::Progress => busyButClickableCursor(), diff --git a/winit/src/changelog/unreleased.md b/winit/src/changelog/unreleased.md index c90eb11227..409a203c0c 100644 --- a/winit/src/changelog/unreleased.md +++ b/winit/src/changelog/unreleased.md @@ -55,3 +55,4 @@ changelog entry. - On Redox, handle `EINTR` when reading from `event_socket` instead of panicking. - On Wayland, switch from using the `ahash` hashing algorithm to `foldhash`. - On macOS, fix borderless game presentation options not sticking after switching spaces. +- Use new macOS 15 cursors for resize icons.