Repository navigation
Conversation
MrBeldum
added a commit
that referenced
this pull request
Oct 18, 2026
…icture Work from 2026-10-03, not yet tried on Windows hardware (Hermes offline). - With capture on automatic, Latch prefers the Virtual Display Driver even while a physical monitor is connected; the engine restores the physical displays when the stream disconnects. - A windowless user task (LatchCursorUser) keeps a custom game cursor's whole shape inside the streamed display (crates/host/src/cursor.rs), so a cursor with a transparent top-left hotspot no longer disappears off the bottom or right edge; it follows resolution and shape changes, respects the game's own confinement and lets go when the game hides its cursor. - Mac bundle staged in dist.noindex, release workflow to match. Rebased onto PR #26 (fix/vps-stream-clipboard). Both changed how the stream profile is kept, and neither side's version could simply win: #26's one-time marker (now stream-profile-v4) would never run the virtual display choice on a host that already has it, and #27's reconcile every 30 s re-wrote all of the engine conf, so settings an owner picked in the engine's own page (nvenc_twopass, minimum_fps_target, the display option) were put back and the engine restarted, and on Linux #26's engine conf would have been enforced the same way. Now: - The full engine conf stays a versioned one-time migration, exactly as #26 has it, on every platform. - On Windows only, once that is in place, the service keeps just the capture display current every 30 s (virtual_display::capture/follow): output_name and dd_configuration_option, nothing else, and it logs which keys it changed whenever it restarts the engine. - The display ID Latch set is remembered (capture-display in the data directory), so a driver that comes back under a new ID after a reinstall still counts as automatic and capture follows it, instead of staying pointed at a display that no longer exists. When the owner picks another display, the display option Latch set goes back. - A PC that never had the driver is not asked anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrBeldum
force-pushed
the
feat/windows-cursor-in-picture
branch
from
October 18, 2026 00:45
ff41047 to
d308f7e
Compare
Owner
Author
|
Restacked on #28 (the audit fixes, itself on #26) and reworked after review:
Still untested on Windows hardware: the cursor guard and VDD follow. CI compiles and tests the pure parts. 🤖 Generated with Claude Code |
MrBeldum
added a commit
that referenced
this pull request
Oct 18, 2026
…icture Work from 2026-10-03, not yet tried on Windows hardware (Hermes offline). - With capture on automatic, Latch prefers the Virtual Display Driver even while a physical monitor is connected; the engine restores the physical displays when the stream disconnects. - A windowless user task (LatchCursorUser) keeps a custom game cursor's whole shape inside the streamed display (crates/host/src/cursor.rs), so a cursor with a transparent top-left hotspot no longer disappears off the bottom or right edge; it follows resolution and shape changes, respects the game's own confinement and lets go when the game hides its cursor. - Mac bundle staged in dist.noindex, release workflow to match. Rebased onto PR #26 (fix/vps-stream-clipboard). Both changed how the stream profile is kept, and neither side's version could simply win: #26's one-time marker (now stream-profile-v4) would never run the virtual display choice on a host that already has it, and #27's reconcile every 30 s re-wrote all of the engine conf, so settings an owner picked in the engine's own page (nvenc_twopass, minimum_fps_target, the display option) were put back and the engine restarted, and on Linux #26's engine conf would have been enforced the same way. Now: - The full engine conf stays a versioned one-time migration, exactly as #26 has it, on every platform. - On Windows only, once that is in place, the service keeps just the capture display current every 30 s (virtual_display::capture/follow): output_name and dd_configuration_option, nothing else, and it logs which keys it changed whenever it restarts the engine. - The display ID Latch set is remembered (capture-display in the data directory), so a driver that comes back under a new ID after a reinstall still counts as automatic and capture follows it, instead of staying pointed at a display that no longer exists. When the owner picks another display, the display option Latch set goes back. - A PC that never had the driver is not asked anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrBeldum
force-pushed
the
feat/windows-cursor-in-picture
branch
from
October 18, 2026 00:52
d308f7e to
52d301d
Compare
MrBeldum
added a commit
that referenced
this pull request
Oct 18, 2026
…icture Work from 2026-10-03, not yet tried on Windows hardware (Hermes offline). - With capture on automatic, Latch prefers the Virtual Display Driver even while a physical monitor is connected; the engine restores the physical displays when the stream disconnects. - A windowless user task (LatchCursorUser) keeps a custom game cursor's whole shape inside the streamed display (crates/host/src/cursor.rs), so a cursor with a transparent top-left hotspot no longer disappears off the bottom or right edge; it follows resolution and shape changes, respects the game's own confinement and lets go when the game hides its cursor. - Mac bundle staged in dist.noindex, release workflow to match. Rebased onto PR #26 (fix/vps-stream-clipboard). Both changed how the stream profile is kept, and neither side's version could simply win: #26's one-time marker (now stream-profile-v4) would never run the virtual display choice on a host that already has it, and #27's reconcile every 30 s re-wrote all of the engine conf, so settings an owner picked in the engine's own page (nvenc_twopass, minimum_fps_target, the display option) were put back and the engine restarted, and on Linux #26's engine conf would have been enforced the same way. Now: - The full engine conf stays a versioned one-time migration, exactly as #26 has it, on every platform. - On Windows only, once that is in place, the service keeps just the capture display current every 30 s (virtual_display::capture/follow): output_name and dd_configuration_option, nothing else, and it logs which keys it changed whenever it restarts the engine. - The display ID Latch set is remembered (capture-display in the data directory), so a driver that comes back under a new ID after a reinstall still counts as automatic and capture follows it, instead of staying pointed at a display that no longer exists. When the owner picks another display, the display option Latch set goes back. - A PC that never had the driver is not asked anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrBeldum
force-pushed
the
feat/windows-cursor-in-picture
branch
from
October 18, 2026 01:10
52d301d to
79ed8a1
Compare
…icture Work from 2026-10-03, not yet tried on Windows hardware (Hermes offline). - With capture on automatic, Latch prefers the Virtual Display Driver even while a physical monitor is connected; the engine restores the physical displays when the stream disconnects. - A windowless user task (LatchCursorUser) keeps a custom game cursor's whole shape inside the streamed display (crates/host/src/cursor.rs), so a cursor with a transparent top-left hotspot no longer disappears off the bottom or right edge; it follows resolution and shape changes, respects the game's own confinement and lets go when the game hides its cursor. - Mac bundle staged in dist.noindex, release workflow to match. Rebased onto PR #26 (fix/vps-stream-clipboard). Both changed how the stream profile is kept, and neither side's version could simply win: #26's one-time marker (now stream-profile-v4) would never run the virtual display choice on a host that already has it, and #27's reconcile every 30 s re-wrote all of the engine conf, so settings an owner picked in the engine's own page (nvenc_twopass, minimum_fps_target, the display option) were put back and the engine restarted, and on Linux #26's engine conf would have been enforced the same way. Now: - The full engine conf stays a versioned one-time migration, exactly as #26 has it, on every platform. - On Windows only, once that is in place, the service keeps just the capture display current every 30 s (virtual_display::capture/follow): output_name and dd_configuration_option, nothing else, and it logs which keys it changed whenever it restarts the engine. - The display ID Latch set is remembered (capture-display in the data directory), so a driver that comes back under a new ID after a reinstall still counts as automatic and capture follows it, instead of staying pointed at a display that no longer exists. When the owner picks another display, the display option Latch set goes back. - A PC that never had the driver is not asked anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…viewer watches The guard confined every custom cursor by its whole bitmap. A 32x32 or 64x64 game cursor with its tip at the hotspot (most RTS and MOBA cursors) stopped 31-63 px short of the right and bottom edges: edge panning never triggered and buttons in that band could not be clicked, for no gain, since that tip was always visible at the edge. It now reads the cursor's pixels (alpha, or the AND/XOR masks) and only keeps the visible pixel nearest the hotspot on screen; a cursor drawn at its hotspot is never clipped. The guard was on whenever the engine reported a running app, and the Desktop app keeps running after the viewer disconnects, so a local player's cursor stayed confined until the engine restarted. It now also needs the engine log's last word to be CLIENT CONNECTED (a disconnect or a ping timeout ends it). The node launched PowerShell every 30 s to check the guard's task, on the service's tick thread. A node in the desktop session (the Run-key start) now runs the guard as its own child process; only a node in session 0 uses the task, registered once, without a logon trigger that could start it for a dead node's process ID, and run with schtasks. The guard checks that its parent PID is still a latch-host process, and sleeps a second at a time while no viewer is connected. The clip bookkeeping is a small state machine with the Windows calls behind a trait, so its rules are tested: a game's own confinement is kept and put back, a clip someone else set is never lifted, a desktop that was free is freed again (not set to the old desktop's size), and a clip left by a guard that was killed is recognised and lifted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…covery After a stream, Sunshine's display recovery logs "Currently available devices:" with a list of "<device_id> - <friendly_name>" strings (display_device.cpp, try_revert_settings), not the objects it logs at startup. output_in() parsed that list, found no friendly_name on the strings and reported no virtual display, so a host still on automatic capture was not switched to the driver until a later engine start logged the object form. Both forms are read now; the latest device list still decides, and other text that begins "Currently available " is skipped instead of hiding the list before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One reading of 'is a viewer connected' for the update deferral, setup and the cursor guard: the last CLIENT CONNECTED, CLIENT DISCONNECTED or Ping Timeout line decides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrBeldum
force-pushed
the
feat/windows-cursor-in-picture
branch
from
October 18, 2026 01:35
79ed8a1 to
1485721
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.
Uncommitted work from 2026-10-03 (Windows cursor handling for game streams), committed so it isn't lost. Draft: not yet run on Windows hardware (Hermes has been offline); CI's Windows job is the first compile of the Windows-only parts.
LatchCursorUser, keeps a custom game cursor's whole shape inside the streamed display (crates/host/src/cursor.rs), so a cursor with a transparent top-left hotspot no longer disappears off the bottom/right edge. It follows resolution and cursor-shape changes, respects the game's own confinement, and lets go when the game hides its cursor.dist.noindexwith the release workflow to match (the same change is in VPS desktops: own size, sizes below 1080p, Linux clipboard, pairing fix #26).Checked on macOS:
cargo fmt --check, clippy-D warningsfor latch-host and latch-client.🤖 Generated with Claude Code