Skip to content

VirtualDisplay: the BOOL return's encoding follows the architecture - #87

Merged
Saffsanity merged 7 commits into
Saffsanity:mainfrom
kyleparisi:virtual-display-bool-encoding
Oct 19, 2026
Merged

Saffsanity merged 7 commits into
Saffsanity:mainfrom
kyleparisi:virtual-display-bool-encoding

Conversation

@kyleparisi

Copy link
Copy Markdown
Contributor

applySettings: is the one selector in VirtualDisplay.Runtime.privateAPISurface that returns BOOL, and its expected encoding was the literal "B@:@". That is what the Objective-C runtime reports only where OBJC_BOOL_IS_BOOL holds, which is arm64. On x86_64 macOS BOOL is signed char, so the runtime reports "c@:@", Runtime.method throws Failure.changedSignature, and the virtual display is given up on even though CGVirtualDisplay is present and working normally.

The fix takes the encoding per architecture. No behaviour change on arm64 — the encoding there is the "B@:@" it has always been.

I appreciate this is a file that deliberately refuses to guess about private API, which is exactly why the wrong expectation is worth correcting: the guard is doing its job, it is just checking against a spelling that only one architecture uses.

How it shows up

swift run -c release SillHost --virtual-display-selftest on an Intel Mac, before:

Virtual display self-test (macOS Version 15.7.3 (Build 24G419))
  Screen Recording preflight: true, Accessibility trusted: false [informational]
  FAIL CGVirtualDisplay applySettings: changed signature: expected B@:@, found c@:@

After:

  private API: all 17 selectors present
  created id 4128835 in 14 ms; online at requested mode: true after 1832 ms
  bounds (0.0, 0.0, 1000.0, 700.0), backing 2000×1400 px
  cursor reach: warp to (500.0, 350.0) → (500.0, 350.0) (on display: true)
  CGGetOnlineDisplayList contains it: true; CGDisplayIsActive true
  SCShareableContent lists it after 88 ms
  destroyed: gone from CGGetOnlineDisplayList after 54 ms: true

In a running host the symptom is quieter: every --virtual-display pick logs the Virtual display fallback … line and streams the real window, so it reads as "the private API moved" rather than "this Mac spells BOOL differently."

Environment

Hardware Mac mini (2018), Macmini8,1 — 6-core Intel Core i5-8500B @ 3.0 GHz, Apple T2, Intel UHD 630
macOS 15.7.3 (24G419)
Toolchain Command Line Tools 16.4, Apple Swift 6.1.2 (swiftlang-6.1.2.1.2 clang-1700.0.13.5), macOS 15.5 SDK
Base commit 985a733 (main)
Device iPhone (iPhone17,5), Sill 0.5.1 (4) from the App Store

Note this is not the documented toolchain (Xcode 27 on macOS 26/27), because Xcode 27 cannot be installed on macOS 15. Built with swift build -c release and Scripts/make-app.sh under Command Line Tools only.

Context: what else an Intel build needs

Not part of this PR, recorded in case it is useful to anyone else arriving here. The repository is otherwise architecture-clean — no #if arch(...) anywhere in Sources/ or iOSClient/, and no ARCHS pinning in the Mac build scripts. The arm64-only binary is a consequence of swift build defaulting to the host architecture, exactly as Scripts/release.sh's own comment anticipates ("The site says Apple silicon: change that if this ever lists x86_64"). The encoding above was the single genuine architecture dependency I found, and it is invisible to a grep because it lives in a string literal.

One further change is needed to compile on macOS 15, which I am deliberately not proposing: StreamProtocol/RemoteIdentity.swift calls SecIdentityCreate, which is declared in Security/SecIdentity.h in the macOS 26 SDK and no earlier one (macOS 15.5's header has only SecIdentityCreateWithCertificate). The symbol itself has shipped in Security.framework for years — dlsym finds it on macOS 15.7.3 — so a local @_silgen_name declaration returning Unmanaged<SecIdentity>? (CF Create rule) is enough to build. That is me compiling against an SDK the project does not claim to support, so it belongs in my tree, not yours.

Performance on this hardware, for the record

The virtual display works, but Apple silicon's encoder is doing much more of the work than an Intel/T2 machine can. Posting the numbers because the README's Apple silicon requirement is well justified on throughput grounds, and anyone finding this issue should know what to expect rather than assume a misconfiguration:

This Mac mini (T2) Repo's figures (Apple silicon)
Frame age (encode → device) 55–61 ms (max 123–136) 8–10 ms
rtt, same LAN 4–6 ms 6–9 ms
Hardware HEVC, 3024×1898 cap.complete 60 → enc.out 37, enc.mailboxDrop 23 57–60 fps after a session refresh
Sustained synthetic stream 36.3 fps, 0 network drops ~60 fps

The network is not the constraint; the encoder is, at roughly 27 ms/frame where Apple silicon manages 9. Glass-to-glass lands near 80–110 ms rather than the 40–60 ms the brief targets. Dropping Resolution to Standard helps considerably more here than it would on Apple silicon.

Two T2-specific notes that may interest you independent of Intel:

  • The T2's AVE encoder is single-instance. A second concurrent session fails in the kernel with Cannot open AVE instance, there appears to be another instance already open! → err = -12915. The slow-state session replacement in HEVCEncoder (replacesSlowSessions, on by default) opens a new session alongside the live one, which cannot succeed on this hardware. In practice it never fired during real use — SILL_TEST_ENCODER_RECYCLE=0 is the escape hatch — but the "two sessions share one engine" assumption documented in CLAUDE.md is arm64-specific.
  • --encoder-selftest fails on this machine for the same reason: its 256×256 launch probe still holds the engine when the stream-sized session opens. Normal host startup is unaffected, since the probe is released before streaming begins.

Tested

  • Tests/checks/run-all.sh — 39 of 40 pass. The exception is duo, which fails for a reason unrelated to this change and would fail the same way on an unmodified main with this toolchain: on Swift 6.1.2 the type checker gives up on a literal CGFloat sum in the check's own source.

    Tests/checks/duo/main.swift:115:5: error: the compiler is unable to type-check
    this expression in reasonable time; try breaking up the expression into
    distinct sub-expressions
    115 | let controls: CGFloat = 12 + 78 + 2 * 10 + 48 + 22
    

    That check compiles only iOSClient/DuoPosture.swift and its own main.swift, neither of which this PR touches. Swift 6.3 under Xcode 27 evidently handles the expression; annotating the literals (or splitting the sum) would make the check build on older toolchains too, if that is worth anything to you.

  • swift build -c release, and Scripts/make-app.sh (ad hoc signed; actool is unavailable without Xcode, so the icon is generic)

  • --virtual-display-selftest before and after, output above

  • Sill.app 0.5.1 running as the host: paired with the App Store iPhone app via QR over the TLS home door, streamed the whole desktop at 4096×2304 and individual windows (Chrome, iTerm2), switching sources live

  • No encoder fallback, hang, or slow-state replacement in the log across the session

Not tested: anything on arm64 — I have no Apple silicon Mac, so the unchanged "B@:@" path is reasoned about rather than run. The iOS app was not built (it needs the iOS 27.1 SDK, unreachable on macOS 15); the App Store build was used instead. If a reproducer uses a shallow clone, note that make-app.sh derives CFBundleVersion from git rev-list --count HEAD and will report a wrong build number.

On Intel support generally

I am not asking you to support Intel Macs, and closing this is a perfectly reasonable call — the throughput numbers above make the case for the Apple silicon requirement better than any argument would. The encoding fix stands on its own though: it is two lines, changes nothing on arm64, and makes the private-API guard check what the platform actually reports instead of rejecting a working method.

`applySettings:` is the one selector in `privateAPISurface` that returns
`BOOL`, and its encoding was spelled "B@:@". That is what the Objective-C
runtime reports only where `OBJC_BOOL_IS_BOOL` holds, which is arm64. On
x86_64 macOS `BOOL` is `signed char`, so the runtime reports "c@:@",
`Runtime.method` threw `Failure.changedSignature`, and every virtual display
fell back to streaming the real window although `CGVirtualDisplay` was
present and working.

Found on an Intel Mac (Core i5-8500B, Apple T2) on macOS 15.7.3, where
`--virtual-display-selftest` reported:

  FAIL CGVirtualDisplay applySettings: changed signature: expected B@:@, found c@:@

With the encoding taken per architecture the same selftest reports all 17
selectors present, and creates, brings online at 2x, warps the cursor onto
and destroys a display normally. No change on arm64: the encoding there is
the "B@:@" it always was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sj4qVTN3JiDaQL1FjyycXv
@Saffsanity

Copy link
Copy Markdown
Owner

From a pass over all the open pull requests (nothing is decided yet): this pairs with #88, which makes Sill.app universal, and with both as they are the x86_64 slice would refuse the virtual display on macOS 26 Intel Macs, because the tester in #62 ran an x86_64 build on macOS 26.7.1 that passed the self-test with B@:@. Accepting both B@:@ and c@:@ on any architecture (with the return typed as ObjCBool) would let the two ship together and let CI's arm64 build compile the check; the comment near the call also says Failure.changedSignature where the case is signatureChanged.

Saffsanity and others added 3 commits October 20, 2026 00:53
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>
…s ObjCBool

This branch took applySettings:'s encoding from the architecture ("c@:@"
on x86_64, "B@:@" on arm64). But the spelling comes from how the Mac's
CoreGraphics was built, and x86_64 has spelled it both ways:
- An Intel Mac mini with macOS 15.7.3 reported "c@:@" (this pull request).
- An Intel machine with macOS 26.7.1 passed the self test with an x86_64
  build of 985a733 (build 585), which expected "B@:@" alone (Saffsanity#62). The
  encoding itself was not printed.
- Under Rosetta on macOS 27.0.1 this Mac reads c24@0:8@16; natively it
  reads B24@0:8@16.
With #if arch, the x86_64 slice that Saffsanity#88 builds would have refused the
virtual display on macOS 26 Intel Macs, the newest macOS they can run.

What changes, as Noah asked here on 2026-10-19:
- privateAPISurface writes the return "B" again. Runtime.method also
  accepts it spelled "c" (VirtualDisplay.TypeEncoding.accepted), on every
  architecture. There is no #if arch, so CI's arm64 build compiles the
  only path. A refusal now reads "expected B@:@ or c@:@, found ...".
- applySettings: returns ObjCBool, which is BOOL on each architecture.
  On x86_64 any byte but 0 is YES, which is right for both spellings; a
  Swift Bool takes AL as it comes. On arm64 it compiles to the same code
  as the Bool before.
- The comment that named Failure.changedSignature went with #if arch. The
  new one names Failure.signatureChanged, the case's real name.
- normalized moves into TypeEncoding beside accepted. Both are pure, for
  a check (next commit).

docs/DEVELOPMENT.md says what the self test checks first, and names the
two spellings.

Verified on this Mac (M2 Pro, macOS 27.0.1):
- swift build -c release, arm64 and --arch x86_64 (own scratch path):
  only the known CaptureProbe warning, plus --arch's notice that x86_64
  is deprecated.
- --virtual-display-selftest, arm64 and under arch -x86_64. A temporary
  switch, not committed, skipped its pointer warp, HID move and
  ScreenCaptureKit call. "private API: all 17 selectors present" with
  B24@0:8@16 natively and c24@0:8@16 under Rosetta. The 1000x700 display
  came online at 2000x1400 (applySettings: returned YES through ObjCBool)
  and was gone 53 and 66 ms after destroy. Exit 0 both times.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inst measured encodings

Neither CI nor any Mac here ever reads applySettings: spelled "c" except
under Rosetta. So without a check, nothing would catch the previous
commit's rule if it broke. The rule is pure (VirtualDisplay.TypeEncoding),
so it gets a check, as CLAUDE.md's conventions ask.

What it checks:
- Every method's encoding, as method_getTypeEncoding gave it on an M2 Pro
  with macOS 27.0.1, natively and under Rosetta, passes for its entry.
  These come from a probe that only looks the methods up.
- applySettings: as reported from Intel Macs passes too: "c@:@" on macOS
  15.7.3 (Saffsanity#87) and "B@:@" on macOS 26.7.1 (Saffsanity#62, inferred).
- The surface has one entry per measured method, written without offsets.
- A BOOL return passes spelled "B" or "c". Nothing else passes: not
  another type, not a BOOL argument, not a void or object return; an entry
  written "c" stays "c".
- normalized removes the offsets and nothing else.

It compiles VirtualDisplay.swift whole, as VirtualDisplayProbe does. Only
the static surface and TypeEncoding run, so it looks up no private class
and makes no display. Runtime.method's three lines that call the rule are
glue, which the self test exercises.

141 checks; 13 of 13 mutants caught: the c spelling dropped, only c, every
return or any B widened, "C" for "c", the c before the B, "c" widened to
B, the offsets kept or alone kept, applySettings: written c, setHiDPI:
written as a BOOL, a method left off, an entry with offsets. Listed in
Tests/checks/README.md, CLAUDE.md's Layout, docs/DEVELOPMENT.md and ci.yml's
mutants matrix. run-all.sh with it, keychain, origin, clientlink and
settings-window: all passed.

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
…ry slice

Noah wrote here on 2026-10-19 that whether releases go universal is still
open in Saffsanity#62. As this branch stood, make-app.sh made every build universal,
which settles that question. The next release.sh run would ship an x86_64
slice that has never streamed on an Intel Mac, and every --install --open
would take twice as long.

What changes:
- make-app.sh builds both slices only with SILL_UNIVERSAL=1. That path is
  this pull request's own, unchanged: one build per triple, its own
  scratch path, lipo. Unset, it builds for this Mac's architecture as
  before, and still refreshes .build/release/SillMenuBar. Measured on an
  M2 Pro with Xcode 27.1 (2026-10-20): 50 s cold against 97 s universal;
  after a one-line host change, 21 s against 42 s.
- release.sh's check_signature reads every slice. codesign verifies every
  architecture but shows only this Mac's, so an x86_64 slice without
  Developer ID, the hardened runtime or a timestamp would have passed. It
  now loops over lipo -archs with codesign --architecture, and reads each
  slice's entitlements once, into a variable (not a pipe into grep -q).
- docs/DEVELOPMENT.md says how to build a universal Sill.app for an Intel
  tester. README, the site, the App Store text and the cask's depends_on
  arch stay Apple silicon until the x86_64 slice has streamed on an Intel
  Mac. CLAUDE.md's Layout and Build and run say the same.

Verified on this Mac (M2 Pro, macOS 27.0.1, Xcode 27.1):
- swift build -c release, arm64 and --arch x86_64 (own scratch path):
  only the known CaptureProbe warning, plus --arch's x86_64 deprecation
  notice.
- make-app.sh without --install: unset gives "arm64"; SILL_UNIVERSAL=1
  gives "x86_64 arm64". Both: minos 14.0 and sdk 27.0 on every slice,
  codesign --verify --deep --strict passes, build 702.
- A dry run of release signing, universal (SILL_RELEASE_DRY_RUN=1,
  Developer ID, no profile): both slices have Developer ID, the hardened
  runtime and a timestamp; check_signature passes; spctl says
  "Unnotarized Developer ID". The bundle was deleted after.
- check_signature stops a development build at "(x86_64) is not signed
  with Developer ID". Against a stand-in codesign whose x86_64 slice lacks
  the hardened runtime, main's check_signature passes and this one fails.
- With Saffsanity#87's change applied and a temporary switch (not committed) that
  skips the self test's pointer warp, HID move and ScreenCaptureKit call,
  the universal binary's --virtual-display-selftest passes on both slices:
  B24@0:8@16 on arm64, c24@0:8@16 on x86_64 under Rosetta, all 17
  selectors, the display online and destroyed.
- Without Saffsanity#87, the x86_64 slice fails ("expected B@:@, found c@:@"), so
  the two ship together.
- Tests/checks/run-all.sh dmg-layout keychain update-policy clientlink:
  all passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity and others added 3 commits October 20, 2026 04:09
Main moved from d1fa97e to 9a8e30c with Saffsanity#136 (the Apps list's folders,
Saffsanity#76), which added the installed-apps check. It and this branch each added
a check to ci.yml's one-line mutants matrix, which conflicted: the line
now lists both, installed-apps and virtual-display-api, in sorted order
with the 43 it had. Tests/checks/README.md and CLAUDE.md merged by
themselves and keep both checks' rows and Layout entries. Saffsanity#136 did not
touch VirtualDisplay.swift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ySettings: call

The check compared a hand copy of Runtime.method's decision with
TypeEncoding, so it could not tell when Runtime.method itself stopped
using the rule. With Runtime.method's guard back to main's equality,
which is this pull request's bug, or with the applySettings: call
expecting "c@:@", which would refuse the display on every Apple silicon
Mac, all 141 checks still passed (the review of fcc4957).

Two internal ways into the private Runtime, each used by the code as
well as by the check:
- VirtualDisplay.methodProblem(cls:selector:encoding:) gives
  Runtime.method's decision for one entry of the surface: nil, or the
  line checkPrivateAPI lists. checkPrivateAPI now asks it for every
  entry, setDispatchQueue: still standing in for setQueue:, with the
  same lines as before.
- VirtualDisplay.applySettings(_:to:) is Runtime.applySettings moved
  out of Runtime, its body unchanged; init sends applySettings: through
  it.

The check makes NSObject subclasses at run time (objc_allocateClassPair,
class_addMethod) instead of copying the decision:
- Every encoding it judged by hand (measured, reported or made up) is
  put on a method of such a class and judged by methodProblem.
- Three more classes have an applySettings: typed B24@0:8@16, c24@0:8@16
  and C24@0:8@16, answering what the NSNumber they are sent says.
  methodProblem takes the first two for the surface's "B@:@" and refuses
  the third with "... changed signature: expected B@:@ or c@:@, found
  C@:@". applySettings(_:to:) reads YES and NO from the first two, and
  the third is refused before it is called.
- A method a class lacks and a class that is not there give their lines.
No private class is looked up and no display is made.

152 checks, 0 failed (141 before); compiled for x86_64 and run under
Rosetta, the same. 17 of 17 mutants caught, each by a failing check: the
13 before, and four of the glue: Runtime.method's guard back to one
spelling, Runtime.method without normalized, applySettings: sent
expecting "c@:@", and applySettings:'s NO read as YES. ApplyFn returning
Bool is not among them: on arm64 that compiles to the same code as
ObjCBool, so no arm64 run can catch it.

Comments: the macOS 26.7.1 machine in Saffsanity#62 runs macOS through OpenCore,
and its "B" is inferred; TypeEncoding's sources are measured on Apple
silicon and reported from Intel machines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tests/checks/README.md: virtual-display-api's row says what runs now
  (Runtime.method's decision and the applySettings: call, on classes the
  check makes at run time), 152 checks and 17 mutants, and what CI does
  not see: on arm64 the only "c" methods are the check's own, and
  ObjCBool compiles to the same code as Bool there. The row also says
  the macOS 26.7.1 "B@:@" is inferred, not printed, from build 585
  passing the self test on an OpenCore machine (Saffsanity#62). The paragraph on
  the counts says the check came with Saffsanity#87.
- docs/DEVELOPMENT.md said macOS has spelled the BOOL both ways on Intel
  Macs. Now: an Intel Mac mini with macOS 15.7.3 printed "c" (Saffsanity#87); "B"
  on Intel is inferred from that OpenCore machine; Apple silicon reads
  "B", and "c" under Rosetta.
- CLAUDE.md's Layout says what the check runs, and that the Intel
  encodings are reported, not measured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Saffsanity

Copy link
Copy Markdown
Owner

Three commits were added on this branch since fcc4957; the head is now 71aec66.

  1. A merge of main (9a8e30c). Apps list: the apps in a folder of their own (#76) #136 added the installed-apps check to the same one-line mutants matrix in ci.yml, so the line conflicted. It now lists both checks. Main has not changed VirtualDisplay.swift.
  2. The check now runs the real decision. Before, Tests/checks/virtual-display-api judged encodings with a copy of Runtime.method's logic, so reverting Runtime.method's guard to the old equality (the bug this pull request fixes), or making the applySettings: call expect "c@:@", still passed all 141 checks.
    • VirtualDisplay.methodProblem(cls:selector:encoding:) gives Runtime.method's decision for one entry of the surface; checkPrivateAPI now uses it and lists the same lines as before.
    • VirtualDisplay.applySettings(_:to:) is Runtime.applySettings moved out of Runtime unchanged; init calls it.
    • The check makes NSObject subclasses at run time (objc_allocateClassPair, class_addMethod) and puts each encoding on a method of one. Three have an applySettings: typed B24@0:8@16, c24@0:8@16 and C24@0:8@16: the first two pass and read YES and NO through ObjCBool; the third is refused with "expected B@:@ or c@:@, found C@:@". No private class is looked up.
    • 152 checks; 17 of 17 mutants caught, among them the guard reverted, normalized dropped, the call expecting "c@:@" and the answer ignored. ApplyFn returning Bool is not among them: on arm64 it compiles to the same code as ObjCBool, so CI cannot tell them apart.
  3. Docs. docs/DEVELOPMENT.md and the checks README now say the "B" on macOS 26.7.1 is inferred, not printed: Feature Request: Support Intel based Macs #62's OpenCore machine passed the self test with an x86_64 build that took "B" alone. The README row also says that on arm64 the only "c" methods the check runs are its own.

Verified on an M2 Pro with macOS 27.0.1: release builds for arm64 and x86_64; the check and its mutants, and the check built for x86_64 and run under Rosetta; run-all.sh for virtual-display-api, installed-apps, keychain and origin; a scratch driver built from this VirtualDisplay.swift, which natively read B24@0:8@16, found all 17 selectors and created a display that came online at 2000×1400, and under Rosetta read c24@0:8@16 and found all 17 selectors (on fcc4957 the same driver also created and removed a display under Rosetta), without the self test's pointer warp, HID move and ScreenCaptureKit steps.

Nothing has run on Intel hardware; the merge commit will say so. It merges once CI passes on this head, with #88 right after it.

@Saffsanity
Saffsanity merged commit 125be9d into Saffsanity:main Oct 19, 2026
2 checks passed
HunterAhlquist added a commit to HunterAhlquist/sill that referenced this pull request Oct 19, 2026
…ding) into pencil-pressure

CI's mutants matrix keeps both new checks, pen and virtual-display-api.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity pushed a commit that referenced this pull request Oct 19, 2026
make-app.sh built Sill.app with a plain swift build, which builds for the Mac
that runs it. Every Sill.app so far is arm64 only for that reason. It now
builds the menu bar app once for arm64 and once for x86_64, each with its own
scratch path under .build/universal, and joins the two slices with lipo.
vtool, the icon and the signature use the universal binary as before.

Not one swift build --arch arm64 --arch x86_64: that needs Xcode's XCBuild,
and with the Command Line Tools alone it stopped at once. Not one shared
.build: under Xcode 27 each switch of triple cost a 16 s relink, so no
rebuild stayed at ~2 s.

The x86_64 slice still needs #87 for the virtual display. Each slice
compiles on its own, so #87's #if arch(x86_64) lands in the right one.

Checked: Tests/checks/run-all.sh, all passed. make-app.sh with Xcode 27.1:
universal, minos 14.0 and sdk 27.0 in both slices, codesign --verify --deep
--strict passes, 2.3 s unchanged. make-app.sh with the Command Line Tools
alone (Swift 6.3.3): universal, the generic icon as before. The universal
app's --encoder-selftest: 150 of 150 hardware frames, as an arm64-only build.
Not run on an Intel Mac.
Saffsanity added a commit to scripsweave/sill that referenced this pull request Oct 19, 2026
Main gained Saffsanity#110 (Shift-Return and Shift-Tab), Saffsanity#136 (apps in folders,
the installed-apps check), Saffsanity#87 (the virtual display's BOOL encoding, the
virtual-display-api check) and Saffsanity#88 (a universal Sill.app on request).
Merged so this branch builds and checks against today's main. Only
ci.yml's one-line mutants matrix conflicted: both sides kept, sorted
(46 checks: main's installed-apps and virtual-display-api beside this
branch's pairing-sharing; ledger has no mutants).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to Code-Tomato/sill that referenced this pull request Oct 20, 2026
…ffsanity#88 beside Send Audio

Main gained Saffsanity#110 (Shift+Return and Shift+Tab from an iPad's keyboard reach
the Mac with the shift: InputOverlay, KeyChords and the key-strokes check),
Saffsanity#87 (VirtualDisplay's BOOL return read as "B" or "c", with its new
virtual-display-api check) and Saffsanity#88 (Sill.app universal with
SILL_UNIVERSAL=1, release.sh checking every slice). Two conflicts, both
lists, both sides kept:
- ci.yml's mutants matrix: the sorted union, 49 checks, which are exactly
  the folders with a mutants.py (the sound's audio-codec,
  audio-packetizer, audio-playout and ledger, and main's
  virtual-display-api).
- Tests/checks/README.md: the opening list names both the sound's checks
  and the virtual display's encodings; the history keeps main's
  virtual-display-api sentence, then the audio branch's.
CLAUDE.md and docs/DEVELOPMENT.md merged by themselves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit that referenced this pull request Oct 20, 2026
…he universal Mac app) into pencil-pressure-rebased

Only ci.yml's mutants matrix conflicted: it lists both new checks, pen and
virtual-display-api, sorted (46 checks, every folder with a mutants.py).
CLAUDE.md, the checks' README and DEVELOPMENT.md merged by themselves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit that referenced this pull request Oct 20, 2026
 Intel) into display-stepping

ci.yml's mutants matrix gained virtual-display-api on main and
display-stepping here: both kept, sorted. CLAUDE.md, docs/DEVELOPMENT.md and
Tests/checks/README.md merged by themselves (main's Layout, Build and run and
check rows beside this branch's).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit that referenced this pull request Oct 20, 2026
…nd the universal Mac app) into thumbnail-hold

Conflicts kept both sides: CI's mutants matrix (thumbnail-hold and virtual-display-api, sorted),
the checks README's opening and its history line, and CLAUDE.md's list of checks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Saffsanity added a commit to acalatrava/sill that referenced this pull request Oct 20, 2026
…, Saffsanity#87, Saffsanity#88)

Main gained Shift+Return and Shift+Tab from the iPad (Saffsanity#110), the virtual display's BOOL
encodings with their check virtual-display-api (Saffsanity#87), and a universal Sill.app on request (Saffsanity#88).
Three files conflicted, each resolved keeping both sides: ci.yml's mutants matrix as the sorted
union (display-wake and virtual-display-api, every check folder but ledger), and the lists of
what the pure checks decide in Tests/checks/README.md (its intro and provenance note) and
docs/DEVELOPMENT.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to addhumal/sill that referenced this pull request Oct 20, 2026
Main gained Saffsanity#110 (Shift+Return and Shift+Tab from a hardware keyboard: InputOverlay, KeyChords and
the key-strokes check), Saffsanity#87 (the virtual display's BOOL encodings, its virtual-display-api check)
and Saffsanity#88 (a universal Sill.app with SILL_UNIVERSAL=1). Only ci.yml's mutants matrix conflicted:
both new checks kept, keyframe-recovery and virtual-display-api, in sorted order. None of it
touches the display path, the host's window commands, kind 44 or the keyframe check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
westsoever added a commit to westsoever/sill that referenced this pull request Oct 20, 2026
…nto main

Merged locally from Saffsanity/sill pull/66/head (fe6c001) onto main (4d990e9).

Conflicts:
- WindowCatalog.findInstalledApps: main's InstalledApps.find (Saffsanity#76, Saffsanity#135) kept,
  with the PR's Finder from CoreServices added after it.
- ci.yml: the mutants matrix is the union of both lists.
- Tests/checks/README.md: main's key-strokes, installed-apps and remote-rules
  rows; the PR's protocol row.

Fix after the merge: VirtualDisplay.resize called Runtime.applySettings, which
Saffsanity#87 replaced with VirtualDisplay.applySettings(_:to:).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyleparisi
kyleparisi deleted the virtual-display-bool-encoding branch October 22, 2026 14:45
Saffsanity added a commit to addhumal/sill that referenced this pull request Oct 26, 2026
Main gained Saffsanity#110 (Shift+Return and Shift+Tab), Saffsanity#136 (apps in folders), Saffsanity#87 (the
virtual display's BOOL encoding, the virtual-display-api check) and Saffsanity#88 (a universal
Sill.app on request). Two conflicts, each keeping both sides: ci.yml's mutants matrix
(connection-list and virtual-display-api, sorted) and the checks README's sentence on
where each check came from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to cinminori/sill that referenced this pull request Oct 26, 2026
…affsanity#88)

Main gained Saffsanity#110 (at 2814629, already merged here, so nothing of it is new),
Saffsanity#87 (the virtual display's BOOL encoding, with the virtual-display-api check)
and Saffsanity#88 (a universal Mac app for Intel testers). Two textual conflicts, lists
where each side added an entry: CI's mutants matrix keeps text-composition and
virtual-display-api, and CLAUDE.md's list of checks both. The checks' README
and DEVELOPMENT.md merged by themselves; the sentence listing the pure checks
is wrapped again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to addhumal/sill that referenced this pull request Oct 27, 2026
Main gained Saffsanity#110 (Shift+Return and Shift+Tab reach the Mac from an iPad:
InputOverlay, KeyChords and the key-strokes check) and Saffsanity#87 (VirtualDisplay's
BOOL return spelled "B" or "c", with the virtual-display-api check). Neither
touches a file this branch changes but CLAUDE.md's Layout, docs/DEVELOPMENT.md
and Tests/checks/README.md, whose lines merged by themselves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Saffsanity

Copy link
Copy Markdown
Owner

Thank you @kyleparisi, your encoding fix is in the Mac nightly, the first universal download, Apple silicon and Intel in one app! Since you have the 2018 Mac mini, you may well be the first to run this build on a real Intel Mac: with Sill for iPhone and iPad 0.5.5 (5) on TestFlight or the App Store's 0.5.1, I'd love to hear here (or in #62) whether the virtual display comes up and what frame rate you get. Nightlies build as 0.5.5 with rising build numbers and Sill's update check never offers them, so you install them yourself; 0.5.1 stays the supported release.

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.

2 participants