Skip to content

fix(webrtc): preserve input on cursor hide - #596

Merged
zortos293 merged 3 commits into
mainfrom
capy/cursor-flush-transition
Jul 5, 2026
Merged

fix(webrtc): preserve input on cursor hide#596
zortos293 merged 3 commits into
mainfrom
capy/cursor-flush-transition

Conversation

@zortos293

@zortos293 zortos293 commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

This PR fixes a bug where raw mouse input was discarded immediately after the native cursor overlay hid. When the cursor transitioned from visible (absolute positioning) to hidden (relative positioning), the previous flush logic would send the pending absolute packet and clear the relative accumulators without sending them, causing the first movement input to be dropped.

Changes:

  • Updated flushMouse in opennow-stable/src/renderer/src/gfn/webrtcClient.ts to support mixed batches: it now sends any pending absolute packet followed immediately by any pending relative packets within the same flush cycle, rather than zeroing out relative deltas.

Open OPE-247 OPE-247


Note

Medium Risk
Changes live mouse input encoding in the WebRTC client; incorrect batching could cause cursor drift or double movement, but scope is limited to flush/queue logic.

Overview
Fixes dropped mouse movement when the native cursor overlay hides mid-batch and the client switches from absolute to relative packets.

flushMouse no longer clears pending relative deltas after sending an absolute packet or returns after only the absolute send. A single flush can emit absolute first, then relative in one cycle with a shared timestamp, matching official GFN mixed-batch ordering.

queueMouseMovement now zeros stale relative accumulators when the overlay cursor is visible and an absolute position is queued, so an absolute pin is not followed by obsolete relative deltas that would drift the server cursor off the overlay.

Reviewed by Cursor Bugbot for commit d0da4d8. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Improved mouse input batching to correctly transmit mixed absolute cursor moves and relative deltas in the right order.
    • Added more reliable handling for edge cases where rapid input could previously result in dropped movements or leftover motion.
    • Enhanced overlay-visible cursor updates by ensuring any pending relative residue is flushed before applying the overlay-pinned absolute cursor position.

…ing mixed absolute/relative.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
@zortos293 zortos293 added the capy Generated by capy.ai label Jul 5, 2026 — with Image Capy AI
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

flushMouse() in webrtcClient.ts now batches absolute and relative mouse packets together while preserving ordering and residual movement state. The cursor-visible path also flushes pending relative residue before queuing the pinned overlay cursor.

Changes

Mouse Flush Batching Fix

Layer / File(s) Summary
Combined absolute and relative packet flush
opennow-stable/src/renderer/src/gfn/webrtcClient.ts
flushMouse() now computes a shared batchTimestampUs, sends absolute and relative packets together instead of returning early after an absolute send, tracks sentAny, preserves residual relative movement, and updates the simulated cursor baseline after relative sends.
Cursor visibility flush before pinning
opennow-stable/src/renderer/src/gfn/webrtcClient.ts
When the overlay cursor becomes visible, pending relative residue is flushed with flushMouse(true) before clearing the relative floats and enqueueing the absolute pinned cursor position.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: preserving mouse input when the cursor overlay hides.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch capy/cursor-flush-transition

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0da4d861f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

dy: dyServer,
timestampUs: batchTimestampUs,
});
this.sendInputPacket(payload, INPUT_MOUSE_REL);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Send mixed mouse batches over an ordered path

When partially reliable HID is enabled for mouse input, this second sendInputPacket can use the unordered input_channel_partially_reliable path; checked createDataChannels, where that channel is created with ordered: false. In the cursor-visible-to-hidden transition this now emits the absolute and relative parts as two separate data-channel messages, so the relative movement can arrive before the absolute packet and then be overwritten by it, recreating the dropped-first-move behavior this change is trying to fix. The mixed batch needs to be kept in one ordered payload/path, or otherwise avoid using unordered delivery for the dependent pair.

Useful? React with 👍 / 👎.

zortos293 and others added 2 commits July 5, 2026 09:54
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@opennow-stable/src/renderer/src/gfn/webrtcClient.ts`:
- Around line 3798-3806: The mouse flush in webrtcClient.ts currently splits the
reliable relative residue and the deferred absolute pin across different sends,
allowing the absolute packet to overtake the earlier relative flush. Update the
logic around flushMouse and the
pendingMouseDxFloat/pendingMouseDyFloat/pendingMouseAbs handling so the
INPUT_MOUSE_ABS path is sent on the reliable channel too, or ensure both packets
are emitted together in the same reliable flush.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 58b8f91b-97fc-4f8a-9e6e-d285226c21d7

📥 Commits

Reviewing files that changed from the base of the PR and between f582542 and aa5dfd6.

📒 Files selected for processing (1)
  • opennow-stable/src/renderer/src/gfn/webrtcClient.ts

Comment on lines +3798 to +3806
if (
Math.abs(this.pendingMouseDxFloat) >= 0.5
|| Math.abs(this.pendingMouseDyFloat) >= 0.5
) {
flushMouse(true);
}
this.pendingMouseDxFloat = 0;
this.pendingMouseDyFloat = 0;
this.pendingMouseAbs = abs;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm whether INPUT_MOUSE_ABS is eligible for the partially-reliable (unordered) channel.
fd -t f 'inputProtocol.ts' opennow-stable/src | while read -r f; do
  echo "== $f =="
  rg -n -C3 'isPartiallyReliableHidTransferEligible|partiallyReliableHidMaskForInputType|INPUT_MOUSE_ABS|INPUT_MOUSE_REL' "$f"
done

Repository: OpenCloudGaming/OpenNOW

Length of output: 2054


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=opennow-stable/src/renderer/src/gfn/webrtcClient.ts

echo "== flushMouse / pendingMouseAbs region =="
sed -n '3520,3825p' "$file" | cat -n

echo
echo "== sendInputPacket / channel selection =="
rg -n -C4 'function sendInputPacket|sendInputPacket\(|isPartiallyReliableHidTransferEligible|partiallyReliableHidMaskForInputType|forceReliable|mixedBatch|pendingMouseAbs' "$file"

Repository: OpenCloudGaming/OpenNOW

Length of output: 19529


Deferred abs pin can overtake the reliable relative flush

This splits the rel→abs sequence across two flushes. INPUT_MOUSE_ABS can go over the partially reliable unordered channel, so the deferred abs packet can arrive before the earlier reliable relative residue and shift the cursor off the overlay. Keep the abs on the reliable channel too, or send both in the same reliable flush.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@opennow-stable/src/renderer/src/gfn/webrtcClient.ts` around lines 3798 -
3806, The mouse flush in webrtcClient.ts currently splits the reliable relative
residue and the deferred absolute pin across different sends, allowing the
absolute packet to overtake the earlier relative flush. Update the logic around
flushMouse and the pendingMouseDxFloat/pendingMouseDyFloat/pendingMouseAbs
handling so the INPUT_MOUSE_ABS path is sent on the reliable channel too, or
ensure both packets are emitted together in the same reliable flush.

@zortos293
zortos293 merged commit 7a7b82c into main Jul 5, 2026
20 checks passed
Chizuui pushed a commit to Chizuui/OpenNOW-Modified that referenced this pull request Aug 11, 2026
* Preserve relative input during cursor visibility transitions by allowing mixed absolute/relative.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Send mixed abs+rel mouse batches over the ordered reliable channel

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Preserve raw-input deltas queued before cursor-visible transition

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant