From e4379a136c7287984029d058d55d40cecd4a1eec Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Mon, 23 Feb 2026 02:37:48 -0800 Subject: [PATCH] Match terminal flash ring padding to browser --- Sources/GhosttyTerminalView.swift | 23 +++++++++++++++---- Sources/Panels/BrowserPanelView.swift | 4 ++-- Sources/Panels/Panel.swift | 2 ++ cmuxTests/CmuxWebViewKeyEquivalentTests.swift | 2 ++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Sources/GhosttyTerminalView.swift b/Sources/GhosttyTerminalView.swift index f4a83671..71258f18 100644 --- a/Sources/GhosttyTerminalView.swift +++ b/Sources/GhosttyTerminalView.swift @@ -4429,16 +4429,29 @@ final class GhosttySurfaceScrollView: NSView { } private func updateNotificationRingPath() { - updateOverlayRingPath(layer: notificationRingLayer, bounds: notificationRingOverlayView.bounds) + updateOverlayRingPath( + layer: notificationRingLayer, + bounds: notificationRingOverlayView.bounds, + inset: 2, + radius: 6 + ) } private func updateFlashPath() { - updateOverlayRingPath(layer: flashLayer, bounds: flashOverlayView.bounds) + updateOverlayRingPath( + layer: flashLayer, + bounds: flashOverlayView.bounds, + inset: CGFloat(FocusFlashPattern.ringInset), + radius: CGFloat(FocusFlashPattern.ringCornerRadius) + ) } - private func updateOverlayRingPath(layer: CAShapeLayer, bounds: CGRect) { - let inset: CGFloat = 2 - let radius: CGFloat = 6 + private func updateOverlayRingPath( + layer: CAShapeLayer, + bounds: CGRect, + inset: CGFloat, + radius: CGFloat + ) { layer.frame = bounds guard bounds.width > inset * 2, bounds.height > inset * 2 else { layer.path = nil diff --git a/Sources/Panels/BrowserPanelView.swift b/Sources/Panels/BrowserPanelView.swift index d4f9b2ba..f0c65a81 100644 --- a/Sources/Panels/BrowserPanelView.swift +++ b/Sources/Panels/BrowserPanelView.swift @@ -255,10 +255,10 @@ struct BrowserPanelView: View { webView } .overlay { - RoundedRectangle(cornerRadius: 10) + RoundedRectangle(cornerRadius: FocusFlashPattern.ringCornerRadius) .stroke(Color.accentColor.opacity(focusFlashOpacity), lineWidth: 3) .shadow(color: Color.accentColor.opacity(focusFlashOpacity * 0.35), radius: 10) - .padding(6) + .padding(FocusFlashPattern.ringInset) .allowsHitTesting(false) } .overlay(alignment: .topLeading) { diff --git a/Sources/Panels/Panel.swift b/Sources/Panels/Panel.swift index 4a9f62ff..a0a719c4 100644 --- a/Sources/Panels/Panel.swift +++ b/Sources/Panels/Panel.swift @@ -24,6 +24,8 @@ enum FocusFlashPattern { static let keyTimes: [Double] = [0, 0.25, 0.5, 0.75, 1] static let duration: TimeInterval = 0.9 static let curves: [FocusFlashCurve] = [.easeOut, .easeIn, .easeOut, .easeIn] + static let ringInset: Double = 6 + static let ringCornerRadius: Double = 10 static var segments: [FocusFlashSegment] { let stepCount = min(curves.count, values.count - 1, keyTimes.count - 1) diff --git a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift index 689b736a..45e2a54e 100644 --- a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift +++ b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift @@ -213,6 +213,8 @@ final class FocusFlashPatternTests: XCTestCase { XCTAssertEqual(FocusFlashPattern.keyTimes, [0, 0.25, 0.5, 0.75, 1]) XCTAssertEqual(FocusFlashPattern.duration, 0.9, accuracy: 0.0001) XCTAssertEqual(FocusFlashPattern.curves, [.easeOut, .easeIn, .easeOut, .easeIn]) + XCTAssertEqual(FocusFlashPattern.ringInset, 6, accuracy: 0.0001) + XCTAssertEqual(FocusFlashPattern.ringCornerRadius, 10, accuracy: 0.0001) } func testFocusFlashPatternSegmentsCoverFullDoublePulseTimeline() {