App-side chrome: new "Pointer Cursor" toggle (Settings -> Editor, outpost.pointerCursorEnabled, on by default) driving a shared .pointerCursorOnHover() view modifier (push/pop NSCursor.pointingHand, macOS-only, no-op on iOS) wired onto every clickable sidebar/list row: collection tree rows + disclosure chevron, flat collection list, document outline rows, collection-overview tab bar + document/search rows, global search results, command palette rows. In-document link hover: MarkdownEditorConfiguration gets a new pointerCursorOverLinksWhileEditing flag (default true). Read-only mode already showed a pointing hand over links unconditionally; editable mode never did (I-beam only) until now - applyReadOnlyCursor in NativeTextView+CursorRects.swift now applies the same over any .link range while editing too, gated by the flag. Wiki links already carry .link alongside their own custom .wikiLinkID, so they're covered with no extra work. Closes out the last item from the original preferences-wiring scope.
39 lines
1.1 KiB
Swift
39 lines
1.1 KiB
Swift
import SwiftUI
|
|
|
|
#if os(macOS)
|
|
import AppKit
|
|
|
|
/// Pointing-hand cursor while the mouse is over a clickable sidebar/list row,
|
|
/// gated by the "Pointer Cursor" setting (Settings → Editor → Pointer Cursor).
|
|
/// `didPush` tracks whether this instance actually pushed a cursor, so a
|
|
/// mid-hover toggle of the preference can never leave `NSCursor`'s push/pop
|
|
/// stack unbalanced — pop only fires for a push this same hover made.
|
|
private struct PointerCursorOnHover: ViewModifier {
|
|
@AppStorage("outpost.pointerCursorEnabled") private var isEnabled = true
|
|
@State private var didPush = false
|
|
|
|
func body(content: Content) -> some View {
|
|
content.onHover { hovering in
|
|
if hovering {
|
|
guard isEnabled else { return }
|
|
NSCursor.pointingHand.push()
|
|
didPush = true
|
|
} else if didPush {
|
|
NSCursor.pop()
|
|
didPush = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
func pointerCursorOnHover() -> some View {
|
|
modifier(PointerCursorOnHover())
|
|
}
|
|
}
|
|
#else
|
|
extension View {
|
|
func pointerCursorOnHover() -> some View { self }
|
|
}
|
|
#endif
|