From 1c831d041af2fdf03be3c560a88bbb9f75fa1983 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 11 May 2026 21:59:45 -0700 Subject: [PATCH 01/10] test: cover tab bar button animation policy --- .../Internal/Styling/TabBarButtonAnimationPolicy.swift | 5 +++++ Tests/BonsplitTests/BonsplitTests.swift | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift diff --git a/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift b/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift new file mode 100644 index 00000000..73d26adb --- /dev/null +++ b/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift @@ -0,0 +1,5 @@ +import Foundation + +enum TabBarButtonAnimationPolicy { + static let disablesIncidentalButtonAnimations = false +} diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index 853c2bbd..944c52fb 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -223,6 +223,13 @@ final class BonsplitTests: XCTestCase { XCTAssertEqual(defaults.splitDown, "Split Down") } + func testTabBarButtonChromeDisablesIncidentalAnimations() { + XCTAssertTrue( + TabBarButtonAnimationPolicy.disablesIncidentalButtonAnimations, + "Tab bar button hover/press/visibility chrome must not animate; rapid shortcut tab selection should not inherit stale button animation transactions." + ) + } + func testDefaultSplitActionButtons() { XCTAssertEqual( BonsplitConfiguration.SplitActionButton.defaults, From f2f5fa11d48b929cccbc1a29a0d8d42e5c82a344 Mon Sep 17 00:00:00 2001 From: Lawrence Chen Date: Fri, 8 May 2026 18:19:56 -0700 Subject: [PATCH 02/10] fix: disable tab bar button animations --- .../Styling/TabBarButtonAnimationPolicy.swift | 2 +- .../Bonsplit/Internal/Views/TabBarView.swift | 18 +++++++++----- .../Bonsplit/Internal/Views/TabItemView.swift | 24 ++++++++++++++----- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift b/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift index 73d26adb..40ecdcbf 100644 --- a/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift +++ b/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift @@ -1,5 +1,5 @@ import Foundation enum TabBarButtonAnimationPolicy { - static let disablesIncidentalButtonAnimations = false + static let disablesIncidentalButtonAnimations = true } diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index e5866935..94cc3d63 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -1019,7 +1019,7 @@ struct TabBarView: View { splitButtonBackdropChrome .opacity(shouldShowSplitButtons ? 1 : 0) .allowsHitTesting(false) - .animation(.easeInOut(duration: 0.14), value: shouldShowSplitButtons) + .tabBarButtonAnimationsDisabled() } .overlay(maskedTabBarBottomSeparatorChrome) .overlay { @@ -1050,10 +1050,10 @@ struct TabBarView: View { onDoubleClick: { performNewTerminalSplitButtonAction() }, - onHoverChanged: { isHoveringTabBar = $0 } + onHoverChanged: { updateTabBarHover($0) } )) .overlay( - TabBarHoverTrackingView { isHoveringTabBar = $0 } + TabBarHoverTrackingView { updateTabBarHover($0) } ) .overlay( TabBarManualReorderTrackingView( @@ -1104,6 +1104,12 @@ struct TabBarView: View { // MARK: - Tab Item + private func updateTabBarHover(_ hovering: Bool) { + withTransaction(Transaction(animation: nil)) { + isHoveringTabBar = hovering + } + } + @ViewBuilder private func tabItem(for tab: TabItem, at index: Int) -> some View { let contextMenuState = contextMenuState(for: tab, at: index) @@ -1360,8 +1366,8 @@ struct TabBarView: View { .saturation(tabBarSaturation) .opacity(shouldShowSplitButtons ? 1 : 0) .allowsHitTesting(shouldShowSplitButtons) - .frame(height: tabBarHeight, alignment: .trailing) - .animation(.easeInOut(duration: 0.14), value: shouldShowSplitButtons) + .frame(height: tabBarHeight, alignment: .trailing) + .tabBarButtonAnimationsDisabled() } } @@ -1863,7 +1869,7 @@ private struct SplitActionButtonStyle: ButtonStyle { .contentShape(Rectangle()) .foregroundStyle(TabBarColors.splitActionIcon(for: appearance, isPressed: configuration.isPressed)) .opacity(configuration.isPressed ? 0.72 : 1.0) - .animation(.easeOut(duration: 0.08), value: configuration.isPressed) + .tabBarButtonAnimationsDisabled() } } diff --git a/Sources/Bonsplit/Internal/Views/TabItemView.swift b/Sources/Bonsplit/Internal/Views/TabItemView.swift index dfb85c79..f0d28d55 100644 --- a/Sources/Bonsplit/Internal/Views/TabItemView.swift +++ b/Sources/Bonsplit/Internal/Views/TabItemView.swift @@ -9,6 +9,13 @@ extension View { func tabControlShortcutHintVisibilityAnimation(value: Value) -> some View { animation(TabControlShortcutHintAnimation.visibility, value: value) } + + func tabBarButtonAnimationsDisabled() -> some View { + transaction { transaction in + transaction.animation = nil + transaction.disablesAnimations = true + } + } } private enum TabControlShortcutHintDebugSettings { @@ -164,10 +171,13 @@ struct TabItemView: View { } .buttonStyle(.plain) .onHover { hovering in - isZoomHovered = hovering + withTransaction(Transaction(animation: nil)) { + isZoomHovered = hovering + } } .saturation(saturation) .accessibilityLabel("Exit zoom") + .tabBarButtonAnimationsDisabled() } } @@ -201,8 +211,9 @@ struct TabItemView: View { onSelect() } .onHover { hovering in - // Keep icon rendering stable while hovering; only accessory/background elements animate. - isHovered = hovering + withTransaction(Transaction(animation: nil)) { + isHovered = hovering + } } .accessibilityElement(children: .combine) .accessibilityLabel(tab.title) @@ -426,14 +437,15 @@ struct TabItemView: View { } .buttonStyle(.plain) .onHover { hovering in - isCloseHovered = hovering + withTransaction(Transaction(animation: nil)) { + isCloseHovered = hovering + } } .saturation(saturation) } } .frame(width: accessorySlotSize, height: accessorySlotSize) - .animation(.easeInOut(duration: TabBarMetrics.hoverDuration), value: isHovered) - .animation(.easeInOut(duration: TabBarMetrics.hoverDuration), value: isCloseHovered) + .tabBarButtonAnimationsDisabled() } } From 277bff2a89cb8f408ed5b58f211537d18e8db793 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Tue, 12 May 2026 13:20:17 -0700 Subject: [PATCH 03/10] fix: derive tab indicator frame from selection --- .../Styling/TabBarButtonAnimationPolicy.swift | 5 -- .../Bonsplit/Internal/Views/TabBarView.swift | 37 ++++++------ Tests/BonsplitTests/BonsplitTests.swift | 57 ++++++++++++++++--- 3 files changed, 68 insertions(+), 31 deletions(-) delete mode 100644 Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift diff --git a/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift b/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift deleted file mode 100644 index 40ecdcbf..00000000 --- a/Sources/Bonsplit/Internal/Styling/TabBarButtonAnimationPolicy.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -enum TabBarButtonAnimationPolicy { - static let disablesIncidentalButtonAnimations = true -} diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index 94cc3d63..a7bf0807 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -47,16 +47,6 @@ public enum BonsplitTabBarHitRegionRegistry { } } -private struct SelectedTabFramePreferenceKey: PreferenceKey { - static let defaultValue: CGRect? = nil - - static func reduce(value: inout CGRect?, nextValue: () -> CGRect?) { - if let next = nextValue() { - value = next - } - } -} - private struct TabFramePreferenceKey: PreferenceKey { static let defaultValue: [UUID: CGRect] = [:] @@ -251,6 +241,14 @@ enum TabBarStyling { SplitActionButtonImageCache.shared.image(for: data) } + static func selectedTabFrame( + selectedTabId: UUID?, + tabFrames: [UUID: CGRect] + ) -> CGRect? { + guard let selectedTabId else { return nil } + return tabFrames[selectedTabId] + } + enum ScrollTarget: Equatable { case leading case selectedTab(UUID) @@ -762,7 +760,6 @@ struct TabBarView: View { @State private var scrollOffset: CGFloat = 0 @State private var contentWidth: CGFloat = 0 @State private var containerWidth: CGFloat = 0 - @State private var selectedTabFrameInBar: CGRect? @State private var tabFramesInBar: [UUID: CGRect] = [:] @State private var measuredSplitButtonLaneWidth: CGFloat = 0 @State private var splitButtonScrollOffset: CGFloat = 0 @@ -849,6 +846,13 @@ struct TabBarView: View { tabBarLayout.trailingTabContentInset } + private var selectedTabFrameInBar: CGRect? { + TabBarStyling.selectedTabFrame( + selectedTabId: pane.selectedTabId, + tabFrames: tabFramesInBar + ) + } + private var leadingScrollAnchorId: String { "tab-bar-leading-\(pane.id.id.uuidString)" } @@ -1088,11 +1092,10 @@ struct TabBarView: View { .onAppear { controlKeyMonitor.start() } - .onPreferenceChange(SelectedTabFramePreferenceKey.self) { frame in - selectedTabFrameInBar = frame - } .onPreferenceChange(TabFramePreferenceKey.self) { frames in - tabFramesInBar = frames + withTransaction(Transaction(animation: nil)) { + tabFramesInBar = frames + } } .onPreferenceChange(SplitButtonLaneWidthPreferenceKey.self) { width in measuredSplitButtonLaneWidth = width @@ -1167,10 +1170,6 @@ struct TabBarView: View { GeometryReader { geometry in let frame = geometry.frame(in: .named("tabBar")) Color.clear - .preference( - key: SelectedTabFramePreferenceKey.self, - value: pane.selectedTabId == tab.id ? frame : nil - ) .preference( key: TabFramePreferenceKey.self, value: [tab.id: frame] diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index 944c52fb..6339b5a1 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -223,13 +223,6 @@ final class BonsplitTests: XCTestCase { XCTAssertEqual(defaults.splitDown, "Split Down") } - func testTabBarButtonChromeDisablesIncidentalAnimations() { - XCTAssertTrue( - TabBarButtonAnimationPolicy.disablesIncidentalButtonAnimations, - "Tab bar button hover/press/visibility chrome must not animate; rapid shortcut tab selection should not inherit stale button animation transactions." - ) - } - func testDefaultSplitActionButtons() { XCTAssertEqual( BonsplitConfiguration.SplitActionButton.defaults, @@ -605,6 +598,56 @@ final class BonsplitTests: XCTestCase { ) } + func testTabBarSelectedChromeFrameFollowsCurrentSelection() { + let firstTabId = UUID() + let secondTabId = UUID() + let layout = TabBarLayout( + tabBarHeight: 28, + splitButtonCount: 0, + splitButtonLaneVisible: false, + reservesSplitButtonLane: false + ) + let frames = [ + firstTabId: CGRect(x: 12, y: 0, width: 120, height: 28), + secondTabId: CGRect(x: 144, y: 0, width: 96, height: 28), + ] + let totalWidth: CGFloat = 300 + + let firstSelectedFrame = TabBarStyling.selectedTabFrame( + selectedTabId: firstTabId, + tabFrames: frames + ) + let secondSelectedFrame = TabBarStyling.selectedTabFrame( + selectedTabId: secondTabId, + tabFrames: frames + ) + let firstIndicatorFrame = layout.selectedIndicatorFrame( + selectedTabFrame: firstSelectedFrame, + totalWidth: totalWidth + ) + let secondIndicatorFrame = layout.selectedIndicatorFrame( + selectedTabFrame: secondSelectedFrame, + totalWidth: totalWidth + ) + + XCTAssertEqual(firstIndicatorFrame?.minX, frames[firstTabId]?.minX) + XCTAssertEqual( + secondIndicatorFrame?.minX, + frames[secondTabId]?.minX, + "Selected tab chrome must be derived from the current selected tab id, not a cached frame from a previous selection." + ) + let nilSelectedFrame = TabBarStyling.selectedTabFrame( + selectedTabId: nil, + tabFrames: frames + ) + XCTAssertNil( + layout.selectedIndicatorFrame( + selectedTabFrame: nilSelectedFrame, + totalWidth: totalWidth + ) + ) + } + func testTabBarLayoutIgnoresMeasuredSplitButtonLaneWidthWithoutButtons() { let layout = TabBarLayout( tabBarHeight: 28, From 78e8989a19f36ce64b071542c41e96667460abd0 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 21:52:03 -0700 Subject: [PATCH 04/10] fix: narrow tab bar animation transaction --- Sources/Bonsplit/Internal/Views/TabItemView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/Bonsplit/Internal/Views/TabItemView.swift b/Sources/Bonsplit/Internal/Views/TabItemView.swift index 1ae372f6..4985fd65 100644 --- a/Sources/Bonsplit/Internal/Views/TabItemView.swift +++ b/Sources/Bonsplit/Internal/Views/TabItemView.swift @@ -13,7 +13,6 @@ extension View { func tabBarButtonAnimationsDisabled() -> some View { transaction { transaction in transaction.animation = nil - transaction.disablesAnimations = true } } } From eb3ffa9f043834b06011e91d3ada3db61d527b79 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 21:55:09 -0700 Subject: [PATCH 05/10] fix: hard-clip split action lane --- Sources/Bonsplit/Internal/Views/TabBarView.swift | 6 ++++++ Tests/BonsplitTests/BonsplitTests.swift | 1 + 2 files changed, 7 insertions(+) diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index 494452be..50f97fba 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -1494,6 +1494,12 @@ struct TabBarView: View { private var splitButtonChrome: some View { if shouldRenderSplitButtons { splitButtons + .frame(width: splitButtonsBackdropWidth, height: tabBarHeight, alignment: .trailing) + .mask { + Rectangle() + .frame(width: splitButtonsBackdropWidth, height: tabBarHeight) + } + .clipped() .saturation(tabBarSaturation) .opacity(shouldShowSplitButtons ? 1 : 0) .allowsHitTesting(shouldShowSplitButtons) diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index b33632d2..82eed020 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -3600,6 +3600,7 @@ final class BonsplitTests: XCTestCase { return renderedTabBarValue( isFocused: true, appearance: appearance, + size: NSSize(width: 320, height: TabBarMetrics.barHeight), configurePane: { pane in let leading = TabItem(title: "", icon: nil) let selected = TabItem(title: "", icon: nil) From 9edc5075832eb4d4b09d07253abc847793471002 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 21:59:02 -0700 Subject: [PATCH 06/10] fix: bound unmeasured split action lane --- Sources/Bonsplit/Internal/Views/TabBarView.swift | 2 +- Tests/BonsplitTests/BonsplitTests.swift | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index 50f97fba..3b143a13 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -478,7 +478,7 @@ struct TabBarLayout: Equatable { } var maximumSplitButtonLaneWidth: CGFloat { - guard availableWidth > 0 else { return fullSplitButtonLaneWidth } + guard availableWidth > 0 else { return 0 } let fractionLimit = availableWidth * TabBarStyling.maximumSplitButtonLaneWidthFraction return max(fractionLimit, trailingWhitespaceBeforeSplitButtonLane) } diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index 82eed020..e0974cbd 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -408,6 +408,7 @@ final class BonsplitTests: XCTestCase { + (3 * TabBarStyling.splitButtonsSpacing) let layout = TabBarLayout( tabBarHeight: 28, + availableWidth: 800, splitButtonCount: 4, splitButtonLaneVisible: true, reservesSplitButtonLane: true, From cbe03481804f3fd903371150090a32b1a7cecc22 Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 22:01:30 -0700 Subject: [PATCH 07/10] fix: contain split action lane rendering --- Sources/Bonsplit/Internal/Views/TabBarView.swift | 1 + Tests/BonsplitTests/BonsplitTests.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index 3b143a13..0e2256dd 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -1656,6 +1656,7 @@ struct TabBarView: View { } .frame(width: laneWidth, height: tabBarHeight, alignment: .trailing) .contentShape(Rectangle()) + .compositingGroup() .clipped() } diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index e0974cbd..21daefcf 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -408,7 +408,6 @@ final class BonsplitTests: XCTestCase { + (3 * TabBarStyling.splitButtonsSpacing) let layout = TabBarLayout( tabBarHeight: 28, - availableWidth: 800, splitButtonCount: 4, splitButtonLaneVisible: true, reservesSplitButtonLane: true, @@ -424,6 +423,7 @@ final class BonsplitTests: XCTestCase { func testTabBarLayoutExpandsForMeasuredSplitButtonLaneWidth() { let layout = TabBarLayout( tabBarHeight: 28, + availableWidth: 800, splitButtonCount: 4, splitButtonLaneVisible: true, reservesSplitButtonLane: true, From ba85532beaaba48a1ccaf6aa2cbd42a6a45724eb Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 22:03:42 -0700 Subject: [PATCH 08/10] fix: ignore zero tab width for action lane --- Sources/Bonsplit/Internal/Views/TabBarView.swift | 3 ++- Tests/BonsplitTests/BonsplitTests.swift | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/Bonsplit/Internal/Views/TabBarView.swift b/Sources/Bonsplit/Internal/Views/TabBarView.swift index 0e2256dd..b4aa5ec2 100644 --- a/Sources/Bonsplit/Internal/Views/TabBarView.swift +++ b/Sources/Bonsplit/Internal/Views/TabBarView.swift @@ -485,7 +485,8 @@ struct TabBarLayout: Equatable { var trailingWhitespaceBeforeSplitButtonLane: CGFloat { guard availableWidth > 0, - let tabContentWidthExcludingSplitButtonLane else { + let tabContentWidthExcludingSplitButtonLane, + tabContentWidthExcludingSplitButtonLane > 0 else { return 0 } return max(0, availableWidth - tabContentWidthExcludingSplitButtonLane) diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index 21daefcf..e07a198c 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -451,6 +451,22 @@ final class BonsplitTests: XCTestCase { XCTAssertTrue(layout.splitButtonLaneOverflowsViewport) } + func testTabBarLayoutDoesNotTreatZeroTabContentAsTrailingWhitespace() { + let layout = TabBarLayout( + tabBarHeight: 28, + availableWidth: 240, + tabContentWidthExcludingSplitButtonLane: 0, + splitButtonCount: 12, + splitButtonLaneVisible: true, + reservesSplitButtonLane: true, + measuredSplitButtonLaneWidth: 400 + ) + + XCTAssertEqual(layout.maximumSplitButtonLaneWidth, 60) + XCTAssertEqual(layout.visibleSplitButtonLaneWidth, 60) + XCTAssertEqual(layout.trailingTabContentInset, 60) + } + func testTabBarLayoutUsesTrailingWhitespaceBeforeClippingSplitButtons() { let measuredWidth = TabBarStyling.splitButtonsBackdropWidth(buttonCount: 10) let layout = TabBarLayout( From 9e48fe9644b799f17b696c66ce38dd9f2a6daafd Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 22:05:46 -0700 Subject: [PATCH 09/10] test: crowd action lane overflow fixture --- Tests/BonsplitTests/BonsplitTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index e07a198c..24bd4667 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -3450,7 +3450,7 @@ final class BonsplitTests: XCTestCase { showSplitButtons: true, size: size, configurePane: { pane in - let tabs = (0..<8).map { _ in TabItem(title: "", icon: nil) } + let tabs = (0..<16).map { _ in TabItem(title: "", icon: nil) } pane.tabs = tabs pane.selectedTabId = tabs.first?.id } From e093031f8d21daefc19d3a6bfd725ca8556798fb Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Mon, 18 May 2026 22:07:44 -0700 Subject: [PATCH 10/10] test: sample action lane edge for overflow --- Tests/BonsplitTests/BonsplitTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/BonsplitTests/BonsplitTests.swift b/Tests/BonsplitTests/BonsplitTests.swift index 24bd4667..69a3bdff 100644 --- a/Tests/BonsplitTests/BonsplitTests.swift +++ b/Tests/BonsplitTests/BonsplitTests.swift @@ -3458,9 +3458,9 @@ final class BonsplitTests: XCTestCase { maximumBrightness( in: hostingView, sampleRect: NSRect( - x: 100, + x: size.width - splitButtonLaneWidth - 16, y: 5, - width: size.width - splitButtonLaneWidth - 108, + width: 8, height: size.height - 10 ) )