Skip to content

fix(v3): guard nil AllowDarkModeForWindow to avoid startup panic#5793

Merged
leaanthony merged 4 commits into
wailsapp:masterfrom
roachadam:fix/windows-1809-dark-mode-panic
Jul 26, 2026
Merged

fix(v3): guard nil AllowDarkModeForWindow to avoid startup panic#5793
leaanthony merged 4 commits into
wailsapp:masterfrom
roachadam:fix/windows-1809-dark-mode-panic

Conversation

@roachadam

@roachadam roachadam commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes a nil-pointer panic on startup when a window uses a Dark (or system-dark) native title bar on Windows builds that do not load the dark-mode uxtheme APIs — e.g. Windows 10 1809 / Windows Server 2019 (build 17763).

pkg/w32/theme.go loads AllowDarkModeForWindow (and siblings) only on build >= 18334, so on 1809 the package-level w32.AllowDarkModeForWindow is nil. (*windowsWebviewWindow).run called it unguarded in the Dark and dark SystemDefault branches (webview_window_windows.go), while w32.SetMenuTheme` already guards the identical call.

The fix extracts the call into a small applyDarkMode helper that nil-guards it (mirroring the guard w32.SetMenuTheme already uses) and calls it from both branches, so the window degrades gracefully (default title bar) instead of panicking. No behavior change on builds that load the procs; no new dependencies.

Fixes #5792

Type of change

  • 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?

Built a minimal v3 app with Windows: application.WindowsWindow{Theme: application.Dark} and ran it on Windows Server 2019 (build 17763): before, it panicked on startup; after, the window opens normally.
Reproduction repo: https://github.com/roachadam/wails-1809-dark-title-bar-poc.

  • Windows
  • macOS
  • Linux

Test Configuration

Wails: v3.0.0-alpha2.117
OS:    Windows Server 2019 Standard Evaluation, 1809 (Build 17763)
Arch:  amd64
WebView2 runtime: 150.0.4078.65

Wails is not installed on this VM, so there is no wails3 doctor output. Reproduced with a minimal app instead: my existing app (built on v3.0.0-alpha.68) failed to start on Windows Server 2019 Standard Evaluation (build 17763). I reproduced the panic in isolation using the POC above built against the tagged v3.0.0-alpha2.117 release, then rebuilt the POC against this fix and confirmed the window opens normally.

Checklist:

  • (v2 only) I have updated website/src/pages/changelog.mdx with details of this PR (v3 changelog entries are added automatically)
  • 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

  • Bug Fixes
    • Fixed a Windows startup crash that could occur when using a dark or system-dark window theme.
    • Improved compatibility with Windows versions where dark-mode system APIs are unavailable.

…indows 1809

pkg/w32/theme.go loads the undocumented dark-mode uxtheme exports (including
AllowDarkModeForWindow) only on Windows build >= 18334, so on older builds such
as Windows 10 1809 / Windows Server 2019 (build 17763) the package-level
AllowDarkModeForWindow is nil.

The Dark and system-dark branches of (*windowsWebviewWindow).run called it
unguarded, so a window with Windows.Theme == Dark (or SystemDefault while the OS
is in dark mode) panicked on startup with a nil pointer dereference before the
window was shown. w32.SetMenuTheme already guards the identical call.

Extract the call into an applyDarkMode method, which nil-guards it, and use it
from both branches so the window degrades gracefully instead of crashing.

Fixes wailsapp#5792
@github-actions github-actions Bot added Documentation Improvements or additions to documentation Windows v3-alpha labels Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • v3/UNRELEASED_CHANGELOG.md
⛔ Files ignored due to path filters (110)
  • docs/public/d2/docs/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/lifecycle-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/contributing/codebase-layout-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/lifecycle-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/contributing/codebase-layout-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/lifecycle-0.svg is excluded by !**/*.svg
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: dae6ff29-4b7a-49dd-8d5f-5860dd79732b

📥 Commits

Reviewing files that changed from the base of the PR and between eda4f52 and 17d8d2e.

⛔ Files ignored due to path filters (110)
  • docs/public/d2/docs/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/concepts/lifecycle-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/contributing/codebase-layout-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/de/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/fr/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/concepts/lifecycle-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/id/contributing/codebase-layout-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ja/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ko/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/pt/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/ru/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-cn/concepts/lifecycle-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-2.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-3.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-4.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-5.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-6.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/architecture-7.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/bridge-0.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/bridge-1.svg is excluded by !**/*.svg
  • docs/public/d2/docs/zh-tw/concepts/lifecycle-0.svg is excluded by !**/*.svg
📒 Files selected for processing (1)
  • v3/UNRELEASED_CHANGELOG.md

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Windows dark-theme initialization now uses a nil-safe helper before invoking the optional dark-mode API. Both dark system-default and explicit dark themes avoid startup panics on builds without that API, and the fix is documented in the unreleased changelog.

Changes

Windows dark-mode startup fix

Layer / File(s) Summary
Nil-safe dark-mode theme setup
v3/pkg/application/webview_window_windows.go, v3/UNRELEASED_CHANGELOG.md
Dark system-default and explicit dark themes call applyDarkMode, which checks whether AllowDarkModeForWindow is available before invoking it. The changelog records the fix.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • wailsapp/wails#5790: Addresses the same Windows startup panic involving the unavailable dark-mode API.

Suggested labels: Bug, v3, size:XS

Suggested reviewers: wayneforrest, taliesin-ai, mbaklor

Poem

A rabbit found a dark-mode snare,
And guarded the Windows call with care.
No nil hop, no startup fright,
Just graceful themes from day to night.
Thump thump! Fixed and bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: guarding nil AllowDarkModeForWindow to prevent a startup panic.
Description check ✅ Passed The description covers the fix, issue number, testing, configuration, and change type well enough for this repository.
Linked Issues check ✅ Passed The code matches #5792 by nil-guarding dark-mode window setup and preserving behavior on supported Windows builds.
Out of Scope Changes check ✅ Passed The changes stay focused on the reported Windows dark-mode panic and the related changelog entry.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@leaanthony leaanthony left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Correct: AllowDarkModeForWindow is a lazily-resolved uxtheme export that is nil on builds below 18334 (Windows 10 1809 / Server 2019), and the two call sites in run() were the only unguarded ones. Folding them into applyDarkMode matches the guard already used by w32.SetMenuTheme, so the pattern stays consistent. Changelog entry included.

Resolves the UNRELEASED_CHANGELOG conflict by keeping both entries: the 32-bit
updater fix that just landed on master and this PR's dark-mode nil guard.

Claude-Session: https://claude.ai/code/session_01FigQqUQbNu9ngE4a2CSNm8
@leaanthony
leaanthony merged commit 0805349 into wailsapp:master Jul 26, 2026
20 checks passed
leaanthony pushed a commit that referenced this pull request Jul 26, 2026
…lowDarkModeForWindow to avoid startup panic
leaanthony added a commit that referenced this pull request Jul 26, 2026
…mitting the renders (#5827)

Two problems, one cause.

The d2 diagrams were never localised: every label in every locale is English.
What the per-locale copies actually held was drift. The translation pipeline
copied the d2 block when a page was translated and never re-synced it when the
English diagram changed, so seven locales rendered an older architecture
diagram than the English page, with English labels, on a page explaining how
Wails works. de, fr, ja and ru were byte-identical to each other and different
from English, which is the signature of a stale copy rather than a translation.

Separately, 110 generated SVGs were committed to the repository in #5793. They
are build output: astro-d2 writes one per diagram per locale, so the count
scales with locales x diagrams and grows as translation coverage improves.

- Sync the d2 source from each English page into its translated counterparts,
  where the diagram counts line up. Prose is untouched, verified by stripping
  the d2 blocks and confirming the remainder is byte-identical.
- Untrack docs/public/d2 and gitignore it.

Nine files are deliberately not synced because they need a human. zh-cn's
architecture page has four diagrams where English has eight, and eight locales
have one lifecycle diagram where English has two: the English pages gained
diagrams the translations never received. Inserting a diagram into translated
prose is not a mechanical substitution, so the tool reports these and stops.

Verified: clean rebuild, 1711 pages, no page loss. architecture-0 went from
three variants across locales to one shared render everywhere except zh-cn,
which is one of the deliberately skipped files. Every other diagram is now a
single variant across all locales. All 110 diagram references in the built
HTML resolve to a file on disk, so no broken images.

Claude-Session: https://claude.ai/code/session_01FigQqUQbNu9ngE4a2CSNm8

Co-authored-by: taliesin-ai <lea.anthony@gmail.com>
leaanthony added a commit that referenced this pull request Jul 26, 2026
…mitting the renders (#5833)

docs: make English the single source for diagram source, and stop committing the renders (#5827)

Two problems, one cause.

The d2 diagrams were never localised: every label in every locale is English.
What the per-locale copies actually held was drift. The translation pipeline
copied the d2 block when a page was translated and never re-synced it when the
English diagram changed, so seven locales rendered an older architecture
diagram than the English page, with English labels, on a page explaining how
Wails works. de, fr, ja and ru were byte-identical to each other and different
from English, which is the signature of a stale copy rather than a translation.

Separately, 110 generated SVGs were committed to the repository in #5793. They
are build output: astro-d2 writes one per diagram per locale, so the count
scales with locales x diagrams and grows as translation coverage improves.

- Sync the d2 source from each English page into its translated counterparts,
  where the diagram counts line up. Prose is untouched, verified by stripping
  the d2 blocks and confirming the remainder is byte-identical.
- Untrack docs/public/d2 and gitignore it.

Nine files are deliberately not synced because they need a human. zh-cn's
architecture page has four diagrams where English has eight, and eight locales
have one lifecycle diagram where English has two: the English pages gained
diagrams the translations never received. Inserting a diagram into translated
prose is not a mechanical substitution, so the tool reports these and stops.

Verified: clean rebuild, 1711 pages, no page loss. architecture-0 went from
three variants across locales to one shared render everywhere except zh-cn,
which is one of the deliberately skipped files. Every other diagram is now a
single variant across all locales. All 110 diagram references in the built
HTML resolve to a file on disk, so no broken images.

Claude-Session: https://claude.ai/code/session_01FigQqUQbNu9ngE4a2CSNm8

Co-authored-by: taliesin-ai <lea.anthony@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation v3-alpha Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v3] Nil-pointer panic on startup with a Dark window theme on Windows 10 1809 / Server 2019

2 participants