Add deterministic explicit-start drag support#313
Closed
zengfanfan wants to merge 1 commit into
Closed
Conversation
This was referenced Jul 10, 2026
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.
Summary
Adds backward-compatible deterministic drag options to the existing
Movetool:from_locfor explicit-start drag in one tool call;durationwith intermediate cursor movement;Movedrag options.Motivation
The current
Move(drag=True)contract starts from the process-wide current cursor position. That means callers need one tool call to position the pointer and another to drag, leaving a race window where foreground state or cursor position can change.Issue: #312
Public API and compatibility
Existing calls remain valid:
New optional parameters only apply when
drag=True:from_locsupports the same list / JSON-stringified-list compatibility asloc. Supplying deterministic-drag-only options withoutdrag=Truefails clearly.Safety behavior
PressMousesucceeds,DragDropattemptsReleaseMouseif movement raises.Implementation overview
src/windows_mcp/uia/core.py: adds duration-based movement and release-on-move-failure behavior for left-buttonDragDrop.src/windows_mcp/desktop/service.py: adds explicit start normalization, duration validation, and foreground title/process assertions.src/windows_mcp/tools/input.py: exposes the new optionalMoveparameters while preserving legacy behavior.README.md: documents deterministicMovedrag usage.Testing
Focused checks passed:
Focused pytest result:
Full repository gates were also run. They still show pre-existing baseline failures unrelated to this PR:
Manual validation
A generic pointer-event fixture was used before implementation to verify the existing public contract can emit down/intermediate-move/up events, and to isolate the contract gap to implicit global cursor start state. The new deterministic path is covered by unit tests for explicit start, intermediate movement, guard failure before drag, and release-on-move-failure.
Notes
This PR intentionally does not include private consumer paths, screenshots, local planning documents, or unrelated cleanup. It is opened as a draft while API feedback on #312 is pending.