macos: pointer style uses macOS 15 helpers

This commit is contained in:
Mitchell Hashimoto
2024-09-20 21:35:49 -07:00
parent e89a4f7408
commit 0e1258b7fe
3 changed files with 35 additions and 21 deletions

View File

@ -83,6 +83,7 @@ extension Ghostty {
.focusedValue(\.ghosttySurfaceCellSize, surfaceView.cellSize) .focusedValue(\.ghosttySurfaceCellSize, surfaceView.cellSize)
#if canImport(AppKit) #if canImport(AppKit)
.backport.pointerVisibility(surfaceView.pointerVisible ? .visible : .hidden) .backport.pointerVisibility(surfaceView.pointerVisible ? .visible : .hidden)
.backport.pointerStyle(surfaceView.pointerStyle)
.onReceive(pubBecomeKey) { notification in .onReceive(pubBecomeKey) { notification in
guard let window = notification.object as? NSWindow else { return } guard let window = notification.object as? NSWindow else { return }
guard let surfaceWindow = surfaceView.window else { return } guard let surfaceWindow = surfaceView.window else { return }

View File

@ -39,7 +39,8 @@ extension Ghostty {
@Published var surfaceSize: ghostty_surface_size_s? = nil @Published var surfaceSize: ghostty_surface_size_s? = nil
// Whether the pointer should be visible or not // Whether the pointer should be visible or not
@Published var pointerVisible: Bool = true @Published private(set) var pointerVisible: Bool = true
@Published private(set) var pointerStyle: BackportPointerStyle = .default
// An initial size to request for a window. This will only affect // An initial size to request for a window. This will only affect
// then the view is moved to a new window. // then the view is moved to a new window.
@ -102,7 +103,6 @@ extension Ghostty {
private var markedText: NSMutableAttributedString private var markedText: NSMutableAttributedString
private(set) var focused: Bool = true private(set) var focused: Bool = true
private var prevPressureStage: Int = 0 private var prevPressureStage: Int = 0
private var cursor: NSCursor = .iBeam
private var appearanceObserver: NSKeyValueObservation? = nil private var appearanceObserver: NSKeyValueObservation? = nil
// This is set to non-null during keyDown to accumulate insertText contents // This is set to non-null during keyDown to accumulate insertText contents
@ -267,49 +267,49 @@ extension Ghostty {
func setCursorShape(_ shape: ghostty_mouse_shape_e) { func setCursorShape(_ shape: ghostty_mouse_shape_e) {
switch (shape) { switch (shape) {
case GHOSTTY_MOUSE_SHAPE_DEFAULT: case GHOSTTY_MOUSE_SHAPE_DEFAULT:
cursor = .arrow pointerStyle = .default
case GHOSTTY_MOUSE_SHAPE_CONTEXT_MENU:
cursor = .contextualMenu
case GHOSTTY_MOUSE_SHAPE_TEXT: case GHOSTTY_MOUSE_SHAPE_TEXT:
cursor = .iBeam pointerStyle = .horizontalText
case GHOSTTY_MOUSE_SHAPE_CROSSHAIR:
cursor = .crosshair
case GHOSTTY_MOUSE_SHAPE_GRAB: case GHOSTTY_MOUSE_SHAPE_GRAB:
cursor = .openHand pointerStyle = .grabIdle
case GHOSTTY_MOUSE_SHAPE_GRABBING: case GHOSTTY_MOUSE_SHAPE_GRABBING:
cursor = .closedHand pointerStyle = .grabActive
case GHOSTTY_MOUSE_SHAPE_POINTER: case GHOSTTY_MOUSE_SHAPE_POINTER:
cursor = .pointingHand pointerStyle = .link
case GHOSTTY_MOUSE_SHAPE_W_RESIZE: case GHOSTTY_MOUSE_SHAPE_W_RESIZE:
cursor = .resizeLeft pointerStyle = .resizeLeft
case GHOSTTY_MOUSE_SHAPE_E_RESIZE: case GHOSTTY_MOUSE_SHAPE_E_RESIZE:
cursor = .resizeRight pointerStyle = .resizeRight
case GHOSTTY_MOUSE_SHAPE_N_RESIZE: case GHOSTTY_MOUSE_SHAPE_N_RESIZE:
cursor = .resizeUp pointerStyle = .resizeUp
case GHOSTTY_MOUSE_SHAPE_S_RESIZE: case GHOSTTY_MOUSE_SHAPE_S_RESIZE:
cursor = .resizeDown pointerStyle = .resizeDown
case GHOSTTY_MOUSE_SHAPE_NS_RESIZE: case GHOSTTY_MOUSE_SHAPE_NS_RESIZE:
cursor = .resizeUpDown pointerStyle = .resizeUpDown
case GHOSTTY_MOUSE_SHAPE_EW_RESIZE: case GHOSTTY_MOUSE_SHAPE_EW_RESIZE:
cursor = .resizeLeftRight pointerStyle = .resizeLeftRight
case GHOSTTY_MOUSE_SHAPE_VERTICAL_TEXT: case GHOSTTY_MOUSE_SHAPE_VERTICAL_TEXT:
cursor = .iBeamCursorForVerticalLayout pointerStyle = .default
// These are not yet supported. We should support them by constructing a
// PointerStyle from an NSCursor.
case GHOSTTY_MOUSE_SHAPE_CONTEXT_MENU:
fallthrough
case GHOSTTY_MOUSE_SHAPE_CROSSHAIR:
fallthrough
case GHOSTTY_MOUSE_SHAPE_NOT_ALLOWED: case GHOSTTY_MOUSE_SHAPE_NOT_ALLOWED:
cursor = .operationNotAllowed pointerStyle = .default
default: default:
// We ignore unknown shapes. // We ignore unknown shapes.

View File

@ -16,3 +16,16 @@ extension View {
) )
} }
} }
extension View {
func pointerStyleFromCursor(_ cursor: NSCursor) -> some View {
if #available(macOS 15.0, *) {
return self.pointerStyle(.image(
Image(nsImage: cursor.image),
hotSpot: .init(x: cursor.hotSpot.x, y: cursor.hotSpot.y)
))
} else {
return self
}
}
}