@@ -89,34 +89,50 @@ extension STTextView {
89
89
}
90
90
}
91
91
92
- removeInsertionPointView ( )
92
+ var existingViews = contentView. subviews. filter { view in
93
+ type ( of: view) == STInsertionPointView . self
94
+ }
93
95
94
96
for selectionFrame in textSelectionFrames where !selectionFrame. isNull && !selectionFrame. isInfinite {
95
97
let insertionViewFrame = CGRect ( origin: selectionFrame. origin, size: CGSize ( width: max ( 2 , selectionFrame. width) , height: selectionFrame. height) ) . pixelAligned
96
-
97
- var textInsertionIndicator : any STInsertionPointIndicatorProtocol
98
- if let customTextInsertionIndicator = self . delegateProxy. textViewInsertionPointView ( self , frame: CGRect ( origin: . zero, size: insertionViewFrame. size) ) {
99
- textInsertionIndicator = customTextInsertionIndicator
98
+ let insertionView : STInsertionPointView
99
+ // re-use existing insertion views
100
+ if !existingViews. isEmpty {
101
+ // reuse existing insertion view
102
+ insertionView = existingViews. removeFirst ( ) as! STInsertionPointView
103
+ insertionView. frame = insertionViewFrame
100
104
} else {
101
- if #available( macOS 14 , * ) {
102
- textInsertionIndicator = STTextInsertionIndicatorNew ( frame: CGRect ( origin: . zero, size: insertionViewFrame. size) )
105
+ // add new views that exedes existing views
106
+ var textInsertionIndicator : any STInsertionPointIndicatorProtocol
107
+ if let customTextInsertionIndicator = self . delegateProxy. textViewInsertionPointView ( self , frame: CGRect ( origin: . zero, size: insertionViewFrame. size) ) {
108
+ textInsertionIndicator = customTextInsertionIndicator
103
109
} else {
104
- textInsertionIndicator = STTextInsertionIndicatorOld ( frame: CGRect ( origin: . zero, size: insertionViewFrame. size) )
110
+ if #available( macOS 14 , * ) {
111
+ textInsertionIndicator = STTextInsertionIndicatorNew ( frame: CGRect ( origin: . zero, size: insertionViewFrame. size) )
112
+ } else {
113
+ textInsertionIndicator = STTextInsertionIndicatorOld ( frame: CGRect ( origin: . zero, size: insertionViewFrame. size) )
114
+ }
105
115
}
106
- }
107
116
108
- let insertionView = STInsertionPointView ( frame: insertionViewFrame, textInsertionIndicator: textInsertionIndicator)
109
- insertionView. clipsToBounds = false
110
- insertionView. insertionPointColor = insertionPointColor
117
+ insertionView = STInsertionPointView ( frame: insertionViewFrame, textInsertionIndicator: textInsertionIndicator)
118
+ insertionView. clipsToBounds = false
119
+ insertionView. insertionPointColor = insertionPointColor
120
+ contentView. addSubview ( insertionView)
121
+ }
111
122
112
123
if isFirstResponder {
113
124
insertionView. blinkStart ( )
114
125
} else {
115
126
insertionView. blinkStop ( )
116
127
}
128
+ }
117
129
118
- contentView. addSubview ( insertionView)
130
+ // remove unused insertion points (unused)
131
+ for v in existingViews {
132
+ v. removeFromSuperview ( )
119
133
}
134
+ existingViews. removeAll ( )
135
+
120
136
} else if !shouldDrawInsertionPoint {
121
137
removeInsertionPointView ( )
122
138
}
@@ -132,9 +148,12 @@ extension STTextView {
132
148
133
149
@available ( macOS 14 . 0 , * )
134
150
private class STTextInsertionIndicatorNew : NSTextInsertionIndicator , STInsertionPointIndicatorProtocol {
151
+ // NSTextInsertionIndicator start as visible (blinking)
152
+ private var _isVisible : Bool = true
135
153
136
154
override init ( frame frameRect: CGRect ) {
137
155
super. init ( frame: frameRect)
156
+ autoresizingMask = [ . width, . height]
138
157
}
139
158
140
159
@available ( * , unavailable)
@@ -153,11 +172,17 @@ private class STTextInsertionIndicatorNew: NSTextInsertionIndicator, STInsertion
153
172
}
154
173
155
174
func blinkStart( ) {
156
- displayMode = . automatic
175
+ if !_isVisible {
176
+ _isVisible = true
177
+ displayMode = . automatic
178
+ }
157
179
}
158
180
159
181
func blinkStop( ) {
160
- displayMode = . hidden
182
+ if _isVisible {
183
+ _isVisible = false
184
+ displayMode = . hidden
185
+ }
161
186
}
162
187
163
188
open override var isFlipped : Bool {
@@ -180,6 +205,7 @@ private class STTextInsertionIndicatorOld: NSView, STInsertionPointIndicatorProt
180
205
wantsLayer = true
181
206
layer? . backgroundColor = insertionPointColor. cgColor
182
207
layer? . cornerRadius = 1
208
+ autoresizingMask = [ . width, . height]
183
209
}
184
210
185
211
@available ( * , unavailable)
0 commit comments