Skip to content

feat(napi): XamlWindow (XAML Islands) and agile JS delegates - #38

Merged
triniwiz merged 2 commits into
mainfrom
feat/napi-xaml-islands
Nov 6, 2026
Merged

triniwiz merged 2 commits into
mainfrom
feat/napi-xaml-islands

Conversation

@triniwiz

@triniwiz triniwiz commented Nov 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Agile JS delegates. Event sources that only accept agile handlers, such as DispatcherQueueTimer.Tick, rejected JS functions with "The object must support the IAgileObject interface". Both delegate implementations (classic and napi) already run off-thread invokes on the owner JS thread, so QueryInterface now answers IAgileObject.
  • XamlWindow in @nativescript/windows-napi. Hosts Windows.UI.Xaml content (XAML Islands) in a Win32 window:
    • style: 'dialog' (title bar, close box, optional owner) or 'popup' (borderless, not in the taskbar or Alt+Tab), plus topmost and theme.
    • PreTranslateMessage runs from a WH_GETMESSAGE hook, so Tab and access keys work no matter who owns the message loop.
    • DPI-aware place(): centers over a window, or on the pointer's monitor.
    • activate / deactivate / close / closed events are queued on the dispatcher, so JS never runs inside the window procedure.
    • Helpers: foregroundWindow, activateWindow, enableWindow, windowProcessId. Window handles come in as numbers, bigints or Buffers. They are window handles, not memory pointers: user32 validates them.
  • XAML Islands need maxversiontested 10.0.18362 or later in the host executable's manifest. electron.exe has it; node.exe doesn't, so XamlWindow throws a clear error there.

Testing

  • npm test in windows-napi: 442 passed, 0 failed across 23 suites, including the new xaml-host-test.js. Under node.exe the new suite only checks the error path.
  • ELECTRON_RUN_AS_NODE=1 electron.exe test/xaml-host-test.js (Electron 45.2.3): 14 passed. This covers create, content, place, show/hide, events and close.
  • cargo check -p runtime (classic) passes.
  • Ran two demo apps in Electron 45 on Windows 11 by driving them with real input:
    • Modal error dialog: owned by a BrowserWindow, with a scrollable stack trace, Copy, Tab/Esc/Alt+F4, and a clean exit when the owner closes.
    • Borderless input panel: opened by a global shortcut, it hands the foreground back to the previous app on Enter/Esc and dismisses itself on deactivate.

Event sources that only accept agile handlers, such as
DispatcherQueueTimer.Tick, rejected JS functions with
"The object must support the IAgileObject interface". Both delegate
implementations already run off-thread invokes on the owner JS thread,
so they now say so in QueryInterface (classic and napi).

The IAgileObject IID moves to value.rs and is shared.
Adds XAML Islands hosting to @nativescript/windows-napi:

- xaml_host.rs: a host window ('dialog' or borderless 'popup'),
  DesktopWindowXamlSource attach, PreTranslateMessage from a
  WH_GETMESSAGE hook so Tab and access keys work whoever owns the
  message loop, DPI-aware placement, and activate / deactivate /
  close / closed events queued on the dispatcher so JS never runs
  inside the window procedure.
- Helpers: foregroundWindow, activateWindow, enableWindow,
  windowProcessId. Window handles are accepted as numbers, bigints or
  Buffers (as returned by getNativeWindowHandle()).
- nswinrt.js: XamlWindow class (theme detection, events, a clear error
  when the host manifest lacks maxversiontested).
- test/xaml-host-test.js; README section.
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 65c13ebb-698b-46eb-95ff-6ef4c0ae69ad

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
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@triniwiz
triniwiz merged commit a4ba191 into main Nov 6, 2026
3 checks passed
@triniwiz
triniwiz deleted the feat/napi-xaml-islands branch November 6, 2026 02:24
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.

1 participant