-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[Feature]support WindowSetSystemDefaultTheme,WindowSetLightTheme,WindowSetDarkTheme for darwin(#4654) #4656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
WalkthroughAdds macOS appearance support: new SetAppearance layers implemented in Objective-C (C bridge + WailsContext) and exposed to Go frontend; Window theme functions now call into the new appearance setter. Documentation updated to mark Linux unsupported for those theming methods. Changes
Sequence DiagramsequenceDiagram
participant App as App code (Go runtime)
participant Win as Window (darwin/window.go)
participant CBridge as C bridge (Application.m)
participant WailsCtx as WailsContext
participant macOS as AppKit (NSWindow)
App->>Win: call SetAppearance("Aqua"/"DarkAqua"/default)
Win->>CBridge: SetAppearance(ctx, cString)
CBridge->>CBridge: dispatch_async(main thread)
CBridge->>WailsCtx: [ctx SetAppearance:NSString]
WailsCtx->>WailsCtx: resolve NSAppearance by name
WailsCtx->>macOS: window.appearance = resolvedAppearance
macOS-->>WailsCtx: applied
WailsCtx-->>CBridge: return
CBridge-->>Win: return
Win->>Win: free C resources
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
v2/internal/frontend/desktop/darwin/Application.h(1 hunks)v2/internal/frontend/desktop/darwin/Application.m(1 hunks)v2/internal/frontend/desktop/darwin/WailsContext.m(1 hunks)v2/internal/frontend/desktop/darwin/frontend.go(2 hunks)v2/internal/frontend/desktop/darwin/window.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- v2/internal/frontend/desktop/darwin/Application.m
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4534
File: v3/examples/liquid-glass/README.md:44-46
Timestamp: 2025-08-24T03:55:43.103Z
Learning: macOS 26 is the version that introduces native NSGlassEffectView support for Liquid Glass effects, representing a new internal/development versioning scheme beyond the publicly documented macOS 15 Sequoia.
📚 Learning: 2024-09-20T23:34:29.841Z
Learnt from: nixpare
Repo: wailsapp/wails PR: 3763
File: v3/examples/keybindings/main.go:16-17
Timestamp: 2024-09-20T23:34:29.841Z
Learning: In the codebase, `application.Options.KeyBindings` uses the `application.Window` type, whereas `application.WebviewWindowOptions.KeyBindings` uses `*application.WebviewWindow`. This is intentional and acceptable.
Applied to files:
v2/internal/frontend/desktop/darwin/frontend.go
🧬 Code graph analysis (2)
v2/internal/frontend/desktop/darwin/window.go (3)
v2/internal/frontend/desktop/windows/window.go (1)
Window(21-48)v2/internal/frontend/desktop/linux/window.go (1)
Window(40-53)v2/internal/frontend/desktop/linux/calloc.go (1)
NewCalloc(18-20)
v2/internal/frontend/desktop/darwin/frontend.go (4)
v2/internal/frontend/frontend.go (1)
Frontend(79-142)v2/internal/frontend/runtime/wrapper/runtime.js (2)
WindowSetLightTheme(80-82)WindowSetDarkTheme(84-86)v2/pkg/runtime/window.go (2)
WindowSetLightTheme(50-53)WindowSetDarkTheme(55-58)v2/internal/frontend/runtime/desktop/window.js (2)
WindowSetLightTheme(28-30)WindowSetDarkTheme(32-34)
🔇 Additional comments (3)
v2/internal/frontend/desktop/darwin/Application.h (1)
45-45: C API surface addition looks consistentThe new
SetAppearance(void* ctx, const char* appearance)declaration fits the existing window API shape and matches the Go wrapper usage; no issues from the header side.v2/internal/frontend/desktop/darwin/window.go (1)
315-320: I'm unable to complete the verification due to repository cloning issues in the sandbox environment. Without direct access to the codebase, I cannot verify:
- The current
SetAppearanceimplementation and its interaction withWindowSetSystemDefaultTheme- Whether the C layer (
C.SetAppearance) actually supportsNULLpointers for the "clear override" behavior- How similar bridge methods in the codebase handle edge cases
- Whether empty/default appearance strings are ever actually passed to this method
Since this is a repository-specific code review that requires examining:
- The implementation context at lines 315-320
- Related methods like
WindowSetSystemDefaultThemeandmac.DefaultAppearance- The C layer bindings and their NULL-handling behavior
- Project conventions for similar patterns
I cannot provide a definitive rewritten review comment without this information.
Please retry the verification when repository access is available, or provide direct access to: - v2/internal/frontend/desktop/darwin/window.go (lines 310-330) - Usage of SetAppearance and related appearance-handling code - C layer definitions for SetAppearance behaviorv2/internal/frontend/desktop/darwin/frontend.go (1)
31-31: Based on my verification attempts, I've discovered a critical discrepancy that prevents me from fully validating the review comment.Key Finding: According to Wails v2 documentation,
WindowSetSystemDefaultTheme,SetLightTheme, andSetDarkThemeare Windows-only APIs. macOS appearance in Wails v2 is configured at app startup viamac.Options.Appearance(using NSAppearance names), and there is no runtime theme-switching API for macOS in v2 (planned for v3).The review references these methods allegedly being in
v2/internal/frontend/desktop/darwin/frontend.goat lines 219-229, which contradicts the documented API surface. This suggests either:
- The PR introduces new macOS theme methods not currently in Wails (outside documented behavior)
- The file path or line numbers are misidentified
- The review assumptions about which file these methods are in may be incorrect
Technical Context: The review's underlying concerns about
DefaultAppearancesemantics and nil-checks are technically sound — if such methods exist, they would need to setNSApplication.appearance = nilto properly reset to system default. However, I cannot verify whether the flagged code actually contains these implementations without direct repository access.
System default theme reset behavior needs verification against actual PR code. Review concerns about nil-checks and DefaultAppearance semantics are technically valid, but the file location and method signatures require manual inspection to confirm the issues apply.
| - (void) SetAppearance:(NSString*)appearance { | ||
| if (appearance != nil) { | ||
| NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance]; | ||
| if (nsAppearance != nil) { | ||
| [self.mainWindow setAppearance:nsAppearance]; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find WailsContext.m file
find . -name "WailsContext.m" -type fRepository: wailsapp/wails
Length of output: 172
🌐 Web query:
WailsContext.m SetAppearance method Wails macOS
💡 Result:
The SetAppearance method (in v2’s macOS bridge WailsContext.m) applies the app’s mac Appearance option by mapping the Wails mac.AppearanceType to Apple’s NSAppearance names (e.g. NSAppearanceNameAqua, NSAppearanceNameDarkAqua, Vibrant variants, accessibility high-contrast variants) and setting the macOS appearance on the app/window (via NSApp/NSWindow NSAppearance APIs). This is what enables Wails’ native light/dark/vibrant/high‑contrast appearance support. [1][2]
Sources:
- Wails docs — mac Appearance / Options (lists the NSAppearance names exposed by Wails). [1]
- Wails internal mac implementation reference (WailsContext.* is the Objective‑C bridge used for macOS). [2]
🌐 Web query:
NSAppearance appearanceNamed nil setAppearance macOS
💡 Result:
Short answer:
- [NSAppearance appearanceNamed:] with a nil name returns nil (no appearance created).
- Calling setAppearance:nil on an NSAppearanceCustomization (for example [NSApp setAppearance:nil] or view.window.appearance = nil) resets that object to the default/inherited behavior — AppKit will then apply the system appearance (inherit from ancestors). [Apple docs]. [WWDC/notes].
Example:
- To force dark: [NSApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]];
- To go back to system/default: [NSApp setAppearance:nil];. (developer.apple.com)
References:
- NSApplication.appearance — Apple Developer (appearance is nil → AppKit applies current system appearance). [Apple]. (developer.apple.com)
- WWDC / Advanced Dark Mode notes (appearance inheritance; assign nil to reset to default). (nilotic.github.io)
Citations:
- 1: https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc
- 2: https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc
- 3: https://nilotic.github.io/2018/09/28/Advanced-Dark-Mode.html?utm_source=openai
🌐 Web query:
Wails DefaultAppearance system default theme option
💡 Result:
DefaultAppearance tells Wails to use the macOS system appearance (follow the OS setting). If the user switches system light/dark, the app will follow the system default. [1][2]
Example (Go options):
Mac: &mac.Options{
Appearance: mac.DefaultAppearance,
} [1][2]
Sources: Wails Options docs. [1] https://wails.io/docs/v2.9.0/reference/options [2] https://wails.io/docs/reference/options
Based on my verification through web search, I can confirm the technical claims in the review comment:
Verified facts:
- ✅
NSAppearance.appearanceNamed:returnsnilfor unknown/default appearance names - ✅ Calling
setAppearance:nilon an NSAppearanceCustomization resets it to system default behavior - ✅ Wails'
DefaultAppearanceis explicitly meant for "use the macOS system appearance" - ✅ The current
SetAppearanceimplementation (lines 348-355) skips callingsetAppearance:whenappearanceNamed:returnsnil
This means the review comment's core claim is correct: the current implementation cannot restore the system default appearance because it never calls setAppearance:nil when the appearance name is unknown or default.
Make SetAppearance capable of restoring system default and match CreateWindow semantics
The current SetAppearance implementation skips calling setAppearance: when appearanceNamed: returns nil. Since nil is the signal to restore system default in AppKit, this prevents WindowSetSystemDefaultTheme from working correctly after a Light/Dark override—the window will retain its explicit appearance instead of reverting to the system default.
This contradicts the DefaultAppearance contract ("use the macOS system appearance"). Align the behavior with AppKit semantics by allowing nil or empty appearance values to explicitly clear the override:
- (void) SetAppearance:(NSString*)appearance {
- if (appearance != nil) {
- NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance];
- if (nsAppearance != nil) {
- [self.mainWindow setAppearance:nsAppearance];
- }
- }
-}
+ (void) SetAppearance:(NSString*)appearance {
+ if (self.shuttingDown) {
+ return;
+ }
+ // Nil or empty => clear explicit override, letting the system choose.
+ if (appearance == nil || [appearance length] == 0) {
+ [self.mainWindow setAppearance:nil];
+ return;
+ }
+
+ NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance];
+ // This matches the CreateWindow behavior: if nsAppearance is nil,
+ // setAppearance:nil restores system default.
+ [self.mainWindow setAppearance:nsAppearance];
+}(And optionally, refactor the CreateWindow appearance block to call this method to avoid duplicated logic.)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - (void) SetAppearance:(NSString*)appearance { | |
| if (appearance != nil) { | |
| NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance]; | |
| if (nsAppearance != nil) { | |
| [self.mainWindow setAppearance:nsAppearance]; | |
| } | |
| } | |
| } | |
| - (void) SetAppearance:(NSString*)appearance { | |
| if (self.shuttingDown) { | |
| return; | |
| } | |
| // Nil or empty => clear explicit override, letting the system choose. | |
| if (appearance == nil || [appearance length] == 0) { | |
| [self.mainWindow setAppearance:nil]; | |
| return; | |
| } | |
| NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance]; | |
| // This matches the CreateWindow behavior: if nsAppearance is nil, | |
| // setAppearance:nil restores system default. | |
| [self.mainWindow setAppearance:nsAppearance]; | |
| } |
🤖 Prompt for AI Agents
In v2/internal/frontend/desktop/darwin/WailsContext.m around lines 348 to 355,
SetAppearance currently skips calling setAppearance: when NSAppearance
appearanceNamed: returns nil, preventing callers from restoring the system
default; update SetAppearance to treat nil or empty appearance names (and the
explicit DefaultAppearance token) as an instruction to call [self.mainWindow
setAppearance:nil] so the window reverts to the macOS system appearance, and in
other cases call setAppearance: with the resolved NSAppearance (keeping existing
null-checks only to distinguish unknown-name→nil semantics); also consider
refactoring CreateWindow to reuse this method so both follow the same semantics.
|
I will get to this. Thanks for your patience 🙏 |
|



Description
Support functions: WindowSetSystemDefaultTheme,WindowSetLightTheme,WindowSetDarkTheme for darwin(basing on v2.10.2) and update documents. And it test OK in my device.
Feature #4654 (issue)
Type of change
Please select the option that is relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using
wails doctor.If you checked Linux, please specify the distro and version.
Test Configuration
wails on feature/4654-runtime-SetAppearance-for-darwin ❯ wails doctor Wails Doctor # Wails Version | v2.10.2 # System ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | OS | MacOS | | Version | 15.6.1 | | ID | 24G90 | | Branding | | | Go Version | go1.24.4 | | Platform | darwin | | Architecture | arm64 | | CPU 1 | Apple M1 | | CPU 2 | Apple M1 | | GPU | Chipset Model: Apple M1 Type: GPU Bus: Built-In Total Number of Cores: 8 Vendor: Apple (0x106b) Metal Support: Metal 3 | | Memory | 16GB | └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ # Dependencies ┌────────────────────────────────────────────────────────────────────────┐ | Dependency | Package Name | Status | Version | | Xcode command line tools | N/A | Installed | 2410 | | Nodejs | N/A | Installed | 24.3.0 | | npm | N/A | Installed | 11.4.2 | | *Xcode | N/A | Installed | 26.0.1 (17A400) | | *upx | N/A | Available | | | *nsis | N/A | Available | | | | └─────────────────────── * - Optional Dependency ────────────────────────┘ # Diagnosis Optional package(s) installation details: - upx : Available at https://upx.github.io/ - nsis : More info at https://wails.io/docs/guides/windows-installer/ SUCCESS Your system is ready for Wails development! ♥ If Wails is useful to you or your company, please consider sponsoring the project: https://github.com/sponsors/leaanthonyGO Unit Test:
Checklist:
website/src/pages/changelog.mdxwith details of this PRSummary by CodeRabbit
New Features
Bug Fixes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.