3
0
Fork
You've already forked slint-baseview
2

Add unbounded ("infinite") mouse-drag mode #5

Open
PepperBoy wants to merge 2 commits from PepperBoy/slint-baseview:feat/unbounded-mouse-movement into main
pull from: PepperBoy/slint-baseview:feat/unbounded-mouse-movement
merge into: RustAudio:main
RustAudio:main
First-time contributor
Copy link

Lets you keep dragging a control (e.g. a rotary knob) past the window/screen edge and have the value keep changing. While a drag is active, the OS cursor is hidden and pinned, and Slint receives an accumulated "virtual" position so the drag distance grows without bound. On release the cursor reappears (and optionally warps back to where the drag started).

Stock baseview (0.1.x) has no cursor warp/hide/relative-pointer API. Rather than fork it, this adds a small self-contained cursor shim inside slint-baseview, so it works against stock baseview.

Usage

Enable on pointer-down; release disables it automatically (like JUCE's auto-disable on mouse-up):

letmouse=handler.mouse_control();// Clone + Send + Sync handle
handler.component().on_drag_started(move||mouse.enable_unbounded_movement(true));

Demo: cargo run --example unbounded_drag.

Per platform

  • macOS — freezes the cursor (CGAssociateMouseAndMouseCursorPosition), reads motion from CGGetLastMouseDelta. Pure CoreGraphics FFI.
  • Windows / X11 — warp cursor back to window center each move; delta measured from center. (haven't tested)
  • Other — no-op.

Files

  • src/cursor.rs — new: the SlintMouseControl handle, state machine, and platform backends.
  • src/lib.rs — wires it into SlintWindowHandler; auto-disables on pointer release.
  • build.rs + examples/unbounded_drag/ — the demo.
Lets you keep dragging a control (e.g. a rotary knob) past the window/screen edge and have the value keep changing. While a drag is active, the OS cursor is hidden and pinned, and Slint receives an accumulated "virtual" position so the drag distance grows without bound. On release the cursor reappears (and optionally warps back to where the drag started). Stock baseview (0.1.x) has no cursor warp/hide/relative-pointer API. Rather than fork it, this adds a small self-contained cursor shim inside `slint-baseview`, so it works against stock baseview. ### Usage Enable on pointer-down; release disables it automatically (like JUCE's auto-disable on mouse-up): ```rust let mouse = handler.mouse_control(); // Clone + Send + Sync handle handler.component().on_drag_started(move || mouse.enable_unbounded_movement(true)); ``` Demo: `cargo run --example unbounded_drag`. ### Per platform - **macOS** — freezes the cursor (`CGAssociateMouseAndMouseCursorPosition`), reads motion from `CGGetLastMouseDelta`. Pure CoreGraphics FFI. - **Windows / X11** — warp cursor back to window center each move; delta measured from center. (haven't tested) - **Other** — no-op. ### Files - `src/cursor.rs` — new: the `SlintMouseControl` handle, state machine, and platform backends. - `src/lib.rs` — wires it into `SlintWindowHandler`; auto-disables on pointer release. - `build.rs` + `examples/unbounded_drag/` — the demo.
Lets a control (e.g. a rotary knob) be dragged past the window edge without
the OS cursor escaping. Stock crates.io baseview (0.1.x) exposes no cursor
warp / visibility / relative-pointer API, so this adds one as a small,
additive, per-platform shim (src/cursor.rs) -- no baseview fork required.
While active, the cursor is hidden and Slint receives an accumulated drag
position:
- macOS: freeze via CGAssociateMouseAndMouseCursorPosition(false) (no in-drag
 warp; avoids the post-warp event-suppression interval); motion recovered
 from CGGetLastMouseDelta. Pure CoreGraphics C FFI, no objc2 dependency.
 Optional restore via CGWarpMouseCursorPosition.
- Windows: hide (ShowCursor) + warp the cursor to the window center on enable
 and back to center each move (SetCursorPos/ClientToScreen); report
 origin + accumulated delta.
- X11: same center-warp approach via XWarpPointer + XFixesHideCursor.
Warping to the window center (rather than the press point) maximizes edge
headroom and keeps mouse events flowing. The recenter's own synthetic move
lands on center (zero delta) and is skipped.
Public, additive surface on SlintWindowHandler:
- enable_unbounded_movement(restore_position: bool)
- disable_unbounded_movement()
- is_unbounded_requested() -> bool
- mouse_control() -> SlintMouseControl (cloneable Send+Sync handle for use
 from 'static Slint pointer callbacks)
New re-exported type: SlintMouseControl. Requests are queued and applied on
the GUI thread (like queue_resize), so they are safe to call from Slint
pointer-press/release callbacks.
Adds an examples/unbounded_drag example demonstrating the feature; the
counter example is left unchanged.
A button release ends the drag that started it, so the handler now
disables unbounded movement automatically on ButtonReleased (mirroring
JUCE's auto-disable on mouse-up). The disable is queued and applied
after the release dispatches, so the release still reports the
accumulated virtual position before the cursor is shown/restored.
Consumers now wire a single press callback; disable_unbounded_movement
stays public for cancelling a drag without a mouse-up (e.g. Escape).
Simplify the unbounded_drag example accordingly.
PepperBoy force-pushed feat/unbounded-mouse-movement from 668500f840 to 9db498defc 2026年06月26日 23:01:10 +02:00 Compare
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u feat/unbounded-mouse-movement:PepperBoy-feat/unbounded-mouse-movement
git switch PepperBoy-feat/unbounded-mouse-movement

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff PepperBoy-feat/unbounded-mouse-movement
git switch PepperBoy-feat/unbounded-mouse-movement
git rebase main
git switch main
git merge --ff-only PepperBoy-feat/unbounded-mouse-movement
git switch PepperBoy-feat/unbounded-mouse-movement
git rebase main
git switch main
git merge --no-ff PepperBoy-feat/unbounded-mouse-movement
git switch main
git merge --squash PepperBoy-feat/unbounded-mouse-movement
git switch main
git merge --ff-only PepperBoy-feat/unbounded-mouse-movement
git switch main
git merge PepperBoy-feat/unbounded-mouse-movement
git push origin main
Sign in to join this conversation.
No reviewers
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
RustAudio/slint-baseview!5
Reference in a new issue
RustAudio/slint-baseview
No description provided.
Delete branch "PepperBoy/slint-baseview:feat/unbounded-mouse-movement"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?