Skip to content

fix: engine_render_gated in built manifests (#322) + WSUI panel aspect from the workspace tile (#323) - #324

Merged
dfattal merged 2 commits into
mainfrom
fix/shell-sidecar-flag-and-wsui-tile-aspect
Sep 14, 2026
Merged

dfattal merged 2 commits into
mainfrom
fix/shell-sidecar-flag-and-wsui-tile-aspect

Conversation

@dfattal

@dfattal dfattal commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Two independent shell-mode fixes, one commit each. Both were observed on the live panel on 2026-09-13 against plug-in v2.19.1, runtime v2.16.31, shell 2.2.0.

#322 — every dev build launched by the shell rendered a black tile

The shell launches a 3D app SW_HIDE unless the app's manifest declares that its engine gates rendering on a shown window. Unity does gate on it, so a hidden player submits black eye slices while the provider's own trace looks perfect. Only the displayxr-unity-samples NSIS installer added the key by hand, which is why an installed sample worked and a fresh build of the same scene did not.

BuildManifestJson serves both bodies — the sidecar next to the exe (CLI launch path) and the registered manifest under %LOCALAPPDATA% (launcher path) — so the flag is emitted there, immediately after "type", unconditionally. The processor only ever writes manifests for Unity players, and the key is harmless on the launcher path. No other field, value or ordering changes.

Changed: Editor/DisplayXRBuildProcessor.cs (one field), CHANGELOG.md.

#323 — WindowSpaceUI overlay stretched with the workspace tile

Under the shell Unity's main window is launched minimized and never follows the tile, so Screen.width/height stay frozen at the launch size. The eye swapchain does follow the tile (the provider re-polls the tile canvas every reconcile), but TryGetPanelPixelSize read Screen.*, so the overlay RT was never re-created and the runtime's stretch into the fractional panel rect stopped being the identity — a narrow tile squeezed the UI horizontally.

  • New export displayxr_get_render_canvas_size(w, h): returns 1 plus the live workspace-tile canvas when dxr_prov_workspace_tile_size has one, 0 otherwise. It lives in displayxr_native_shared.cpp, which every platform compiles, and reads only the provider's cached pixel counts — no Win32 geometry call, so nothing crosses a DPI space, and no new platform ifdef. On macOS and Linux the tile size is never polled, so it returns 0 and behaviour there is byte-identical.
  • C# prefers it when shell mode is on and it answers non-zero, and falls back to Screen.* otherwise. The existing kResizeSettleSeconds debounce then absorbs tile drag-resizes exactly as it absorbs window resizes today.
  • One log line, emitted only when the source switches (TryGetPanelPixelSize runs twice a frame, so this must never be per-frame): "[DisplayXR] wsui: panel size source = workspace tile (777x875)".
  • Shell mode and a missing entry point are both latched, so the steady state adds no per-frame P/Invoke.

Changed: native~/displayxr_native_shared.cpp, native~/displayxr_exports.h, Runtime/DisplayXRNative.cs, Runtime/DisplayXRWindowSpaceUI.cs, the rebuilt Windows DLL, CHANGELOG.md.

Verification

  • native~\build-win.bat succeeded, no new warnings. Runtime/Plugins/Windows/x64/displayxr_unity.dll — SHA256 a48552cef0a89765a3cfc1e3521399e8812725d3953304649ac2afa297322a45, 207,872 bytes; the new export string is present in the image.
  • Both samples/urp-singlepass-ui and samples/birp-multipass were rebuilt from displayxr-unity-samples against this working tree (local file: override, not committed there). Both players' sidecars now carry "engine_render_gated": true, and both players ship this exact DLL.
  • Hardware verification of the two visual symptoms (black tile, squeezed overlay) is with the author on the Leia SR panel; do not merge before that lands.

Fixes #322
Fixes #323

🤖 Generated with Claude Code

https://claude.ai/code/session_012co2j1fdmZ2AdEAp4Y3xpp

dfattal and others added 2 commits September 14, 2026 00:00
…t bodies (#322)

The shell launches a 3D app SW_HIDE unless its manifest declares that the
engine gates rendering on a shown window. Unity does gate on it, so every
player built by this processor came up as a black tile under the shell: the
provider acquires, releases and xrEndFrames the swapchain perfectly while the
eye slices stay black. Only the displayxr-unity-samples NSIS installer added
the key by hand, which is why an installed sample worked and a fresh build of
the same scene did not.

BuildManifestJson serves both bodies (the <exe>.displayxr.json sidecar that
feeds the CLI launch path, and the registered %LOCALAPPDATA% manifest that
feeds the launcher path), so emit the flag there, right after "type". It is
unconditional: the processor only ever writes manifests for Unity players,
and the flag is harmless on the launcher path. No other field or ordering
changes.

Fixes #322

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012co2j1fdmZ2AdEAp4Y3xpp
…shell (#323)

Under the shell Unity's main window is launched minimized and never follows
the workspace tile, so Screen.width/height stay frozen at the launch size.
The eye swapchain still tracks the tile (the provider re-polls the tile canvas
every reconcile), but TryGetPanelPixelSize read Screen.*, so the overlay RT was
never re-created and the runtime's stretch into the fractional panel rect
stopped being the identity: a narrow tile squeezed the UI horizontally.

Expose the size the provider already knows as displayxr_get_render_canvas_size
- it returns 1 plus the live workspace-tile canvas when dxr_prov_workspace_tile_size
has one, 0 otherwise. It lives in displayxr_native_shared.cpp, which every
platform compiles, and reads only the provider's cached pixel counts: no Win32
geometry, so nothing crosses a DPI space, and no new platform ifdef. On macOS and
Linux the tile size is never polled, so it returns 0 and the caller is unchanged.

C# prefers it when shell mode is on and it answers non-zero, and falls back to
Screen.* otherwise; the existing kResizeSettleSeconds debounce then absorbs tile
drag-resizes exactly as it absorbs window resizes. One log line records which
source is live, emitted only when it switches (TryGetPanelPixelSize runs twice
a frame). Shell mode and a missing entry point are both latched, so neither
adds a per-frame P/Invoke.

Fixes #323

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012co2j1fdmZ2AdEAp4Y3xpp
@dfattal
dfattal merged commit 10afbe3 into main Sep 14, 2026
8 checks passed
@dfattal
dfattal deleted the fix/shell-sidecar-flag-and-wsui-tile-aspect branch September 14, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant