Skip to content

fix(linux): re-apply signal handlers periodically to survive JSC lazy init - #5507

Merged
leaanthony merged 4 commits into
masterfrom
fix/linux-signal-handler-jsc-race
May 27, 2026
Merged

leaanthony merged 4 commits into
masterfrom
fix/linux-signal-handler-jsc-race

Conversation

@leaanthony

@leaanthony leaanthony commented May 25, 2026 •

Copy link
Copy Markdown
Member

Problem

Closes #5506

WebKit's JavaScriptCore (JSC) lazily installs signal handlers when JavaScript first executes — not at WebView creation time. These handlers (SIGSEGV for JIT crash recovery, SIGUSR1 for GC thread synchronisation) are registered without SA_ONSTACK, overwriting Go's handlers which require the flag.

When a JIT page fault occurs, the kernel delivers SIGSEGV on the normal stack instead of the alternate signal stack. JSC's handler runs and calls Go's handler as a fallback; Go's sigtramp detects the missing SA_ONSTACK flag and panics:

non-Go code set up signal handler without SA_ONSTACK flag

Root Cause

The existing one-shot fix (g_idle_add in v2, direct call in v3) runs before any JavaScript has executed. JSC installs its bad handlers later — when the first JS runs — wiping out the fix entirely.

The reporter's workaround confirmed this: a g_timeout_add polling at 50ms intervals prevented the crash because it continuously re-applied the fix through the JSC initialisation window.

Fix

Add a g_timeout_add_full periodic timer (50ms, 100 iterations = 5 seconds) on the GTK main thread that re-applies install_signal_handlers() throughout the JSC lazy-initialisation window. The g_free destroy-notify prevents a memory leak if the app exits before the timer completes.

The existing one-shot idle/direct calls are preserved as the "first immediate fix" layer. The periodic timer takes over from there and covers the race window.

Files Changed

  • v2 v2/internal/frontend/desktop/linux/frontend.go — periodic timer added to fix_signal_handlers_after_gtk_init()
  • v3 GTK4 v3/pkg/application/linux_cgo.c + .h + .go — new schedule_signal_handler_fix() called from appNew()
  • v3 GTK3 v3/pkg/application/linux_cgo_gtk3.go — same logic inline, called inside fixSignalHandlers.Do

Summary by CodeRabbit

  • Bug Fixes
    • Improved Linux stability when loading web content by applying an additional signal fix, adding a short (~5s) periodic retry that re-applies the fix every 50ms during startup, and re-applying the fix once a page finishes loading to reduce crashes and improve reliability.

Review Change Stack

… init

WebKit's JavaScriptCore (JSC) lazily installs signal handlers (SIGSEGV for
JIT crash recovery, SIGUSR1 for GC thread sync) when JavaScript first
executes - not at WebView creation. These handlers are registered without
SA_ONSTACK, overwriting Go's handler which requires it.

The existing one-shot fix runs before any JS executes, so JSC wipes it out
immediately when it initialises. A 50ms periodic timer (100 iterations =
5s) running on the GTK main thread re-applies install_signal_handlers()
throughout the JSC initialisation window, ensuring Go's SA_ONSTACK
requirement is always satisfied.

Fixes #5506
Copilot AI review requested due to automatic review settings May 25, 2026 10:04
@coderabbitai

coderabbitai Bot commented May 25, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7c5a2d55-3956-401e-b1a9-49ce1e08af23

📥 Commits

Reviewing files that changed from the base of the PR and between 7a3459d and 1ce4492.

📒 Files selected for processing (1)
  • v3/pkg/application/linux_cgo.go

Walkthrough

Adds C and Go changes that repeatedly re-apply install_signal_handlers() (now covering SIGUSR1) via a GLib timeout scheduler and calls to re-run the fix during WebView creation and after page load (DomReady / WEBKIT_LOAD_FINISHED).

Changes

Signal Handler Timeout Retry

Layer / File(s) Summary
C GLib timeout and header
v3/pkg/application/linux_cgo.h, v3/pkg/application/linux_cgo.c
Adds schedule_signal_handler_fix(void) declaration; extends install_signal_handlers() to include SIGUSR1; adds a GLib timeout callback that calls install_signal_handlers() every 50ms for a short countdown and exports schedule_signal_handler_fix() which allocates the countdown and registers the timeout.
V3 Go + GTK integration
v3/pkg/application/linux_cgo.go, v3/pkg/application/linux_cgo_gtk3.go
Adds fixSignalHandlers sync.Once, calls C.install_signal_handlers() and C.schedule_signal_handler_fix() on first WebView creation, updates GTK3-side install_signal_handlers() to include SIGUSR1, and re-invokes C.install_signal_handlers() on WEBKIT_LOAD_FINISHED.
V2 frontend timeout and DomReady re-apply
v2/internal/frontend/desktop/linux/frontend.go
Extends install_signal_handlers() to include SIGUSR1; adds install_signal_handlers_timeout scheduled via g_timeout_add_full (50ms ticks for ~5s) in addition to existing g_idle_add; calls C.install_signal_handlers() on "DomReady".

Sequence Diagram(s)

sequenceDiagram
  participant App as Go App
  participant WebView
  participant GLibTimer as GLib Timer
  participant C as install_signal_handlers

  App->>WebView: create WebView (first)
  App->>C: C.install_signal_handlers() (initial)
  App->>C: C.schedule_signal_handler_fix() (starts GLib timer)
  WebView->>C: WebKit/JSC may install signal handlers (including SIGUSR1)
  GLibTimer->>C: timeout tick -> call install_signal_handlers() (every 50ms)
  C-->>GLibTimer: continue until countdown expires (~5s)
  WebView->>App: WEBKIT_LOAD_FINISHED / DomReady
  App->>C: C.install_signal_handlers() (re-apply after load)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • wailsapp/wails#4855: Prior change that added the one-shot g_idle_add mitigation and adjusted fix_signal_handlers_after_gtk_init().
  • wailsapp/wails#4856: Related updates to the Linux WebKit signal-handler workaround and timing around WebView creation.

Suggested labels

Linux, Bug, v3, go

Suggested reviewers

  • atterpac

Poem

🐰 I hop through C and GLib ticks,

fifty-millisecond mends and little tricks,
SIGUSR1 gets SA_ONSTACK back in line,
five seconds of watching keeps handlers fine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: re-applying signal handlers periodically to address JSC lazy initialization issues on Linux.
Description check ✅ Passed The PR description is comprehensive, including a clear problem statement, root cause analysis, the proposed fix, and files changed. However, the testing section of the template checklist is not filled out.
Linked Issues check ✅ Passed The code changes directly address issue #5506 by implementing a periodic timer-based signal handler re-application (50ms, 5 seconds) and load-finished hooks, matching the verified workaround and addressing the root cause of JSC lazy initialization overwriting Go's SA_ONSTACK handlers.
Out of Scope Changes check ✅ Passed All changes are focused on signal handler re-application for Linux JSC compatibility across v2 and v3 versions, with no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/linux-signal-handler-jsc-race

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses Linux startup crashes caused by WebKit JavaScriptCore lazily overwriting Go’s signal handlers without SA_ONSTACK by periodically re-applying Wails’ install_signal_handlers() during the early initialization window (instead of relying only on a one-shot fix).

Changes:

  • Add a GLib g_timeout_add_full timer (50ms, 100 iterations) to repeatedly call install_signal_handlers() for ~5 seconds.
  • Introduce schedule_signal_handler_fix() for v3 GTK4 (C + header) and invoke it from appNew().
  • Apply the same periodic scheduling approach to v3 GTK3 and v2 Linux frontend initialization.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
v3/pkg/application/linux_cgo.h Declares schedule_signal_handler_fix() for GTK4 build path.
v3/pkg/application/linux_cgo.go Schedules the periodic signal-handler reapply during app creation (GTK4 path).
v3/pkg/application/linux_cgo.c Implements the periodic timer callback + scheduler (GTK4 path).
v3/pkg/application/linux_cgo_gtk3.go Adds equivalent periodic timer logic and schedules it once (GTK3 path).
v2/internal/frontend/desktop/linux/frontend.go Adds periodic timer scheduling after GTK init (v2 path).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread v3/pkg/application/linux_cgo.go Resolved
Comment thread v3/pkg/application/linux_cgo.c Resolved
Comment thread v3/pkg/application/linux_cgo_gtk3.go Resolved
…imer

Addresses code review feedback on #5507:

- Add SIGUSR1 to install_signal_handlers(): JSC uses SIGUSR1 for GC
  thread synchronisation and installs it without SA_ONSTACK (visible as
  "Overriding existing handler for signal 10" in stderr). The fix_signal
  helper only adds SA_ONSTACK to whatever handler is already registered,
  so this is safe for both Go's and JSC's handler.

- Hook WEBKIT_LOAD_FINISHED (v3 GTK4/GTK3) and DomReady (v2): by
  page-load completion JSC is guaranteed to have initialised and
  installed all its signal handlers. A targeted call to
  install_signal_handlers() here provides a deterministic, event-driven
  fix that complements the periodic timer.

- Anchor the GTK4 periodic timer to first WebView creation (sync.Once
  inside windowNewWebview) rather than appNew(), mirroring the GTK3
  pattern. This ensures the 5s coverage window starts when JSC can
  actually initialise, not before any WebView exists.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@v3/pkg/application/linux_cgo.go`:
- Around line 1196-1201: The GTK4 path currently only calls
C.schedule_signal_handler_fix() inside fixSignalHandlers.Do, leaving a 0–50ms
window; update the fixSignalHandlers.Do block to first call
C.install_signal_handlers() immediately (mirroring the GTK3 path) and then call
C.schedule_signal_handler_fix() so the handlers are installed once right away
before the periodic 50ms timer is armed; reference the existing
fixSignalHandlers.Do, C.install_signal_handlers, and
C.schedule_signal_handler_fix symbols when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6986ea11-ee10-4b99-8ca0-14c6e81e8d7f

📥 Commits

Reviewing files that changed from the base of the PR and between 1d7d141 and 7a3459d.

📒 Files selected for processing (4)
  • v2/internal/frontend/desktop/linux/frontend.go
  • v3/pkg/application/linux_cgo.c
  • v3/pkg/application/linux_cgo.go
  • v3/pkg/application/linux_cgo_gtk3.go

Comment thread v3/pkg/application/linux_cgo.go Resolved
@Adam-D-Lewis

Adam-D-Lewis commented May 26, 2026 •

Copy link
Copy Markdown

Verified this fixes a real-world Wails 2 app on Ubuntu 26.04 LTS + libwebkit2gtk-4.1-0 2.52.3-0ubuntu0.26.04.2.

Test app: nebari-dev/nebi at main (commit f024a78). Without this PR, nebi-desktop crashes within 1-2 seconds of startup with the canonical fatal:

Overriding existing handler for signal 10. Set JSC_SIGNAL_FOR_GC if you want WebKit to use a different signal
signal 11 received but handler not on signal stack
fatal error: non-Go code set up signal handler without SA_ONSTACK flag

Test method:

  • Fresh worktree of nebi at main
  • go get github.com/wailsapp/wails/v2@v2.12.0
  • replace github.com/wailsapp/wails/v2 => /local/checkout/of/this/PR/v2
  • No app-side workaround in place

With this PR applied: app runs cleanly, serves real HTTP traffic through the embedded asset server, exits cleanly on window close. Reproduced over multiple runs. Looking forward to the merge — would let us delete the workaround.

(Downstream tracking issue: nebari-dev/nebi#350.)

Adam-D-Lewis added a commit to nebari-dev/nebi that referenced this pull request May 26, 2026
…dler clobbering (#351)

* fix(desktop): re-apply SA_ONSTACK so WebKitGTK JSC doesn't crash Go runtime

Wails 2.11.0 installed SA_ONSTACK on signal handlers before gtk_init, which
let WebKit's later signal install (without SA_ONSTACK) clobber it. Bump to
Wails 2.12.0, which defers the fix to g_idle_add after gtk_init, AND add a
linux-only background ticker that re-applies SA_ONSTACK on SIGSEGV/SIGBUS/etc.
JavaScriptCore installs its GC/Wasm trap handlers lazily on first JS context
creation — which can land after the one-shot idle pass — so a periodic
re-fix is needed to be reliable on Ubuntu 24.04+ / libwebkit2gtk-4.1.

Verified: nebi-desktop now boots, serves the embedded API for 30+ seconds
of clicking around, and exits cleanly on window close.

* fix(desktop): document upstream removal condition and add SIGUSR1

Reference upstream Wails fix wailsapp/wails#5507 (closes wails#5506) so a
future maintainer knows this Go-side ticker can be deleted once the Wails
release containing that PR lands and we've bumped to it. Also add SIGUSR1
(JSC GC thread sync) to the fix list, matching the additional signal that
the upstream PR fixes.
@leaanthony
leaanthony merged commit 6329e9d into master May 27, 2026
14 of 16 checks passed
@leaanthony
leaanthony deleted the fix/linux-signal-handler-jsc-race branch May 27, 2026 13:24
leaanthony added a commit that referenced this pull request Jun 3, 2026
…ze (#5530)

WebKit's JavaScriptCore uses SIGUSR1 to suspend/resume threads for
conservative GC stack scanning. The signal-handler fix added in
alpha.97 (#5507) re-applied SA_ONSTACK to every signal it touched,
including SIGUSR1. Once JSC installs its own SIGUSR1 handler it owns the
signal (Go no longer handles it), so forcing SA_ONSTACK makes that
handler run on Go's alternate signal stack, breaking GC thread
synchronisation. This froze the WebKit UI during idle garbage
collection (most visibly with the inspector open) while the Go backend
kept running.

Remove fix_signal(SIGUSR1) from install_signal_handlers in v3 (GTK4 +
GTK3) and v2. The genuine #5506 fix for SIGSEGV/SIGBUS (which Go needs
SA_ONSTACK for) is unaffected.

Fixes #5527

https://claude.ai/code/session_01AtT1CjDNRArXv1eddXte2a

Co-authored-by: Claude <noreply@anthropic.com>
SivanCola added a commit to yuanchenglu/DeepSeek-Reasonix that referenced this pull request Jul 19, 2026
Problem:
Wails v2.12 repairs Linux signal handlers only once, before JavaScriptCore may lazily replace them, so affected WebKitGTK applications can still abort during startup.

Root cause:
JavaScriptCore installs handlers after the one-shot repair and can drop the SA_ONSTACK flag required by the Go runtime. Moving JSC GC to SIGUSR2 does not restore those flags and is not the upstream fix.

Fix:
Backport the final Wails v2.13 Linux strategy: reapply SA_ONSTACK every 50 ms for a bounded five-second startup window and once again at DomReady, while leaving SIGUSR1 under JavaScriptCore ownership. Keep Wails v2.12 and retain the NVIDIA DMA-BUF workaround. Non-Linux hooks are no-ops.

Upstream: wailsapp/wails#5507, wailsapp/wails#5530

Verification:
- go test ./... (desktop)
- go build ./... (desktop)
- go vet ./... (desktop)
- go test ./... (repository root)
- GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build ./... (desktop)
- GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build ./... (desktop)
- git diff --check
SivanCola added a commit to esengine/DeepSeek-Reasonix that referenced this pull request Jul 19, 2026
…WebKit 启动信号修复 (#6655)

* fix(desktop): add WebKit2GTK 2.50 SIGUSR1 signal workaround for Linux crash

WebKit2GTK 2.50.x changed internal GObject type registration in ways that
interact badly with the Go runtime's SIGUSR1 signal handler, causing a
SIGABRT inside webkit_user_content_manager_new() on certain Linux
distributions (Deepin 23, Arch). The crash produces no useful error
output — just a white window that exits with code 1.

Root cause: Go's runtime uses SIGUSR1 (signal 10) for thread management,
and JavaScriptCore also uses SIGUSR1 for conservative GC stack scanning.
When Go registers its handler first, WebKit's attempt to set its own is
overridden, corrupting the GObject type system during webview setup.

This commit adds two workarounds applied via package init() before Wails
initialises the webview:

1. JSC_SIGNAL_FOR_GC=12 — tells JavaScriptCore to use SIGUSR2 instead of
   SIGUSR1, eliminating the signal conflict at the source.

2. WEBKIT_DISABLE_DMABUF_RENDERER=1 on NVIDIA GPUs — the DMA-BUF
   compositing path in WebKit2GTK 2.50.x is unstable with NVIDIA's
   proprietary driver; disabling it falls back to the stable software
   OpenGL path.

Also bumps the Wails dependency from v2.12.0 to v2.13.0 for additional
Linux/WebKit compatibility fixes from the upstream.

Tested on: Deepin 23, WebKit2GTK 2.50.4, Go 1.26.5, NVIDIA GT 1030
(driver 580.119.02), X11 session.

Cache-impact: none
Cache-guard: none (desktop/init only, no prompt/tool prefix changes)
System-prompt-review: none

* fix(desktop): keep WebKit workaround Linux-only

Problem:
The PR coupled a Linux WebKit compatibility workaround to a cross-platform Wails v2.13.0 upgrade with placeholder checksums, and the new Linux file redeclared an existing NVIDIA helper.

Root cause:
The dependency bump expanded the change beyond the affected platform, while the compatibility file duplicated platform support already owned by nvidia_wayland_linux.go.

Fix:
Restore Wails v2.12.0 and its verified checksums, reuse the existing Linux NVIDIA detector, and format the compatibility file.

Verification:
- go mod tidy
- go build ./...
- go test ./...
- git diff --check

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>

* fix(desktop): backport Linux WebKit signal repair

Problem:
Wails v2.12 repairs Linux signal handlers only once, before JavaScriptCore may lazily replace them, so affected WebKitGTK applications can still abort during startup.

Root cause:
JavaScriptCore installs handlers after the one-shot repair and can drop the SA_ONSTACK flag required by the Go runtime. Moving JSC GC to SIGUSR2 does not restore those flags and is not the upstream fix.

Fix:
Backport the final Wails v2.13 Linux strategy: reapply SA_ONSTACK every 50 ms for a bounded five-second startup window and once again at DomReady, while leaving SIGUSR1 under JavaScriptCore ownership. Keep Wails v2.12 and retain the NVIDIA DMA-BUF workaround. Non-Linux hooks are no-ops.

Upstream: wailsapp/wails#5507, wailsapp/wails#5530

Verification:
- go test ./... (desktop)
- go build ./... (desktop)
- go vet ./... (desktop)
- go test ./... (repository root)
- GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build ./... (desktop)
- GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build ./... (desktop)
- git diff --check

* Scope Linux WebKit renderer fallback to safe mode

Problem:
All Linux NVIDIA launches inherited WEBKIT_DISABLE_DMABUF_RENDERER, disabling accelerated backing store, while the signal-repair comments implied coverage of failures before the GTK main loop.

Root cause:
The renderer fallback ran from package initialization without recovery gating. The backported GLib timer only dispatches after GTK enters its main loop.

Fix:
Apply the DMA-BUF fallback only to Safe Mode NVIDIA launches before Wails creates WebKit, preserve preconfigured environment values, keep other platforms as no-ops, and document the signal fix boundary. Add focused policy and platform tests.

Verification:
- cd desktop && go test ./...
- cd desktop && go vet ./...
- cd desktop && go build ./...
- cd desktop && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build ./...
- git diff --check

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>

---------

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>
izll pushed a commit to izll/agent-session-manager-desktop that referenced this pull request Aug 12, 2026
The app died within a second of launching on one machine, with

    non-Go code set up signal handler without SA_ONSTACK flag

and a locally built binary was blamed for it. It was not: a byte-identical
copy of the released 0.9.25 binary crashed the same way, 5 runs out of 5,
while the same file ran fine from another directory — so the difference was
never the build.

WebKit's JavaScriptCore installs its signal handlers lazily, when JavaScript
first runs, and registers them without SA_ONSTACK, overwriting Go's. Wails
2.11 applied its fix once at start-up, before any JS had executed, so JSC
wiped it moments later. Whether the crash happened was then a race, which is
what made it look like the binary's location mattered.

Wails 2.14.0 carries the upstream fix (wailsapp/wails#5507): it re-applies
the handlers every 50ms for five seconds, covering the whole JSC
initialisation window. Verified on the machine that crashed — 3 runs out of
3 start, then run for 12 seconds with 44 threads and 2 WebKit processes,
where the old build failed 5 out of 5 from the same directory.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
zuohuadong pushed a commit to zuohuadong/volt-gui that referenced this pull request Aug 30, 2026
…WebKit 启动信号修复 (#6655)

* fix(desktop): add WebKit2GTK 2.50 SIGUSR1 signal workaround for Linux crash

WebKit2GTK 2.50.x changed internal GObject type registration in ways that
interact badly with the Go runtime's SIGUSR1 signal handler, causing a
SIGABRT inside webkit_user_content_manager_new() on certain Linux
distributions (Deepin 23, Arch). The crash produces no useful error
output — just a white window that exits with code 1.

Root cause: Go's runtime uses SIGUSR1 (signal 10) for thread management,
and JavaScriptCore also uses SIGUSR1 for conservative GC stack scanning.
When Go registers its handler first, WebKit's attempt to set its own is
overridden, corrupting the GObject type system during webview setup.

This commit adds two workarounds applied via package init() before Wails
initialises the webview:

1. JSC_SIGNAL_FOR_GC=12 — tells JavaScriptCore to use SIGUSR2 instead of
   SIGUSR1, eliminating the signal conflict at the source.

2. WEBKIT_DISABLE_DMABUF_RENDERER=1 on NVIDIA GPUs — the DMA-BUF
   compositing path in WebKit2GTK 2.50.x is unstable with NVIDIA's
   proprietary driver; disabling it falls back to the stable software
   OpenGL path.

Also bumps the Wails dependency from v2.12.0 to v2.13.0 for additional
Linux/WebKit compatibility fixes from the upstream.

Tested on: Deepin 23, WebKit2GTK 2.50.4, Go 1.26.5, NVIDIA GT 1030
(driver 580.119.02), X11 session.

Cache-impact: none
Cache-guard: none (desktop/init only, no prompt/tool prefix changes)
System-prompt-review: none

* fix(desktop): keep WebKit workaround Linux-only

Problem:
The PR coupled a Linux WebKit compatibility workaround to a cross-platform Wails v2.13.0 upgrade with placeholder checksums, and the new Linux file redeclared an existing NVIDIA helper.

Root cause:
The dependency bump expanded the change beyond the affected platform, while the compatibility file duplicated platform support already owned by nvidia_wayland_linux.go.

Fix:
Restore Wails v2.12.0 and its verified checksums, reuse the existing Linux NVIDIA detector, and format the compatibility file.

Verification:
- go mod tidy
- go build ./...
- go test ./...
- git diff --check

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>

* fix(desktop): backport Linux WebKit signal repair

Problem:
Wails v2.12 repairs Linux signal handlers only once, before JavaScriptCore may lazily replace them, so affected WebKitGTK applications can still abort during startup.

Root cause:
JavaScriptCore installs handlers after the one-shot repair and can drop the SA_ONSTACK flag required by the Go runtime. Moving JSC GC to SIGUSR2 does not restore those flags and is not the upstream fix.

Fix:
Backport the final Wails v2.13 Linux strategy: reapply SA_ONSTACK every 50 ms for a bounded five-second startup window and once again at DomReady, while leaving SIGUSR1 under JavaScriptCore ownership. Keep Wails v2.12 and retain the NVIDIA DMA-BUF workaround. Non-Linux hooks are no-ops.

Upstream: wailsapp/wails#5507, wailsapp/wails#5530

Verification:
- go test ./... (desktop)
- go build ./... (desktop)
- go vet ./... (desktop)
- go test ./... (repository root)
- GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build ./... (desktop)
- GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build ./... (desktop)
- git diff --check

* Scope Linux WebKit renderer fallback to safe mode

Problem:
All Linux NVIDIA launches inherited WEBKIT_DISABLE_DMABUF_RENDERER, disabling accelerated backing store, while the signal-repair comments implied coverage of failures before the GTK main loop.

Root cause:
The renderer fallback ran from package initialization without recovery gating. The backported GLib timer only dispatches after GTK enters its main loop.

Fix:
Apply the DMA-BUF fallback only to Safe Mode NVIDIA launches before Wails creates WebKit, preserve preconfigured environment values, keep other platforms as no-ops, and document the signal fix boundary. Add focused policy and platform tests.

Verification:
- cd desktop && go test ./...
- cd desktop && go vet ./...
- cd desktop && go build ./...
- cd desktop && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build ./...
- git diff --check

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>

---------

Co-authored-by: SivanCola <32437197+SivanCola@users.noreply.github.com>
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.

Linux: SA_ONSTACK lost on some Wails 2.12 apps; one-shot g_idle_add mitigation doesn't catch every case

3 participants