Repository navigation
Reverse Scrolling: a switch that turns a finger's drag around (#143) - #159
Conversation
…nity#143) A device-only switch in Settings, This iPad: off by default, never sent to the Mac. While on, a finger's drag scrolls the content the other way, and its coast after the lift keeps that direction. A trackpad's and a mouse wheel's scrolls are left to the device's own system setting. ScrollDirection.factor is pure, so the protocol check covers it, with three mutants.
|
From a pass over all the open pull requests (nothing is decided yet): #107 adds an |
Main gained Saffsanity#153 (the checks' build scripts quote their paths) and Saffsanity#142 (saved Macs keep a typed destination across a key change). Only Tests/checks/README.md conflicted: the protocol row is this branch's, the remote-rules row main's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…round too The switch reached only a finger's drag over the picture. Two fingers on the on-screen trackpad of the upright layouts scroll the same way (the content follows the fingers), so the switch now turns both around, each scroll's deltas and the coast after its lift, read once as the scroll begins. A trackpad or mouse connected to the device is left to iPadOS's own Natural Scrolling, which has already turned its scroll events. ScrollDirection names the four sources (finger, pad, trackpad, wheel) and which the switch reaches; the protocol check covers every source with the switch off and on (205 checks, 32 mutants: 8 for the rule). TrackpadSurface's two-finger deltas go through one scroll(dx:dy:) that applies the factor, used by the pan, the DEBUG input test and the new script step. The footnote says what it turns and, on an iPad, that a connected trackpad or mouse follows its own Natural Scrolling setting. DEBUG: -SillInputScript gains drag DX,DY (a finger over the picture) and padscroll DX,DY (two fingers on the pad), each with its coast; -SillSettingsScroll reverse opens the panel at the switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SILL_TEST_INPUT_LOG printed every scroll event a synthetic host would post as
"scroll", so a test could not tell which way a device's scroll went. It now
prints the point deltas and where the event sits in a gesture ("Test input:
scroll dy -12 dx 0, gesture changed (none)": positive dy moves the content
down), which is how Reverse Scrolling's direction is checked live. TEST ONLY:
nothing changes without the variable, and only a --synthetic host takes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…What's New DEVELOPMENT.md gets a section on what the switch turns and what it leaves to iPadOS, and the harness's new steps; CLAUDE.md's Layout and Build and run name ScrollDirection, the pad's scroll and the arguments; README's input bullet a sentence. The site's words go between Reverse Scrolling markers, cut by a perl line in the release checklist before the release that ships them: the privacy policy lists the switch among what stays on the device (beside three-finger gestures and Larger Picture; its date today's), and the support page has a short section on scrolling the other way. The next What's New draft gains a paragraph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged main in (8137184, no rebase). The only conflict was the |
ArfiArfath21 merged main (4d990e9) into the pull request's branch with no change to the code; this branch had already merged the same main. Only Tests/checks/README.md's protocol row conflicted: this branch's row stays (205 + 8 checks, 32 mutants, the on-screen trackpad's two-finger scroll among them), since the fork's 196 + 8 and 27 predate the pad's cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the file One line of the section ran to 115 columns where the file wraps near 78; the words are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…itch off TrackpadView.swift and InputOverlay.swift now read StreamClient.reverseScrollOn and ScrollDirection as each scroll begins, which the rig's scratch app did not have, so Tests/touchrig/run.sh no longer compiled this branch's surfaces. The rig compiles StreamProtocol's ScrollDirection.swift beside Input.swift where the sources have it (a --rev from before the switch has none), and Stubs.swift gives StreamClient's switch, off: the rig's verdicts compare the surfaces with those before the switch, whose scrolls go the natural way. DEVELOPMENT.md's section on the rig says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rolling Only docs/release-checklist.md conflicted: both branches mark words on the site for the release that ships them. Both stay: the paragraph names the clipboard's, the display wake's and Reverse Scrolling's markers and the greps that show each cut, and the republish's commands keep both perl lines, the display wake's first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y#159 The paragraph after the table says which branch each count comes from; the protocol row's 205 + 8 checks and 32 mutants include this branch's cases for the four scroll sources and their eight mutants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto reverse-scrolling Three docs files met, each keeping both sides: CLAUDE.md's Layout (the StreamProtocol paragraph with ScrollDirection beside Saffsanity#93's kind 44, and the TrackpadView and HEVCDisplayView paragraph beside the keyframe recovery), the checks README's lede, and the release checklist's paragraph on marked words, which now names Clipboard, Keyframe, Display wake and Reverse Scrolling once each, with all four perl lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main brings Saffsanity#159, Reverse Scrolling (issue Saffsanity#143): ScrollDirection in StreamProtocol, the device's switch in the Settings panel's This iPad group, a finger's drag over the picture and the portrait trackpad's two-finger scroll turned around with their coast, InputScript's drag and padscroll steps, its words in privacy.html and support.html between Reverse Scrolling markers, and protocol's ScrollDirection cases and mutants. Where it met Saffsanity#117 (the connect screen's tiles and groups): - Tests/checks/README.md: the closing sentence names both, `connection-list` with Saffsanity#117 (Saffsanity#116) and `protocol`'s Reverse Scrolling cases and mutants with Saffsanity#159 (issue Saffsanity#143). The connection-list row (Saffsanity#117), and the protocol row and the lede's Reverse Scrolling phrase (Saffsanity#159), merged by themselves. - docs/release-checklist.md: both sides had rewritten the paragraph on marked words the same way and each added its own marker. It now names every marker once, Clipboard, Keyframe, Display wake, Tiles and Reverse Scrolling, with every grep, and both perl lines stay (Tiles, then Reverse Scrolling). Run on a copy of the merged site: the five perl lines leave no marker, the clipboard grep prints only privacy.html's log line and the other four print nothing, also with either feature's words left unmarked. - Merged by themselves, each checked against both parents: CLAUDE.md (Layout's ScrollDirection, InputOverlay and TrackpadView lines and Build and run's lines beside Saffsanity#117's ConnectionList and check list; neither side has a Current step entry), docs/DEVELOPMENT.md, site/privacy.html (each item inside its own marker), iOSClient/ContentView.swift (Saffsanity#159's harness contract lines and InputScript's steps beside Saffsanity#117's connect screen and its contract lines) and iOSClient/StreamClient.swift (reverseScrollKey beside macGroups, macPreviews and the tile's picture at tearDown). No Swift file conflicted. ci.yml's mutants matrix is Saffsanity#117's (Saffsanity#159 left it alone): sorted, with connection-list and protocol. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sleep Only Tests/checks/README.md conflicted, two neighbouring rows each side changed alone: this branch's `policy` row (issue Saffsanity#105's cases, 507 and 201) and main's `protocol` row (Reverse Scrolling's cases, 205 + 8 and 32), both kept as their side wrote them. CLAUDE.md, docs/DEVELOPMENT.md and iOSClient/StreamClient.swift merged by themselves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the head with Saffsanity#159 merged in: a clean release build from a git archive, the iOS app as CI builds it from fresh derived data (the known StreamClient warning now at line 3904), run-all.sh's 48, goodbye's 89 of 89 mutants again (its check compiles every StreamProtocol source, which the merge changed), the bare app's ten goodbye runs again, alike. Policy's 201 of 201 stand from 36e7212's merge: the merge leaves DiscoveryPolicy.swift and the check as they were. The entry names main at c215514. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity#159's Reverse Scrolling (issue Saffsanity#143) beside the sound: the device's own switch (Sill.reverseScroll, never sent) turns a finger's drag over the picture and two fingers on the on-screen trackpad around, coast included (StreamProtocol's ScrollDirection, with protocol's 13 cases and 8 mutants), the touch rig and InputScript's drag and padscroll, and the host's TEST ONLY scroll log line with its deltas and phase (InputInjector.swift, which this branch never touched). No wire change, and no host file both sides changed: the sound's StreamServer, StreamCoordinator and pipeline are as they were. Six files conflicted, each resolved by keeping both sides: - iOSClient/HostSettingsPanel.swift, four hunks. The This iPad group merged by itself in Saffsanity#159's order (Sound from ‹Mac› first, Larger Picture, Share Clipboard, Reverse Scrolling, Three-Finger Gestures). Saffsanity#159's -SillSettingsScroll reverse becomes a case of this branch's startsAt switch (reverseScrollRowID) in place of its startsAtReverseScroll and second scrollTo, whose other line named startsAtGestures, which this branch had folded into startsAt; one onAppear scrolls to whichever the argument names. The type's and the group's doc comments name both sides' rows. - iOSClient/ContentView.swift: the harness contract names -SillSettingsScroll sound and reverse. - CLAUDE.md: the Layout's StreamProtocol paragraph has Audio.swift, then ScrollDirection.swift, then kind 44's sentence once. Saffsanity#159's Layout and Build and run lines and the Current step merged by themselves (Saffsanity#159 has no Current step entry). - Tests/checks/README.md, three hunks: the opening list names Reverse Scrolling and the sound's packets; protocol's row both descriptions, 234 + 8 checks and 42 mutants (the sound's 221 + 8 and 34 with Reverse Scrolling's 13 and 8, from the merged check's run); the history paragraph both clauses, with a sentence on this merge's counts. - docs/release-checklist.md: the paragraph on marked words names each marker once (Clipboard, Keyframe, Display wake, Sound, Reverse Scrolling) with each one's grep, where both sides had rewritten main's repeated paragraph; every perl line kept, Sound's, then Reverse Scrolling's. - docs/app-store-metadata.md: both bullets, the sound's first; the next What's New's draft with both paragraphs is 1,322 characters. site/privacy.html and site/support.html merged by themselves, each pull request's words inside its own markers; with all five blocks taken out as a republish before the releases would, the checklist's greps print what it says (one clipboard line, nothing else). README.md, docs/DEVELOPMENT.md, iOSClient/StreamClient.swift and protocol's main.swift and mutants.py merged by themselves, each side's lines whole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts, each kept whole on both sides: - Tests/touchrig/run.sh: the surfaces compile with TextComposition.swift (this branch) and ScrollDirection.swift (Saffsanity#159), both in the fetch list and on the compile line. - docs/release-checklist.md: the marked words list names other languages and dictation (Saffsanity#147) and Reverse Scrolling (Saffsanity#159), with both perl lines and both greps; a republish simulated on a copy of the merged site/ leaves no marker and no hit for any of the greps (the clipboard's only privacy.html's log line). - README.md's How it works: the input methods' and dictation's sentences, then Reverse Scrolling's. - Tests/checks/README.md's opening list: Reverse Scrolling's clause and the input methods' both. - CLAUDE.md's Layout, InputOverlay: the scroll path with Reverse Scrolling's direction, then the text input's clause. InputOverlay.swift, StreamClient.swift, DEVELOPMENT.md, the metadata and the site merged by themselves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…length CLAUDE.md's Layout names the rule beside the input view and TextInputRules (a Return or a Tab typed as text moves the Mac's caret: carriesReturnOrTab). docs/app-store-metadata.md's dated counts gain the next What's New as the merge with Saffsanity#159 leaves it: Saffsanity#147's paragraph of 247 characters beside Reverse Scrolling's, the draft 1,266 characters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…affsanity#93, Saffsanity#151) into fix/remote-desktop-qr-code Main brought Send Audio as a beta (Saffsanity#94), Reverse Scrolling (Saffsanity#159), SILL_TEST_NO_SCREEN (Saffsanity#227), the Close timeout and the interrupted picture (Saffsanity#93) and a sleeping display woken for a device (Saffsanity#151). Six files conflicted, each resolved keeping both sides: - .github/workflows/ci.yml: the mutants matrix is main's 51 checks with pairing-sharing, sorted: 52, exactly the folders of Tests/checks with a mutants.py. - Sources/SillMenuBar/HostSettings.swift: Saffsanity#94's sendAudio beside showPairingWindowToScreenSharing in Key and in the registered defaults (sendAudio first, a HostConfig knob next to shareClipboard), as Noah's comment of 2026-10-19 settled the overlap: whichever lands second keeps both. HostConfig's sendAudio, read and saved, and this switch's property merged by themselves. - Sources/SillMenuBar/DebugHooks.swift: -SillSetAfter's list names both keys (sendAudio, and showPairingWindowToScreenSharing=0|1; shareClipboard, which both sides had added, once); both cases of apply merged by themselves. - Tests/checks/README.md: main's rewrapped introduction with this PR's "whether screen sharing shows the pairing window"; the pairing-sharing row beside main's phone-portrait and pointer-control rows; the history's list of checks and their pull requests ends with pairing-sharing and Saffsanity#157. - docs/release-checklist.md: the marker paragraph names every marker once (Clipboard, Keyframe, Display wake, Sound, Reverse Scrolling, Pairing window), the screen sharing grep among those that print nothing, and all six perl lines. - CLAUDE.md: both Current step entries, this PR's first, then main's three; Build and run's defaults list with sendAudio and showPairingWindowToScreenSharing; this PR's entry names this merge, and its verification is this merge's (Tests/checks/run-all.sh, all 52; the previews against main's 74d099c, the Devices pane's eight differ, two new, the other 136 byte for byte). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main gained the pairing window shown to screen sharing (Saffsanity#157, issue Saffsanity#108: Settings › Devices' Show the pairing window to screen sharing, PairingWindowSharing and the pairing-sharing check, README, SECURITY.md, DEVELOPMENT.md and the plans, support.html's item marked <!-- Pairing window). Where it met the connect screen's tiles and groups (Saffsanity#117): - .github/workflows/ci.yml: the mutants matrix is the sorted union, connection-list and pairing-sharing both in (53 checks, exactly the folders with a mutants.py). - Tests/checks/README.md: both rows (connection-list after compatibility, pairing-sharing after pairing-address); the history's first sentence names connection-list with Saffsanity#117 (Saffsanity#116), then Reverse Scrolling's with Saffsanity#159 and pairing-sharing with Saffsanity#157 (Saffsanity#108), and main's re-wrapped audio sentences follow unchanged. Main's lede phrase merged by itself (this branch has none). - docs/release-checklist.md: the marked-words paragraph names Clipboard, Keyframe, Display wake, Sound, Tiles (PR Saffsanity#117), Reverse Scrolling and Pairing window (PR Saffsanity#157) once each, with every grep ('tiles|group name' and 'screen sharing' among them), one to a line; the perl lines merged by themselves, Tiles' and Pairing window's among them, seven in all. On a copy of the merged site/, the seven lines leave no marker and the greps print what the paragraph says. Merged by themselves, each differing from the other parent by exactly that side's hunks: CLAUDE.md (main's Current step entry for Saffsanity#157 at the top, this branch having none; Layout's PairingWindowSharing beside the tiles' paragraph; the checks list with connection-list and pairing-sharing; Build and run's defaults list with showPairingWindowToScreenSharing beside the tiles' -SillSettingsScript disconnect step) and docs/DEVELOPMENT.md (main's Through Screen Sharing item and Settings › Devices sentence, the tiles' paragraphs and harness lines). site/privacy.html (the Tiles items) and site/support.html (the Pairing window item) changed on one side each, inside their own markers; the project file on this branch's side only (plutil OK, each id once). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main has moved 253 commits since this branch's base (4d990e9): among them Reverse Scrolling's ScrollDirection in InputOverlay's scroll path (Saffsanity#159) and the text input work (Saffsanity#147, Saffsanity#110). Git merged the four files this branch changes by itself; both sides kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thank you @ArfiArfath21, Reverse Scrolling is in Sill for iPhone and iPad 0.5.5 (5) on TestFlight, in Settings › This iPad (This iPhone on a phone), so you can finally try the switch on a device. It works with the Mac app people have now (0.5.1). Please tell me here how it feels, both the drag and the coast after a flick! The newest Sill for Mac is the nightly build on GitHub: https://github.com/Saffsanity/sill/releases/tag/nightly. This change works with Sill for Mac 0.5.1 as well. |
Closes #143.
A finger's drag scrolls the Mac's content the way a phone does: it follows the finger. #143 asks for the other way round. This adds Reverse Scrolling to Settings, in the This iPad group (This iPhone on a phone), off by default.
Sill.reverseScrollpreference like the gestures and clipboard switches. Nothing is sent to the Mac, no wire change, no new message kind.ScrollDirection.factor(reversed:finger:)is pure and lives inStreamProtocol, so it needed no project-file entry and is covered by theprotocolcheck (4 checks, 3 mutants, all caught).Tests/checks/README.mdhas the new counts.For review
InputOverlay.swift: the sign is applied inscrolled(to:at:)and to the coast's velocity instartMomentum. Worth a look that no other path sends a.scroll(I found none).Verified, and not
Tests/checks/run-all.sh protocolpasses, and its three new mutants are caught.mainalready has there (DeviceHingeContextinDuoPostureReader.swift, which needs the 27.1 SDK), so I could not run the app. I have not tried the switch on a device or in the simulator.AI assistance: this change was written by an AI coding assistant (Claude) at my direction. I reviewed the diff and ran the checks above.