From 2d86127175a914b8dd936d5c5a01cdbfa494b8bc Mon Sep 17 00:00:00 2001 From: Hariharan Mudaliar Date: Thu, 22 Jan 2026 15:57:17 +0530 Subject: [PATCH] Update Liquid Glass for Lock Screen Widgets --- .../xcshareddata/swiftpm/Package.resolved | 2 +- DynamicIsland/ContentView.swift | 19 +-- .../ExtensionLiveActivityViews.swift | 142 ------------------ .../ExtensionLockScreenWidgetView.swift | 27 +++- .../ExtensionLiveActivityManager.swift | 3 +- 5 files changed, 31 insertions(+), 162 deletions(-) diff --git a/DynamicIsland.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DynamicIsland.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ab7b105..37ec1ab 100644 --- a/DynamicIsland.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DynamicIsland.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -7,7 +7,7 @@ "location" : "https://github.com/Ebullioscopic/AtollExtensionKit", "state" : { "branch" : "main", - "revision" : "a1303629e532337594787b981b499560a99c6c93" + "revision" : "ebe35277572a349fad26abeb6fc552cb5251d584" } }, { diff --git a/DynamicIsland/ContentView.swift b/DynamicIsland/ContentView.swift index 9ee6c0e..7504853 100644 --- a/DynamicIsland/ContentView.swift +++ b/DynamicIsland/ContentView.swift @@ -556,20 +556,6 @@ struct ContentView: View { .frame(width: 76, alignment: .trailing) } .frame(height: vm.effectiveClosedNotchHeight + (isHovering ? 8 : 0), alignment: .center) - } else if coordinator.sneakPeek.show, - case let .extensionLiveActivity(bundleID, activityID) = coordinator.sneakPeek.type, - activeSneakPeekStyle == .inline, - vm.notchState == .closed, - !vm.hideOnClosed { - let inlinePayload = extensionLiveActivityManager.payload(bundleIdentifier: bundleID, activityID: activityID) - ExtensionInlineSneakPeekView( - payload: inlinePayload, - accentColor: coordinator.sneakPeek.accentColor ?? .gray, - notchHeight: vm.effectiveClosedNotchHeight, - closedNotchWidth: vm.closedNotchSize.width, - isHovering: isHovering - ) - .transition(AnyTransition.move(edge: .trailing).combined(with: .opacity)) } else if coordinator.sneakPeek.show && Defaults[.inlineHUD] && (coordinator.sneakPeek.type != .music) && (coordinator.sneakPeek.type != .battery) && (coordinator.sneakPeek.type != .timer) && (coordinator.sneakPeek.type != .reminder) && (coordinator.sneakPeek.type != .volume || vm.notchState == .closed) { InlineHUD(type: $coordinator.sneakPeek.type, value: $coordinator.sneakPeek.value, icon: $coordinator.sneakPeek.icon, hoverAnimation: $isHovering, gestureProgress: $gestureProgress) .transition( @@ -1956,7 +1942,10 @@ struct ContentView: View { } private func resolvedSneakPeekStyle() -> SneakPeekStyle { - coordinator.sneakPeek.styleOverride ?? Defaults[.sneakPeekStyles] + if case .extensionLiveActivity = coordinator.sneakPeek.type { + return .standard + } + return coordinator.sneakPeek.styleOverride ?? Defaults[.sneakPeekStyles] } } diff --git a/DynamicIsland/components/Extensions/ExtensionLiveActivityViews.swift b/DynamicIsland/components/Extensions/ExtensionLiveActivityViews.swift index 0a45cfd..79ff2da 100644 --- a/DynamicIsland/components/Extensions/ExtensionLiveActivityViews.swift +++ b/DynamicIsland/components/Extensions/ExtensionLiveActivityViews.swift @@ -304,148 +304,6 @@ struct ExtensionNotchSectionView: View { } } -struct ExtensionInlineSneakPeekView: View { - let payload: ExtensionLiveActivityPayload? - let accentColor: Color - let notchHeight: CGFloat - let closedNotchWidth: CGFloat - let isHovering: Bool - - private let wingPadding: CGFloat = 16 - - private var descriptor: AtollLiveActivityDescriptor? { payload?.descriptor } - private var resolvedAccent: Color { - guard let descriptor else { return accentColor } - return descriptor.accentColor.resolvedColor(fallback: accentColor) - } - private var trailingRenderable: ExtensionTrailingRenderable? { - descriptor.map { resolvedExtensionTrailingRenderable(for: $0) } - } - - private var contentHeight: CGFloat { - max(0, notchHeight - (isHovering ? 0 : 12)) - } - - private var centerWidth: CGFloat { - max(closedNotchWidth + (isHovering ? 8 : 0), 120) - } - - private var iconDiameter: CGFloat { - max(contentHeight - 8, 28) - } - - private var leftWingWidth: CGFloat { - wingPadding + iconDiameter - } - - private var baseTrailingWidth: CGFloat { - max(iconDiameter, 56) - } - - private var trailingContentWidth: CGFloat { - guard let payload else { return baseTrailingWidth } - return ExtensionLayoutMetrics.trailingWidth( - for: payload, - baseWidth: baseTrailingWidth, - maxWidth: baseTrailingWidth + centerWidth * 0.6 - ) - } - - private var rightWingWidth: CGFloat { - wingPadding + trailingContentWidth - } - - private var trailingContentAvailableWidth: CGFloat { - max(0, trailingContentWidth - wingPadding) - } - - var body: some View { - HStack(spacing: 0) { - leadingWing - centerSection - trailingWing - } - .frame(height: notchHeight + (isHovering ? 8 : 0), alignment: .center) - } - - private var leadingWing: some View { - Color.clear - .frame(width: leftWingWidth, height: contentHeight) - .background(alignment: .leading) { - Group { - if let descriptor { - ExtensionLeadingContentView( - content: resolvedExtensionLeadingContent(for: descriptor), - badge: descriptor.badgeIcon, - accent: resolvedAccent, - frameWidth: iconDiameter, - frameHeight: iconDiameter, - defaultIcon: descriptor.leadingIcon - ) - } else { - RoundedRectangle(cornerRadius: iconDiameter * 0.25, style: .continuous) - .fill(resolvedAccent.gradient) - .frame(width: iconDiameter, height: iconDiameter) - } - } - .frame(width: iconDiameter, height: iconDiameter) - .frame(maxHeight: .infinity, alignment: .center) - .padding(.leading, wingPadding / 2) - } - } - - private var centerSection: some View { - Rectangle() - .fill(Color.black) - .frame(width: centerWidth, height: contentHeight) - } - - @ViewBuilder - private var trailingWing: some View { - Color.clear - .frame(width: rightWingWidth, height: contentHeight) - .background(alignment: .trailing) { - if let descriptor, let trailingRenderable { - VStack(alignment: .trailing, spacing: 6) { - switch trailingRenderable { - case let .content(content): - if case .none = content { - Spacer(minLength: 0) - } else { - ExtensionEdgeContentView( - content: content, - accent: resolvedAccent, - availableWidth: trailingContentAvailableWidth, - alignment: .trailing - ) - .frame(maxWidth: trailingContentAvailableWidth, alignment: .trailing) - } - case let .indicator(indicator): - ExtensionProgressIndicatorView( - indicator: indicator, - progress: descriptor.progress, - accent: resolvedAccent, - estimatedDuration: descriptor.estimatedDuration, - maxVisualHeight: contentHeight - ) - } - - Spacer(minLength: 0) - } - .padding(.trailing, wingPadding / 2) - .padding(.vertical, 6) - } else { - RoundedRectangle(cornerRadius: 8, style: .continuous) - .fill(resolvedAccent.opacity(0.25)) - .frame(width: max(32, trailingContentAvailableWidth * 0.6), height: max(16, contentHeight * 0.4)) - .padding(.trailing, wingPadding / 2) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing) - .padding(.vertical, 6) - } - } - } -} - struct ExtensionNotchSectionHeader: View { let section: AtollNotchContentSection diff --git a/DynamicIsland/components/Extensions/ExtensionLockScreenWidgetView.swift b/DynamicIsland/components/Extensions/ExtensionLockScreenWidgetView.swift index c00f26b..f12625f 100644 --- a/DynamicIsland/components/Extensions/ExtensionLockScreenWidgetView.swift +++ b/DynamicIsland/components/Extensions/ExtensionLockScreenWidgetView.swift @@ -83,7 +83,9 @@ struct ExtensionLockScreenWidgetView: View { @ViewBuilder private func backgroundLayer(shape: RoundedRectangle) -> some View { - if shouldUseGlassBackdrop { + if descriptor.material == .liquid { + liquidGlassBackground(shape: shape) + } else if shouldUseGlassHighlight { if #available(macOS 26.0, *) { ZStack { shape @@ -110,6 +112,18 @@ struct ExtensionLockScreenWidgetView: View { } } + @ViewBuilder + private func liquidGlassBackground(shape: RoundedRectangle) -> some View { + LiquidGlassBackground(variant: requestedLiquidGlassVariant, cornerRadius: descriptor.cornerRadius) { + Color.black.opacity(0.08) + } + .overlay { + tintOverlay(shape: shape) + } + .allowsHitTesting(false) + .accessibilityHidden(true) + } + private var baseMaterialStyle: AnyShapeStyle { switch descriptor.material { case .frosted: @@ -160,8 +174,15 @@ struct ExtensionLockScreenWidgetView: View { } } - private var shouldUseGlassBackdrop: Bool { - descriptor.material == .liquid || (appearance?.enableGlassHighlight ?? false) + private var shouldUseGlassHighlight: Bool { + (appearance?.enableGlassHighlight ?? false) && descriptor.material != .liquid + } + + private var requestedLiquidGlassVariant: LiquidGlassVariant { + guard let requested = appearance?.liquidGlassVariant?.rawValue else { + return LiquidGlassVariant.defaultVariant + } + return LiquidGlassVariant.clamped(requested) } @ViewBuilder diff --git a/DynamicIsland/managers/Extensions/ExtensionLiveActivityManager.swift b/DynamicIsland/managers/Extensions/ExtensionLiveActivityManager.swift index 6a71d7e..2fc4cd5 100644 --- a/DynamicIsland/managers/Extensions/ExtensionLiveActivityManager.swift +++ b/DynamicIsland/managers/Extensions/ExtensionLiveActivityManager.swift @@ -172,7 +172,8 @@ final class ExtensionLiveActivityManager: ObservableObject { guard let requestedStyle = config.style else { return nil } switch requestedStyle { case .inline: - return .inline + logDiagnostics("Inline sneak peek requested for \(descriptor.id); host will show standard mode instead") + return .standard case .standard: return .standard }