Skip to content

fix(macos): opt out of Writing Tools to prevent Campo crash (#355) - #406

Merged
simion merged 1 commit into
simion:mainfrom
nvkvin:feature/crash-debug
Oct 14, 2026
Merged

simion merged 1 commit into
simion:mainfrom
nvkvin:feature/crash-debug

Conversation

@nvkvin

@nvkvin nvkvin commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Summary

On macOS 15.1+ (Sequoia / Tahoe 26+), AppKit's CampoLightweightUI subsystem detects mouse dwelling over text selections to show floating Apple Intelligence Writing Tools affordances.
When inspecting or attaching to WKWebView text selections, an internal AppKit assertion fails (*** Assertion failure in <private>, NSCampoLightweightUIController.m:1429), throwing an NSInternalInconsistencyException inside Cocoa's event loop (-[NSApplication sendEvent:]).
Because Tauri's tao hooks sendEvent: via an extern "C" Rust callback without unwinding support, the uncaught exception hitting the FFI boundary causes Rust's runtime to trigger panic_cannot_unwind, terminating the process with SIGABRT ("Abort trap: 6").

This PR opts out of Writing Tools on macOS by setting writingToolsBehavior = -1 (NSWritingToolsBehaviorNone) on WKWebViewConfiguration before the webviews are initialized.

Changes

  • Configured WKWebViewConfiguration with setWritingToolsBehavior: -1 via without_writing_tools in src-tauri/src/lib.rs for both profile windows and the activity monitor window.
  • Wrapped with #[cfg(target_os = "macos")] and added a compile-time no-op pass-through for #[cfg(not(target_os = "macos"))], ensuring zero impact on Windows and Linux builds.
  • Added macOS-only dependency objc2-web-kit with the WKWebViewConfiguration feature in src-tauri/Cargo.toml.
  • Added unit test test_writing_tools_behavior_opt_out asserting writingToolsBehavior is set to -1 on supported macOS runtimes.

Verification

  • Manual testing: Exercised by hand on macOS 27.0.1 (26A434).
    Focused input fields and selected text, then repeatedly switched back and forth across applications with Cmd+Tab while resting the cursor over the text.
    Confirmed that Termic remains fully stable without crashes, dwelling triggers no Campo assertion failures, and right-clicking selected text cleanly omits Writing Tools affordances.
  • cargo test --workspace --lib: 1,354 lib tests, 85 cli tests, and 21 proto tests passed.
  • npm test: All 206 test files and 3,281 tests passed.
  • npm run build: Passed cleanly with zero TypeScript or Vite bundle errors.

Closes #355

On macOS 15.1+ (Sequoia / Tahoe 26+), AppKit's CampoLightweightUI
subsystem attempts to show floating Writing Tools affordances when
the mouse dwells over text. In WKWebView text selections, an internal
AppKit assertion fails (NSCampoLightweightUIController.m:1429), throwing
an NSInternalInconsistencyException across tao's send_event FFI
boundary, which std aborts (SIGABRT).

Setting writingToolsBehavior = -1 (NSWritingToolsBehaviorNone) on
WKWebViewConfiguration before initialization opts out of Writing Tools
and eliminates the crash. On Windows and Linux, without_writing_tools is
a compile-time no-op.

Closes simion#355

@simion simion left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for tracking this down, good catch on the per-window Writing Tools disable.

@simion
simion merged commit 79b9503 into simion:main Oct 14, 2026
4 of 7 checks passed
@simion

simion commented Oct 14, 2026

Copy link
Copy Markdown
Owner

Nit: NSWritingToolsBehaviorNone is used as a raw -1 literal in two places, a named constant would read better.

@simion

simion commented Oct 14, 2026

Copy link
Copy Markdown
Owner

— Simion's agent here, he'll take a look at this shortly.

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.

Bug: App aborts (SIGABRT) when switching back with Cmd+Tab right after typing in an input

2 participants