Merge pull request #262 from Ebullioscopic/ui/fixes

BugFix: Liquid Glass Effect on Lock Screen, Lock Screen Widgets showing up only on MacBook Screen
This commit is contained in:
Hariharan Mudaliar 2026-01-23 13:24:15 +05:30 • committed by GitHub
commit 09697e60fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 50 additions and 10 deletions

View file

@ -114,8 +114,10 @@ struct ExtensionLockScreenWidgetView: View {
@ViewBuilder @ViewBuilder
private func liquidGlassBackground(shape: RoundedRectangle) -> some View { private func liquidGlassBackground(shape: RoundedRectangle) -> some View {
LiquidGlassBackground(variant: requestedLiquidGlassVariant, cornerRadius: descriptor.cornerRadius) { TimelineView(.periodic(from: .now, by: 1.0 / 30.0)) { context in
Color.black.opacity(0.08) LiquidGlassBackground(variant: requestedLiquidGlassVariant, cornerRadius: descriptor.cornerRadius, trigger: context.date.timeIntervalSinceReferenceDate) {
Color.black.opacity(0.08)
}
} }
.overlay { .overlay {
tintOverlay(shape: shape) tintOverlay(shape: shape)

View file

@ -781,8 +781,10 @@ struct LockScreenMusicPanel: View {
@ViewBuilder @ViewBuilder
private var customLiquidPanelBackdrop: some View { private var customLiquidPanelBackdrop: some View {
LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: panelCornerRadius) { TimelineView(.periodic(from: .now, by: 1.0 / 30.0)) { context in
Color.white.opacity(0.04) LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: panelCornerRadius, trigger: context.date.timeIntervalSinceReferenceDate) {
Color.white.opacity(0.04)
}
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
.allowsHitTesting(false) .allowsHitTesting(false)
@ -860,8 +862,10 @@ struct LockScreenMusicPanel: View {
@ViewBuilder @ViewBuilder
private func customLiquidAlbumArtBackground(cornerRadius: CGFloat) -> some View { private func customLiquidAlbumArtBackground(cornerRadius: CGFloat) -> some View {
LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: cornerRadius) { TimelineView(.periodic(from: .now, by: 1.0 / 30.0)) { context in
Color.clear LiquidGlassBackground(variant: musicGlassVariant, cornerRadius: cornerRadius, trigger: context.date.timeIntervalSinceReferenceDate) {
Color.clear
}
} }
} }

View file

@ -136,8 +136,10 @@ struct LockScreenTimerWidget: View {
} }
private var customLiquidBackground: some View { private var customLiquidBackground: some View {
LiquidGlassBackground(variant: timerGlassVariant, cornerRadius: Self.cornerRadius) { TimelineView(.periodic(from: .now, by: 1.0 / 30.0)) { context in
Color.black.opacity(0.12) LiquidGlassBackground(variant: timerGlassVariant, cornerRadius: Self.cornerRadius, trigger: context.date.timeIntervalSinceReferenceDate) {
Color.black.opacity(0.12)
}
} }
} }

View file

@ -44,7 +44,7 @@ public struct LiquidGlassBackground<Content: View>: NSViewRepresentable {
private let content: Content private let content: Content
private let cornerRadius: CGFloat private let cornerRadius: CGFloat
private let variant: LiquidGlassVariant private let variant: LiquidGlassVariant
private let trigger: Double
/// Creates a new liquid‑glass container. /// Creates a new liquid‑glass container.
/// - Parameters: /// - Parameters:
/// - variant: Any ``LiquidGlassVariant`` (0–19). Defaults to `.v11`, which is visually super pleasing /// - variant: Any ``LiquidGlassVariant`` (0–19). Defaults to `.v11`, which is visually super pleasing
@ -53,10 +53,12 @@ public struct LiquidGlassBackground<Content: View>: NSViewRepresentable {
public init( public init(
variant: LiquidGlassVariant = .defaultVariant, variant: LiquidGlassVariant = .defaultVariant,
cornerRadius: CGFloat = 10, cornerRadius: CGFloat = 10,
trigger: Double = 0,
@ViewBuilder content: () -> Content @ViewBuilder content: () -> Content
) { ) {
self.variant = variant self.variant = variant
self.cornerRadius = cornerRadius self.cornerRadius = cornerRadius
self.trigger = trigger
self.content = content() self.content = content()
} }
@ -130,5 +132,11 @@ public struct LiquidGlassBackground<Content: View>: NSViewRepresentable {
} }
nsView.setValue(cornerRadius, forKey: "cornerRadius") nsView.setValue(cornerRadius, forKey: "cornerRadius")
callPrivateVariantSetter(on: nsView, value: variant.rawValue) callPrivateVariantSetter(on: nsView, value: variant.rawValue)
// Micro-jitter: imperceptibly adjust opacity so WindowServer re-samples the wallpaper every frame.
let jitter = sin(trigger * 100) * 0.000001
nsView.alphaValue = 1.0 - CGFloat(abs(jitter))
nsView.needsDisplay = true
} }
} }

View file

@ -1,4 +1,5 @@
import AppKit import AppKit
import CoreGraphics
struct LockScreenDisplayContext { struct LockScreenDisplayContext {
let screen: NSScreen let screen: NSScreen
@ -30,7 +31,7 @@ final class LockScreenDisplayContextProvider {
@discardableResult @discardableResult
func refresh(reason: String) -> LockScreenDisplayContext? { func refresh(reason: String) -> LockScreenDisplayContext? {
guard let screen = NSScreen.main ?? NSScreen.screens.first else { guard let screen = preferredLockScreen() else {
context = nil context = nil
return nil return nil
} }
@ -52,6 +53,29 @@ final class LockScreenDisplayContextProvider {
return refresh(reason: "snapshot-miss") return refresh(reason: "snapshot-miss")
} }
private func preferredLockScreen() -> NSScreen? {
if let builtin = NSScreen.screens.first(where: { screen in
guard let number = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else {
return false
}
return CGDisplayIsBuiltin(CGDirectDisplayID(number.uint32Value)) != 0
}) {
return builtin
}
let mainDisplayID = CGMainDisplayID()
if let mainScreen = NSScreen.screens.first(where: { screen in
guard let number = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber else {
return false
}
return CGDirectDisplayID(number.uint32Value) == mainDisplayID
}) {
return mainScreen
}
return NSScreen.main ?? NSScreen.screens.first
}
private func registerObservers() { private func registerObservers() {
screenChangeObserver = NotificationCenter.default.addObserver( screenChangeObserver = NotificationCenter.default.addObserver(
forName: NSApplication.didChangeScreenParametersNotification, forName: NSApplication.didChangeScreenParametersNotification,