Repository navigation
A hardware keyboard and trackpad on the device: keys without the Keyboard button, Esc, scrolling (#67, #68) - #80
Merged
Merged
Conversation
#68) Esc through a priority key command beside pressesBegan, one key press sent once; hardware keys forwarded whenever a keyboard is attached (HardwareKeyboardPolicy, a pure rule with its check), never the person's own action for the tour's rule; trackpad and mouse-wheel scrolling over the stream. Open questions with the defaults taken, and the test plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mand, trackpad scrolling (#67, #68) A hardware keyboard holds the keyboard by itself (#68). HardwareKeyboardPolicy (pure, Tests/checks/hardware-keyboard: 51 checks, 20,000 random sessions against the invariants, 31 of 31 mutants; in CI's mutants matrix): while GameController's keyboard is attached and nothing open takes the keyboard (Settings, the pairing overlay, the tour, the Apps drawer, the Menus pull-down), the stream's input view takes it at a session's start, after a rotation or a reconnect, and when the last taker closes, so keys and text reach the Mac without the Keyboard button; it lets go when the keyboard goes. The hold is never the person's own: the Keyboard button stays dark and the tour's busy and activity tests ignore it, so keyboard users still get the tour. The button keeps its meaning for the software keyboard (over the hold: the person's; again: back to the hardware keyboard's, the software keyboard gone, keys still going). InputOverlayProxy owns the rule and does what it answers; while the hold is the hardware keyboard's the input view is an empty view with no assistant groups, so nothing is drawn over the stream even where GameController and UIKit disagree (the iOS 27 iPhone simulator: GameController counts its HID keyboard, UIKit still shows the software keyboard). HardwareKeyboardMonitor reads GCKeyboard; DEBUG -SillHardwareKeyboard 1|0 and -SillKeyProbe 1. Esc through a priority key command, sent once (#67): InputOverlayView has Esc key commands (each combination of ctrl, option, shift and command, wantsPriorityOverSystemBehavior) while it holds the keyboard and no EscapeKey is on screen. ForwardedKeys.commanded/pressed/released send one key press once whichever channel delivers it (the press first: the command sends nothing; the command first: the press no later than it is swallowed, with its up). key-strokes: 347 checks (18 new; key commands in the random sessions), 81 of 81 mutants (9 new). DEBUG: an hwkey line for every hardware key and its channel, -SillEscViaCommand 1. The Settings panel closes on Esc through EscapeKey (Done keeps .cancelAction for cmd-period). Trackpad and mouse-wheel scrolling over the stream (#68): two scroll-only pans, continuous (a gesture, then Sill's coast) and discrete (plain deltas), sharing the finger pan's path; a pointer scroll's first event and a lone wheel notch are sent (in the simulator a wheel's pan began and ended at 3 pt with no change). DEBUG: the input test's overlay part, the input script's esc, scroll, wheel, keyboard attach|detach and orient, -SillTurnAt. The touch rig compiles the new rule and stands in for EscapeKey. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…EST ONLY) Key presses, pointer moves and wheel scrolls posted from a virtual HID device inside a simulator of your own (HID.framework's HIDVirtualEventService, as Tests/duorig posts the Duo's hinge; never on the Mac), so UIKit routes them as a real keyboard's and mouse's: pressesBegan, key commands, the text system, GameController, hover and scroll pans. run.sh build | UDID keys SPEC | UDID point SCRIPT. Its README has what it showed on iOS 27.0 simulators: every simulator's GameController counts its own keyboard while UIKit may still show the software keyboard (and counts a hardware keyboard once keys arrive); Esc reaches pressesBegan and a priority key command fires only for a press handed on; a wheel's pan begins with its first notch and a lone notch has no change; phased scrolls from a virtual mouse are discrete; momentum events never reach a pan; iPadOS 27 refuses programmatic turns. EscapeKey: a DEBUG line when it takes Esc, and its comment says what the simulator now shows (it closed the Settings panel and skipped the tour with nothing sent to the Mac). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md's Current step entry and Layout and Build and run; the plan's Results, Untested for Noah and Progress; docs/DEVELOPMENT.md (a section on keyboards and trackpads, the harness's new flags, the key rig); the checks' README (hardware-keyboard, key-strokes' counts); README's How it works; the support page (a keyboard or trackpad with your iPhone or iPad, Control-[ in a terminal); the App Store description's keyboard bullet (2,963 characters) and the next version's What's New (247); the harness contract in ContentView. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d, for Noah to check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uests The plan's Progress and the Current step entry: CI's Build and check on 807c8ef (run 38489635350), the private simulators deleted, and the merge order: the pull request merges into main without a conflict; with #74, #75, #77, #78 and #79 it meets in the docs, and with #79 also in StreamScreen.swift's DEBUG hooks (keep both). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w of #80) The review found that EscapeKey.onScreen counted EscapeKeys in every Sill window, so Settings, the tour or the pairing overlay left open in one window removed the stream's Esc key commands in every other window: on a device that gives Esc only to the key command (#67's premise), Esc then went nowhere in the window in front. Reproduced on a private iPad simulator against a loopback synthetic host (-SillSecondWindow 1 -SillSettings 1 -SillEscViaCommand 1, the key rig's Esc): before, "handed on" and no key 53 at the host; after, "via keyCommand (none): to the Mac" and key 53 down and up. It also found that EscapeKey.Anchor.fire() answered with the newest EscapeKey in any window, so Esc in one window could close another window's panel. Now EscapeKey.onScreen(in:) and fire(in:) take the window: the stream's input view asks about its own window, and the command answers with the newest EscapeKey in the window of the view controller UIKit hands it to (an EscapeKey's command sits on its window's controller, so only a key pressed there reaches it). The DEBUG "escape:" line says how many other windows' EscapeKeys it left alone. Docs: the plan's design and Noah's two-window step, CLAUDE.md's entry, DEVELOPMENT.md; the touch rig's stub follows the new signature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review found that README.md, public as soon as this merges, said Esc reaches the Mac and a trackpad or a mouse scrolls, and so did the support page, the App Store description's keyboard bullet and the next What's New, while no device has shown either: in the simulator Esc came through pressesBegan, which #67's iPad never used, and no real trackpad's events reached the continuous pan. Those words now say only that a keyboard types on the Mac as soon as the picture shows, without the Keyboard button; the plan's new "Words that wait for a device" has each fuller line for when Noah's steps 1, 7 and 9 pass, and the metadata doc points there (the description 2,899 characters, local-only 2,678, the next What's New 138; with the waiting words 2,963, 2,742 and 247). It also found that the support page said the Keyboard button "shows the on-screen keyboard", where with a keyboard attached it brings up the keyboard bar first: now "It brings up your device’s keyboard bar, and from there the on-screen keyboard." CLAUDE.md's "a pan gets no momentum events" is now what it was: a simulator observation, with a device to decide whether iPadOS coasts too. DEVELOPMENT.md says the key command and the trackpad's pan wait for a device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…for Noah (review of #80) The review found that the plan's Untested steps covered VoiceOver but not Full Keyboard Access or Switch Control, which the automatic hold changes the most: with a keyboard attached the stream's input view holds the keyboard whenever nothing is open over the stream, so Tab, Space and the arrows go to the Mac and Esc's commands ask for priority over the focus system, and the Keyboard button's second press goes back to the hold (HardwareKeyboardPolicy.toggled(), checked here) rather than letting go. Someone who moves through Sill's bar from the keyboard may not reach Settings or Disconnect while streaming. The plan gains open question 11 (default: the hold as for anyone until the device step says otherwise; the alternative, no automatic hold while one runs: UIKit has UIAccessibility.isSwitchControlRunning, and the iOS 27.1 SDK's UIKit headers have no test for Full Keyboard Access, so for it the alternative is Q1's) and step 13 for Noah; CLAUDE.md's entry says the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and CLAUDE.md The plan's Results gain "The review (2026-10-14) and its fixes": the four findings and the commit that fixed each, the two-window runs before and after (2fc53ed's build sent no Esc to the host with Settings open in the window behind; this build sent key 53; with a tour in each window, Esc closed the front one's and left the other's alone), the one-window Esc cases again, the two claims that did not hold ("Fixes #68", now Towards; run-all's flaky protocol case), and the verification on 7fdc902: the three iOS builds from new derived data and a clean swift build -c release with the known warnings only, run-all.sh 41 of 41 at the first run, the touch rig 72 of 72, no mutants again (no check compiles a file the review changed). Progress and "Not verified here" follow; CLAUDE.md's entry gets a review bullet and its Verified bullet rewrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 14, 2026
CLAUDE.md keeps both Current step entries, this branch's first; ci.yml's mutants matrix and Tests/checks/README.md take every check; the App Store metadata's next What's New draft has both paragraphs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
CLAUDE.md keeps every Current step entry, this branch's first; ci.yml's mutants matrix and Tests/checks/README.md take window-restore too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Heads-up on the Xcode project file: this PR adds I've moved my own #93's |
CLAUDE.md keeps every Current step entry, this branch's first, and both paragraphs of the harness's arguments; README's How it works keeps the keyboard sentence beside the iPhone bullet; the What's New draft has every paragraph; StreamScreen's harness takes -SillTurnAt beside -SillAXDump and -SillLargerPictureToggle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Esc and scrolling with a trackpad or a mouse showed on the iPad through Universal Control (the plan's Results), so README's How it works, the support page, the App Store description's keyboard bullet and the next What's New take the lines the plan held for them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
addhumal
added a commit
to addhumal/sill
that referenced
this pull request
Oct 15, 2026
Saffsanity#66 both add AC01/FC01)
ashleigh-hopkins
added a commit
to ashleigh-hopkins/sill
that referenced
this pull request
Oct 15, 2026
…FC21 and AC22/FC22: main's HardwareKeyboardPolicy.swift (Saffsanity#80) holds AC01/FC01, and two files under one ID break the project once both are in
ashleigh-hopkins
added a commit
to ashleigh-hopkins/sill
that referenced
this pull request
Oct 15, 2026
…FC21 and AC22/FC22: main's HardwareKeyboardPolicy.swift (Saffsanity#80) holds AC01/FC01, and two files under one ID break the project once both are in
ashleigh-hopkins
added a commit
to ashleigh-hopkins/sill
that referenced
this pull request
Oct 15, 2026
…both sides ci.yml's mutants list and Tests/checks/README.md both sides' checks (key-strokes 348 and 82 with the middle button's case); select() sets both `selecting` and main's missingPolls reset; the exit stops every capture before restoreFits puts sized windows back and the displays go; StreamClient takes Saffsanity#69's foreground rule through ClientPlatform (a Mac app is never in the background) and the Mac viewer still never asks for the Desktop by itself; CLAUDE.md keeps both Current step entries.
Code-Tomato
added a commit
to Code-Tomato/sill
that referenced
this pull request
Oct 18, 2026
… side Main brought PRs Saffsanity#74, Saffsanity#75, Saffsanity#77, Saffsanity#78, Saffsanity#79, Saffsanity#80, Saffsanity#85 and Saffsanity#98. 19 files conflicted; each kept both sides whole. - Wire: kind 32 (the clipboard) beside 43 (the sound); 29-31 and 33-42 stay free for Saffsanity#66. - Settings: shareClipboard beside sendAudio in HostConfig, the app's defaults, the CLI (--no-clipboard, --audio) and sillclient.py. - Larger Picture (Saffsanity#79): row 1 holds Sound before Settings from 384 pt (PhonePortraitLayout.row1Beside); narrower, Sound is the panel's switch. - Saffsanity#75: a regular-mode window that streams on off the catalog's list keeps its sound (StreamCoordinator.streamedPID); before, it stopped. - Docs and check labels that still called 29 the audio plan's, or said 32 was free, now say what the merged tree does. Verified: swift build -c release; iOS Debug and Release for the generic simulator (only the known StreamClient warning); the CLI's CI paths; Tests/checks/run-all.sh, all 47; the mutants of the 25 checks that compile a file both sides changed, 936 of 936 caught. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity
added a commit
to kyleparisi/sill
that referenced
this pull request
Oct 19, 2026
Main moved on since this branch began at 985a733, to d1fa97e (Saffsanity#85, Saffsanity#74, Saffsanity#77, Saffsanity#75, Saffsanity#79, Saffsanity#80, Saffsanity#78, Saffsanity#98, Saffsanity#153 and Saffsanity#142). None of them touched Sources/SillHost/VirtualDisplay.swift, so the merge is clean and this pull request's change applies to main as it is now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity
added a commit
to ipavlidakis/sill
that referenced
this pull request
Oct 19, 2026
Main moved on since this branch began at 985a733, to d1fa97e (Saffsanity#85, Saffsanity#74, Saffsanity#77, Saffsanity#75, Saffsanity#79, Saffsanity#80, Saffsanity#78, Saffsanity#98, Saffsanity#153 and Saffsanity#142). None of them touched Scripts/make-app.sh, so the merge is clean and this pull request's change applies to main as it is now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HunterAhlquist
pushed a commit
to HunterAhlquist/sill
that referenced
this pull request
Oct 19, 2026
… as a pen Hunter Ahlquist's five commits (issue Saffsanity#81), from main at 985a733, merged as they are onto main at d1fa97e and the stale-hover commit before this one. Eighteen files conflicted; every resolution keeps both sides: - StreamMessage: main's clipboard (32), then the pen (still 29 here). - Switcher: WindowList keeps `clipboard` and gains `pencil`; one init with both parameters, and the coordinator's list sends both. - InputOverlay: main moved the finger pan onto the scroll path it shares with the iPad's trackpad and a wheel (Saffsanity#80); the palm guard stays in handlePan, before scroll(gesture, .finger), so it silences fingers only. The view's leave as it goes sits beside main's keyboard proxy. The stale-hover flag of the commit before gives way to PenStrokes.hover, the same rule in both modes (gone() resets it as the view leaves the window). - StreamClient, MockCatalog, HostSettingsPanel, ContentView, sillclient.py: the clipboard's lines and the Pencil's side by side (the This iPad group has Larger Picture, Share Clipboard, the gestures, then Pencil Pressure; -SillInputScript has Saffsanity#80's steps and the pen's; --copy and --pen). - The checks: compatibility runs main's clipboard cases and the pen's, its mutants follow the new init; protocol and pointer-control list both; the README's rows and ci.yml's mutants matrix gain `pen`. - docs/DEVELOPMENT.md: main's hardware keyboard and clipboard sections, then Apple Pencil; site/privacy.html and CLAUDE.md likewise. Left for the commits after this one: the pen's kind 29 is a number main's clipboard, compatibility, protocol and pointer-control checks keep free (they fail on it here), PenStrokes.swift's project IDs AC01/FC01 are HardwareKeyboardPolicy.swift's since Saffsanity#80 (the iOS app does not build here), and the workspace file comes back. swift build -c release passes here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HunterAhlquist
pushed a commit
to HunterAhlquist/sill
that referenced
this pull request
Oct 19, 2026
The fork gave PenStrokes.swift A1000001000000000000AC01 and …FC01, free on 985a733; Saffsanity#80 has since given the same pair to HardwareKeyboardPolicy.swift on main. The project file merges without a conflict but then holds each ID twice, xcodebuild keeps one ("Skipping duplicate build file"), and the iOS build fails on HardwareKeyboardPolicy. A045/F045 (after the pen's kind) are in no project file on main or in any open pull request's head, checked against all of them today. CLAUDE.md's Layout line names the new pair. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HunterAhlquist
pushed a commit
to HunterAhlquist/sill
that referenced
this pull request
Oct 19, 2026
…s rebase Hunter's branch carried a 56-line Current step entry written for his fork (its "the owner" meant him, and its numbers were the fork's); every other open pull request edits the top of that section too, so the entry is now a short one in the section's usual form: what the branch is, the wire, the host, the device, what the maintainer's commits after the merge did, what was verified, and what waits for a device. The details stay where they were already: the plan, the Layout lines and Build and run. PenProbe's line in Build and run says a person runs --post-to-this-mac by hand at the Mac, never an agent (it said "the owner's to run"). docs/pencil-pressure-plan.md gains "Rebased onto main (2026-10-20)": the order of the branch (the stale hover on main's mouse path first, Hunter's five commits merged as they are, the maintainer's commits, main again), the merge's resolutions (WindowList's one init with both `clipboard` and `pencil`, the palm guard in handlePan before Saffsanity#80's shared scroll(gesture, .finger), the stale-hover flag giving way to PenStrokes.hover), kind 45 and the checks it touched, the project IDs, the workspace file, the site's markers, and what was verified with its numbers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
in.textand noin.keywhile he pressed Esc: the iPad never sent it. The device forwarded Esc only frompressesBegan, and iPadOS can keep a hardware Escape from there (UIKit's header: a key command needswantsPriorityOverSystemBehaviorto win over "focus or text-editing system commands"). Sideways there is no on-screen esc at all.allowedScrollTypesMaskreceives, and the stream's pan was fingers-only.What
Device only: no wire change, nothing on the Mac changed. The plan, its eleven open questions with the defaults taken, and every result:
docs/hardware-keyboard-plan.md.InputOverlayViewhas key commands for Esc with each of the sixteen combinations of ⌃, ⌥, ⇧ and ⌘ (wantsPriorityOverSystemBehavior, no title), only while it holds the keyboard and noEscapeKeyis on screen in its own window, so the tour's, the pairing overlay's and the Settings panel's Esc still win while they show. Each Sill window is its own: Settings open in one window leaves Esc to the stream in another, and anEscapeKey's Esc goes to the newest one in the window it was pressed in (EscapeKey.onScreen(in:),fire(in:)). One key press is sent once whichever channel brings it (ForwardedKeys.commanded,pressed,released: the press first, the command sends nothing; the command first, the press no later than it is swallowed with its up). The Settings panel's Done now answers Esc throughEscapeKeytoo (it keeps.cancelActionfor ⌘.). Debug builds print a line for every hardware key and the channel it came by (hwkey: usage 41 down via keyCommand (shift): to the Mac);-SillKeyProbe 1adds GameController's own view.HardwareKeyboardPolicy(new, pure, with its check): while a hardware keyboard is attached (GameController's coalesced keyboard) and nothing open takes the keyboard (Settings, pairing, the tour, the Apps list, the Menus pull-down), the input view holds the keyboard by itself: at a session's start, after a rotation or a reconnect, and when the last of those closes; it lets go while one is open and when the keyboard goes. That hold is never counted as the person's own: the Keyboard button stays dark, and the tour's busy and activity tests ignore it, so keyboard users still get the tour. Nothing is drawn during it (an empty input view, no shortcuts bar), so no on-screen keyboard comes up over the stream even where UIKit and GameController disagree. The Keyboard button keeps its meaning for the software keyboard: pressed over the hold it becomes the person's (iPadOS's own keyboard views come back), pressed again the software keyboard goes and keys still reach the Mac.Tests/keyrig(TEST ONLY, asTests/duorig): a virtual HID keyboard and mouse inside a simulator of your own, so UIKit routes real key and scroll events. Its README has what it showed.The review, fixed
An adversarial review of 2fc53ed re-ran every claim. Each finding was checked here against the code first, then fixed in a commit of its own:
EscapeKeyacross Sill's windows (should-fix; bdc121d).EscapeKey.onScreencounted EscapeKeys in every window, so Settings, the tour, the pairing overlay or the Add a Mac card open in one window removed the stream's Esc key commands in every other, andfire()answered with the newest EscapeKey in any window. NowonScreen(in:)andfire(in:)take the window. Reproduced on a private iPad simulator (-SillSecondWindow 1 -SillSettings 1 -SillEscViaCommand 1, the key rig's Esc then "a"): before, Esc was handed on and the host got only the "a"; after,via keyCommand (none): to the Macand the host got key 53 down and up.toggled()), so the plan has open question 11 (default: the hold as for anyone; UIKit can tell Switch Control, not Full Keyboard Access) and step 13 for Noah.And the two claims that did not hold: this pull request now says Towards #68 (no real trackpad's events reached the continuous pan); and
run-all.sh'sprotocolcheck has a p = 0.001 statistical case ("digits uniform", StreamProtocol's pairing-code generator, not touched here) that failed once for the reviewer and passed alone. Here, on 7fdc902,run-all.shpassed all 41 at the first run.Verified
Before the review (2fc53ed and earlier; the plan's Results):
Tests/checks/hardware-keyboard(new): 51 checks and 20,000 random sessions (690,353 events) against six invariants; 31 of 31 mutants caught; added to CI's mutants matrix.Tests/checks/key-strokes: 347 checks (329 before, 18 new, Esc's key command among the random sessions' keys); 81 of 81 mutants (9 new).CODE_SIGNING_ALLOWED=NO), andswift build -c release: main's warnings only.SillHost --syntheticon loopback (software encoder, its input log), with keys and wheels fromTests/keyrig: Esc, typed text, ⌘W (key 13 with command; Sill's window stayed) and F5 reached the Mac with no Keyboard button; on an iPhone, after a turn sideways and back too; Esc, ⇧Esc, ⌘Esc and ⌥⌘Esc through UIKit's key-command dispatch with their flags; with Settings open Esc closed it and nothing reached the Mac, then keys flowed again; the tour showed with a keyboard attached, a key during it reached nothing, Esc skipped it; a keyboard going let the hold go and its return took it back; on a fresh iPhone the Keyboard button brought the software keyboard up and took it down as main's does; one, two and one wheel notches gave 1, 2 and 1 scrolls.After the review (on 7fdc902; the commit after it is docs only):
CODE_SIGNING_ALLOWED=NO, from new derived data: each succeeded (22, 38 and 18 s) with only the StreamClient.swift:3430 capture warning and appintentsmetadataprocessor's note. The Release binary holds none of the DEBUG strings (the newescape:lines included) and links GameController.swift build -c releasefromgit archiveof 7fdc902: complete in 43.4 s, only the CaptureProbe warning.Tests/checks/run-all.sh: all 41 passed at the first run (347 s; hardware-keyboard 51 checks, key-strokes 347,protocolALL PASS). No check compiles a file the review changed (AddMacCard.swift, InputOverlay.swift, ContentView.swift), so the mutants were not run again: 31 of 31 and 81 of 81 stand.onScreen(in:): 72 scenarios on main's surfaces and on this branch's,compare.py72 checks, 0 failed.swift build -c releasein 51 s,run-all.shall passed with hardware-keyboard's 51 and key-strokes' 347, the iOS app on Xcode 27.1 27A9269 with only the StreamClient capture warning) and on the head 46b208c (run 38499812932).SillHost --synthetic: the two-window case above, before and after; a tour in each of two windows, then Settings opening in the one behind: Esc in the front window closed its own tour and left the other window's EscapeKey alone (1 in other windows, left alone); in one window, Esc closed Settings with nothing at the host, then Esc and "a" reached it; the tour showed 1.10 s after the picture with the keyboard attached, a key during it reached nothing, Esc skipped it, then keys reached the host; Esc, ⇧Esc and ⌥⌘Esc through the key command (-SillEscViaCommand 1), key 53 with each one's flags;-SillInputTest 1's Esc, ⇧Esc and scrolls (104 scroll events); the harness's Add a Mac card closed on Esc. No screen changed, so no harness photos were taken again. The simulators are deleted.Untested, for Noah
On the iPad with a Magic Keyboard, a Debug build (the console's
hwkey:,escape:andkeyboard:lines), streaming a window; the plan's "Untested, for Noah" has each step:hwkey: … via pressesBeganorvia keyCommand; with-SillKeyProbe 1, if onlyvia GameControllercomes, the next fix is a GameController path).-SillTourState fresh) with the keyboard attached.When steps 1, 7 and 9 pass, the words waiting in the plan go into README, the support page and the App Store text.
For the reporter (#67): Control-[ reaches the Mac as Control plus the [ key, which iTerm2, zsh's vi mode and Zed's vim mode take as Escape (untested on a device).
Towards #67 (a device decides which channel brings Esc, and the
hwkey:lines say so). Towards #68 (a real trackpad's two-finger scroll, and whether iPadOS adds a second coast, need a device).🤖 Generated with Claude Code