Repository navigation
Conversation
* docs: update Svelte recommendation * Update routing.mdx * Update changelog.mdx * Updated changelog --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
Fix Windows 11 identification in `wails doctor`
- Replace SW_RESTORE with SW_SHOW flag - Resolves #4109
Update Sponsor Image
Update Sponsor Image
Update Sponsor Image
(cherry picked from commit fe6635c)
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
…4806) Disable suppressesIncrementalRendering on macOS 26+ (Tahoe) to prevent WebView crashes when the frontend performs frequent UI updates. Fixes #4592 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
Updated sponsorship section with JetBrains logo.
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
* fix(v2): Replace ioutl.Discard with io.Discard * docs: Update website changelog --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
WalkthroughThis PR adds a complete multiwindow-close example application for Wails v3, featuring cross-platform build pipelines (macOS, Linux, Windows), a frontend UI for window management, and a Go backend service implementing window lifecycle operations including open, list, and close-by-name strategies. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
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.
Actionable comments posted: 12
🤖 Fix all issues with AI agents
In `@v3/examples/multiwindow-close/build/darwin/Taskfile.yml`:
- Around line 28-53: The build:native task runs from the Taskfile directory
which causes relative paths to break; update the build:native task to set dir to
the repository root so its deps (e.g. common:go:mod:tidy) and the go build
command execute from the repo root and produce outputs in the correct bin path;
modify the build:native task (where BUILD_FLAGS, OUTPUT, DEFAULT_OUTPUT and the
go build line are defined) to include a dir: entry that points to the repository
root.
In `@v3/examples/multiwindow-close/build/linux/appimage/build.sh`:
- Around line 33-34: The mv command uses a glob inside double quotes so the * is
literal and won't match; update the rename step to allow shell glob expansion by
removing quotes around the source glob (keep quotes around the target) or
explicitly resolve the generated filename (e.g., via a shell expansion or find)
before calling mv; target the mv invocation that references APP_NAME (the line
using mv "${APP_NAME}*.AppImage" to "${APP_NAME}.AppImage") so the source is
expanded as APP_NAME*.AppImage and the destination remains quoted.
In `@v3/examples/multiwindow-close/build/linux/desktop`:
- Around line 5-6: The desktop entry's Exec line is hardcoded to
/usr/local/bin/multiwindow which conflicts with the AppImage that installs the
binary to /usr/bin; either make the Exec path configurable during packaging or
remove the absolute path and use the binary name "multiwindow" (so the system
PATH is used) in the desktop file, or change the AppImage packaging to install
to /usr/local/bin to match nfpm; update the Exec line in the desktop file or
adjust the AppImage install location accordingly and ensure packaging templates
(the desktop file generator or AppImage build script) consistently produce the
same install path.
In `@v3/examples/multiwindow-close/build/linux/Taskfile.yml`:
- Around line 72-75: The docker run line that invokes alpine to chown using $(id
-u):$(id -g) is POSIX-only and will fail on Windows; update Taskfile.yml so that
the chown step is executed only on Unix hosts by moving that command into its
own task or step and adding a platform restriction (e.g., platforms:
["linux","darwin"]) or a shell guard that detects POSIX (so the line containing
'docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g)
/app/bin' runs only on Unix), leaving the other docker/mv/mkdir steps unchanged.
In `@v3/examples/multiwindow-close/build/windows/info.json`:
- Around line 2-8: The Windows resource versions in info.json are using 3-part
strings; update them to 4-part format to match the MSIX manifests: change the
value of "fixed"."file_version" from "0.1.0" to "0.1.0.0" and update
"info"."0000"."ProductVersion" (and any other ProductVersion/CompanyName entries
inside the same object) to use the 4-part version "0.1.0.0" so all Windows
metadata is explicitly consistent with the MSIX manifest format.
In `@v3/examples/multiwindow-close/build/windows/msix/app_manifest.xml`:
- Around line 31-45: The manifest references an executable name that may not
match the packaged binary; check and reconcile the Executable attributes on the
Application element (Id="com.example.multiwindow" Executable="multiwindow") and
the desktop:Extension element (Category="windows.fullTrustProcess"
Executable="multiwindow") with the actual MSIX payload (the produced binary
multiWindow.exe); update the manifest Executable values to exactly match the
final packaged filename (including proper casing and .exe extension if present)
or adjust the build/msix packaging step to emit the executable name used in the
manifest so both manifest entries and the packaged binary are identical.
In `@v3/examples/multiwindow-close/build/windows/nsis/wails_tools.nsh`:
- Around line 145-179: The wails.webview2runtime macro currently runs the
WebView2 bootstrapper with ExecWait but doesn't check its exit code; modify the
ExecWait call to capture the installer exit code into a variable (e.g. ExecWait
'"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent
/install' $R0), then test $R0 and if non-zero emit a clear failure message
(DetailPrint/MessageBox using WAILS_INSTALL_WEBVIEW_DETAILPRINT or a descriptive
string) and abort the installer (Abort) so the install stops on WebView2
failure; keep all other logic in the macro (ReadRegStr checks, CreateDirectory,
File) intact.
- Around line 114-135: The uninstall macros wails.writeUninstaller and
wails.deleteUninstaller currently always write/delete under HKLM, which fails
for user-level installs; update both macros to choose the registry root
conditionally (use HKCU for REQUEST_EXECUTION_LEVEL == "user", otherwise HKLM)
following the same pattern used in wails.webview2runtime/wails.setShellContext:
introduce a variable (e.g., UNINST_ROOT) or inline If/StrCmp checks on
${REQUEST_EXECUTION_LEVEL} and then call WriteRegStr/WriteRegDWORD/DeleteRegKey
against that chosen root (and keep SetRegView behavior unchanged); ensure
UninstallString/QuietUninstallString,
Publisher/DisplayName/DisplayVersion/DisplayIcon, and EstimatedSize are written
to the conditional root and Delete uses the same root when removing the key.
In `@v3/examples/multiwindow-close/frontend/public/style.css`:
- Around line 188-192: There's an extra closing brace after the .note rule (the
stray "}" following the .note block) causing a CSS parse error; locate the .note
selector and remove the redundant closing brace so the rule ends with a single
"}" and the file's brace pairs remain balanced, then run a quick CSS lint or
open in a browser to confirm no parse errors.
In `@v3/examples/multiwindow-close/go.mod`:
- Around line 3-5: Update the module's Go version directive in go.mod from "go
1.25" to "go 1.24.0" to match other v3 examples and CI testing; edit the go
directive line in the go.mod file so it reads the 1.24.0 version string to
ensure consistent builds with the v3 examples and CI.
In `@v3/examples/multiwindow-close/greetservice.go`:
- Around line 87-96: The CloseUsingCurrent method dereferences the result of
g.app.Window.Current() without checking for nil; add a nil guard after calling w
:= g.app.Window.Current() (e.g., if w == nil { return WindowSummary{} }) before
calling w.ID(), w.Name(), or w.Close() so the function safely returns an empty
WindowSummary when Current() is nil; update GreetService.CloseUsingCurrent to
check w for nil and only access ID/Name/Close when non-nil.
In `@v3/examples/multiwindow-close/README.md`:
- Line 49: Update the README project structure to accurately list the actual
source files: replace the incorrect `app.go` entry with `main.go` and
`greetservice.go`, and give short descriptions (e.g., `main.go`: application
entrypoint and window management; `greetservice.go`: greeting service/handler
implementation) so the "project structure" section matches the repository
contents.
♻️ Duplicate comments (1)
v3/examples/multiwindow-close/build/darwin/Taskfile.yml (1)
138-147: Covered by working-directory note.Relative paths here rely on the same repo-root assumption mentioned in the comment on Line 41.
🧹 Nitpick comments (12)
v3/examples/multiwindow-close/build/linux/nfpm/scripts/postinstall.sh (1)
3-19: Add icon cache refresh for installed hicolor icons.The package installs icons to
/usr/share/icons/hicolor/128x128/apps/as confirmed in nfpm.yaml. Refreshing the icon cache in postinstall ensures icons appear immediately without restart delays.♻️ Optional addition (guarded)
+if command -v gtk-update-icon-cache >/dev/null 2>&1; then + echo "Updating icon cache..." + gtk-update-icon-cache -q /usr/share/icons/hicolor +else + echo "Warning: gtk-update-icon-cache command not found. Icons may not update immediately." >&2 +fiv3/examples/multiwindow-close/README.md (1)
11-13: Add language specifiers to fenced code blocks.The fenced code blocks are missing language specifiers, which affects syntax highlighting and fails markdown lint checks.
Suggested fix
- ``` + ```bash wails3 dev ```- ``` + ```bash wails3 build ```- ``` + ```bash go run . ```Also applies to: 19-21, 33-35
v3/examples/multiwindow-close/build/linux/appimage/build.sh (1)
8-15: Consider validating required environment variables.The script uses
APP_NAME,APP_BINARY,ICON_PATH, andDESKTOP_FILEwithout validation. Whileset -uwill catch unset variables, explicit validation with descriptive error messages would improve debuggability.Optional: Add validation at script start
+# Validate required environment variables +: "${APP_NAME:?APP_NAME is required}" +: "${APP_BINARY:?APP_BINARY is required}" +: "${ICON_PATH:?ICON_PATH is required}" +: "${DESKTOP_FILE:?DESKTOP_FILE is required}" + # Define variables APP_DIR="${APP_NAME}.AppDir"v3/examples/multiwindow-close/main.go (2)
4-5: Remove duplicate embed import.The
embedpackage is imported twice — once as a regular import and once as a blank import. The blank import_ "embed"is unnecessary whenembed.FSis already used.Proposed fix
import ( "embed" - _ "embed" "log"
19-21: Comment is misleading — no time-based event goroutine exists.The comment states the function "starts a goroutine that emits a time-based event every second," but no such goroutine is present in this code. Update the comment to reflect the actual behavior.
Proposed fix
-// main function serves as the application's entry point. It initializes the application, creates a window, -// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and -// logs any error that might occur. +// main function serves as the application's entry point. It initializes the application, creates a window, +// and runs the application, logging any error that might occur.v3/examples/multiwindow-close/build/darwin/Info.dev.plist (1)
22-23: Use boolean type forNSHighResolutionCapable.
NSHighResolutionCapableshould use a boolean value (<true/>) rather than a string. While macOS may coerce the string, the canonical plist format uses the boolean type.Proposed fix
<key>NSHighResolutionCapable</key> - <string>true</string> + <true/>v3/examples/multiwindow-close/build/darwin/Info.plist (1)
22-23: Use boolean type forNSHighResolutionCapable.Same issue as in
Info.dev.plist— use<true/>instead of<string>true</string>for the canonical plist format.Proposed fix
<key>NSHighResolutionCapable</key> - <string>true</string> + <true/>v3/examples/multiwindow-close/build/linux/nfpm/nfpm.yaml (1)
27-38: Consider broader Debian/Ubuntu compatibility and fix misleading comment.Two issues:
The default dependency
libwebkit2gtk-4.1-0works for Debian 12+ but not Ubuntu 22.04 (which useslibwebkit2gtk-4.0-37). Consider an OR dependency for broader compatibility:depends: - libgtk-3-0 - libwebkit2gtk-4.1-0 | libwebkit2gtk-4.0-37The RPM comment says "WebKit 4.0" but the dependency is
webkit2gtk4.1(WebKit 4.1). The comment should say "WebKit 4.1" to match the actual dependency.♻️ Proposed fix for the comment
- # RPM packages for RHEL/CentOS/AlmaLinux/Rocky Linux (WebKit 4.0) + # RPM packages for RHEL/CentOS/AlmaLinux/Rocky Linux (WebKit 4.1) rpm: depends: - gtk3 - webkit2gtk4.1Based on learnings, Debian 12 uses
libwebkit2gtk-4.1-0while Ubuntu 22.04 useslibwebkit2gtk-4.0-37, and RPM packages for WebKit 4.1 should usewebkit2gtk4.1(which is correct here, but the comment is misleading).v3/examples/multiwindow-close/build/windows/nsis/project.nsi (1)
91-92: Minor: Inconsistent casing in shortcut commands.Line 91 uses
CreateShortcutwhile line 92 usesCreateShortCut. NSIS is case-insensitive so this works, but consistent casing improves readability.♻️ Proposed fix
CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" - CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + CreateShortcut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"v3/examples/multiwindow-close/greetservice.go (1)
46-59: Return an empty slice when the app is nilReturning
nilwill marshal tonull, which forces extra null checks on the frontend. Prefer an empty slice to keep the API shape consistent.♻️ Suggested change
func (g *GreetService) ListWindows() []WindowSummary { if g.app == nil { - return nil + return []WindowSummary{} }v3/examples/multiwindow-close/frontend/src/main.js (1)
54-85: Guard CloseByName actions when?name=is missingIf a child window opens without a
nameparameter, the close actions still execute with an empty string. Depending on backend behavior, that could target the wrong window or silently fail. Consider a small guard to short‑circuit and log a clear message.🧩 Optional helper
function setChildLog(obj) { if (!childLogEl) return; if (typeof obj === 'string') { childLogEl.textContent = obj; return; } @@ } } + +function requireChildName(action) { + if (childName) return true; + setChildLog({action, error: 'missing ?name=...'}); + return false; +} window.closeNoCurrent = async () => { + if (!requireChildName('CloseByName')) return; try { const ok = await Call.ByName('main.GreetService.CloseByName', childName); setChildLog({action: 'CloseByName', childName, ok}); @@ }; window.closeAfterCurrent = async () => { + if (!requireChildName('CloseAfterCurrentByName')) return; try { const ok = await Call.ByName('main.GreetService.CloseAfterCurrentByName', childName); setChildLog({action: 'CloseAfterCurrentByName (calls App.Window.Current first)', childName, ok});v3/examples/multiwindow-close/build/Taskfile.yml (1)
46-80: Consider pinning or vendoring Puppertino CSSThe fetch step pulls from the upstream
mainbranch, which can change over time and make builds non‑reproducible or brittle offline. Consider pinning to a tag/commit or vendoring the CSS in‑repo if stability matters.
| build:native: | ||
| summary: Builds the application natively on macOS | ||
| internal: true | ||
| deps: | ||
| - task: common:go:mod:tidy | ||
| - task: common:build:frontend | ||
| vars: | ||
| BUILD_FLAGS: | ||
| ref: .BUILD_FLAGS | ||
| DEV: | ||
| ref: .DEV | ||
| - task: common:generate:icons | ||
| cmds: | ||
| - go build {{.BUILD_FLAGS}} -o {{.OUTPUT}} | ||
| vars: | ||
| BUILD_FLAGS: '{{if eq .DEV "true"}}-buildvcs=false -gcflags=all="-l"{{else}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{end}}' | ||
| DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}' | ||
| OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}' | ||
| env: | ||
| GOOS: darwin | ||
| CGO_ENABLED: 1 | ||
| GOARCH: '{{.ARCH | default ARCH}}' | ||
| CGO_CFLAGS: "-mmacosx-version-min=10.15" | ||
| CGO_LDFLAGS: "-mmacosx-version-min=10.15" | ||
| MACOSX_DEPLOYMENT_TARGET: "10.15" | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether a working directory is set in the parent Taskfile.
echo "=== Checking for dir settings ==="
rg -n '^\s*dir:' v3/examples/multiwindow-close/build/Taskfile.yml v3/examples/multiwindow-close/build/darwin/Taskfile.yml
echo ""
echo "=== Checking for ROOT_DIR references ==="
rg -n 'ROOT_DIR' v3/examples/multiwindow-close/build/Taskfile.yml v3/examples/multiwindow-close/build/darwin/Taskfile.yml
echo ""
echo "=== Checking includes and task structure in parent ==="
head -50 v3/examples/multiwindow-close/build/Taskfile.ymlRepository: wailsapp/wails
Length of output: 2117
🏁 Script executed:
#!/bin/bash
# Check the structure of darwin/Taskfile.yml to understand variable definitions and includes
echo "=== Full darwin/Taskfile.yml content ==="
cat -n v3/examples/multiwindow-close/build/darwin/Taskfile.yml
echo ""
echo "=== Check if there's a common Taskfile being included ==="
rg -n 'includes:' v3/examples/multiwindow-close/build/darwin/Taskfile.ymlRepository: wailsapp/wails
Length of output: 9591
🏁 Script executed:
#!/bin/bash
# Check parent Taskfile for ROOT_DIR definition and top-level vars
echo "=== Checking parent Taskfile for ROOT_DIR and global vars ==="
head -150 v3/examples/multiwindow-close/build/Taskfile.yml | tail -100Repository: wailsapp/wails
Length of output: 4306
🏁 Script executed:
#!/bin/bash
# Check the very beginning of parent Taskfile for ROOT_DIR and vars
echo "=== First 40 lines of parent Taskfile ==="
head -40 v3/examples/multiwindow-close/build/Taskfile.yml
echo ""
echo "=== Search for ROOT_DIR definition ==="
rg -A2 -B2 'ROOT_DIR|BIN_DIR|APP_NAME' v3/examples/multiwindow-close/build/Taskfile.yml | head -50Repository: wailsapp/wails
Length of output: 1160
🏁 Script executed:
#!/bin/bash
# Check if ROOT_DIR is defined elsewhere or is a built-in variable
echo "=== Search for ROOT_DIR definition anywhere in repo ==="
rg 'ROOT_DIR' v3/examples/multiwindow-close/ --max-count=20
echo ""
echo "=== Check if there's a root Taskfile.yml ==="
find v3/examples/multiwindow-close -name "Taskfile.yml" -o -name "Taskfile.yaml" | head -10
echo ""
echo "=== Check the actual repo structure ==="
ls -la v3/examples/multiwindow-close/
</parameter>Repository: wailsapp/wails
Length of output: 4412
🏁 Script executed:
#!/bin/bash
# Check root Taskfile.yml to find ROOT_DIR definition
echo "=== Root Taskfile.yml ==="
cat -n v3/examples/multiwindow-close/Taskfile.ymlRepository: wailsapp/wails
Length of output: 1176
🏁 Script executed:
#!/bin/bash
# Search for ROOT_DIR in wails documentation or check if it's a built-in task variable
echo "=== Search for ROOT_DIR in all Taskfiles to understand its usage ==="
rg -B3 -A1 'ROOT_DIR' v3/examples/multiwindow-close/build/darwin/Taskfile.yml | head -20
echo ""
echo "=== Check wails repo for ROOT_DIR template variable documentation ==="
rg 'ROOT_DIR' v3/internal/templates --max-count=10
echo ""
echo "=== Check if ROOT_DIR is dynamically set by task itself ==="
rg -n 'ROOT_DIR' v3/pkg --max-count=5Repository: wailsapp/wails
Length of output: 650
🏁 Script executed:
#!/bin/bash
# Check how build:native is invoked and if parent sets working directory
echo "=== Check build:native invocation in darwin/Taskfile.yml ==="
rg -B10 'build:native' v3/examples/multiwindow-close/build/darwin/Taskfile.yml | head -30
echo ""
echo "=== Check if build:frontend sets dir and verify inheritance ==="
rg -A10 'build:frontend:' v3/examples/multiwindow-close/build/Taskfile.yml | head -20
echo ""
echo "=== Verify path resolution - check if paths work from build/darwin/ or need repo root ==="
cat v3/examples/multiwindow-close/build/darwin/Taskfile.yml | grep -A5 'build:native:' | head -15Repository: wailsapp/wails
Length of output: 1269
🏁 Script executed:
#!/bin/bash
# Check if ROOT_DIR is supposed to be auto-injected by wails3 or is a common pattern
echo "=== Search entire wails repo for ROOT_DIR definition patterns ==="
rg 'vars:' v3/internal/templates -A10 | grep -A10 'ROOT_DIR' | head -30
echo ""
echo "=== Check if there's a common Taskfile template that defines ROOT_DIR ==="
find v3/internal/templates -name "*.tmpl*" -o -name "*Taskfile*" | head -20
echo ""
echo "=== Check actual template files for ROOT_DIR ==="
rg 'ROOT_DIR' v3/internal/templatesRepository: wailsapp/wails
Length of output: 1318
🏁 Script executed:
#!/bin/bash
# Check the common Taskfile template to see what variables are actually defined
echo "=== Common Taskfile template ==="
cat v3/internal/templates/_common/Taskfile.tmpl.yml
echo ""
echo "=== Search for how variables are inherited in task includes ==="
rg -A20 'includes:' v3/examples/multiwindow-close/build/darwin/Taskfile.ymlRepository: wailsapp/wails
Length of output: 1711
🏁 Script executed:
#!/bin/bash
# Check if there's a go.mod at different levels that would affect path resolution
echo "=== Check for go.mod files ==="
find v3/examples/multiwindow-close -name "go.mod" -type f
echo ""
echo "=== Check if go build would work from build/darwin/ ==="
ls -la v3/examples/multiwindow-close/build/darwin/
echo ""
echo "=== Verify the actual issue: where would bin/multiWindow be created if running from build/darwin/ ==="
echo "If task runs from build/darwin/ and outputs to 'bin/multiWindow', output goes to:"
echo " build/darwin/bin/multiWindow (WRONG)"
echo "But it should go to:"
echo " bin/multiWindow (from repo root)"
echo ""
echo "=== Check if ROOT_DIR might be auto-injected by wails3 ==="
rg 'ROOT_DIR' v3 --max-count=5 -B2 -A2 | head -40Repository: wailsapp/wails
Length of output: 4767
🏁 Script executed:
#!/bin/bash
# Check wails3 source code to see if ROOT_DIR is auto-injected
echo "=== Check if wails3 injects ROOT_DIR ==="
find v3/cmd -name "*.go" | xargs grep -l "ROOT_DIR" 2>/dev/null | head -5
echo ""
echo "=== Check task runner integration in wails ==="
find v3 -name "*.go" | xargs grep -l "{{.ROOT_DIR}}" 2>/dev/null | head -5
echo ""
echo "=== Try to understand how ROOT_DIR should work by checking go-task documentation patterns ==="
rg 'ROOT_DIR.*:' v3 --max-count=3
echo ""
echo "=== Check if there's any initialization that sets ROOT_DIR ==="
rg 'ROOT_DIR' v3/cmd v3/pkg --max-count=10 -A1Repository: wailsapp/wails
Length of output: 2457
🏁 Script executed:
#!/bin/bash
# Check go-task documentation - ROOT_DIR might be a built-in variable
echo "=== Check all variable usages in build/darwin/Taskfile.yml ==="
rg '{{\.([A-Z_]+)' v3/examples/multiwindow-close/build/darwin/Taskfile.yml -o | sort | uniq
echo ""
echo "=== Check what variables are actually defined ==="
rg -A50 'vars:' v3/examples/multiwindow-close/build/darwin/Taskfile.yml | head -40
echo ""
echo "=== Verify if build:docker references paths that would break without dir ==="
grep -A8 'build:docker:' v3/examples/multiwindow-close/build/darwin/Taskfile.yml | head -15Repository: wailsapp/wails
Length of output: 2016
🏁 Script executed:
#!/bin/bash
# Let's verify the actual problem: check if {{.OUTPUT}} uses absolute or relative paths
echo "=== Trace OUTPUT variable definition ==="
grep -n "OUTPUT:" v3/examples/multiwindow-close/build/darwin/Taskfile.yml
echo ""
echo "=== Trace BIN_DIR and APP_NAME ==="
grep -n "BIN_DIR\|APP_NAME" v3/examples/multiwindow-close/build/Taskfile.yml v3/examples/multiwindow-close/Taskfile.yml
echo ""
echo "=== Check what go:mod:tidy does (first dependency) ==="
grep -A5 'go:mod:tidy:' v3/examples/multiwindow-close/build/Taskfile.yml
echo ""
echo "=== Simulate: if {{.BIN_DIR}} = 'bin' and task runs from build/darwin/, output would be at ==="
echo " build/darwin/bin/multiWindow instead of bin/multiWindow (PROBLEM!)"
echo ""
echo "=== Check if other OS-specific Taskfiles have dir set ==="
rg -A5 'build:native:' v3/examples/multiwindow-close/build/linux/Taskfile.ymlRepository: wailsapp/wails
Length of output: 1466
Set working directory for build:native to ensure commands execute from repo root.
The go build command and dependency common:go:mod:tidy use relative paths that only resolve correctly from the repository root. Without an explicit dir: setting, go-task runs from the Taskfile's location (build/darwin/), causing go mod tidy to fail and output files to create at incorrect paths like build/darwin/bin/multiWindow instead of bin/multiWindow.
🛠️ Minimal fix
build:native:
summary: Builds the application natively on macOS
internal: true
+ dir: '{{.ROOT_DIR}}'
deps:
- task: common:go:mod:tidy🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/darwin/Taskfile.yml` around lines 28 -
53, The build:native task runs from the Taskfile directory which causes relative
paths to break; update the build:native task to set dir to the repository root
so its deps (e.g. common:go:mod:tidy) and the go build command execute from the
repo root and produce outputs in the correct bin path; modify the build:native
task (where BUILD_FLAGS, OUTPUT, DEFAULT_OUTPUT and the go build line are
defined) to include a dir: entry that points to the repository root.
| # Rename the generated AppImage | ||
| mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage" |
There was a problem hiding this comment.
Glob pattern won't expand inside double quotes.
The glob * inside double quotes is treated literally, so mv "${APP_NAME}*.AppImage" will fail to match the generated AppImage file.
Proposed fix
# Rename the generated AppImage
-mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage"
+mv ${APP_NAME}*.AppImage "${APP_NAME}.AppImage"📝 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.
| # Rename the generated AppImage | |
| mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage" | |
| # Rename the generated AppImage | |
| mv ${APP_NAME}*.AppImage "${APP_NAME}.AppImage" |
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/linux/appimage/build.sh` around lines 33
- 34, The mv command uses a glob inside double quotes so the * is literal and
won't match; update the rename step to allow shell glob expansion by removing
quotes around the source glob (keep quotes around the target) or explicitly
resolve the generated filename (e.g., via a shell expansion or find) before
calling mv; target the mv invocation that references APP_NAME (the line using mv
"${APP_NAME}*.AppImage" to "${APP_NAME}.AppImage") so the source is expanded as
APP_NAME*.AppImage and the destination remains quoted.
| # The Exec line includes %u to pass the URL to the application | ||
| Exec=/usr/local/bin/multiwindow %u |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find packaging configuration files
fd -a "nfpm.yaml" "v3/examples/multiwindow-close" 2>/dev/null || echo "No nfpm.yaml found"
# Also check for other packaging configs
fd -a "nfpm\|appimage\|deb\|rpm" "v3/examples/multiwindow-close/build/linux" 2>/dev/null | head -20
# Search for binary path references
rg -n "multiwindow|/usr/(local/)?bin" "v3/examples/multiwindow-close/build" 2>/dev/null | head -30Repository: wailsapp/wails
Length of output: 2735
Desktop entry path conflicts with appimage binary location.
The desktop file hardcodes /usr/local/bin/multiwindow, which matches the nfpm (deb/rpm) installation target. However, the appimage build installs the binary to /usr/bin/, causing the launcher to fail for appimage distributions.
Either update the appimage build to install to /usr/local/bin or make the desktop file path configurable during packaging.
🔧 Example fix (adjust appimage to match nfpm path)
-mkdir -p "${APP_DIR}/usr/bin"
-cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/"
+mkdir -p "${APP_DIR}/usr/local/bin"
+cp -r "${APP_BINARY}" "${APP_DIR}/usr/local/bin/"🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/linux/desktop` around lines 5 - 6, The
desktop entry's Exec line is hardcoded to /usr/local/bin/multiwindow which
conflicts with the AppImage that installs the binary to /usr/bin; either make
the Exec path configurable during packaging or remove the absolute path and use
the binary name "multiwindow" (so the system PATH is used) in the desktop file,
or change the AppImage packaging to install to /usr/local/bin to match nfpm;
update the Exec line in the desktop file or adjust the AppImage install location
accordingly and ensure packaging templates (the desktop file generator or
AppImage build script) consistently produce the same install path.
| - docker run --rm -v "{{.ROOT_DIR}}:/app" {{.GO_CACHE_MOUNT}} {{.REPLACE_MOUNTS}} -e APP_NAME="{{.APP_NAME}}" "{{.CROSS_IMAGE}}" linux {{.DOCKER_ARCH}} | ||
| - docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin | ||
| - mkdir -p {{.BIN_DIR}} | ||
| - mv "bin/{{.APP_NAME}}-linux-{{.DOCKER_ARCH}}" "{{.OUTPUT}}" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the file and check its existence
find . -path "*v3/examples/multiwindow-close/build/linux/Taskfile.yml" -type fRepository: wailsapp/wails
Length of output: 114
🏁 Script executed:
# List the directory structure to understand the context
git ls-files | grep -E "v3/examples/multiwindow-close" | head -20Repository: wailsapp/wails
Length of output: 1155
🏁 Script executed:
# Get the actual content of the Taskfile.yml file
cat -n "v3/examples/multiwindow-close/build/linux/Taskfile.yml"Repository: wailsapp/wails
Length of output: 9426
🏁 Script executed:
# Search for similar task patterns in the codebase to understand Taskfile usage
rg "platforms:" --type yaml -A 2 -B 2 | head -40Repository: wailsapp/wails
Length of output: 3048
Restrict chown command to Unix platforms
The $(id -u):$(id -g) substitution uses POSIX shell syntax and will fail on Windows hosts. Since chown is not available on Windows anyway, restrict this command to Unix platforms.
🔧 Suggested fix
- - docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin
+ - cmd: docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin
+ platforms: [linux, darwin]📝 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.
| - docker run --rm -v "{{.ROOT_DIR}}:/app" {{.GO_CACHE_MOUNT}} {{.REPLACE_MOUNTS}} -e APP_NAME="{{.APP_NAME}}" "{{.CROSS_IMAGE}}" linux {{.DOCKER_ARCH}} | |
| - docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin | |
| - mkdir -p {{.BIN_DIR}} | |
| - mv "bin/{{.APP_NAME}}-linux-{{.DOCKER_ARCH}}" "{{.OUTPUT}}" | |
| - docker run --rm -v "{{.ROOT_DIR}}:/app" {{.GO_CACHE_MOUNT}} {{.REPLACE_MOUNTS}} -e APP_NAME="{{.APP_NAME}}" "{{.CROSS_IMAGE}}" linux {{.DOCKER_ARCH}} | |
| - cmd: docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin | |
| platforms: [linux, darwin] | |
| - mkdir -p {{.BIN_DIR}} | |
| - mv "bin/{{.APP_NAME}}-linux-{{.DOCKER_ARCH}}" "{{.OUTPUT}}" |
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/linux/Taskfile.yml` around lines 72 - 75,
The docker run line that invokes alpine to chown using $(id -u):$(id -g) is
POSIX-only and will fail on Windows; update Taskfile.yml so that the chown step
is executed only on Unix hosts by moving that command into its own task or step
and adding a platform restriction (e.g., platforms: ["linux","darwin"]) or a
shell guard that detects POSIX (so the line containing 'docker run --rm -v
"{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin' runs only on
Unix), leaving the other docker/mv/mkdir steps unchanged.
| "fixed": { | ||
| "file_version": "0.1.0" | ||
| }, | ||
| "info": { | ||
| "0000": { | ||
| "ProductVersion": "0.1.0", | ||
| "CompanyName": "My Company", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's explore the Windows build directory structure
find v3/examples/multiwindow-close/build/windows -type f -name "*.json" -o -name "*.xml" | head -20Repository: wailsapp/wails
Length of output: 239
🏁 Script executed:
# Search for version patterns in the Windows examples
rg -n "file_version|ProductVersion|version" -i v3/examples/multiwindow-close/build/windows/Repository: wailsapp/wails
Length of output: 3486
🏁 Script executed:
# Check for MSIX manifest or other Windows metadata files
fd -e appxmanifest -e xml -e json v3/examples/multiwindow-close/Repository: wailsapp/wails
Length of output: 483
🏁 Script executed:
# Check if there are build scripts or CMakeLists that define version format
fd -e cmake -e bat -e ps1 v3/examples/multiwindow-close/build/Repository: wailsapp/wails
Length of output: 507
🏁 Script executed:
# Look at similar examples to see how versions are handled
fd info.json v3/examples/ --exec cat -n {}Repository: wailsapp/wails
Length of output: 4501
Align Windows resource versions to 4-part format for consistency with MSIX manifest.
The MSIX manifest files (app_manifest.xml, template.xml) use 4-part versions (Version="0.1.0.0"), while info.json stores 3-part versions ("0.1.0"). Although the NSIS build system appends ".0" to create 4-part versions at build time, aligning info.json directly to 4-part format ("0.1.0.0") improves consistency and explicitness across all Windows metadata.
Alignment to 4-part format
- "file_version": "0.1.0"
+ "file_version": "0.1.0.0"
@@
- "ProductVersion": "0.1.0",
+ "ProductVersion": "0.1.0.0",📝 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.
| "fixed": { | |
| "file_version": "0.1.0" | |
| }, | |
| "info": { | |
| "0000": { | |
| "ProductVersion": "0.1.0", | |
| "CompanyName": "My Company", | |
| "fixed": { | |
| "file_version": "0.1.0.0" | |
| }, | |
| "info": { | |
| "0000": { | |
| "ProductVersion": "0.1.0.0", | |
| "CompanyName": "My Company", |
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/windows/info.json` around lines 2 - 8,
The Windows resource versions in info.json are using 3-part strings; update them
to 4-part format to match the MSIX manifests: change the value of
"fixed"."file_version" from "0.1.0" to "0.1.0.0" and update
"info"."0000"."ProductVersion" (and any other ProductVersion/CompanyName entries
inside the same object) to use the 4-part version "0.1.0.0" so all Windows
metadata is explicitly consistent with the MSIX manifest format.
| # Install webview2 by launching the bootstrapper | ||
| # See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment | ||
| !macro wails.webview2runtime | ||
| !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT | ||
| !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" | ||
| !endif | ||
|
|
||
| SetRegView 64 | ||
| # If the admin key exists and is not empty then webview2 is already installed | ||
| ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | ||
| ${If} $0 != "" | ||
| Goto ok | ||
| ${EndIf} | ||
|
|
||
| ${If} ${REQUEST_EXECUTION_LEVEL} == "user" | ||
| # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed | ||
| ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | ||
| ${If} $0 != "" | ||
| Goto ok | ||
| ${EndIf} | ||
| ${EndIf} | ||
|
|
||
| SetDetailsPrint both | ||
| DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" | ||
| SetDetailsPrint listonly | ||
|
|
||
| InitPluginsDir | ||
| CreateDirectory "$pluginsdir\webview2bootstrapper" | ||
| SetOutPath "$pluginsdir\webview2bootstrapper" | ||
| File "MicrosoftEdgeWebview2Setup.exe" | ||
| ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' | ||
|
|
||
| SetDetailsPrint both | ||
| ok: | ||
| !macroend |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
NSIS ExecWait return code capture variable documentation
💡 Result:
In NSIS, ExecWait can capture the launched process’ exit code into a user variable by providing a 2nd parameter:
ExecWait '"$INSTDIR\someprogram.exe" parameters' $0
DetailPrint "Exit code: $0"- Syntax:
ExecWait command [user_var(exit code)][1] - If you do specify the output variable, NSIS writes the process exit code to that variable and sets the error flag only if ExecWait itself fails (e.g., couldn’t start the process). If an error occurs, the output variable is undefined. [1]
- If you do not specify an output variable,
ExecWaitsets the error flag when the executed program returns a non-zero exit code or when an execution error occurs. [1]
Practical pattern:
ClearErrors
ExecWait '"$INSTDIR\application.exe"' $0
IfErrors 0 +2
MessageBox MB_OK "Failed to execute (could not start process)"
StrCmp $0 0 done
MessageBox MB_OK "App returned exit code $0"
done:Sources: [1] [2]
Capture WebView2 bootstrapper exit code and abort on failure.
The current code doesn't check the exit status of the installer, so a failed WebView2 installation will silently proceed and leave the application unusable. Capture the exit code and abort with a clear error message if installation fails.
🔒 Suggested fix
- ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install'
+ ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' $0
+ ${If} $0 != 0
+ MessageBox MB_OK "WebView2 Runtime installation failed (exit code $0)."
+ Quit
+ ${EndIf}📝 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.
| # Install webview2 by launching the bootstrapper | |
| # See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment | |
| !macro wails.webview2runtime | |
| !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT | |
| !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" | |
| !endif | |
| SetRegView 64 | |
| # If the admin key exists and is not empty then webview2 is already installed | |
| ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | |
| ${If} $0 != "" | |
| Goto ok | |
| ${EndIf} | |
| ${If} ${REQUEST_EXECUTION_LEVEL} == "user" | |
| # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed | |
| ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | |
| ${If} $0 != "" | |
| Goto ok | |
| ${EndIf} | |
| ${EndIf} | |
| SetDetailsPrint both | |
| DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" | |
| SetDetailsPrint listonly | |
| InitPluginsDir | |
| CreateDirectory "$pluginsdir\webview2bootstrapper" | |
| SetOutPath "$pluginsdir\webview2bootstrapper" | |
| File "MicrosoftEdgeWebview2Setup.exe" | |
| ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' | |
| SetDetailsPrint both | |
| ok: | |
| !macroend | |
| # Install webview2 by launching the bootstrapper | |
| # See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment | |
| !macro wails.webview2runtime | |
| !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT | |
| !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" | |
| !endif | |
| SetRegView 64 | |
| # If the admin key exists and is not empty then webview2 is already installed | |
| ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | |
| ${If} $0 != "" | |
| Goto ok | |
| ${EndIf} | |
| ${If} ${REQUEST_EXECUTION_LEVEL} == "user" | |
| # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed | |
| ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" | |
| ${If} $0 != "" | |
| Goto ok | |
| ${EndIf} | |
| ${EndIf} | |
| SetDetailsPrint both | |
| DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" | |
| SetDetailsPrint listonly | |
| InitPluginsDir | |
| CreateDirectory "$pluginsdir\webview2bootstrapper" | |
| SetOutPath "$pluginsdir\webview2bootstrapper" | |
| File "MicrosoftEdgeWebview2Setup.exe" | |
| ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' $0 | |
| ${If} $0 != 0 | |
| MessageBox MB_OK "WebView2 Runtime installation failed (exit code $0)." | |
| Quit | |
| ${EndIf} | |
| SetDetailsPrint both | |
| ok: | |
| !macroend |
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/build/windows/nsis/wails_tools.nsh` around
lines 145 - 179, The wails.webview2runtime macro currently runs the WebView2
bootstrapper with ExecWait but doesn't check its exit code; modify the ExecWait
call to capture the installer exit code into a variable (e.g. ExecWait
'"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent
/install' $R0), then test $R0 and if non-zero emit a clear failure message
(DetailPrint/MessageBox using WAILS_INSTALL_WEBVIEW_DETAILPRINT or a descriptive
string) and abort the installer (Abort) so the install stops on WebView2
failure; keep all other logic in the macro (ReadRegStr checks, CreateDirectory,
File) intact.
| .note { | ||
| margin-top: 10px; | ||
| opacity: 0.9; | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
CSS syntax error: extra closing brace.
There's a stray } on line 192 that will cause a CSS parse error. The .note rule is already properly closed on line 191.
🐛 Proposed fix
.note {
margin-top: 10px;
opacity: 0.9;
}
-}📝 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.
| .note { | |
| margin-top: 10px; | |
| opacity: 0.9; | |
| } | |
| } | |
| .note { | |
| margin-top: 10px; | |
| opacity: 0.9; | |
| } |
🧰 Tools
🪛 Biome (2.1.2)
[error] 191-192: Expected a qualified rule, or an at rule but instead found '}'.
Expected a qualified rule, or an at rule here.
(parse)
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/frontend/public/style.css` around lines 188 -
192, There's an extra closing brace after the .note rule (the stray "}"
following the .note block) causing a CSS parse error; locate the .note selector
and remove the redundant closing brace so the rule ends with a single "}" and
the file's brace pairs remain balanced, then run a quick CSS lint or open in a
browser to confirm no parse errors.
| go 1.25 | ||
|
|
||
| require github.com/wailsapp/wails/v3 v3.0.0-alpha.62 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check repo Go version settings (go.work/go.mod/CI).
echo "=== Checking go.work files ==="
fd -a "go.work" 2>/dev/null || echo "No go.work found"
echo -e "\n=== Checking go directives in go.mod files ==="
fd -a "go.mod" 2>/dev/null | while read f; do
echo "File: $f"
rg -n "^go " "$f" 2>/dev/null || echo " (no go directive)"
done
echo -e "\n=== Checking CI Go version settings ==="
fd "\.yml$|\.yaml$" .github 2>/dev/null | while read f; do
echo "File: $f"
rg -n "setup-go|go-version|GOVERSION" "$f" 2>/dev/null || echo " (no Go version config)"
doneRepository: wailsapp/wails
Length of output: 5311
Downgrade Go version to match other v3 examples and CI testing.
The go 1.25 directive is inconsistent: all other v3 examples specify go 1.24.0, and CI tests v3 only against Go 1.24. Change this example to go 1.24.0 to ensure it builds in the current CI environment and maintains consistency across examples.
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/go.mod` around lines 3 - 5, Update the module's
Go version directive in go.mod from "go 1.25" to "go 1.24.0" to match other v3
examples and CI testing; edit the go directive line in the go.mod file so it
reads the 1.24.0 version string to ensure consistent builds with the v3 examples
and CI.
| // CloseUsingCurrent closes whichever window Wails considers "current". | ||
| func (g *GreetService) CloseUsingCurrent() WindowSummary { | ||
| if g.app == nil { | ||
| return WindowSummary{} | ||
| } | ||
|
|
||
| w := g.app.Window.Current() | ||
| info := WindowSummary{ID: w.ID(), Name: w.Name()} | ||
| w.Close() | ||
| return info |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the Window struct and Current() method implementation
fd -t f "window" v3 | grep -E "\.(go)$" | head -20Repository: wailsapp/wails
Length of output: 968
🏁 Script executed:
# Search for Window.Current() method definition
rg "func.*Current\(\)" v3 -A 5Repository: wailsapp/wails
Length of output: 2179
🏁 Script executed:
# Search for Window manager implementation
rg "type Window" v3 -B 2 -A 10 | head -100Repository: wailsapp/wails
Length of output: 5441
🏁 Script executed:
# Get the full Current() method implementation
sed -n '/func (wm \*WindowManager) Current() Window {/,/^}/p' v3/pkg/application/window_manager.goRepository: wailsapp/wails
Length of output: 293
🏁 Script executed:
# Search for usages of .Current() to see how it's typically handled
rg "\.Current\(\)" v3 -B 2 -A 3 | head -80Repository: wailsapp/wails
Length of output: 4854
🏁 Script executed:
# Check tests for Window.Current() to understand expected behavior
rg "Current\(\)" v3 -t go -B 3 -A 3 | grep -A 5 -B 5 "test\|Test"Repository: wailsapp/wails
Length of output: 846
Add nil guard for Window.Current() result
The Window.Current() method can return nil (visible in the implementation: if wm.app.impl == nil { return nil }). The code directly dereferences w.ID() and w.Name() without checking, which will panic if Current returns nil. This pattern is consistently guarded throughout the codebase (menuitem_roles.go, menuitem_dev.go, examples/build/main.go, etc.).
Suggested fix
w := g.app.Window.Current()
+ if w == nil {
+ return WindowSummary{}
+ }
info := WindowSummary{ID: w.ID(), Name: w.Name()}📝 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.
| // CloseUsingCurrent closes whichever window Wails considers "current". | |
| func (g *GreetService) CloseUsingCurrent() WindowSummary { | |
| if g.app == nil { | |
| return WindowSummary{} | |
| } | |
| w := g.app.Window.Current() | |
| info := WindowSummary{ID: w.ID(), Name: w.Name()} | |
| w.Close() | |
| return info | |
| // CloseUsingCurrent closes whichever window Wails considers "current". | |
| func (g *GreetService) CloseUsingCurrent() WindowSummary { | |
| if g.app == nil { | |
| return WindowSummary{} | |
| } | |
| w := g.app.Window.Current() | |
| if w == nil { | |
| return WindowSummary{} | |
| } | |
| info := WindowSummary{ID: w.ID(), Name: w.Name()} | |
| w.Close() | |
| return info |
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/greetservice.go` around lines 87 - 96, The
CloseUsingCurrent method dereferences the result of g.app.Window.Current()
without checking for nil; add a nil guard after calling w :=
g.app.Window.Current() (e.g., if w == nil { return WindowSummary{} }) before
calling w.ID(), w.Name(), or w.Close() so the function safely returns an empty
WindowSummary when Current() is nil; update GreetService.CloseUsingCurrent to
check w for nil and only access ID/Name/Close when non-nil.
|
|
||
| - `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript) | ||
| - `main.go`: The entry point of your Go backend | ||
| - `app.go`: Define your application structure and methods here |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd -e go . v3/examples/multiwindow-close --max-depth 1Repository: wailsapp/wails
Length of output: 141
🏁 Script executed:
sed -n '45,55p' v3/examples/multiwindow-close/README.mdRepository: wailsapp/wails
Length of output: 510
Update README to reflect actual project files.
Line 49 references app.go, but this file does not exist in the example. The directory contains main.go and greetservice.go. Update the project structure section to accurately document these files.
🤖 Prompt for AI Agents
In `@v3/examples/multiwindow-close/README.md` at line 49, Update the README
project structure to accurately list the actual source files: replace the
incorrect `app.go` entry with `main.go` and `greetservice.go`, and give short
descriptions (e.g., `main.go`: application entrypoint and window management;
`greetservice.go`: greeting service/handler implementation) so the "project
structure" section matches the repository contents.
|
Hi there 👋 This PR seems to be an example of the issue and not the fix so moving to draft for now. |
* Fix up templates to correct 1.23.0 * add changelog --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
* Update code block range in howdoesitwork.mdx * docs: add changelog entry for PR #4884 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(v2/linux): fix crash on panic in JS-bound Go methods WebKit2GTK installs signal handlers after gtk_main() starts, overriding our SA_ONSTACK fix. This causes Go panics (e.g., nil pointer dereference) in JS-bound methods to crash with 'non-Go code set up signal handler without SA_ONSTACK flag'. Fix by deferring signal handler installation via g_idle_add() to run after GTK main loop starts, ensuring we fix handlers AFTER WebKit has installed its own. Fixes #3965 * docs: add changelog entry for Linux signal handler fix Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add missing EventsOffAll export to runtime templates The EventsOffAll function was implemented in the internal runtime (desktop/events.js) and exported in the wrapper runtime files, but was missing from the public runtime templates that are generated in user projects. This caused a type mismatch where EventsOffAll was declared in the TypeScript definition but the implementation was missing. This commit adds the EventsOffAll export and type declaration to all frontend framework templates: - Common templates (generate/assets/common) - React / React-TS - Vue / Vue-TS - Svelte / Svelte-TS - Preact / Preact-TS - Lit / Lit-TS - Vanilla / Vanilla-TS Fixes #4703 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * docs: add EventsOffAll to runtime events documentation Added EventsOffAll function documentation to both English and Chinese versions of the runtime events reference. The function was already implemented in Go (pkg/runtime/events.go) and JavaScript (internal/frontend/runtime/desktop/events.js), but was missing from the public documentation. Related to #4703 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * chore: add EventsOffAll fix to changelog Added entry for the EventsOffAll fix to the Unreleased section of the changelog. Related to #4703 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * docs: translate EventsOffAll description to Chinese Improved consistency in Chinese documentation by translating the EventsOffAll description from English to Chinese, matching the style of other event method descriptions. Related to #4703 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: cc <Zhuanz@MacBook-Pro.local> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
Updated getCurrentWindowID to safely access AppKit APIs by dispatching to the main thread when called from non-main threads. This prevents potential crashes or undefined behavior when accessing NSApp and window delegates from arbitrary Go goroutines.
|
Hi! I've found the problem. To resolve this, I've updated the
The actual fix can be found in this commit: 4c4a71c If the change is positively reviewed, I will remove the new example since I don't think it needs to persist. |
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
- Fix Dockerfile path (was pointing to non-existent setupwizard/docker) - Add multi-platform build (linux/amd64 + linux/arm64) - Add QEMU for ARM64 cross-compilation - Add automatic trigger on Dockerfile.cross changes to v3-alpha - Update SDK version default to 14.5 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add test-cross-compile job that tests CGO builds for all 6 platform/arch combos - Add test-non-cgo job for pure Go cross-compilation verification - Add test-summary job with GitHub Actions summary output - Add skip_tests input for manual workflow dispatch - Verify Linux binaries link to required GTK/WebKit libraries - Verify binary format matches expected architecture Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
Co-authored-by: leaanthony <1943904+leaanthony@users.noreply.github.com>
…4921) * feat(v2): add runtime.ResetSignalHandlers() for Linux panic recovery Add a new runtime function that allows users to reset signal handlers before code that might panic from nil pointer dereferences. On Linux, WebKit installs signal handlers without the SA_ONSTACK flag, which prevents Go from properly recovering from panics caused by SIGSEGV and other signals. This function adds SA_ONSTACK to the relevant signal handlers (SIGSEGV, SIGBUS, SIGFPE, SIGABRT). Usage: ```go go func() { defer func() { if err := recover(); err != nil { log.Printf("Recovered: %v", err) } }() runtime.ResetSignalHandlers() // Code that might panic... }() ``` The function is a no-op on macOS and Windows. Fixes #3965 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(v2): add panic-recovery-test example Add an example that demonstrates the Linux signal handler issue (#3965) and verifies the fix using runtime.ResetSignalHandlers(). The example includes: - A Greet function that triggers a nil pointer dereference after a delay - Auto-call from frontend after 5 seconds - README with reproduction steps Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Sorry. Just wanted to merge the upstream, but made a mistake. Will make a new clean PR. |



Description
On macOS, I’m seeing an issue where a window appears closed, but it still shows up in App Exposé after calling App.Window.Current() at some time.
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
Any additional information here: https://discord.com/channels/1042734330029547630/1464733023864881354
wails3 doctor output: