Skip to content

feat: add smooth Bezier movement to dragMouse#172

Open
ulziibay-kernel wants to merge 5 commits intomainfrom
ulziibay-kernel/smooth-drag-mouse
Open

feat: add smooth Bezier movement to dragMouse#172
ulziibay-kernel wants to merge 5 commits intomainfrom
ulziibay-kernel/smooth-drag-mouse

Conversation

@ulziibay-kernel
Copy link
Contributor

@ulziibay-kernel ulziibay-kernel commented Mar 4, 2026

Summary

  • Add smooth (boolean, default true) and duration_ms (integer, 50-10000ms) to DragMouseRequest
  • When smooth=true, drag movement uses human-like Bezier curves between path waypoints instead of linear interpolation (steps_per_segment and step_delay_ms are ignored)
  • Add GenerateMultiSegmentTrajectory to the mousetrajectory library: chains per-pair Bezier curves with proportional point distribution and screen bounds clamping
  • Refactor doDragMouse into doDragMouseLinear (existing behavior) and doDragMouseSmooth (Bezier path with jitter delays)
  • Add multi-segment trajectory tests

This is the counterpart to #148 (smooth moveMouse) — same Bezier approach, now applied to drag operations. A corresponding PR in kernel/kernel will forward smooth and duration_ms through the public API. Overall project tracked at https://linear.app/onkernel/issue/KERNEL-1070/humanize-all-computer-interaction-endpoints

Demo

smooth_drag_demo

Blue = smooth: true (Bezier curves) | Red = smooth: false (linear interpolation)

Test plan

  • All existing unit tests pass
  • New mousetrajectory multi-segment tests (3+ waypoints, 2 waypoints, duration_ms, screen clamping, single point, path continuity)
  • Visual demo script (test_smooth_drag.py) produces recording showing curved vs linear drag paths
  • E2E test on deployed instance

Made with Cursor


Note

Medium Risk
Changes the runtime behavior and timing of DragMouse by defaulting to a new smooth trajectory generator, which could affect automation reliability and edge-case cursor positioning despite added validation/clamping.

Overview
DragMouse now supports human-like dragging via a new smooth flag (default true) and optional duration_ms, switching movement from fixed linear relative steps to a multi-segment Bezier trajectory with eased/jittered per-step delays.

The drag implementation is refactored into doDragMouseLinear (previous behavior) and doDragMouseSmooth, with the smooth path built from a new mousetrajectory.GenerateMultiSegmentTrajectory helper that chains waypoint-to-waypoint curves, distributes points by segment distance, clamps points to screen bounds, and derives a per-step delay from duration_ms.

OpenAPI/OAPI models are updated accordingly (including regenerated embedded swaggerSpec), and new unit tests cover multi-waypoint trajectory generation, duration behavior, clamping, and path continuity.

Written by Cursor Bugbot for commit 3884879. This will update automatically on new commits. Configure here.

ulziibay-kernel and others added 3 commits March 2, 2026 11:05
Covers click, type, press key, scroll, and drag mouse with
performance-first algorithms (zero additional xdotool process spawns).
Includes the existing Bezier curve mouse movement as reference.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Add smooth (boolean, default false) and duration_ms (integer, 50-10000ms)
  to DragMouseRequest in OpenAPI spec
- Add GenerateMultiSegmentTrajectory to mousetrajectory library: chains
  per-pair Bezier curves with proportional point distribution and screen
  bounds clamping
- Refactor doDragMouse into doDragMouseLinear (existing behavior) and
  doDragMouseSmooth (Bezier path with jitter delays)
- Add multi-segment trajectory tests and visual demo script

Made-with: Cursor
- Change smooth default from false to true (matching moveMouse behavior)
- Add drag_demo.html with draggable ball and persistent path visualization
- Fix waypoint marker coordinates (viewport vs screen offset)
- Add smooth_drag_demo.gif for PR illustration

Made-with: Cursor
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

}
func (s *ApiService) doDragMouseSmooth(ctx context.Context, log *slog.Logger, body oapi.DragMouseRequest, btn string, screenWidth, screenHeight int) error {
if body.DurationMs != nil && (*body.DurationMs < 50 || *body.DurationMs > 10000) {
return &validationError{msg: "duration_ms must be between 50 and 10000"}
Copy link

Choose a reason for hiding this comment

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

Late validation causes unintended mouse click on invalid input

Medium Severity

The duration_ms validation inside doDragMouseSmooth runs after Phase 1 has already executed mousedown. When the validation fails, the parent error handler sends mouseup as cleanup — effectively producing an unintended click at the start position before returning a 400 error. The duration_ms bounds check needs to happen before Phase 1's mousedown to avoid this side effect.

Additional Locations (1)

Fix in Cursor Fix in Web

points[i][1] = maxY
}
}
}
Copy link

Choose a reason for hiding this comment

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

Duplicated clampPoints utility across two packages

Low Severity

The new unexported clampPoints function in mousetrajectory.go is functionally identical to the existing clampPoints in computer.go. Having two copies of the same logic increases maintenance burden and risk of inconsistent fixes. Since GenerateMultiSegmentTrajectory now handles clamping internally, consider exporting it from one location.

Fix in Cursor Fix in Web

@ulziibay-kernel ulziibay-kernel requested a review from rgarcia March 4, 2026 16:07
Drop drag_demo.html, smooth_drag_demo.gif, test_smooth_drag.py,
and humanize-computer-endpoints.md from this branch.

Made-with: Cursor
- Replace per-step Go-side sleeps (O(n) fork+exec) with a single
  xdotool arg chain using inline sleep directives (1 fork+exec)
- Add smoothstep easing (3t²-2t³) for step delays: slow at pickup
  and placement, fast in the middle, matching natural drag behavior
- Aligns with the performance-first design in the humanize plan

Made-with: Cursor
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