Repository navigation
feat: dxr::CursorDepth — app-side helper for the runtime-drawn depth cursor (ADR-046 Amendment 2) - #75
Merged
Conversation
…cursor (ADR-046 Amendment 2) XR_DXR_cursor_depth v5 lets the runtime draw the depth cursor; the app only owns the depth under the pointer. common/cursor_depth.h does the rest of the per-frame bookkeeping every app would otherwise re-type: - pointer -> canvas UV (window adapters: Win32 HWND, Cocoa NSView*, Xlib Display*/Window; a manual setPointerUV() + onDepthCursorShownChanged() path for Wayland / Android / displayxr::linux_window / anything else); - the cursor FOOTPRINT (tip + ring around the arrow body, the same rule as the runtime and the web SDK's cursorArrowFootprint) as rays from the two outer views of the PREVIOUS locate; setRayCast() reduces "ray -> first hit" to the hint's nearest point, setHitTest() gives full control, useDepthLayer() hands it to the runtime (spec v2); - chaining hint [-> drawInfo] [-> options] [-> source] on XrViewLocateInfo and drawState [-> placement] on XrViewState, gated per spec version; - hiding the OS cursor exactly while willDraw (or, in DrawMode::App, while the placement is active), never on a runtime that cannot draw. Zero cost when not enabled: enable(0) leaves both chains untouched and the OS cursor alone; enabled, a frame allocates nothing. No graphics-API code. The core is header-only and platform-neutral, so it is part of displayxr::rules (Android legs can use it). Tests (tests/cursor_depth_test.cpp): canvas UV, footprint vs the web rule, footprint rays against a Kooima pair under a camera-rig transform, nearest hit, chain order per spec version, show/hide transitions; all 9 mutants of the core are killed. The X11 adapter gets a compile + Xvfb smoke target on the Linux CI legs. The standalone extension-header pin moves to displayxr-extensions@af2de88 (XR_DXR_cursor_depth SPEC_VERSION 5). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dfattal
force-pushed
the
feat/cursor-depth-helper
branch
from
October 11, 2026 09:06
b627517 to
4ff0525
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
common/cursor_depth.h:dxr::CursorDepth, the app-side helper for the depth-aware cursor (XR_DXR_cursor_depthv5, ADR-046 Amendment 2 §B: the runtime draws, the app chooses the look). The runtime-side contract is merged on displayxr-runtimemain(#1941). With this helper, a native OpenXR app adopts the runtime-drawn cursor in about 10 lines. The app writes only "ray → first hit".Adoption
enable(0)(or never calling it) leaves both struct chains untouched and never touches the OS cursor. When enabled, a frame allocates nothing.setRayCast: footprint rays from the two outer views of the previous locate; the hit nearest the viewer is kept.setHitTest: full control, with the rays already built.useDepthLayer(true)(spec v2): the runtime reads the submitted depth.cursorArrowFootprint): the tip, plus a ring around the arrow body. A custom sprite's footprint follows its hotspot and aspect.dxr::cursorFootprintRays()is public for apps that do their own chaining.XrViewLocateInfo: hint → [drawInfo v5] → [options v3] → [source v2] → the app's previous chain;XrViewState: drawState → [placement] → previous.willDraw. On a pre-v5 runtime it is never hidden.DrawMode::Appkeeps v1–v4 app-drawn placement working (placement(),appShouldDraw()).displayxr::rules(Android).HWNDcursor_depth_win32.cppWM_SETCURSOR/HTCLIENT→SetCursor(NULL)via a chained wndproc (installable from the render thread), client area onlyNSView*cursor_depth_macos.mmNSCursor hide/unhide, on the main thread(Display*, Window)cursor_depth_x11.h(the app links libX11; this lib does not)displayxr::linux_window/ anything elsesetPointerUV()/clearPointerUV()+onDepthCursorShownChanged(cb)win.set_cursor(shown ? DxrCursor::Hidden : DxrCursor::Default)Other changes:
displayxr-extensions@af2de88(XR_DXR_cursor_depthSPEC_VERSION 5).Evidence
tests/cursor_depth_test.cpp(newdisplayxr_cursor_depth_test) passes on macOS, and all 6 ctest targets pass locally. It covers:willDrawguard, the disabled guard, the fov→ray v-axis, and two spec-version gates). The test killed all 9.cursor_depth_win32.cppcompiles clean with MinGW-w64-Wall -Wextra. The header and.mmare clean under clang-Wall -Wextra.cube_handle_metal_macosis ported onto this branch: test_apps(cube_handle_metal_macos): adopt the depth cursor through dxr::CursorDepth (needs displayxr-common tag) displayxr-runtime#1943 (draft). I built it against this branch viaFETCHCONTENT_SOURCE_DIR_DISPLAYXR_COMMON, ran it headless (SIM_DISPLAY_OUTPUT=sbs DISPLAYXR_CURSOR_DEPTH_UV=…) and read the atlas captures:main's hand-written code measured the same on the same box (−21 / −24 px, −0.066).DISPLAYXR_CURSOR_DEPTH_DRAW=appcrosshair and theDISPLAYXR_CURSOR_DEPTH_SPRITE=customring both render.DISPLAYXR_CURSOR_DEPTH=0nothing is drawn.Not tested
willDraw = FALSEtoday anyway.setPointerUV(). I did not exercise real mouse movement withNSCursorhide/unhide on a panel.🤖 Generated with Claude Code