Skip to content

Conversation

@AkimioJR
Copy link
Contributor

@AkimioJR AkimioJR commented Oct 20, 2025

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.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

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.

  • Windows
  • macOS
  • Linux

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/leaanthony

GO Unit Test:

wails/v2 on  feature/4654-runtime-SetAppearance-for-darwin via 🐹 v1.25.1 
❯ go test ./...
?       github.com/wailsapp/wails/v2    [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails  [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails/flags    [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails/internal [no test files]
# github.com/wailsapp/wails/v2/internal/frontend/desktop/darwin
WailsContext.m:164:18: warning: 'setShowsBaselineSeparator:' is deprecated: first deprecated in macOS 15.0 - No longer supported [-Wdeprecated-declarations]
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSToolbar.h:299:16: note: property 'showsBaselineSeparator' is declared deprecated here
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSToolbar.h:299:16: note: 'setShowsBaselineSeparator:' has been explicitly marked deprecated here
ok      github.com/wailsapp/wails/v2/cmd/wails/internal/dev     0.488s
?       github.com/wailsapp/wails/v2/cmd/wails/internal/gomod   [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails/internal/logutils        [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails/internal/template        [no test files]
?       github.com/wailsapp/wails/v2/cmd/wails/internal/template/base   [no test files]
?       github.com/wailsapp/wails/v2/internal/app       [no test files]
ok      github.com/wailsapp/wails/v2/internal/binding   0.648s
ok      github.com/wailsapp/wails/v2/internal/binding/binding_test      1.196s
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import   [no test files]
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/binding_test_nestedimport [no test files]
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/float_package     [no test files]
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/int_package       [no test files]
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/map_package       [no test files]
?       github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/uint_package      [no test files]
?       github.com/wailsapp/wails/v2/internal/colour    [no test files]
?       github.com/wailsapp/wails/v2/internal/frontend  [no test files]
?       github.com/wailsapp/wails/v2/internal/frontend/desktop  [no test files]
?       github.com/wailsapp/wails/v2/internal/frontend/desktop/darwin   [no test files]
?       github.com/wailsapp/wails/v2/internal/frontend/dispatcher       [no test files]
ok      github.com/wailsapp/wails/v2/internal/frontend/runtime  1.363s
?       github.com/wailsapp/wails/v2/internal/frontend/runtime/wrapper  [no test files]
ok      github.com/wailsapp/wails/v2/internal/fs        1.829s
ok      github.com/wailsapp/wails/v2/internal/github    2.043s
?       github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd [no test files]
?       github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfdutil      [no test files]
ok      github.com/wailsapp/wails/v2/internal/go-common-file-dialog/util2.430s
ok      github.com/wailsapp/wails/v2/internal/gomod     2.829s
?       github.com/wailsapp/wails/v2/internal/goversion [no test files]
?       github.com/wailsapp/wails/v2/internal/logger    [no test files]
?       github.com/wailsapp/wails/v2/internal/menumanager       [no test files]
?       github.com/wailsapp/wails/v2/internal/process   [no test files]
ok      github.com/wailsapp/wails/v2/internal/project   3.181s
?       github.com/wailsapp/wails/v2/internal/s [no test files]
ok      github.com/wailsapp/wails/v2/internal/shell     2.712s
?       github.com/wailsapp/wails/v2/internal/signal    [no test files]
ok      github.com/wailsapp/wails/v2/internal/staticanalysis    6.001s
?       github.com/wailsapp/wails/v2/internal/system    [no test files]
?       github.com/wailsapp/wails/v2/internal/system/operatingsystem    [no test files]
?       github.com/wailsapp/wails/v2/internal/system/packagemanager     [no test files]
?       github.com/wailsapp/wails/v2/internal/typescriptify     [no test files]
?       github.com/wailsapp/wails/v2/internal/webview2runtime   [no test files]
?       github.com/wailsapp/wails/v2/pkg/application    [no test files]
ok      github.com/wailsapp/wails/v2/pkg/assetserver    2.854s
?       github.com/wailsapp/wails/v2/pkg/assetserver/webview    [no test files]
?       github.com/wailsapp/wails/v2/pkg/buildassets    [no test files]
?       github.com/wailsapp/wails/v2/pkg/clilogger      [no test files]
ok      github.com/wailsapp/wails/v2/pkg/commands/bindings      8.103s
ok      github.com/wailsapp/wails/v2/pkg/commands/build 3.204s
ok      github.com/wailsapp/wails/v2/pkg/commands/buildtags     3.242s
ok      github.com/wailsapp/wails/v2/pkg/git    2.973s
?       github.com/wailsapp/wails/v2/pkg/logger [no test files]
ok      github.com/wailsapp/wails/v2/pkg/mac    3.653s
ok      github.com/wailsapp/wails/v2/pkg/menu   2.886s
?       github.com/wailsapp/wails/v2/pkg/menu/colours   [no test files]
ok      github.com/wailsapp/wails/v2/pkg/menu/keys      2.477s
ok      github.com/wailsapp/wails/v2/pkg/options        2.129s
?       github.com/wailsapp/wails/v2/pkg/options/assetserver    [no test files]
?       github.com/wailsapp/wails/v2/pkg/options/linux  [no test files]
?       github.com/wailsapp/wails/v2/pkg/options/mac    [no test files]
?       github.com/wailsapp/wails/v2/pkg/options/windows        [no test files]
?       github.com/wailsapp/wails/v2/pkg/runtime        [no test files]
ok      github.com/wailsapp/wails/v2/pkg/templates      2.613s
?       github.com/wailsapp/wails/v2/pkg/templates/base [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/generate     [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/generate/plain       [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/lit        [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/lit-ts     [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/plain      [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/preact     [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/preact-ts  [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/react      [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/react-ts   [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/svelte     [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/svelte-ts  [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/vanilla    [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/vanilla-ts [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/vue        [no test files]
?       github.com/wailsapp/wails/v2/pkg/templates/templates/vue-ts     [no test files]
?       github.com/wailsapp/wails/v2/tools/release      [no test files]

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • New Features

    • macOS: Window appearance control added — set Light, Dark or System Default themes.
  • Bug Fixes

    • Appearance changes now apply reliably on macOS windows.
  • Documentation

    • Theme method docs clarified: Linux unsupported; macOS supported for window theming.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Walkthrough

Adds 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

Cohort / File(s) Summary
Objective-C C bridge layer
v2/internal/frontend/desktop/darwin/Application.h, v2/internal/frontend/desktop/darwin/Application.m
Added SetAppearance(void* ctx, const char* appearance) C function bridging to WailsContext and dispatching the call on the main thread.
WailsContext interface & implementation
v2/internal/frontend/desktop/darwin/WailsContext.h, v2/internal/frontend/desktop/darwin/WailsContext.m
Added - (void) SetAppearance:(NSString*)appearance; which resolves an NSAppearance by name and applies it to the main window when available.
Go frontend bindings
v2/internal/frontend/desktop/darwin/frontend.go, v2/internal/frontend/desktop/darwin/window.go
Imported mac appearance names and added (*Window) SetAppearance(appearance string); WindowSetSystemDefaultTheme / WindowSetLightTheme / WindowSetDarkTheme now call the new setter.
Documentation
website/docs/reference/runtime/window.mdx
Updated theming method docs from “Windows only.” to “Linux is unsupported.”

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to main-thread dispatch in Application.m and safety of safeInit/string conversions.
  • Verify NSAppearance name mapping and behavior when appearance is nil or unrecognized.
  • Confirm Go-to-C memory allocation/deallocation in window.go is correct.

Suggested labels

Enhancement, Documentation, MacOS

Suggested reviewers

  • leaanthony

Poem

🐰 With twitching nose I hop and cheer,

I paint the Mac with light and sheer.
From dark to aqua, themes take flight—
I set the look, then off I bite! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main feature: adding support for three window theming functions (WindowSetSystemDefaultTheme, WindowSetLightTheme, WindowSetDarkTheme) for macOS, with explicit issue reference (#4654).
Description check ✅ Passed The description covers key sections: summary of changes, feature type selection, testing confirmation on macOS with system details (wails doctor output), unit test results, and most checklist items completed. Documentation updates are confirmed as done.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between edd9224 and c02afb9.

📒 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 consistent

The 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:

  1. The current SetAppearance implementation and its interaction with WindowSetSystemDefaultTheme
  2. Whether the C layer (C.SetAppearance) actually supports NULL pointers for the "clear override" behavior
  3. How similar bridge methods in the codebase handle edge cases
  4. 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 WindowSetSystemDefaultTheme and mac.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 behavior
v2/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, and SetDarkTheme are Windows-only APIs. macOS appearance in Wails v2 is configured at app startup via mac.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.go at lines 219-229, which contradicts the documented API surface. This suggests either:

  1. The PR introduces new macOS theme methods not currently in Wails (outside documented behavior)
  2. The file path or line numbers are misidentified
  3. The review assumptions about which file these methods are in may be incorrect

Technical Context: The review's underlying concerns about DefaultAppearance semantics and nil-checks are technically sound — if such methods exist, they would need to set NSApplication.appearance = nil to 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.

Comment on lines +348 to +355
- (void) SetAppearance:(NSString*)appearance {
if (appearance != nil) {
NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance];
if (nsAppearance != nil) {
[self.mainWindow setAppearance:nsAppearance];
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find WailsContext.m file
find . -name "WailsContext.m" -type f

Repository: 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:

  1. NSApplication.appearance — Apple Developer (appearance is nil → AppKit applies current system appearance). [Apple]. (developer.apple.com)
  2. WWDC / Advanced Dark Mode notes (appearance inheritance; assign nil to reset to default). (nilotic.github.io)

Citations:


🌐 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:

  1. NSAppearance.appearanceNamed: returns nil for unknown/default appearance names
  2. ✅ Calling setAppearance:nil on an NSAppearanceCustomization resets it to system default behavior
  3. ✅ Wails' DefaultAppearance is explicitly meant for "use the macOS system appearance"
  4. ✅ The current SetAppearance implementation (lines 348-355) skips calling setAppearance: when appearanceNamed: returns nil

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.

Suggested change
- (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.

@leaanthony
Copy link
Member

I will get to this. Thanks for your patience 🙏

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants