Skip to content

Commit 5b7f145

Browse files
committed
macos: make terminal smaller to account for legacy scrollbar
When the preferred scrollbar style is "legacy", the scrollbar takes up space that offsets the actual terminal. To prevent reflow, we detect this before the scrollbar becomes visible and shrink our terminal width to prepare for it. This doesn't account for the style changing at runtime, yet.
1 parent 3b8e683 commit 5b7f145

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

macos/Sources/Ghostty/SurfaceScrollView.swift

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,35 @@ class SurfaceScrollView: NSView {
142142
// Only update sizes if we have a valid (non-zero) content size. The content size
143143
// can be zero when this is added early to a view, or to an invisible hierarchy.
144144
// Practically, this happened in the quick terminal.
145-
let contentSize = scrollView.contentSize
146-
if contentSize.width > 0 && contentSize.height > 0 {
147-
// Keep document width synchronized with content width
148-
documentView.setFrameSize(CGSize(
149-
width: contentSize.width,
150-
height: documentView.frame.height
151-
))
152-
153-
// Inform the actual pty of our size change
154-
surfaceView.sizeDidChange(contentSize)
145+
var contentSize = scrollView.contentSize
146+
guard contentSize.width > 0 && contentSize.height > 0 else {
147+
synchronizeSurfaceView()
148+
return
155149
}
156150

151+
// If we have a legacy scrollbar and its not visible, then we account for that
152+
// in advance, because legacy scrollbars change our contentSize and force reflow
153+
// of our terminal which is not desirable.
154+
// See: https://github.com/ghostty-org/ghostty/discussions/9254
155+
let style = scrollView.verticalScroller?.scrollerStyle ?? NSScroller.preferredScrollerStyle
156+
if style == .legacy {
157+
if (scrollView.verticalScroller?.isHidden ?? true) {
158+
let scrollerWidth = NSScroller.scrollerWidth(for: .regular, scrollerStyle: .legacy)
159+
contentSize.width -= scrollerWidth
160+
}
161+
}
162+
163+
// Keep document width synchronized with content width
164+
documentView.setFrameSize(CGSize(
165+
width: contentSize.width,
166+
height: documentView.frame.height
167+
))
168+
169+
// Inform the actual pty of our size change. This doesn't change the actual view
170+
// frame because we do want to render the whole thing, but it will prevent our
171+
// rows/cols from going into the non-content area.
172+
surfaceView.sizeDidChange(contentSize)
173+
157174
// When our scrollview changes make sure our surface view is synchronized
158175
synchronizeSurfaceView()
159176
}

0 commit comments

Comments
 (0)