Allow smaller sidebar widths (#1420)

* Add sidebar minimum width UI regression test

* Allow narrower sidebar resizing

* Set smaller sidebar minimum to 180
This commit is contained in:
Lawrence Chen 2026-03-13 21:40:25 -07:00 committed by GitHub
parent 623262493b
commit 6c644d930d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 14 deletions

View file

@ -1646,7 +1646,7 @@ struct ContentView: View {
nonisolated private static let commandPaletteCommandsPrefix = ">"
private static let commandPaletteVisiblePreviewResultLimit = 48
private static let commandPaletteVisiblePreviewCandidateLimit = 192
private static let minimumSidebarWidth: CGFloat = 186
private static let minimumSidebarWidth: CGFloat = CGFloat(SessionPersistencePolicy.minimumSidebarWidth)
private static let maximumSidebarWidthRatio: CGFloat = 1.0 / 3.0
private enum SidebarResizerHandle: Hashable {
@ -1673,10 +1673,19 @@ struct ContentView: View {
return max(Self.minimumSidebarWidth, fallbackScreenWidth * Self.maximumSidebarWidthRatio)
}
static func clampedSidebarWidth(_ candidate: CGFloat, maximumWidth: CGFloat) -> CGFloat {
let minimumWidth = Self.minimumSidebarWidth
let sanitizedMaximumWidth = max(minimumWidth, maximumWidth.isFinite ? maximumWidth : minimumWidth)
guard candidate.isFinite else {
return CGFloat(SessionPersistencePolicy.defaultSidebarWidth)
}
return max(minimumWidth, min(sanitizedMaximumWidth, candidate))
}
private func clampSidebarWidthIfNeeded(availableWidth: CGFloat? = nil) {
let nextWidth = max(
Self.minimumSidebarWidth,
min(maxSidebarWidth(availableWidth: availableWidth), sidebarWidth)
let nextWidth = Self.clampedSidebarWidth(
sidebarWidth,
maximumWidth: maxSidebarWidth(availableWidth: availableWidth)
)
guard abs(nextWidth - sidebarWidth) > 0.5 else { return }
withTransaction(Transaction(animation: nil)) {
@ -1685,12 +1694,7 @@ struct ContentView: View {
}
private func normalizedSidebarWidth(_ candidate: CGFloat) -> CGFloat {
let minWidth = CGFloat(SessionPersistencePolicy.minimumSidebarWidth)
let maxWidth = max(minWidth, maxSidebarWidth())
if !candidate.isFinite {
return CGFloat(SessionPersistencePolicy.defaultSidebarWidth)
}
return max(minWidth, min(maxWidth, candidate))
Self.clampedSidebarWidth(candidate, maximumWidth: maxSidebarWidth())
}
private func activateSidebarResizerCursor() {
@ -1881,9 +1885,9 @@ struct ContentView: View {
activateSidebarResizerCursor()
let startWidth = sidebarDragStartWidth ?? sidebarWidth
let nextWidth = max(
Self.minimumSidebarWidth,
min(maxSidebarWidth(availableWidth: availableWidth), startWidth + value.translation.width)
let nextWidth = Self.clampedSidebarWidth(
startWidth + value.translation.width,
maximumWidth: maxSidebarWidth(availableWidth: availableWidth)
)
withTransaction(Transaction(animation: nil)) {
sidebarWidth = nextWidth

View file

@ -8,7 +8,7 @@ enum SessionSnapshotSchema {
enum SessionPersistencePolicy {
static let defaultSidebarWidth: Double = 200
static let minimumSidebarWidth: Double = 186
static let minimumSidebarWidth: Double = 180
static let maximumSidebarWidth: Double = 600
static let minimumWindowWidth: Double = 300
static let minimumWindowHeight: Double = 200

View file

@ -0,0 +1,17 @@
import XCTest
#if canImport(cmux_DEV)
@testable import cmux_DEV
#elseif canImport(cmux)
@testable import cmux
#endif
final class SidebarWidthPolicyTests: XCTestCase {
func testContentViewClampAllowsNarrowSidebarBelowLegacyMinimum() {
XCTAssertEqual(
ContentView.clampedSidebarWidth(184, maximumWidth: 600),
184,
accuracy: 0.001
)
}
}

View file

@ -37,6 +37,30 @@ final class SidebarResizeUITests: XCTestCase {
XCTAssertGreaterThanOrEqual(leftDelta, -122, "Resizer moved farther than requested drag-left offset")
}
func testSidebarResizerAllowsSmallerMinimumWidth() {
let app = XCUIApplication()
app.launch()
let window = app.windows.firstMatch
XCTAssertTrue(window.waitForExistence(timeout: 5.0))
let elements = app.descendants(matching: .any)
let resizer = elements["SidebarResizer"]
XCTAssertTrue(resizer.waitForExistence(timeout: 5.0))
XCTAssertTrue(waitForElementHittable(resizer, timeout: 5.0), "Expected sidebar resizer to become hittable")
let start = resizer.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
let farLeft = start.withOffset(CGVector(dx: -max(200, window.frame.width), dy: 0))
start.press(forDuration: 0.1, thenDragTo: farLeft)
let sidebarWidth = max(0, resizer.frame.midX - window.frame.minX)
XCTAssertLessThanOrEqual(
sidebarWidth,
185,
"Expected sidebar minimum width to allow a narrower sidebar than the previous 186 px floor. width=\(sidebarWidth)"
)
}
func testSidebarResizerHasMaximumWidthCap() {
let app = XCUIApplication()
app.launch()