Skip to content

Commit d773937

Browse files
Merge branch 'main' into itembox
2 parents 838d939 + 509d7b2 commit d773937

File tree

6 files changed

+31
-8
lines changed

6 files changed

+31
-8
lines changed

Sources/CodeEditTextView/TextLayoutManager/TextLayoutManager+Public.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension TextLayoutManager {
1313
}
1414

1515
public func estimatedWidth() -> CGFloat {
16-
maxLineWidth
16+
maxLineWidth + edgeInsets.horizontal
1717
}
1818

1919
/// Finds a text line for the given y position relative to the text view.

Sources/CodeEditTextView/TextLayoutManager/TextLayoutManager.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,12 @@ public class TextLayoutManager: NSObject {
266266
// Update the visible lines with the new set.
267267
visibleLineIds = newVisibleLines
268268

269-
if originalHeight != lineStorage.height || layoutView?.frame.size.height != lineStorage.height {
270-
delegate?.layoutManagerHeightDidUpdate(newHeight: lineStorage.height)
271-
}
269+
#if DEBUG
270+
isInLayout = false
271+
#endif
272+
273+
// These are fine to update outside of `isInLayout` as our internal data structures are finalized at this point
274+
// so laying out again won't break our line storage or visible line.
272275

273276
if maxFoundLineWidth > maxLineWidth {
274277
maxLineWidth = maxFoundLineWidth
@@ -278,9 +281,10 @@ public class TextLayoutManager: NSObject {
278281
delegate?.layoutManagerYAdjustment(yContentAdjustment)
279282
}
280283

281-
#if DEBUG
282-
isInLayout = false
283-
#endif
284+
if originalHeight != lineStorage.height || layoutView?.frame.size.height != lineStorage.height {
285+
delegate?.layoutManagerHeightDidUpdate(newHeight: lineStorage.height)
286+
}
287+
284288
needsLayout = false
285289
}
286290

Sources/CodeEditTextView/TextSelectionManager/TextSelectionManager.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,16 @@ public class TextSelectionManager: NSObject {
188188
if didUpdate {
189189
delegate?.setNeedsDisplay()
190190
cursorTimer.resetTimer()
191+
resetSystemCursorTimers()
192+
}
193+
}
194+
195+
private func resetSystemCursorTimers() {
196+
guard #available(macOS 14, *) else { return }
197+
for cursorView in textSelections.compactMap({ $0.view as? NSTextInsertionIndicator }) {
198+
let frame = cursorView.frame
199+
cursorView.frame = .zero
200+
cursorView.frame = frame
191201
}
192202
}
193203

Sources/CodeEditTextView/TextView/TextView+Delete.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ extension TextView {
6060
guard extendedRange.location >= 0 else { continue }
6161
textSelection.range.formUnion(extendedRange)
6262
}
63+
selectionManager.textSelections.sort(by: { $0.range.location < $1.range.location })
6364
KillRing.shared.kill(
6465
strings: selectionManager.textSelections.map(\.range).compactMap({ textStorage.substring(from: $0) })
6566
)

Sources/CodeEditTextView/TextView/TextView+Layout.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ extension TextView {
5858
inputContext?.invalidateCharacterCoordinates()
5959
}
6060

61+
/// Updates the view's frame if needed depending on wrapping lines, a new maximum width, or changed available size.
62+
/// - Returns: Whether or not the view was updated.
6163
@discardableResult
6264
public func updateFrameIfNeeded() -> Bool {
6365
var availableSize = scrollView?.contentSize ?? .zero
@@ -83,7 +85,7 @@ extension TextView {
8385
if didUpdate {
8486
needsLayout = true
8587
needsDisplay = true
86-
layoutManager.layoutLines()
88+
layoutManager.setNeedsLayout()
8789
}
8890

8991
if isSelectable {

Sources/CodeEditTextView/TextView/TextView+ReplaceCharacters.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ extension TextView {
4242
layoutManager.endTransaction()
4343
selectionManager.notifyAfterEdit()
4444
NotificationCenter.default.post(name: Self.textDidChangeNotification, object: self)
45+
46+
// `scrollSelectionToVisible` is a little expensive to call every time. Instead we just check if the first
47+
// selection is entirely visible. `.contains` checks that all points in the rect are inside.
48+
if let selection = selectionManager.textSelections.first, !visibleRect.contains(selection.boundingRect) {
49+
scrollSelectionToVisible()
50+
}
4551
}
4652

4753
/// Replace the characters in a range with a new string.

0 commit comments

Comments
 (0)