Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bb3f680
fix: avoid model rollback on document close by tracking session edits
dafi Sep 7, 2026
42fcc12
fix: open the double-clicked history entry, not the stale paths
dafi Sep 7, 2026
a2c9cb8
fix(file-compare): ask to save dirty files before replacing them
dafi Sep 7, 2026
8b4ac46
refactor: share the console pane between the file and the folder window
dafi Sep 12, 2026
4071dfd
refactor: share the comparison status bar between the file and the fo…
dafi Sep 12, 2026
4c918d2
fix(folder-compare): hide the context menu items while a comparison runs
dafi Sep 12, 2026
b30a1c2
perf(file-compare): build the line detail view on TextKit 1
dafi Sep 12, 2026
0714d7f
fix(file-compare): keep the EOL label away from the panel edge
dafi Sep 12, 2026
f7e8542
perf(file-compare): compute the widest column once per comparison
dafi Sep 12, 2026
2a533fc
perf(file-compare): skip the second walk over the common prefix
dafi Sep 12, 2026
ea3a08d
fix(file-compare): reload the row heights only when the column width …
dafi Sep 12, 2026
3277c16
fix: flush the pending changes before reading isDocumentEdited
dafi Sep 12, 2026
3ce4eed
fix(file-compare): ask before the session options drop unsaved edits
dafi Sep 12, 2026
ddc9790
feat(file-compare): run the comparison detached from the main thread
dafi Sep 12, 2026
6307091
chore: suppress XCode warnings relative to future modifications
dafi Sep 13, 2026
535cdb3
refactor: pin the details stack views instead of seeding its frame
dafi Sep 13, 2026
c0f89a2
feat: customize document window keyboard navigation
dafi Sep 14, 2026
fc6224c
fix: handle the negated value correctly
dafi Sep 14, 2026
5401c1b
fix: resolve race condition occurring when ask to stop long running o…
dafi Sep 14, 2026
53a6b7c
refactor: move to folder feature because depends from CommonPrefs
dafi Sep 15, 2026
d3f9072
fix: make operation state thread-safe
dafi Sep 15, 2026
bb75d55
fix: fix race condition when comparing folders
dafi Sep 18, 2026
baf0488
refactor: use always the workspace version to create installation zip
dafi Sep 18, 2026
5274898
fix: handle scriptable errors
dafi Sep 18, 2026
d5d6d66
refactor: modernize xcode project
dafi Sep 25, 2026
8153412
refactor: remove custom component in flavor of auto-layout
dafi Sep 25, 2026
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
Prev Previous commit
Next Next commit
refactor: pin the details stack views instead of seeding its frame
  • Loading branch information
dafi committed Sep 13, 2026
commit 535cdb33fd034862a8e0bedba6cb345cebe859b7
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
// Copyright (c) 2025 visualdiffer.com
//

// the stack view is a pane of the console splitter, so its frame is still the seed one when
// the constraints are first evaluated and it must already clear the height its content needs,
// or that first pass is unsatisfiable and causes AppKit to log a conflict
private let detailsStackSeedHeight: CGFloat = 400.0

extension FilesWindowController {
func createDifferenceCounters() -> DifferenceCounters {
let view = DifferenceCounters(frame: .zero)
Expand Down Expand Up @@ -112,11 +107,18 @@ extension FilesWindowController {
func createLineDetailsStackWithViews(_ views: [NSView]) -> NSStackView {
let view = NSStackView(views: views)

view.frame = NSRect(x: 0, y: 0, width: 1, height: detailsStackSeedHeight)
view.orientation = .vertical
view.alignment = .width
view.distribution = .fill

// the arranged views are pinned directly to the stack to avoid cross-hierarchy constraints
for arrangedView in views {
NSLayoutConstraint.activate([
arrangedView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
arrangedView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
}

return view
}

Expand Down Expand Up @@ -153,6 +155,7 @@ extension FilesWindowController {
topView.addSubview(leftView)
topView.addSubview(rightView)

// the thumbnail is sized and positioned by the top view that owns it
NSLayoutConstraint.activate([
leftView.leadingAnchor.constraint(equalTo: topView.leadingAnchor),
leftView.topAnchor.constraint(equalTo: topView.topAnchor, constant: 18),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ extension FilesWindowController: ComparisonActivityDisplayable {
consoleSplitter.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
consoleSplitter.bottomAnchor.constraint(equalTo: differenceCounters.topAnchor, constant: -2),

// the stack view is laid out by the splitter, pinning the thumbnail to it joins
// the panels it contains to the constraint system
fileThumbnail.leadingAnchor.constraint(equalTo: detailsStackView.leadingAnchor),
fileThumbnail.widthAnchor.constraint(equalToConstant: 15),

// linesDetailView has a fixed height
linesDetailView.heightAnchor.constraint(equalToConstant: 46),
])
Expand Down
7 changes: 6 additions & 1 deletion Sources/SharedUI/Components/ConsoleDisplayable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
// Copyright (c) 2026 visualdiffer.com
//

// the console pane is laid out by the splitter, so its frame is still the seed one when the
// constraints are first evaluated and it must already clear the height its own content needs,
// or that first pass is unsatisfiable and causes AppKit to log a conflict
private let consoleSeedHeight: CGFloat = 120.0

// the log console pane, shared by the file and the folder window so the two cannot drift apart
@MainActor
protocol ConsoleDisplayable: ConsoleViewDelegate {
Expand All @@ -20,7 +25,7 @@ protocol ConsoleDisplayable: ConsoleViewDelegate {

extension ConsoleDisplayable {
func createConsoleView() -> ConsoleView {
let view = ConsoleView(frame: NSRect(x: 0, y: 0, width: 1, height: 0))
let view = ConsoleView(frame: NSRect(x: 0, y: 0, width: 1, height: consoleSeedHeight))
view.delegate = self

return view
Expand Down