diff --git a/DynamicIsland/Localizable.xcstrings b/DynamicIsland/Localizable.xcstrings index 4d9a948..10a426a 100644 --- a/DynamicIsland/Localizable.xcstrings +++ b/DynamicIsland/Localizable.xcstrings @@ -8068,6 +8068,10 @@ "comment" : "A toggle that enables or disables the use of HUDs.", "isCommentAutoGenerated" : true }, + "Enable media panel blur" : { + "comment" : "A toggle switch that enables or disables the blur effect on the media panel.", + "isCommentAutoGenerated" : true + }, "Enable music live activity" : { "localizations" : { "ar" : { @@ -14872,6 +14876,14 @@ } } }, + "Only applies when Material is set to Frosted Glass." : { + "comment" : "A description of the media panel blur setting, visible only when Material is set to Frosted Glass.", + "isCommentAutoGenerated" : true + }, + "Only available when Material is set to Frosted Glass." : { + "comment" : "A description of a feature that is only available when a specific setting is enabled.", + "isCommentAutoGenerated" : true + }, "Only download icon" : { "extractionState" : "stale", "localizations" : { diff --git a/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift b/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift index cf6d56d..5dd6e02 100644 --- a/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift +++ b/DynamicIsland/components/LockScreen/LockScreenMusicPanel.swift @@ -48,6 +48,10 @@ struct LockScreenMusicPanel: View { private let collapsedLyricsExtraHeight: CGFloat = 64 private let expandedLyricsExtraHeight: CGFloat = 96 + private var shouldUseFrostedBlur: Bool { + enableBlur && !usesLiquidGlass + } + private var currentSize: CGSize { let base = isExpanded ? Self.expandedSize : Self.collapsedSize return CGSize(width: base.width, height: base.height + totalExtraHeight) @@ -680,12 +684,10 @@ struct LockScreenMusicPanel: View { @ViewBuilder private var panelBackground: some View { - if enableBlur { - if usesLiquidGlass { - liquidPanelBackground - } else { - frostedPanelBackground - } + if usesLiquidGlass { + liquidPanelBackground + } else if shouldUseFrostedBlur { + frostedPanelBackground } else { RoundedRectangle(cornerRadius: panelCornerRadius) .fill(Color.black.opacity(0.45)) @@ -695,13 +697,7 @@ struct LockScreenMusicPanel: View { @ViewBuilder private var liquidPanelBackground: some View { if #available(macOS 26.0, *) { - RoundedRectangle(cornerRadius: panelCornerRadius) - .glassEffect( - .clear - //.tint(Color.white.opacity(0.12)) - .interactive(), - in: .rect(cornerRadius: panelCornerRadius) - ) + clearLiquidGlassSurface(cornerRadius: panelCornerRadius) } } @@ -720,24 +716,13 @@ struct LockScreenMusicPanel: View { @ViewBuilder private func albumArtBackground(cornerRadius: CGFloat) -> some View { - if enableBlur { - if usesLiquidGlass { - if #available(macOS 26.0, *) { - RoundedRectangle(cornerRadius: cornerRadius) - .glassEffect( - .clear - //.tint(Color.white.opacity(0.16)) - .interactive(), - in: .rect(cornerRadius: cornerRadius) - ) - } else { - RoundedRectangle(cornerRadius: cornerRadius) - .fill(.ultraThinMaterial) - } - } else { - RoundedRectangle(cornerRadius: cornerRadius) - .fill(.ultraThinMaterial) + if usesLiquidGlass { + if #available(macOS 26.0, *) { + clearLiquidGlassSurface(cornerRadius: cornerRadius) } + } else if shouldUseFrostedBlur { + RoundedRectangle(cornerRadius: cornerRadius) + .fill(.ultraThinMaterial) } else { RoundedRectangle(cornerRadius: cornerRadius) .fill(Color.black.opacity(0.35)) @@ -762,6 +747,16 @@ struct LockScreenMusicPanel: View { isExpanded ? 18 : 12 } + @available(macOS 26.0, *) + private func clearLiquidGlassSurface(cornerRadius: CGFloat) -> some View { + RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) + .fill(.clear) // Keep surface true to Apple's "Clear" glass guidance + .glassEffect( + .clear.interactive(), + in: .rect(cornerRadius: cornerRadius) + ) + } + private func logPanelAppearance(event: String = "✅ View appeared") { let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss.SSS" diff --git a/DynamicIsland/components/Settings/SettingsView.swift b/DynamicIsland/components/Settings/SettingsView.swift index b13dea7..cfb52d0 100644 --- a/DynamicIsland/components/Settings/SettingsView.swift +++ b/DynamicIsland/components/Settings/SettingsView.swift @@ -1364,6 +1364,7 @@ struct Media: View { @Default(.musicControlWindowEnabled) private var musicControlWindowEnabled @Default(.enableLockScreenMediaWidget) private var enableLockScreenMediaWidget @Default(.showSneakPeekOnTrackChange) private var showSneakPeekOnTrackChange + @Default(.lockScreenGlassStyle) private var lockScreenGlassStyle private func highlightID(_ title: String) -> String { SettingsTab.media.highlightID(for: title) @@ -1493,8 +1494,15 @@ struct Media: View { .disabled(!enableLockScreenMediaWidget) Defaults.Toggle("Show panel border", key: .lockScreenPanelShowsBorder) .disabled(!enableLockScreenMediaWidget) - Defaults.Toggle("Enable media panel blur", key: .lockScreenPanelUsesBlur) - .disabled(!enableLockScreenMediaWidget) + if lockScreenGlassStyle == .frosted { + Defaults.Toggle("Enable media panel blur", key: .lockScreenPanelUsesBlur) + .disabled(!enableLockScreenMediaWidget) + .settingsHighlight(id: highlightID("Enable media panel blur")) + } else { + unavailableBlurRow + .opacity(enableLockScreenMediaWidget ? 1 : 0.5) + .settingsHighlight(id: highlightID("Enable media panel blur")) + } } header: { Text("Lock Screen Integration") } footer: { @@ -1525,6 +1533,17 @@ struct Media: View { return MediaControllerType.allCases } } + + private var unavailableBlurRow: some View { + VStack(alignment: .leading, spacing: 4) { + Text("Enable media panel blur") + .foregroundStyle(.secondary) + Text("Only applies when Material is set to Frosted Glass.") + .font(.caption) + .foregroundStyle(.secondary) + } + .frame(maxWidth: .infinity, alignment: .leading) + } } struct CalendarSettings: View { @@ -2506,9 +2525,15 @@ struct LockScreenSettings: View { Defaults.Toggle("Show panel border", key: .lockScreenPanelShowsBorder) .disabled(!enableLockScreenMediaWidget) .settingsHighlight(id: highlightID("Show panel border")) - Defaults.Toggle("Enable media panel blur", key: .lockScreenPanelUsesBlur) - .disabled(!enableLockScreenMediaWidget) - .settingsHighlight(id: highlightID("Enable media panel blur")) + if lockScreenGlassStyle == .frosted { + Defaults.Toggle("Enable media panel blur", key: .lockScreenPanelUsesBlur) + .disabled(!enableLockScreenMediaWidget) + .settingsHighlight(id: highlightID("Enable media panel blur")) + } else { + blurSettingUnavailableRow + .opacity(enableLockScreenMediaWidget ? 1 : 0.5) + .settingsHighlight(id: highlightID("Enable media panel blur")) + } } header: { Text("Media Panel") } footer: { @@ -2633,6 +2658,19 @@ struct LockScreenSettings: View { } } +extension LockScreenSettings { + private var blurSettingUnavailableRow: some View { + VStack(alignment: .leading, spacing: 4) { + Text("Enable media panel blur") + .foregroundStyle(.secondary) + Text("Only available when Material is set to Frosted Glass.") + .font(.caption) + .foregroundStyle(.secondary) + } + .frame(maxWidth: .infinity, alignment: .leading) + } +} + private struct LockScreenPositioningControls: View { @Default(.lockScreenWeatherVerticalOffset) private var weatherOffset @Default(.lockScreenMusicVerticalOffset) private var musicOffset