Update Lock Screen Customization

This commit is contained in:
Hariharan Mudaliar 2026-01-22 13:13:55 +05:30
commit 8720de3cf7
No known key found for this signature in database
GPG key ID: 025583EB0BE5640E
7 changed files with 749 additions and 46 deletions

View file

@ -11,6 +11,8 @@ import Defaults
struct LockScreenMusicPanel: View {
private struct GlassLogSnapshot: Equatable {
let style: LockScreenGlassStyle
let customizationMode: LockScreenGlassCustomizationMode
let variantRawValue: Int
let usesLiquidGlass: Bool
}
@ -32,6 +34,8 @@ struct LockScreenMusicPanel: View {
@State private var isParallaxSuspended = false
@State private var lastLoggedGlassSnapshot: GlassLogSnapshot?
@Default(.lockScreenGlassStyle) var lockScreenGlassStyle
@Default(.lockScreenGlassCustomizationMode) private var glassCustomizationMode
@Default(.lockScreenMusicLiquidGlassVariant) private var musicGlassVariant
@Default(.lockScreenShowAppIcon) var showAppIcon
@Default(.lockScreenPanelShowsBorder) var showPanelBorder
@Default(.lockScreenPanelUsesBlur) var enableBlur
@ -70,12 +74,21 @@ struct LockScreenMusicPanel: View {
isExpanded ? expandedPanelCornerRadius : collapsedPanelCornerRadius
}
private var usesLiquidGlass: Bool {
private var usesCustomLiquidGlass: Bool {
glassCustomizationMode == .customLiquid
}
private var usesStandardLiquidGlass: Bool {
guard glassCustomizationMode == .standard else { return false }
if #available(macOS 26.0, *) {
return lockScreenGlassStyle == .liquid
}
return false
}
private var usesLiquidGlass: Bool {
usesCustomLiquidGlass || usesStandardLiquidGlass
}
var body: some View {
if isActive {
@ -138,6 +151,14 @@ struct LockScreenMusicPanel: View {
.onChange(of: lockScreenGlassStyle) { _, _ in
logGlassState(reason: "Glass style updated")
}
.onChange(of: glassCustomizationMode) { _, _ in
logGlassState(reason: "Glass mode updated")
}
.onChange(of: musicGlassVariant) { _, _ in
if usesCustomLiquidGlass {
logGlassState(reason: "Liquid variant updated")
}
}
.scaleEffect(animator.isPresented ? 1 : 0.9, anchor: .center)
.opacity(animator.isPresented ? 1 : 0)
.animation(.spring(response: 0.52, dampingFraction: 0.8), value: animator.isPresented)
@ -723,8 +744,10 @@ struct LockScreenMusicPanel: View {
@ViewBuilder
private var panelBackgroundLayer: some View {
if usesLiquidGlass {
liquidPanelBackdrop
if usesCustomLiquidGlass {
customLiquidPanelBackdrop
} else if usesStandardLiquidGlass {
standardLiquidPanelBackdrop
} else if shouldUseFrostedBlur {
frostedPanelBackground
} else {
@ -733,7 +756,7 @@ struct LockScreenMusicPanel: View {
}
@ViewBuilder
private var liquidPanelBackdrop: some View {
private var standardLiquidPanelBackdrop: some View {
if #available(macOS 26.0, *) {
GlassTextBackdrop(cornerRadius: panelCornerRadius)
.frame(maxWidth: .infinity, maxHeight: .infinity)
@ -742,6 +765,16 @@ struct LockScreenMusicPanel: View {
}
}
@ViewBuilder
private var customLiquidPanelBackdrop: some View {
LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: panelCornerRadius) {
Color.white.opacity(0.04)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.allowsHitTesting(false)
.accessibilityHidden(true)
}
private var frostedPanelBackground: some View {
RoundedRectangle(cornerRadius: panelCornerRadius)
.fill(.ultraThinMaterial)
@ -768,7 +801,9 @@ struct LockScreenMusicPanel: View {
@ViewBuilder
private func albumArtBackground(cornerRadius: CGFloat) -> some View {
if usesLiquidGlass {
if usesCustomLiquidGlass {
customLiquidAlbumArtBackground(cornerRadius: cornerRadius)
} else if usesStandardLiquidGlass {
if #available(macOS 26.0, *) {
clearLiquidGlassSurface(cornerRadius: cornerRadius)
}
@ -809,8 +844,20 @@ struct LockScreenMusicPanel: View {
)
}
@ViewBuilder
private func customLiquidAlbumArtBackground(cornerRadius: CGFloat) -> some View {
LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: cornerRadius) {
Color.clear
}
}
private func logGlassState(reason: String) {
let snapshot = GlassLogSnapshot(style: lockScreenGlassStyle, usesLiquidGlass: usesLiquidGlass)
let snapshot = GlassLogSnapshot(
style: lockScreenGlassStyle,
customizationMode: glassCustomizationMode,
variantRawValue: musicGlassVariant.rawValue,
usesLiquidGlass: usesLiquidGlass
)
guard snapshot != lastLoggedGlassSnapshot else { return }
lastLoggedGlassSnapshot = snapshot
@ -831,9 +878,18 @@ struct LockScreenMusicPanel: View {
return "\(entry.name)=\(mode)"
}.joined(separator: ", ")
print("[LockScreenMusicPanel] \(reason) – style=\(lockScreenGlassStyle.rawValue), usesLiquidGlass=\(usesLiquidGlass), components[\(componentSummary)], macOS \(currentOSVersionDescription())")
let modeDescription: String
if usesCustomLiquidGlass {
modeDescription = "Custom Liquid (variant \(musicGlassVariant.rawValue))"
} else if usesStandardLiquidGlass {
modeDescription = "Standard Liquid"
} else {
modeDescription = lockScreenGlassStyle.rawValue
}
if lockScreenGlassStyle == .liquid && !usesLiquidGlass {
print("[LockScreenMusicPanel] \(reason) – customization=\(glassCustomizationMode.rawValue), mode=\(modeDescription), components[\(componentSummary)], macOS \(currentOSVersionDescription())")
if glassCustomizationMode == .standard && lockScreenGlassStyle == .liquid && !usesStandardLiquidGlass {
print("[LockScreenMusicPanel] Liquid Glass requested but unavailable on this macOS build. Falling back to frosted visuals.")
}
}

View file

@ -7,8 +7,10 @@ struct LockScreenTimerWidget: View {
@ObservedObject private var animator: LockScreenTimerWidgetAnimator
@ObservedObject private var timerManager = TimerManager.shared
@Default(.lockScreenGlassStyle) private var glassStyle
@Default(.lockScreenTimerWidgetUsesBlur) private var enableTimerBlur
@Default(.lockScreenTimerGlassStyle) private var timerGlassStyle
@Default(.lockScreenTimerGlassCustomizationMode) private var timerGlassCustomizationMode
@Default(.lockScreenTimerLiquidGlassVariant) private var timerGlassVariant
@Default(.lockScreenTimerWidgetUsesBlur) private var timerGlassModeIsGlass
@Default(.timerPresets) private var timerPresets
@MainActor
@ -78,29 +80,45 @@ struct LockScreenTimerWidget: View {
)
}
private var usesLiquidGlass: Bool {
private var timerSurfaceMode: LockScreenTimerSurfaceMode {
timerGlassModeIsGlass ? .glass : .classic
}
private var usesGlassBackground: Bool {
timerSurfaceMode == .glass
}
private var usesCustomLiquidGlass: Bool {
guard usesGlassBackground else { return false }
return timerGlassStyle == .liquid && timerGlassCustomizationMode == .customLiquid
}
private var usesStandardLiquidGlass: Bool {
guard usesGlassBackground else { return false }
guard timerGlassStyle == .liquid else { return false }
if #available(macOS 26.0, *) {
return glassStyle == .liquid
return timerGlassCustomizationMode == .standard
}
return false
}
@ViewBuilder
private var widgetBackground: some View {
if enableTimerBlur {
if usesLiquidGlass {
liquidBackground
if usesGlassBackground {
if usesCustomLiquidGlass {
customLiquidBackground
} else if timerGlassStyle == .liquid {
standardLiquidBackground
} else {
frostedBackground
}
} else {
RoundedRectangle(cornerRadius: Self.cornerRadius, style: .continuous)
.fill(Color.black.opacity(0.65))
classicBackground
}
}
@ViewBuilder
private var liquidBackground: some View {
private var standardLiquidBackground: some View {
if #available(macOS 26.0, *) {
RoundedRectangle(cornerRadius: Self.cornerRadius, style: .continuous)
.glassEffect(
@ -112,11 +130,22 @@ struct LockScreenTimerWidget: View {
}
}
private var customLiquidBackground: some View {
LiquidGlassBackground(variant: timerGlassVariant, cornerRadius: Self.cornerRadius) {
Color.black.opacity(0.12)
}
}
private var frostedBackground: some View {
RoundedRectangle(cornerRadius: Self.cornerRadius, style: .continuous)
.fill(.ultraThinMaterial)
}
private var classicBackground: some View {
RoundedRectangle(cornerRadius: Self.cornerRadius, style: .continuous)
.fill(Color.black.opacity(0.65))
}
private var pauseIcon: String {
timerManager.isPaused ? "play.fill" : "pause.fill"
}