feat: Liquid Glass effect for macOS 26 (Tahoe)#1139
Closed
bianyeyu wants to merge 1 commit into
Closed
Conversation
Use NSGlassEffectView as the candidate panel background on macOS 26+, falling back to the existing NSVisualEffectView on older systems. Changes: - SquirrelPanel: wrap content views inside NSGlassEffectView.contentView when running on macOS 26, with proper frame/bounds propagation for both horizontal and vertical layouts - SquirrelView: make panelLayer background transparent in glass mode so the system glass material shows through The glass effect is gated behind `#available(macOS 26.0, *)` and `theme.translucency`, ensuring full backward compatibility. Users on older macOS versions see no change. Tested on macOS 26.5 (25F71) with Squirrel 1.1.2.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR adds a macOS 26+ “Liquid Glass” rendering path for the candidate panel when translucency is enabled, while preserving the existing NSVisualEffectView path for older macOS versions.
Changes:
- Use
NSGlassEffectViewas the panelcontentViewon macOS 26+ and route sizing/rotation through its inner content view. - Adjust background fill behavior in
SquirrelViewwhen translucency + macOS 26+ is active. - Update translucency/alpha handling to account for the new glass-backed rendering path.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| sources/SquirrelView.swift | Clears the panel fill on macOS 26+ when translucency is enabled so the glass effect can show through. |
| sources/SquirrelPanel.swift | Introduces a macOS 26+ NSGlassEffectView content view path and updates layout/alpha behavior accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+52
to
+63
| if #available(macOS 26.0, *) { | ||
| let glass = NSGlassEffectView() | ||
| glass.cornerRadius = 12 | ||
| glass.autoresizingMask = [.width, .height] | ||
| let innerView = NSView() | ||
| innerView.autoresizingMask = [.width, .height] | ||
| innerView.addSubview(view) | ||
| innerView.addSubview(view.textView) | ||
| glass.contentView = innerView | ||
| glassBack = glass | ||
| self.contentView = glass | ||
| } else { |
Comment on lines
+52
to
+68
| if #available(macOS 26.0, *) { | ||
| let glass = NSGlassEffectView() | ||
| glass.cornerRadius = 12 | ||
| glass.autoresizingMask = [.width, .height] | ||
| let innerView = NSView() | ||
| innerView.autoresizingMask = [.width, .height] | ||
| innerView.addSubview(view) | ||
| innerView.addSubview(view.textView) | ||
| glass.contentView = innerView | ||
| glassBack = glass | ||
| self.contentView = glass | ||
| } else { | ||
| back.blendingMode = .behindWindow | ||
| back.material = .hudWindow | ||
| back.state = .active | ||
| back.wantsLayer = true | ||
| back.layer?.mask = view.shape |
|
|
||
| if #available(macOS 26.0, *) { | ||
| let glass = NSGlassEffectView() | ||
| glass.cornerRadius = 12 |
Comment on lines
559
to
573
| if theme.translucency { | ||
| var backFrame = subviewFrame | ||
| backFrame.size.width += theme.pagingOffset | ||
| back.frame = backFrame | ||
| back.appearance = NSApp.effectiveAppearance | ||
| back.isHidden = false | ||
| if usesLiquidGlass { | ||
| if #available(macOS 26.0, *), let glass = glassBack as? NSGlassEffectView { | ||
| glass.cornerRadius = theme.cornerRadius | ||
| } | ||
| } else { | ||
| back.frame = backFrame | ||
| back.appearance = NSApp.effectiveAppearance | ||
| back.isHidden = false | ||
| } | ||
| } else { | ||
| back.isHidden = true | ||
| } |
| } | ||
|
|
||
| alphaValue = theme.alpha | ||
| alphaValue = usesLiquidGlass ? 1 : theme.alpha |
Comment on lines
+37
to
+40
| private var usesLiquidGlass: Bool { | ||
| if #available(macOS 26.0, *) { return true } | ||
| return false | ||
| } |
Member
|
@LEOYoon-Tsaw LEO 老師有沒有試驗過? |
Member
|
There are too much unnecessary changes in the PR. I've created another one #1141 that only makes 10 lines of change. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NSGlassEffectViewas the candidate panel background on macOS 26+, falling back toNSVisualEffectViewon older systemsSquirrelView's panel layer transparent in glass mode so the system Liquid Glass material shows through#available(macOS 26.0, *)andtheme.translucencyChanges
SquirrelPanel.swift:NSGlassEffectViewas windowcontentViewon macOS 26+, with content views embedded viaglass.contentViewalphaValue = 1in glass mode (glass manages its own transparency)SquirrelView.swift:panelLayer.fillColortoNSColor.clearwhen Liquid Glass is active, so the glass effect is visible beneath the textHow to enable
Set
translucency: truein yoursquirrel.custom.yaml(already the default for many themes):Test plan
#availableguard ensures no change on macOS < 26Screenshots
Tested on macOS 26.5 Tahoe with Liquid Glass theme. The candidate panel now uses the native system glass material, automatically adapting to content behind the window.
🤖 Generated with Claude Code