Skip to content

iOS: hold, then drag, on the picture in Direct Touch (#178) - #292

Open
addhumal wants to merge 3 commits into
Saffsanity:mainfrom
addhumal:direct-drag
Open

addhumal wants to merge 3 commits into
Saffsanity:mainfrom
addhumal:direct-drag

Conversation

@addhumal

@addhumal addhumal commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Towards #178 (@sirasterthecat-png: "an optional direct-touch drag gesture … while preserving the current scrolling/right-click behavior"). Device only, no wire change.

A finger held on the picture for 0.45 s:

  • lifted where it was pressed (within 8 pt): a right click there, as before, but at the lift instead of at 0.45 s;
  • moved on past 8 pt: the left button goes down where it was pressed, follows the finger, and comes up where it lifts, so a window, a slider or a selection moves under the finger.

A tap still clicks and a finger that moves before the hold still scrolls. A cancel or a three-finger stroke mid-drag lets the button up and clicks nothing. The drag is the left button's down, moves and up, as the Pencil's already are, so every Sill for Mac takes it.

  • TouchHold (iOSClient/TouchHold.swift, pure): the rule. InputOverlayView's long press feeds it and sends what it returns.
  • The tour's touch row: "Touch and hold to right-click, or hold, then drag, to move a window or select text."
  • Tests/touchrig: RIG_ONLY=hold runs the real overlay's holds; a stand-in for ClipboardPolicy.pasteKey so the rig builds again on main; H7's compare.py holds only the trackpad's hold-and-move to the events before.

Checks

  • Tests/checks/touch-hold (new, in CI's mutants matrix): 32 checks (20,000 random holds against a model: no button left down), 21 of 21 mutants caught.
  • Tests/checks/tour: the new row's words; run-all.sh: all 64.
  • The iOS app: Debug and Release for the simulator, Debug for a device; only the known StreamClient warning.
  • The touch rig on a simulator, the real overlay with synthesized touches. Main: the hold-and-move right-clicked at 0.47 s and dropped the moves. This branch: pointer to the finger at 0.45 s, left down once past 8 pt, each move, left up at the lift. The tap, the one-finger scroll and its coast: the same events as main.

What I tried

  • On a 14-inch MacBook Pro (M4 Pro, macOS 27.0.1), Xcode 27.2: the touch rig (RIG_ONLY=hold Tests/touchrig/run.sh), the real InputOverlayView driven by synthesized touches on an iPad Pro 11-inch (M5) simulator, iOS 27.0, against main's overlay (--rev upstream/main). A hold lifted in place right-clicked at the lift (634 ms; main 467 ms), a hold moved 60 pt sent left down at the start, ten moves and left up at the lift (main: a right click, the moves dropped), a cancel mid-drag let the button up, and a tap and a one-finger scroll were main's events exactly.
  • No real iPad or iPhone yet, and no Mac receiving the drag from a device (the host side is the Pencil's, unchanged).

Not tested

  • A real finger on an iPad or iPhone (the rig's touches are synthesized): the feel of the 8 pt slop, and a right click that now comes at the lift.
  • A second finger landing mid-drag (on the rig: the picture zooms, the Mac's pointer holds still, the button comes up at the lift).
  • With Option to use the stream picture as a relative trackpad (#178) #222 (Trackpad mode): whichever lands second keeps both tour rows' words.

…ds again

KeyChords.swift's paste chord reads ClipboardPolicy.pasteKey since the clipboard's Paste on the Mac,
and the rig compiles KeyChords.swift without StreamProtocol's clipboard: main's rig stopped at
'cannot find ClipboardPolicy in scope'.
…y#178)

A finger held 0.45 s on the picture and lifted where it was pressed (within 8 pt) right-clicks there,
now at the lift; moved on past 8 pt it presses the left button where it was pressed and drags to where
it lifts, so a window, a slider or a selection moves under the finger. A tap and a scroll are as before;
a cancel or a three-finger stroke mid-drag lets the button up. No wire change: left down, moves, left up,
as the Pencil's.

TouchHold (pure, Tests/checks/touch-hold: 32 checks, 21 of 21 mutants, in CI's matrix); InputOverlay's
long press feeds it. The tour's touch row says it. The touch rig's RIG_ONLY=hold runs the real overlay's
holds: main right-clicked at 0.47 s and dropped the moves; this sends left down, the moves and left up.
…nts before (Saffsanity#178)

The picture's hold drags since TouchHold, so a comparison against a base before it reported the
overlay's 'hold 0.6 s, then move 60 and lift' as a regression.

This branch has not been deployed

No deployments
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