mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
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:
commit
09697e60fb
5 changed files with 50 additions and 10 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue