From 98dfa7a7e5a99296f07eadaceadea9a656459bb6 Mon Sep 17 00:00:00 2001 From: Hariharan Mudaliar Date: Sun, 8 Mar 2026 16:36:56 +0530 Subject: [PATCH] HotFix: Inline Volume HUD --- DynamicIsland/ContentView.swift | 2 +- .../LockScreenLiveActivityOverlay.swift | 26 +++++++++++++------ .../LockScreenLiveActivityWindowManager.swift | 23 +++++++++++----- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/DynamicIsland/ContentView.swift b/DynamicIsland/ContentView.swift index d5cb4a6..8797339 100644 --- a/DynamicIsland/ContentView.swift +++ b/DynamicIsland/ContentView.swift @@ -735,7 +735,7 @@ struct ContentView: View { } if coordinator.sneakPeek.show { - if (coordinator.sneakPeek.type != .music) && (coordinator.sneakPeek.type != .battery) && (coordinator.sneakPeek.type != .timer) && !Defaults[.inlineHUD] && ((coordinator.sneakPeek.type != .volume && coordinator.sneakPeek.type != .brightness && coordinator.sneakPeek.type != .backlight) || vm.notchState == .closed) { + if (coordinator.sneakPeek.type != .music) && (coordinator.sneakPeek.type != .battery) && (coordinator.sneakPeek.type != .timer) && (coordinator.sneakPeek.type != .reminder) && (coordinator.sneakPeek.type != .capsLock) && !coordinator.sneakPeek.type.isExtensionPayload && !Defaults[.inlineHUD] && ((coordinator.sneakPeek.type != .volume && coordinator.sneakPeek.type != .brightness && coordinator.sneakPeek.type != .backlight) || vm.notchState == .closed) { SystemEventIndicatorModifier(eventType: $coordinator.sneakPeek.type, value: $coordinator.sneakPeek.value, icon: $coordinator.sneakPeek.icon, sendEventBack: { _ in // }) diff --git a/DynamicIsland/components/LockScreen/LockScreenLiveActivityOverlay.swift b/DynamicIsland/components/LockScreen/LockScreenLiveActivityOverlay.swift index d4b9967..9d58864 100644 --- a/DynamicIsland/components/LockScreen/LockScreenLiveActivityOverlay.swift +++ b/DynamicIsland/components/LockScreen/LockScreenLiveActivityOverlay.swift @@ -27,13 +27,14 @@ struct LockScreenLiveActivityOverlay: View { @ObservedObject var model: LockScreenLiveActivityOverlayModel @ObservedObject var animator: LockIconAnimator let notchSize: CGSize + var isDynamicIslandMode: Bool = false private var indicatorSize: CGFloat { max(0, notchSize.height - 12) } private var horizontalPadding: CGFloat { - cornerRadiusInsets.closed.bottom + isDynamicIslandMode ? 8 : cornerRadiusInsets.closed.bottom } private var totalWidth: CGFloat { @@ -44,6 +45,10 @@ struct LockScreenLiveActivityOverlay: View { Self.collapsedScale(for: notchSize) } + private var topOffset: CGFloat { + isDynamicIslandMode ? dynamicIslandTopOffset : 0 + } + @State private var isHovering: Bool = false var body: some View { @@ -66,12 +71,17 @@ struct LockScreenLiveActivityOverlay: View { .padding(.horizontal, horizontalPadding) .background(Color.black) .clipShape( - NotchShape( - topCornerRadius: cornerRadiusInsets.closed.top, - bottomCornerRadius: cornerRadiusInsets.closed.bottom - ) + isDynamicIslandMode + ? AnyShape(DynamicIslandPillShape( + cornerRadius: max(notchSize.height / 2, dynamicIslandPillCornerRadiusInsets.closed.standard) + )) + : AnyShape(NotchShape( + topCornerRadius: cornerRadiusInsets.closed.top, + bottomCornerRadius: cornerRadiusInsets.closed.bottom + )) ) - .frame(width: totalWidth, height: notchSize.height) + .padding(.top, topOffset) + .frame(width: totalWidth, height: notchSize.height + topOffset) .scaleEffect(x: max(model.scale, collapsedScale) * (isHovering ? 1.03 : 1.0), y: 1 * (isHovering ? 1.03 : 1.0), anchor: .center) @@ -88,9 +98,9 @@ struct LockScreenLiveActivityOverlay: View { } extension LockScreenLiveActivityOverlay { - static func collapsedScale(for notchSize: CGSize) -> CGFloat { + static func collapsedScale(for notchSize: CGSize, isDynamicIslandMode: Bool = false) -> CGFloat { let indicatorSize = max(0, notchSize.height - 12) - let horizontalPadding = cornerRadiusInsets.closed.bottom + let horizontalPadding = isDynamicIslandMode ? 8.0 : cornerRadiusInsets.closed.bottom let totalWidth = notchSize.width + (indicatorSize * 2) + (horizontalPadding * 2) guard totalWidth > 0 else { return 1 } return notchSize.width / totalWidth diff --git a/DynamicIsland/managers/LockScreenLiveActivityWindowManager.swift b/DynamicIsland/managers/LockScreenLiveActivityWindowManager.swift index 4a05c8b..7770b04 100644 --- a/DynamicIsland/managers/LockScreenLiveActivityWindowManager.swift +++ b/DynamicIsland/managers/LockScreenLiveActivityWindowManager.swift @@ -37,6 +37,16 @@ class LockScreenLiveActivityWindowManager { private var workspaceObservers: [NSObjectProtocol] = [] private var currentNotchSize: CGSize? + /// Whether the target screen uses Dynamic Island (pill) mode. + private var isDynamicIslandMode: Bool { + isDynamicIslandModeForScreen(lockContext()?.screen) + } + + private func isDynamicIslandModeForScreen(_ screen: NSScreen?) -> Bool { + guard let screen else { return false } + return shouldUseDynamicIslandMode(for: screen.localizedName) + } + private init() { registerScreenChangeObservers() } @@ -49,11 +59,12 @@ class LockScreenLiveActivityWindowManager { private func windowSize(for notchSize: CGSize) -> CGSize { let indicatorWidth = max(0, notchSize.height - 12) - let horizontalPadding = cornerRadiusInsets.closed.bottom + let horizontalPadding = isDynamicIslandMode ? 8 : cornerRadiusInsets.closed.bottom + let topOffset: CGFloat = isDynamicIslandMode ? dynamicIslandTopOffset : 0 let totalWidth = notchSize.width + (indicatorWidth * 2) + (horizontalPadding * 2) - return CGSize(width: totalWidth, height: notchSize.height) + return CGSize(width: totalWidth, height: notchSize.height + topOffset) } private func frame(for windowSize: CGSize, on screen: NSScreen) -> NSRect { @@ -145,7 +156,7 @@ class LockScreenLiveActivityWindowManager { if let hostingView { hostingView.frame = CGRect(origin: .zero, size: targetFrame.size) - hostingView.rootView = LockScreenLiveActivityOverlay(model: overlayModel, animator: overlayAnimator, notchSize: context.notchSize) + hostingView.rootView = LockScreenLiveActivityOverlay(model: overlayModel, animator: overlayAnimator, notchSize: context.notchSize, isDynamicIslandMode: isDynamicIslandMode) } currentNotchSize = context.notchSize @@ -164,7 +175,7 @@ class LockScreenLiveActivityWindowManager { let targetFrame = frame(for: windowSize, on: screen) window.setFrame(targetFrame, display: true) - let overlayView = LockScreenLiveActivityOverlay(model: overlayModel, animator: overlayAnimator, notchSize: notchSize) + let overlayView = LockScreenLiveActivityOverlay(model: overlayModel, animator: overlayAnimator, notchSize: notchSize, isDynamicIslandMode: isDynamicIslandMode) if let hostingView { hostingView.rootView = overlayView @@ -197,7 +208,7 @@ class LockScreenLiveActivityWindowManager { hideTask?.cancel() guard let context = lockContext() else { return } - let collapsedScale = LockScreenLiveActivityOverlay.collapsedScale(for: context.notchSize) + let collapsedScale = LockScreenLiveActivityOverlay.collapsedScale(for: context.notchSize, isDynamicIslandMode: isDynamicIslandMode) overlayAnimator.update(isLocked: true) overlayModel.scale = collapsedScale @@ -249,7 +260,7 @@ class LockScreenLiveActivityWindowManager { let targetScale: CGFloat if let notchSize = currentNotchSize { - targetScale = LockScreenLiveActivityOverlay.collapsedScale(for: notchSize) + targetScale = LockScreenLiveActivityOverlay.collapsedScale(for: notchSize, isDynamicIslandMode: isDynamicIslandMode) } else { targetScale = 0.7 }