Repository navigation
fix(ios): deliver simulator edge swipes as screen-edge touches - #4211
Conversation
|
@gronxb is attempting to deploy a commit to the Callstack Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
All reported issues were addressed across 15 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
|
At c57133a, two issues need fixes before merge. Could the HID contact owner guarantee a terminal event before dispatching touch-down? Touch-up construction can fail after down, including after a failed move, leaving UIKit with an active finger and subsequent interactions in the wrong state. Reserve and retain a usable release or cancel event across every exit, and test constructor failures after down to verify terminal dispatch before disposal. The runner execution decision selects an eased HID schedule while successful edge flings report endpoint-hold. CLI JSON, Node and MCP consumers therefore receive incorrect timing metadata. Return the actual schedule through the backend result, preserve it in gestureResponseData, and amend ADR 0013 and the timing vocabulary to describe the edge schedule while keeping simulator policy out of shared semantic parsing. Could the existing runner execution policy resolve contact kind and motion schedule together, return the schedule through backendResult, and keep event creation and guaranteed terminal dispatch in one HID contact owner? Align the execution-profile contract and ADR 0013 first, then remove competing timing inference when execution supplies its schedule. Not blocking: You can take or leave an app-observed regression through the production gesture command that checks edge-recognizer began and ended, navigation pop, and ordinary swipe and pan controls, while retaining the planner and wire-contract checks. The two existing threads no longer apply: constructor failure now propagates an error, and registry IDs now skip unreadable IDs. Your app-observed report covers 3/3 edge cases on iOS 26.4, 27.2 and the Duo open and closed, with ordinary swipe and pan controls. Physical devices keep their previous route. The only failing check is the Vercel deployment authorization, which is not a code problem. No conflicts are known. Before merge, please guarantee a terminal touch event, return the actual timing, and rerun the edge-recognizer cases with the swipe and pan controls on the fixed head. |
There was a problem hiding this comment.
All reported issues were addressed across 16 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
|
At 48bd4f0, both earlier issues are fixed. A terminal event is reserved before touch-down and sent on every exit, and the runner now reports the schedule it actually ran. The new fault cases catch the old missing-terminal regression. Your live run on the native fix plus the metadata recheck at this head cover the change. One design question before merge: could the contact function stay private to its owner? The new The earlier threads on contact failures, registry IDs, touching state and schedule names are fixed, and the ADR example now matches the code. The only failing check is the Vercel deployment authorization, which is not a code problem. No conflicts are known. |
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
|
At 7a39ef0, the code looks good. The contact owner is now private to its file, and the fault-injection facade lives in The only failing check is the Vercel deployment authorization, which is not a code problem. No conflicts are known. |
|
At 9544fa2, the selector now accepts a touchscreen that names no Could the eligibility rule then be narrowed to what that host shows? Today a sole candidate is accepted whether its The first-run left-edge failure after a boot or fold is worth keeping an eye on, but nothing ties it to this change. The only failing check is the Vercel deployment authorization, which is not a code problem. No conflicts are known. |
|
At 8a57d06, a touchscreen without The newly accepted candidate has only been selected from fake HID services, so affected hosts may still fail to deliver screen-edge touches despite the passing unit tests (selection). Please run the edge-preset repro at this head on an affected iOS 18.1 or 26.5 host and capture the HID service inventory, the selected registry ID with Transport missing, and passing app-observed results for all three edge recognizer and navigation cases and the in-page controls. Could touchscreen eligibility and ambiguity use one typed simulator service-identity selector, with diagnostics derived from its selection? First, establish a reliable identity for the missing-Transport service from affected-host evidence. The only failing check is the Vercel deployment authorization, which is not a code problem. No conflicts are known. |
XCTest synthesized touches carry no digitizer edge mask, so on an iOS simulator gesture swipe left-edge and right-edge never started a UIScreenEdgePanGestureRecognizer or the navigation edge pop gesture. Edge swipe presets now plan a screen-edge contact. On an iOS simulator the runner dispatches it as one HID touch with the edge mask, through the touchscreen service of the app's display. Other gestures and physical devices keep their current paths. Fixes callstack#4208
A frame that failed to build was dropped while the gesture still reported success. Fail before touch-down, lift early after a failed move, and return the reason instead.
The edge recognizer on a rotated panel, such as the iPhone Duo inner panel, never began: FromEdgeFlat/Tip touches carry no swipe direction, and a fast first move left the edge region in one frame. A hand swipe on the simulator carries SwipeLocked and the native swipe direction on every frame and starts slowly. Send the same mask, ease the contact in along the planned path, and use the display's oldest touchscreen service when a window adds another.
A service whose registry ID could not be read still counted as a match, so a later valid service could leave the sender at 0.
…vent A touch-up that could not be built after touch-down left UIKit with an active finger. The edge contact owner now builds a cancel event before touch-down and, after touch-down, sends the touch-up or that cancel on every exit. Unit tests fail each HID constructor in turn and check what reaches the event system.
Edge flings ran an eased HID schedule but reported endpoint-hold. The runner execution policy now resolves the contact and its schedule together and returns the schedule as executionProfile. The daemon keeps a reported schedule and infers the planned profile only when a backend reports none. ADR 0013 records edge-ease-in and the reporting rule.
Address review: a backend-reported executionProfile is what ran, so the daemon keeps any reported string and reports the planned profile only when a backend reports none. Drop the TS schedule list that existed only to filter it. The cancel test also checks that touch-down and each move before the cancel touched.
Address review: the contact function and HID table were exported only so unit tests could inject faults. Make them static and compile the test facade in the same file under AGENT_DEVICE_RUNNER_UNIT_TESTS, so the packaged runner ships no fault-injection interface.
…runner Address review: the packager copies Objective-C sources verbatim, so the AGENT_DEVICE_RUNNER_UNIT_TESTS block in RunnerSimulatorEdgeTouch.m shipped and the package leak guard rejected it. Move the contact owner into a header whose declarations all have internal linkage, include it from the runner and from the test facade in UnitTests/, and keep the shipped source free of the unit-test macro.
Reported on iOS 18.1 and 26.5 simulators: the display's touchscreen service passed the usage, display and registry checks but read no Transport, so edge swipes failed with "no simulator touchscreen HID service". The oldest CoreDevice touchscreen still wins. Without one, the display's only remaining candidate is used, and several are refused as ambiguous with how each Transport read (missing, other type, other value). The no-candidate error now names the stage that rejected the touchscreens. Unit tests cover the reported service, CoreDevice precedence, duplicates, ambiguity and the error.
…ole one Address review: the fallback accepted a sole candidate whatever its Transport read. Only a missing Transport has been reported, so a touchscreen with a Transport of another value or type is no longer a candidate, and the display refuses to pick a sender while one is present without a CoreDevice touchscreen. The runner logs the selected service and its properties as AGENT_DEVICE_RUNNER_EDGE_TOUCHSCREEN so a host run shows which sender an edge touch used.
8a57d06 to
3b94f2e
Compare
|
At 3b94f2e, the code looks good and the rebase keeps the edge-contact behavior. The evidence I asked for in the earlier review is now in the PR body: the headless iOS 26.5 run at this head reaches the touchscreen that reports no The CI jobs on this head are still queued, and none has failed. No conflicts are known. |
|
At 7483e8d, the code looks good. The new commit is empty, so the tree is the same as 3b94f2e, which I reviewed earlier (#4211 (comment)). All 11 checks now pass and there are no conflicts. |
Summary
On iOS simulators,
gesture swipe left-edge/right-edgenever started edge recognizers or the navigation edge pop: XCTest touches carry no edge information, even at x = 0.Edge presets now plan a
screen-edgecontact (contactOrigin). On an iOS simulator, the runner sends that plan as one HID contact the way a hand swipe arrives:SwipeLockedplus the native swipe direction on every frame, through the oldest touchscreen service of the app's display (the lit panel on a foldable). The contact eases in along the planned path, because a first move that leaves the edge region in one frame fails the recognizer on a wide panel. Edge and sampled gestures resolve their surface and native samples through one helper on the surface geometry from #4189.UnitTests/, which the packager drops.CoreDeviceone wins, as before. A touchscreen hasTransport=CoreDeviceonly while Xcode's Device Hub shows the simulator, through the simulator'sdtuhidd. A headless simulator, or one without Device Hub, has only theSimulatorHIDtouchscreen, which names noTransport(reported on iOS 18.1 and 26.5); without aCoreDevicecandidate, the display's sole touchscreen with a missingTransportis used. Several such touchscreens are ambiguous, and aTransportof another value or type refuses, so an unexpected sender is never picked. Errors name the stage that rejected the touchscreens. The runner logs the chosen service and its properties asAGENT_DEVICE_RUNNER_EDGE_TOUCHSCREEN.executionProfile(edge-ease-infor this path).gestureResponseDatakeeps any schedule the backend reports and uses the planned profile only when a backend reports none. ADR 0013 recordsedge-ease-inand that rule. Plans still cannot request it.Other gestures and physical devices keep their paths. 23 files. Fixes #4208.
Validation
Rebased onto
66438647e(#4189 replaced the rotation frame with surface geometry). At3b94f2eae:pnpm check:affected --run --base 66438647e --head 3b94f2eae: passed,exactCommit=true.pnpm check:package: passed.testAlertActivationConfirmsBeforeDeadlineWithoutHandlingTheNotificationBannerandtestFreshCoordinateTapContainsUnavailableTextInputProbefail on66438647etoo../repro.sh: iPhone 16e iOS 26.4, iPhone 16e iOS 27.2, iPhone Duo iOS 27.1: 5/5 each, every edge touch through the touchscreen withoutTransport.Before the rebase, at
8a57d06ae, base035c2b6ca. The repro tables below ran at8a57d06ae, except iPhone 16 (9544fa2cf; it was taken by another session), replaced by iPhone 17 Pro on iOS 26.4.pnpm check:package: passed, no test code in the packed files.pnpm check:affected --run --head 8a57d06ae: passed,exactCommit=true.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS=1, iOS 26.4) include HID constructor failures at each frame and touchscreen selection over fake services. Without the cancel dispatch, the move/lift failure test fails. The reported service (noTransport) failed selection withdisplay 1 has no simulator touchscreen HID servicebefore9544fa2cf../repro.sh, three edge cases plus in-page swipe and pan controls:9544fa2cf)Headless (
simctl boot, no Device Hub), every touchscreen withoutTransport:9544fa2cf(7a39ef071)8a57d06aedisplay 1 has no simulator touchscreen HID serviceCoreDevicetouchscreen of the app's display. Headless, every run selected the display's sole touchscreen withoutTransport. A headless scan of iOS 26.4, 26.5, 27.0, 27.1 and 27.2 (iPhone, iPad, Duo) found noTransporton any touchscreen.--jsontiming:right-edge→edge-ease-in,swipe right→endpoint-hold,pan→timed-pan.touchesCancelled, and the next touch begins normally.Open risks: physical devices are unchanged and untested. On the first run right after a fold, the left-edge recognizer case failed once on the Duo: the touchscreen it selected was not yet in the service list printed seconds earlier, so the fold was still recreating the display's HID services. The next two runs passed 5/5.