Skip to content

Commit c5b7c1d

Browse files
Use System Cursor (#251)
1 parent cf85789 commit c5b7c1d

File tree

7 files changed

+70
-9
lines changed

7 files changed

+70
-9
lines changed

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
"kind" : "remoteSourceControl",
4242
"location" : "https://github.com/apple/swift-collections.git",
4343
"state" : {
44-
"revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
45-
"version" : "1.1.0"
44+
"revision" : "ee97538f5b81ae89698fd95938896dec5217b148",
45+
"version" : "1.1.1"
4646
}
4747
},
4848
{

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample/Views/ContentView.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct ContentView: View {
1919
@State private var font: NSFont = NSFont.monospacedSystemFont(ofSize: 12, weight: .regular)
2020
@AppStorage("wrapLines") private var wrapLines: Bool = true
2121
@State private var cursorPositions: [CursorPosition] = []
22+
@AppStorage("systemCursor") private var useSystemCursor: Bool = false
2223

2324
init(document: Binding<CodeEditSourceEditorExampleDocument>, fileURL: URL?) {
2425
self._document = document
@@ -32,6 +33,13 @@ struct ContentView: View {
3233
LanguagePicker(language: $language)
3334
.frame(maxWidth: 100)
3435
Toggle("Wrap Lines", isOn: $wrapLines)
36+
if #available(macOS 14, *) {
37+
Toggle("Use System Cursor", isOn: $useSystemCursor)
38+
} else {
39+
Toggle("Use System Cursor", isOn: $useSystemCursor)
40+
.disabled(true)
41+
.help("macOS 14 required")
42+
}
3543
Spacer()
3644
Text(getLabel(cursorPositions))
3745
}
@@ -47,7 +55,8 @@ struct ContentView: View {
4755
tabWidth: 4,
4856
lineHeight: 1.2,
4957
wrapLines: wrapLines,
50-
cursorPositions: $cursorPositions
58+
cursorPositions: $cursorPositions,
59+
useSystemCursor: useSystemCursor
5160
)
5261
}
5362
.onAppear {

Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
"kind" : "remoteSourceControl",
4242
"location" : "https://github.com/apple/swift-collections.git",
4343
"state" : {
44-
"revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
45-
"version" : "1.1.0"
44+
"revision" : "ee97538f5b81ae89698fd95938896dec5217b148",
45+
"version" : "1.1.1"
4646
}
4747
},
4848
{

Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift

+33-4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
4242
/// character's width between characters, etc. Defaults to `1.0`
4343
/// - bracketPairHighlight: The type of highlight to use to highlight bracket pairs.
4444
/// See `BracketPairHighlight` for more information. Defaults to `nil`
45+
/// - useSystemCursor: If true, uses the system cursor on `>=macOS 14`.
4546
/// - undoManager: The undo manager for the text view. Defaults to `nil`, which will create a new CEUndoManager
4647
/// - coordinators: Any text coordinators for the view to use. See ``TextViewCoordinator`` for more information.
4748
public init(
@@ -62,6 +63,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
6263
isSelectable: Bool = true,
6364
letterSpacing: Double = 1.0,
6465
bracketPairHighlight: BracketPairHighlight? = nil,
66+
useSystemCursor: Bool = true,
6567
undoManager: CEUndoManager? = nil,
6668
coordinators: [any TextViewCoordinator] = []
6769
) {
@@ -82,6 +84,11 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
8284
self.isSelectable = isSelectable
8385
self.letterSpacing = letterSpacing
8486
self.bracketPairHighlight = bracketPairHighlight
87+
if #available(macOS 14, *) {
88+
self.useSystemCursor = useSystemCursor
89+
} else {
90+
self.useSystemCursor = false
91+
}
8592
self.undoManager = undoManager
8693
self.coordinators = coordinators
8794
}
@@ -131,6 +138,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
131138
isSelectable: Bool = true,
132139
letterSpacing: Double = 1.0,
133140
bracketPairHighlight: BracketPairHighlight? = nil,
141+
useSystemCursor: Bool = true,
134142
undoManager: CEUndoManager? = nil,
135143
coordinators: [any TextViewCoordinator] = []
136144
) {
@@ -151,6 +159,11 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
151159
self.isSelectable = isSelectable
152160
self.letterSpacing = letterSpacing
153161
self.bracketPairHighlight = bracketPairHighlight
162+
if #available(macOS 14, *) {
163+
self.useSystemCursor = useSystemCursor
164+
} else {
165+
self.useSystemCursor = false
166+
}
154167
self.undoManager = undoManager
155168
self.coordinators = coordinators
156169
}
@@ -172,6 +185,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
172185
private var isSelectable: Bool
173186
private var letterSpacing: Double
174187
private var bracketPairHighlight: BracketPairHighlight?
188+
private var useSystemCursor: Bool
175189
private var undoManager: CEUndoManager?
176190
package var coordinators: [any TextViewCoordinator]
177191

@@ -195,6 +209,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
195209
isEditable: isEditable,
196210
isSelectable: isSelectable,
197211
letterSpacing: letterSpacing,
212+
useSystemCursor: useSystemCursor,
198213
bracketPairHighlight: bracketPairHighlight,
199214
undoManager: undoManager
200215
)
@@ -238,6 +253,15 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
238253
return
239254
}
240255

256+
updateControllerParams(controller: controller)
257+
258+
controller.reloadUI()
259+
return
260+
}
261+
262+
/// Update the parameters of the controller.
263+
/// - Parameter controller: The controller to update.
264+
func updateControllerParams(controller: TextViewController) {
241265
if controller.font != font {
242266
controller.font = font
243267
}
@@ -276,12 +300,16 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
276300
controller.letterSpacing = letterSpacing
277301
}
278302

279-
controller.bracketPairHighlight = bracketPairHighlight
303+
if controller.useSystemCursor != useSystemCursor {
304+
controller.useSystemCursor = useSystemCursor
305+
}
280306

281-
controller.reloadUI()
282-
return
307+
controller.bracketPairHighlight = bracketPairHighlight
283308
}
284309

310+
/// Checks if the controller needs updating.
311+
/// - Parameter controller: The controller to check.
312+
/// - Returns: True, if the controller's parameters should be updated.
285313
func paramsAreEqual(controller: NSViewControllerType) -> Bool {
286314
controller.font == font &&
287315
controller.isEditable == isEditable &&
@@ -296,7 +324,8 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
296324
controller.indentOption == indentOption &&
297325
controller.tabWidth == tabWidth &&
298326
controller.letterSpacing == letterSpacing &&
299-
controller.bracketPairHighlight == bracketPairHighlight
327+
controller.bracketPairHighlight == bracketPairHighlight &&
328+
controller.useSystemCursor == useSystemCursor
300329
}
301330
}
302331

Sources/CodeEditSourceEditor/Controller/TextViewController.swift

+21
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,18 @@ public class TextViewController: NSViewController {
153153
}
154154
}
155155

156+
/// If true, uses the system cursor on macOS 14 or greater.
157+
public var useSystemCursor: Bool {
158+
get {
159+
textView.useSystemCursor
160+
}
161+
set {
162+
if #available(macOS 14, *) {
163+
textView.useSystemCursor = newValue
164+
}
165+
}
166+
}
167+
156168
var highlighter: Highlighter?
157169

158170
/// The tree sitter client managed by the source editor.
@@ -198,6 +210,7 @@ public class TextViewController: NSViewController {
198210
isEditable: Bool,
199211
isSelectable: Bool,
200212
letterSpacing: Double,
213+
useSystemCursor: Bool,
201214
bracketPairHighlight: BracketPairHighlight?,
202215
undoManager: CEUndoManager? = nil
203216
) {
@@ -221,6 +234,13 @@ public class TextViewController: NSViewController {
221234

222235
super.init(nibName: nil, bundle: nil)
223236

237+
let platformGuardedSystemCursor: Bool
238+
if #available(macOS 14, *) {
239+
platformGuardedSystemCursor = useSystemCursor
240+
} else {
241+
platformGuardedSystemCursor = false
242+
}
243+
224244
self.textView = TextView(
225245
string: string,
226246
font: font,
@@ -230,6 +250,7 @@ public class TextViewController: NSViewController {
230250
isEditable: isEditable,
231251
isSelectable: isSelectable,
232252
letterSpacing: letterSpacing,
253+
useSystemCursor: platformGuardedSystemCursor,
233254
delegate: self
234255
)
235256
}

Tests/CodeEditSourceEditorTests/TagEditingTests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ final class TagEditingTests: XCTestCase {
4747
isEditable: true,
4848
isSelectable: true,
4949
letterSpacing: 1.0,
50+
useSystemCursor: false,
5051
bracketPairHighlight: .flash
5152
)
5253
let tsClient = TreeSitterClient(executor: .init(forceSync: true))

Tests/CodeEditSourceEditorTests/TextViewControllerTests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ final class TextViewControllerTests: XCTestCase {
4747
isEditable: true,
4848
isSelectable: true,
4949
letterSpacing: 1.0,
50+
useSystemCursor: false,
5051
bracketPairHighlight: .flash
5152
)
5253

0 commit comments

Comments
 (0)