diff --git a/Sources/ContentView.swift b/Sources/ContentView.swift index 6b6eeb1d..6a9f9fd6 100644 --- a/Sources/ContentView.swift +++ b/Sources/ContentView.swift @@ -6437,10 +6437,6 @@ private struct TabItemView: View { usesInvertedActiveForeground ? Color.white.opacity(0.8) : cmuxAccentColor() } - private var activeSelectionColor: Color { - resolvedCustomTabColor ?? Color(nsColor: sidebarSelectedWorkspaceBackgroundNSColor(for: colorScheme)) - } - private var shortcutHintEmphasis: Double { usesInvertedActiveForeground ? 1.0 : 0.9 } @@ -6495,7 +6491,6 @@ private struct TabItemView: View { .foregroundColor(activeSecondaryColor(0.8)) } - Text(tab.title) .font(.system(size: 12.5, weight: titleFontWeight)) .foregroundColor(activePrimaryTextColor) @@ -6953,11 +6948,11 @@ private struct TabItemView: View { private var backgroundColor: Color { switch activeTabIndicatorStyle { case .leftRail: - if isActive { return activeSelectionColor } + if isActive { return Color(nsColor: sidebarSelectedWorkspaceBackgroundNSColor(for: colorScheme)) } if isMultiSelected { return cmuxAccentColor().opacity(0.25) } return Color.clear case .solidFill: - if isActive { return activeSelectionColor } + if isActive { return Color(nsColor: sidebarSelectedWorkspaceBackgroundNSColor(for: colorScheme)) } if let custom = resolvedCustomTabColor { if isMultiSelected { return custom.opacity(0.35) } return custom.opacity(0.7) diff --git a/Sources/GhosttyTerminalView.swift b/Sources/GhosttyTerminalView.swift index ee1a7616..efdb0fe4 100644 --- a/Sources/GhosttyTerminalView.swift +++ b/Sources/GhosttyTerminalView.swift @@ -3951,11 +3951,11 @@ final class GhosttySurfaceScrollView: NSView { notificationRingOverlayView.layer?.masksToBounds = false notificationRingOverlayView.autoresizingMask = [.width, .height] notificationRingLayer.fillColor = NSColor.clear.cgColor - notificationRingLayer.strokeColor = cmuxAccentNSColor().cgColor + notificationRingLayer.strokeColor = NSColor.systemBlue.cgColor notificationRingLayer.lineWidth = 2.5 notificationRingLayer.lineJoin = .round notificationRingLayer.lineCap = .round - notificationRingLayer.shadowColor = cmuxAccentNSColor().cgColor + notificationRingLayer.shadowColor = NSColor.systemBlue.cgColor notificationRingLayer.shadowOpacity = 0.35 notificationRingLayer.shadowRadius = 3 notificationRingLayer.shadowOffset = .zero @@ -3968,11 +3968,11 @@ final class GhosttySurfaceScrollView: NSView { flashOverlayView.layer?.masksToBounds = false flashOverlayView.autoresizingMask = [.width, .height] flashLayer.fillColor = NSColor.clear.cgColor - flashLayer.strokeColor = cmuxAccentNSColor().cgColor + flashLayer.strokeColor = NSColor.systemBlue.cgColor flashLayer.lineWidth = 3 flashLayer.lineJoin = .round flashLayer.lineCap = .round - flashLayer.shadowColor = cmuxAccentNSColor().cgColor + flashLayer.shadowColor = NSColor.systemBlue.cgColor flashLayer.shadowOpacity = 0.6 flashLayer.shadowRadius = 6 flashLayer.shadowOffset = .zero @@ -4145,27 +4145,6 @@ final class GhosttySurfaceScrollView: NSView { surfaceView.onTriggerFlash = handler } - private func resolvedWorkspaceFocusFlashColor() -> NSColor { - guard let tabId = surfaceView.tabId, - let app = AppDelegate.shared, - let manager = app.tabManagerFor(tabId: tabId) ?? app.tabManager, - let workspace = manager.tabs.first(where: { $0.id == tabId }) else { - return cmuxAccentNSColor() - } - return Workspace.resolvedFocusFlashColor(customColorHex: workspace.customColor) - } - - private func setFocusFlashColor(_ color: NSColor?) { - let resolved = color ?? resolvedWorkspaceFocusFlashColor() - CATransaction.begin() - CATransaction.setDisableActions(true) - notificationRingLayer.strokeColor = resolved.cgColor - notificationRingLayer.shadowColor = resolved.cgColor - flashLayer.strokeColor = resolved.cgColor - flashLayer.shadowColor = resolved.cgColor - CATransaction.commit() - } - func setBackgroundColor(_ color: NSColor) { guard let layer = backgroundView.layer else { return } CATransaction.begin() @@ -4191,7 +4170,6 @@ final class GhosttySurfaceScrollView: NSView { return } - setFocusFlashColor(nil) CATransaction.begin() CATransaction.setDisableActions(true) notificationRingOverlayView.isHidden = !visible @@ -4414,7 +4392,7 @@ final class GhosttySurfaceScrollView: NSView { } #endif - func triggerFlash(color: NSColor? = nil) { + func triggerFlash() { DispatchQueue.main.async { [weak self] in guard let self else { return } #if DEBUG @@ -4422,7 +4400,6 @@ final class GhosttySurfaceScrollView: NSView { Self.recordFlash(for: surfaceId) } #endif - self.setFocusFlashColor(color) self.updateFlashPath() self.flashLayer.removeAllAnimations() self.flashLayer.opacity = 0 diff --git a/Sources/Panels/BrowserPanel.swift b/Sources/Panels/BrowserPanel.swift index 7135ffe3..9188d093 100644 --- a/Sources/Panels/BrowserPanel.swift +++ b/Sources/Panels/BrowserPanel.swift @@ -1313,7 +1313,6 @@ final class BrowserPanel: Panel, ObservableObject { /// Increment to request a UI-only flash highlight (e.g. from a keyboard shortcut). @Published private(set) var focusFlashToken: Int = 0 - @Published private(set) var focusFlashColor: NSColor = cmuxAccentNSColor() /// Sticky omnibar-focus intent. This survives view mount timing races and is /// cleared only after BrowserPanelView acknowledges handling it. @@ -1521,8 +1520,7 @@ final class BrowserPanel: Panel, ObservableObject { workspaceId = newWorkspaceId } - func triggerFlash(color: NSColor? = nil) { - focusFlashColor = color ?? cmuxAccentNSColor() + func triggerFlash() { focusFlashToken &+= 1 } diff --git a/Sources/Panels/BrowserPanelView.swift b/Sources/Panels/BrowserPanelView.swift index fbcc815a..ea282f33 100644 --- a/Sources/Panels/BrowserPanelView.swift +++ b/Sources/Panels/BrowserPanelView.swift @@ -296,10 +296,6 @@ struct BrowserPanelView: View { ) } - private var focusFlashColor: Color { - Color(nsColor: panel.focusFlashColor) - } - var body: some View { VStack(spacing: 0) { addressBar @@ -307,8 +303,8 @@ struct BrowserPanelView: View { } .overlay { RoundedRectangle(cornerRadius: FocusFlashPattern.ringCornerRadius) - .stroke(focusFlashColor.opacity(focusFlashOpacity), lineWidth: 3) - .shadow(color: focusFlashColor.opacity(focusFlashOpacity * 0.35), radius: 10) + .stroke(cmuxAccentColor().opacity(focusFlashOpacity), lineWidth: 3) + .shadow(color: cmuxAccentColor().opacity(focusFlashOpacity * 0.35), radius: 10) .padding(FocusFlashPattern.ringInset) .allowsHitTesting(false) } diff --git a/Sources/Panels/Panel.swift b/Sources/Panels/Panel.swift index b3dac0fe..a0a719c4 100644 --- a/Sources/Panels/Panel.swift +++ b/Sources/Panels/Panel.swift @@ -1,6 +1,5 @@ import Foundation import Combine -import AppKit /// Type of panel content public enum PanelType: String, Codable, Sendable { @@ -71,8 +70,7 @@ public protocol Panel: AnyObject, Identifiable, ObservableObject where ID == UUI func unfocus() /// Trigger a focus flash animation for this panel. - /// - Parameter color: Optional override color for this flash. - func triggerFlash(color: NSColor?) + func triggerFlash() } /// Extension providing default implementations diff --git a/Sources/Panels/TerminalPanel.swift b/Sources/Panels/TerminalPanel.swift index 08104709..c8ba8507 100644 --- a/Sources/Panels/TerminalPanel.swift +++ b/Sources/Panels/TerminalPanel.swift @@ -166,8 +166,8 @@ final class TerminalPanel: Panel, ObservableObject { surface.needsConfirmClose() } - func triggerFlash(color: NSColor? = nil) { - hostedView.triggerFlash(color: color) + func triggerFlash() { + hostedView.triggerFlash() } func applyWindowBackgroundIfActive() { diff --git a/Sources/Workspace.swift b/Sources/Workspace.swift index fc43ab46..4844d501 100644 --- a/Sources/Workspace.swift +++ b/Sources/Workspace.swift @@ -2934,23 +2934,8 @@ final class Workspace: Identifiable, ObservableObject { // MARK: - Flash/Notification Support - nonisolated static func resolvedFocusFlashColor( - customColorHex: String?, - fallback: NSColor = cmuxAccentNSColor() - ) -> NSColor { - guard let normalizedHex = customColorHex.flatMap(WorkspaceTabColorSettings.normalizedHex), - let color = NSColor(hex: normalizedHex) else { - return fallback - } - return color - } - - private var focusFlashColor: NSColor { - Self.resolvedFocusFlashColor(customColorHex: customColor) - } - func triggerFocusFlash(panelId: UUID) { - panels[panelId]?.triggerFlash(color: focusFlashColor) + panels[panelId]?.triggerFlash() } func triggerNotificationFocusFlash( @@ -2966,7 +2951,7 @@ final class Workspace: Identifiable, ObservableObject { if requiresSplit && !isSplit { return } - terminalPanel.triggerFlash(color: focusFlashColor) + terminalPanel.triggerFlash() } func triggerDebugFlash(panelId: UUID) { diff --git a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift index 105493f1..0677a847 100644 --- a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift +++ b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift @@ -2848,26 +2848,6 @@ final class WorkspaceTabColorSettingsTests: XCTestCase { XCTAssertNotEqual(rendered.hexString(), originalHex) XCTAssertGreaterThan(rendered.luminance, base.luminance) } - - func testWorkspaceFocusFlashColorUsesCustomHexWhenValid() { - let fallback = NSColor(hex: "#112233")! - let resolved = Workspace.resolvedFocusFlashColor( - customColorHex: " c0392b ", - fallback: fallback - ) - - XCTAssertEqual(resolved.hexString(), "#C0392B") - } - - func testWorkspaceFocusFlashColorFallsBackWhenHexIsInvalid() { - let fallback = NSColor(hex: "#112233")! - let resolved = Workspace.resolvedFocusFlashColor( - customColorHex: "not-a-color", - fallback: fallback - ) - - XCTAssertEqual(resolved.hexString(), "#112233") - } } final class WorkspaceAutoReorderSettingsTests: XCTestCase {