Skip to content

Remove Problematic CATransaction, Fix Lines Disappearing #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,48 +1,39 @@
{
"pins" : [
{
"identity" : "mainoffender",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattmassicotte/MainOffender",
"state" : {
"revision" : "343cc3797618c29b48b037b4e2beea0664e75315",
"version" : "0.1.0"
}
},
{
"identity" : "rearrange",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ChimeHQ/Rearrange",
"state" : {
"revision" : "8f97f721d8a08c6e01ab9f7460e53819bef72dfa",
"version" : "1.5.3"
"revision" : "5ff7f3363f7a08f77e0d761e38e6add31c2136e1",
"version" : "1.8.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
"version" : "1.0.4"
"revision" : "9bf03ff58ce34478e66aaee630e491823326fd06",
"version" : "1.1.3"
}
},
{
"identity" : "swiftlintplugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/lukepistrol/SwiftLintPlugin",
"state" : {
"revision" : "f69b412a765396d44dc9f4788a5b79919c1ca9e3",
"version" : "0.2.2"
"revision" : "5a65f4074975f811da666dfe31a19850950b1ea4",
"version" : "0.56.2"
}
},
{
"identity" : "textstory",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ChimeHQ/TextStory",
"state" : {
"revision" : "8883fa739aa213e70e6cb109bfbf0a0b551e4cb5",
"version" : "0.8.0"
"revision" : "8dc9148b46fcf93b08ea9d4ef9bdb5e4f700e008",
"version" : "0.9.0"
}
}
],
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let package = Package(
// Text mutation, storage helpers
.package(
url: "https://github.com/ChimeHQ/TextStory",
from: "0.8.0"
from: "0.9.0"
),
// Useful data structures
.package(
Expand All @@ -27,7 +27,7 @@ let package = Package(
// SwiftLint
.package(
url: "https://github.com/lukepistrol/SwiftLintPlugin",
from: "0.2.2"
from: "0.52.2"
)
],
targets: [
Expand Down
29 changes: 24 additions & 5 deletions Sources/CodeEditTextView/TextLayoutManager/TextLayoutManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public class TextLayoutManager: NSObject {
public var isInTransaction: Bool {
transactionCounter > 0
}
#if DEBUG
/// Guard variable for an assertion check in debug builds.
/// Ensures that layout calls are not overlapping, potentially causing layout issues.
/// This is used over a lock, as locks in performant code such as this would be detrimental to performance.
/// Also only included in debug builds. DO NOT USE for checking if layout is active or not. That is an anti-pattern.
private var isInLayout: Bool = false
#endif

weak var layoutView: NSView?

Expand Down Expand Up @@ -188,15 +195,26 @@ public class TextLayoutManager: NSObject {

// MARK: - Layout

/// Asserts that the caller is not in an active layout pass.
/// See docs on ``isInLayout`` for more details.
private func assertNotInLayout() {
#if DEBUG // This is redundant, but it keeps the flag debug-only too which helps prevent misuse.
assert(!isInLayout, "layoutLines called while already in a layout pass. This is a programmer error.")
#endif
}

/// Lays out all visible lines
func layoutLines(in rect: NSRect? = nil) { // swiftlint:disable:this function_body_length
assertNotInLayout()
guard layoutView?.superview != nil,
let visibleRect = rect ?? delegate?.visibleRect,
!isInTransaction,
let textStorage else {
return
}
CATransaction.begin()
#if DEBUG
isInLayout = true
#endif
let minY = max(visibleRect.minY - verticalLayoutPadding, 0)
let maxY = max(visibleRect.maxY + verticalLayoutPadding, 0)
let originalHeight = lineStorage.height
Expand Down Expand Up @@ -237,13 +255,11 @@ public class TextLayoutManager: NSObject {
}
} else {
// Make sure the used fragment views aren't dequeued.
usedFragmentIDs.formUnion(linePosition.data.typesetter.lineFragments.map(\.data.id))
usedFragmentIDs.formUnion(linePosition.data.lineFragments.map(\.data.id))
}
newVisibleLines.insert(linePosition.data.id)
}

CATransaction.commit()

// Enqueue any lines not used in this layout pass.
viewReuseQueue.enqueueViews(notInSet: usedFragmentIDs)

Expand All @@ -262,6 +278,9 @@ public class TextLayoutManager: NSObject {
delegate?.layoutManagerYAdjustment(yContentAdjustment)
}

#if DEBUG
isInLayout = false
#endif
needsLayout = false
}

Expand Down Expand Up @@ -302,7 +321,7 @@ public class TextLayoutManager: NSObject {
let relativeMinY = max(layoutData.minY - position.yPos, 0)
let relativeMaxY = max(layoutData.maxY - position.yPos, relativeMinY)

for lineFragmentPosition in line.typesetter.lineFragments.linesStartingAt(
for lineFragmentPosition in line.lineFragments.linesStartingAt(
relativeMinY,
until: relativeMaxY
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ extension TextView {
delegate?.textView(self, didReplaceContentsIn: range, with: string)
}

layoutManager.endTransaction()
textStorage.endEditing()
layoutManager.endTransaction()
selectionManager.notifyAfterEdit()
NotificationCenter.default.post(name: Self.textDidChangeNotification, object: self)
}
Expand Down
Loading