Skip to content

intial ydotool integeration#209

Merged
imxade merged 3 commits into
AOSSIE-Org:mainfrom
imxade:ydotool
Feb 27, 2026
Merged

intial ydotool integeration#209
imxade merged 3 commits into
AOSSIE-Org:mainfrom
imxade:ydotool

Conversation

@imxade
Copy link
Copy Markdown
Contributor

@imxade imxade commented Feb 27, 2026

Addressed Issues:

Fixes #(127)

Description

initial ydotool support, rolled with gemini

Functional Verification

  • Please check off the behaviors verified with this change.

Authentication

  • Connection doesn't work without a valid token.

Basic Gestures

  • One-finger tap: Verified as Left Click.

  • Two-finger tap: Verified as Right Click.

  • Click and drag: Verified selection behavior.

  • Pinch to zoom: Verified zoom functionality (if applicable).

Modes & Settings

  • Cursor mode: Cursor moves smoothly and accurately.

  • Scroll mode: Page scrolls as expected.

  • Sensitivity: Verified changes in cursor speed/sensitivity settings.

  • Invert Scrolling: Verified scroll direction toggles correctly.

Advanced Input

  • Key combinations: Verified "hold" behavior for modifiers (e.g., Ctrl+C) and held keys are shown in buffer.

  • Keyboard input: Verified Space, Backspace, and Enter keys work correctly.

  • Glide typing: Verified path drawing and text output.

  • Voice input: Verified speech-to-text functionality.

  • Backspace doesn't send the previous input.

Any other gesture or input behavior introduced:

  • New Gestures: Verified any other gesture or input behavior introduced in this PR.

Additional Notes:

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.

  • My code follows the project's code style and conventions

  • I have performed a self-review of my own code

  • I have commented my code, particularly in hard-to-understand areas

  • If applicable, I have made corresponding changes or additions to the documentation

  • If applicable, I have made corresponding changes or additions to tests

  • My changes generate no new warnings or errors

  • I have joined the and I will share a link to this PR with the project maintainers there

  • I have read the

  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.

  • Incase of UI change I've added a demo video.

⚠️ AI Notice - Important!
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.

Summary by CodeRabbit

  • New Features
    • Intelligent mouse movement: attempts relative cursor moves first, and falls back to absolute positioning if needed.
    • Detects availability of the underlying system tool and caches its status to improve reliability and performance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 27, 2026

Warning

Rate limit exceeded

@imxade has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 440302a and e439d00.

📒 Files selected for processing (1)
  • src/server/ydotool.ts

Walkthrough

The PR adds a new ydotool module providing checkYdotool() and moveRelative(dx, dy) and updates InputHandler's "move" handling to attempt relative movement first via moveRelative, falling back to computing and applying absolute coordinates if relative movement fails.

Changes

Cohort / File(s) Summary
New ydotool Module
src/server/ydotool.ts
Adds checkYdotool() and moveRelative(dx, dy) with caching of availability, execFile-based invocation of the ydotool binary, and error handling that invalidates cache and returns false on failure.
Updated Input Handler
src/server/InputHandler.ts
Alters "move" message handling to call moveRelative(dx, dy) first and, if it returns false, compute new absolute mouse position from current coordinates and call setPosition. Also adds import of moveRelative.

Sequence Diagram

sequenceDiagram
    participant Client
    participant InputHandler
    participant YdotoolModule as ydotool Module
    participant System as System/ydotool Binary

    Client->>InputHandler: send "move" (dx, dy)
    InputHandler->>YdotoolModule: moveRelative(dx, dy)
    YdotoolModule->>YdotoolModule: checkYdotool()?
    alt ydotool Available
        YdotoolModule->>System: execFile mousemove dx dy
        System-->>YdotoolModule: success / failure
        alt success
            YdotoolModule-->>InputHandler: return true
        else failure
            YdotoolModule->>YdotoolModule: invalidate cache, log
            YdotoolModule-->>InputHandler: return false
        end
    else ydotool Unavailable
        YdotoolModule-->>InputHandler: return false
    end
    alt Relative movement failed (false)
        InputHandler->>InputHandler: getPosition() -> current
        InputHandler->>InputHandler: compute newPos = current + (dx, dy)
        InputHandler->>System: setPosition(newPos)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

Typescript Lang

Poem

🐰 I hopped along with dx and dy,
I asked ydotool first — give it a try!
If commands fumble and pathways bend,
I compute the spot and hop again. ✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'intial ydotool integeration' clearly identifies the main change: initial integration of ydotool support, which aligns with the actual code changes adding ydotool module and relative mouse movement functionality.
Description check ✅ Passed The PR description includes the required template sections: addressed issue (#127), a brief description explaining the ydotool support initiative, functional verification checklist, and project contribution checklist, though most verification items remain unchecked.

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

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

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
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/server/InputHandler.ts`:
- Around line 114-127: Normalize the dx/dy deltas to integers before calling
moveRelative to avoid ydotool rejecting floats: coerce msg.dx and msg.dy (the
values passed into moveRelative in InputHandler) to integers (e.g., Math.round
or Math.trunc) the same way the scroll handler does, then call moveRelative with
those integer deltas; keep the existing fallback block that reads
mouse.getPosition and uses Math.round when computing the absolute position.

In `@src/server/ydotool.ts`:
- Around line 58-62: The catch block that sets isYdotoolAvailable = false on any
error (inside the mousemove handler) wrongly disables ydotool permanently;
change it so transient errors don't flip the flag: either remove the
unconditional assignment and just log and return false, or only set
isYdotoolAvailable = false for definitive, non-transient errors (e.g., detect
ENOENT/command-not-found or permission/installation errors by inspecting
err.code or err.message). Optionally add a single retry attempt before giving up
or schedule clearing the flag after a short backoff so relative movement can
recover; reference isYdotoolAvailable and the mousemove function in ydotool.ts
when making the change.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d16be8 and f3ae284.

📒 Files selected for processing (2)
  • src/server/InputHandler.ts
  • src/server/ydotool.ts

Comment thread src/server/InputHandler.ts
Comment thread src/server/ydotool.ts
Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (1)
src/server/ydotool.ts (1)

58-62: ⚠️ Potential issue | 🟠 Major

Avoid process-lifetime disable after a single mousemove failure.

Line 61 unconditionally sets isYdotoolAvailable = false, so transient runtime failures permanently disable relative movement until restart.

Suggested fix
 	} catch (err) {
 		console.error("[ydotool] Error executing mousemove:", err)
-		// Consider it unavailable for future calls to avoid repeated failing attempts
-		isYdotoolAvailable = false
+		// Transient failures should trigger re-probe on next call.
+		isYdotoolAvailable = null
+		ydotoolPath = null
 		return false
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/server/ydotool.ts` around lines 58 - 62, The code currently sets
isYdotoolAvailable = false inside the mousemove catch block, which permanently
disables ydotool after a single transient failure; modify the catch in the
mousemove (or equivalent) function to avoid unconditionally flipping
isYdotoolAvailable: instead, detect permanent/unrecoverable errors (e.g.,
missing binary or spawn ENOENT by checking err.code) before setting
isYdotoolAvailable = false, and for other errors implement a lightweight
retry/failure-threshold (e.g., consecutiveFailureCount ++ and only set
isYdotoolAvailable = false after N consecutive failures or set a timestamp and
re-enable after a cooldown) so transient runtime errors don’t disable ydotool
for the process.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/server/ydotool.ts`:
- Around line 20-21: The execFileAsync calls (used to detect and invoke ydotool
in ydotoolPath assignment and the later child invocation) lack timeouts and can
hang; update both uses of execFileAsync to pass a timeout option (e.g., {
timeout: <ms> }) so the child process is killed after a bounded time, and add
error handling for timeout errors (catch the thrown error from execFileAsync,
detect timeout, and log/handle gracefully rather than letting the call hang).
Specifically, modify the call that resolves ydotoolPath (where
execFileAsync("which", ["ydotool"]) is used) and the execFileAsync invocation(s)
that run ydotool (around the block that spawns the ydotool commands) to include
the timeout option and proper catch logic.

---

Duplicate comments:
In `@src/server/ydotool.ts`:
- Around line 58-62: The code currently sets isYdotoolAvailable = false inside
the mousemove catch block, which permanently disables ydotool after a single
transient failure; modify the catch in the mousemove (or equivalent) function to
avoid unconditionally flipping isYdotoolAvailable: instead, detect
permanent/unrecoverable errors (e.g., missing binary or spawn ENOENT by checking
err.code) before setting isYdotoolAvailable = false, and for other errors
implement a lightweight retry/failure-threshold (e.g., consecutiveFailureCount
++ and only set isYdotoolAvailable = false after N consecutive failures or set a
timestamp and re-enable after a cooldown) so transient runtime errors don’t
disable ydotool for the process.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3ae284 and 440302a.

📒 Files selected for processing (1)
  • src/server/ydotool.ts

Comment thread src/server/ydotool.ts
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.

1 participant