Repository navigation
feat(d3d11): the window handle follows the majority segment (multi-screen M6, ADR-047 Amendment 2) — stacked on #1878 - #1880
Merged
Conversation
… Amendment 2) comp_segments_majority (the oxr_segment_views_majority rule over a segment table) and comp_segments_owner_*: which screen's DP holds the window handle. A hand-off is due only when another screen holds the majority, beats the owner by >= 20 % of the on-screen area (a 60/40 dead band between two screens) and has done so continuously for 0.5 s; a failed target is not retried until the majority leaves it; a screen without a DP factory is never a target. Pure and host-tested: dead band, hold, dip-restarts-the-clock, a drag swept across the seam never flaps, hand-back, failure latch, no-owner recovery. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reen M6, ADR-047 Amendment 2) The segment DP of the screen holding the majority of a straddling window now owns the real HWND (the vendor's drag phase-snap, KEEP_DRAG_SNAP on Leia); every other DP is windowless and phased by set_present_origin. Before, the HWND stayed with the primary screen's DP. A weaver is one per HWND and a live DP's window is never re-pointed, so a hand-off (between two weaves, under c->mutex) makes a windowless replacement for the old owner first (abort if that fails), swaps it in and destroys the old owner's DP, then makes the new owner's DP with the HWND through create_dp_d3d11_for_screen, rolling back to the old owner on failure. A frame weaves with the old pair or the new pair, never with a gap. The primary screen keeps a DP as the session's own: the compositor swaps display_processor through a swap_primary hook that re-sends transparency, 2D/3D mode, eye-tracking mode and this weave's timing/backdrop, and guards the exchange against its unlocked app-thread readers with a leaf dp_swap_mutex. A bracket hook detaches the own window's snap provider across the hand-off and re-arms it on the DP that now holds the window. A windowless primary gets its present origin on the split path, which stays engaged until the hand-back. Lifecycle retires never touch the owner's DP. One WARN per flip. Sessions without a real window (shared texture) keep the old rule; a single screen, or a window that never leaves the primary, is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…endment 2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dfattal
force-pushed
the
feat/win-segments-hwnd-majority
branch
from
October 9, 2026 09:41
26caa4d to
66eaef0
Compare
dfattal
added a commit
that referenced
this pull request
Oct 9, 2026
Amendment 2 is the window handle following the majority segment (#1880), which lands first; the service / IPC path becomes Amendment 3 everywhere this branch names it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
dfattal
added a commit
that referenced
this pull request
Oct 9, 2026
Amendment 2 is the window handle following the majority segment (#1880), which lands first; the service / IPC path becomes Amendment 3 everywhere this branch names it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
dfattal
added a commit
that referenced
this pull request
Oct 9, 2026
Amendment 2 is the window handle following the majority segment (#1880), which lands first; the service / IPC path becomes Amendment 3 everywhere this branch names it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Stacked on #1878. Merge #1878 first, then this. The base is
mainso the PR lands there, which means the diff below also shows #1878's three commits until #1878 merges. The commits that belong to this PR are the top three.What
This is the follow-up to David's 2026-10-07 call ("HWND stays with the primary DP for now, majority hand-off = follow-up"), and it ships ADR-047 Decision 2's "the real HWND goes to the majority-area segment's DP" on Windows D3D11. When most of a straddling window sits on another screen, that screen's segment DP gets the real HWND, so the vendor's drag phase-snap (
KEEP_DRAG_SNAPon Leia) and the window anchor follow it. The former owner becomes windowless and gets its phase fromset_present_origin.Design
Majority rule: the segment with the largest window-px area. On an exact tie the primary wins, otherwise the leftmost. This is the same rule as
oxr_segment_views_majority, now also available ascomp_segments_majority.Hysteresis (
comp_segments_owner_*, pure, unit-tested): a hand-off is due only when the challenger beats the current owner by ≥ 20 % of the window's on-screen area, which is a 60/40 dead band between two screens, continuously for 0.5 s. A dip back into the dead band restarts the clock. A target whose hand-off failed is not retried until the majority leaves it. A screen with no DP factory is never a target.Swap sequence (one weaver per HWND, and a live DP's window is never re-pointed). It runs on the weave thread under
c->mutex, between two weaves:create_dp_d3d11_for_screenand swap it in. If that fails, roll back so the old owner takes the HWND again.Each frame weaves with either the old pair or the new pair, never with a gap.
The primary screen always keeps a DP, because it is the session's own DP (eyes, mode, background, timing). The compositor swaps
display_processorthrough aswap_primaryhook:dp_swap_mutex.brackethook detaches the own window's snap provider across the hand-off and re-arms it on the DP that now holds the HWND.While the primary DP is windowless, the split path stays engaged, even if the window is back on the primary alone, until the hand-back. That way the primary DP keeps getting its present origin. Lifecycle retires never destroy the owner's DP.
Unchanged:
Logs:
segments: window handle handed from '<dev>' to '<dev>' (screen 0x… holds the majority) in N ms …, or… hand-off to '<dev>' FAILED after N ms — rolled back ….the window handle follows the majority screen(or says why it stays).Tests
scripts\build_windows.bat buildexited 0.ctest -R "tests_comp_segments|tests_oxr_segment_views"exited 0, 2/2 passed.tests_comp_segmentsadds two cases: the majority rule, and the owner hysteresis (11 sections).ctestrun has 100/103 passing. The 3 failures are the knowntests_oxr_view_space_mode_*cases, which need a DP with more than 2 views and fail on this box with or without this change.Rig check (two Leia panels: laptop 0x1 at (0,0), DS1 0x2 at (3840,0))
cube_handle_d3d11_win(or a hosted app) on the laptop panel. Confirm the service/app log hassegments: 2 screens … the window handle follows the majority screen.segments: window handle handed from '\\.\DISPLAY1' to '\\.\DISPLAY2' …WARN. Both halves keep weaving with no black frame. Drag snap now acts on the DS1 lattice: release mid-drag and the window lands phase-aligned for the DS1.… handed from '\\.\DISPLAY2' to '\\.\DISPLAY1' …WARN, and the laptop half is phase-correct before and after.DXR_SEGMENTS=0, expect no segmentation and no hand-off lines.Plug-in
No plug-in change is needed. The Leia
leiasr_d3d11_create_for_screenalready takes the HWND (EXTERNAL + KEEP_DRAG_SNAP) or NULL (EXTERNAL plus per-frameset_present_origin), andxrt_plugin.halready documented "the real HWND for the DP of the screen that holds the MAJORITY". One thing for the rig run to confirm: the primary screen's DP is now re-created throughcreate_dp_d3d11_for_screen(windowless, and later with the HWND on hand-back) instead of the session-startcreate_dp_d3d11. On Leia it should be the same weaver config, bound to the primary display.🤖 Generated with Claude Code