From 5f340d9662c8874b814e68ccd95a94dce83519ce Mon Sep 17 00:00:00 2001 From: zy C Date: Sat, 26 Sep 2026 22:00:34 -0700 Subject: [PATCH] apple: upgrade glass token to interactive Liquid Glass, add glass-container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "glass" now applies .glassEffect(.regular.interactive(), in:) on iOS 26/macOS 26 so Lui_element_combine chrome (composer capsule, composer_collapsed, action-button capsules) gets press feedback without a per-app tweak; below 26 the .regularMaterial fallback is unchanged. - New "glass-container" background token wraps the node's subtree in a GlassEffectContainer on iOS 26/macOS 26 so sibling glass surfaces fuse; on older OSes it degrades to the resolved background (a plain container). - Glass surfaces whose wire corner_radius is effectively a full pill — the 999 sentinel or a radius at least half the declared height — now use Capsule() instead of a clamped RoundedRectangle; non-glass shape computation is untouched. --- .../LUIAppleBackend/LUISwiftUIRoot.swift | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/platform/apple/Sources/LUIAppleBackend/LUISwiftUIRoot.swift b/platform/apple/Sources/LUIAppleBackend/LUISwiftUIRoot.swift index 924f372b..d7a4e902 100644 --- a/platform/apple/Sources/LUIAppleBackend/LUISwiftUIRoot.swift +++ b/platform/apple/Sources/LUIAppleBackend/LUISwiftUIRoot.swift @@ -5654,18 +5654,40 @@ private struct LUIOptionalClipModifier: ViewModifier { } } +enum LUIGlassShapePolicy { + /// Wire `corner_radius` values that already describe a full pill — the + /// 999 sentinel used by capsule chrome, or any radius at least half the + /// declared height — select `Capsule()` on glass surfaces so Liquid + /// Glass gets capsule geometry instead of a clamped rounded rectangle. + static func isPill(cornerRadius: CGFloat, height: CGFloat?) -> Bool { + cornerRadius >= 999 || height.map { cornerRadius >= $0 / 2 } == true + } +} + private struct LUIBackgroundStyleModifier: ViewModifier { let name: String? let color: Color let shape: AnyShape + let isPill: Bool @ViewBuilder func body(content: Content) -> some View { + let glassShape: AnyShape = isPill ? AnyShape(Capsule()) : shape if name == "glass" { if #available(iOS 26.0, macOS 26.0, *) { - content.glassEffect(in: shape) + content.glassEffect(.regular.interactive(), in: glassShape) } else { - content.background(.regularMaterial, in: shape) + content.background(.regularMaterial, in: glassShape) + } + } else if name == "glass-container" { + // `content` is the node's whole subtree, so wrapping it groups + // descendant glass surfaces into one fused Liquid Glass region. + if #available(iOS 26.0, macOS 26.0, *) { + GlassEffectContainer { + content.background(color, in: shape) + } + } else { + content.background(color, in: shape) } } else { content.background(color, in: shape) @@ -5777,7 +5799,11 @@ private struct LUISurfaceModifier: ViewModifier { .modifier(LUIBackgroundStyleModifier( name: backgroundName, color: background, - shape: shape + shape: shape, + isPill: model.kind != .avatar && LUIGlassShapePolicy.isPill( + cornerRadius: radius, + height: floored(model.surfaceHeight).map(CGFloat.init) + ) )) .shadow( color: castsShadow ? .black.opacity(0.12) : .clear,