Skip to content

Conversation

@Rozerxshashank
Copy link

@Rozerxshashank Rozerxshashank commented Feb 10, 2026

Fixes: #52

This PR fixes a bug where mouse sensitivity was being applied twice for cursor movement (client hardcoded + server config), while being ignored completely for scroll and zoom events.

Changes:

  1. Removed the sensitivity parameter and its hardcoded 1.5 default. The client now sends raw touch deltas.

  2. Updated InputHandler.ts to apply CONFIG.MOUSE_SENSITIVITY to Scroll and Zoom events. Previously, it only applied sensitivity to mouse movement.

How Has This Been Tested?

Manual Verification: Verified that removing the client-side multiplier correctly delegates sensitivity logic to the server.

Build Check: Ran npm run build to ensure no type errors or build regressions.

Checklist
My code follows the style guidelines of this project
I have performed a self-review of my own code
I have commented my code, particularly in hard-to-understand areas
My changes generate no new warnings.

Summary by CodeRabbit

  • Refactor

    • Centralized input sensitivity: mouse scroll/zoom now use a single global sensitivity; trackpad gestures no longer expose a separate sensitivity parameter.
  • Bug Fix

    • Scroll and zoom amounts are scaled, rounded, and guarded to avoid tiny/zero zooms for more consistent behavior.
  • Improvement

    • Improved input responsiveness and stability (reduced unnecessary re-renders), refined click/focus timing, and better composition (IME) handling.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

Removed client-side sensitivity from the trackpad gesture hook so the client sends raw deltas; server InputHandler now reads CONFIG.MOUSE_SENSITIVITY per event, applies invert/sensitivity scaling, rounds results, and guards zero amounts before performing scroll/zoom actions.

Changes

Cohort / File(s) Summary
Client: gesture hook
src/hooks/useTrackpadGesture.ts
Removed sensitivity parameter from the hook signature and stopped multiplying outgoing zoom/scroll/move deltas — sends raw unscaled sumX, sumY, and delta.
Server: input handling
src/server/InputHandler.ts
Apply per-event scrollSensitivity / zoomSensitivity from CONFIG.MOUSE_SENSITIVITY ?? 1.0, combine with invertMultiplier, round deltas, check amount != 0 before acting; minor whitespace adjustments in move handling.
Client UI: trackpad route
src/routes/trackpad.tsx
Stabilized handlers via useCallback, introduced CLICK_RELEASE_DELAY_MS and INPUT_REFOCUS_DELAY_MS, added isComposingRef for composition state, and replaced inline timeouts with constants.

Sequence Diagram(s)

sequenceDiagram
participant Client as Client
participant Server as Server
participant Config as Config
Client->>Client: capture gesture (sumX, sumY, delta)
Client->>Server: send raw gesture message (sumX, sumY, delta)
Server->>Config: read CONFIG.MOUSE_SENSITIVITY
Config-->>Server: sensitivity
Server->>Server: apply invertMultiplier * sensitivity, round deltas
Server->>Server: if amount != 0 then perform scroll/zoom/move
Server-->>Client: (optional) ack / UI update
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I measured hops with careful paw,
Sent naked deltas without a flaw.
The server scales once, then dances true,
No double-mush—just motion through. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: removed client-side sensitivity double-application' clearly and concisely summarizes the main change: removing the client-side sensitivity parameter to fix double application of sensitivity scaling.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #52: removes the hardcoded 1.5 client-side multiplier from useTrackpadGesture, applies CONFIG.MOUSE_SENSITIVITY to scroll/zoom events in InputHandler, and fixes double-application of sensitivity.
Out of Scope Changes check ✅ Passed All code changes are directly related to fixing the sensitivity bug. The useCallback refactoring in trackpad.tsx is a minor performance optimization that supports the main fix without introducing unrelated functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/routes/trackpad.tsx (2)

93-103: Remaining inline arrows will still cause child re-renders each cycle.

Lines 93, 101, and 113 still use inline arrow functions, which undermines the goal of memoizing handlers with useCallback. If ControlBar and ExtraKeys are wrapped with React.memo (or may be in the future), these unstable references will defeat memoization.

Consider wrapping these as well for consistency:

♻️ Example for the sendKey handler
+    const sendKey = useCallback((k: string) => {
+        send({ type: 'key', key: k });
+    }, [send]);
+
+    const toggleScroll = useCallback(() => {
+        setScrollMode(prev => !prev);
+    }, []);

Then pass sendKey and toggleScroll directly as props. Note the functional updater prev => !prev which avoids capturing scrollMode in the dependency array.


106-120: Aggressive auto-refocus on blur may trap focus on some mobile browsers.

The onBlur handler immediately re-focuses the hidden input after INPUT_REFOCUS_DELAY_MS (10 ms). This can interfere with accessibility tools and prevent users from intentionally dismissing the keyboard. This appears to be pre-existing behavior and not introduced by this PR, but worth noting for a future improvement — e.g., guard the refocus behind a keyboardVisible state toggle.

Tip

We've launched Issue Planner and it is currently in beta. Please try it out and share your feedback on Discord!


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/server/InputHandler.ts`:
- Around line 47-52: The switch cases for 'scroll' (where invertMultiplier and
scrollSensitivity are declared and mouse.scrollDown/mouse.scrollRight are
called) and the 'zoom' case must be wrapped in their own block braces to prevent
const-scope leakage across cases; edit the case 'scroll' and case 'zoom' bodies
to enclose their existing statements in { ... } so invertMultiplier,
scrollSensitivity and any local vars in the 'zoom' case are block-scoped to that
case.
- Around line 50-51: The scroll amounts passed to mouse.scrollDown and
mouse.scrollRight (in InputHandler.ts) can be non-integers because
scrollSensitivity may be a float, causing native truncation; wrap the computed
values (msg.dy * invertMultiplier * scrollSensitivity and msg.dx * -1 *
invertMultiplier * scrollSensitivity) with Math.round() before awaiting
mouse.scrollDown and mouse.scrollRight so the nut-js functions receive integer
ticks (use msg.dy/msg.dx checks as-is).
🧹 Nitpick comments (1)
src/server/InputHandler.ts (1)

27-27: CONFIG.MOUSE_SENSITIVITY ?? 1.0 is repeated three times; the fallback is already in config.tsx.

CONFIG.MOUSE_SENSITIVITY already defaults to 1.0 via the nullish coalescing in src/config.tsx (line 20). The ?? 1.0 here is redundant. Consider reading it once at the top of handleMessage (or as a class field) to keep it DRY:

  async handleMessage(msg: InputMessage) {
+     const sensitivity = CONFIG.MOUSE_SENSITIVITY;
      switch (msg.type) {

Then reuse sensitivity in the move, scroll, and zoom branches.

Also applies to: 49-49, 57-57

@Rozerxshashank
Copy link
Author

Hey @imxade
When I removed that multiplier to fix the cursor sensitivity bug, scroll and zoom events became unscaled. I updated InputHandler.ts to apply the server config to these events as well, ensuring consistent behavior across all gesture types. This makes the fix more robust and prevents a regression in scroll/zoom usability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Sensitivity slider value is not wired to the trackpad, setting is ignored and double-applied

1 participant