Repository navigation
Add Notch island: one opt-in overlay for dictation, meetings and call prompts - #1876
Merged
Merged
Conversation
… prompts A third Dictation window style (Settings > General). The island grows out of the MacBook notch, or hangs from the top edge of a display without one, and carries dictation, the meeting pill and the call-detected prompt. Hover opens a drop-down with the buttons; messages and prompts open it by themselves. The default stays Near text box. The three overlay controllers keep their state machines, timers and actions. In island mode they skip their own panels and push plain snapshots to NotchIslandController, which composes them with the Foundation-pure NotchIslandPresentation and sizes them with NotchIslandGeometry. The panel sits at the status-bar level, is hidden from screen capture and never takes focus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The island used to grow by resizing its window on the main thread, with its content hidden until the grow finished: nothing readable for ~150 ms after the key press and fully in only at ~320 ms. Now the panel is built at launch and opens at a fixed size, and a continuous-corner mask springs out of the notch in Core Animation (on a display without a notch it swells from a small nub at the top edge, on a softer spring). Content sits in place from the first frame and blurs in as the shape uncovers it; when the island resizes, the wings ride the same spring. The window never resizes mid-animation, which removes a one-frame corner snap, and mouse monitors let clicks through everywhere but the island itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The island stays hidden from screen sharing, recordings and screenshots by default, like the other overlays. A new toggle under Settings > General > Dictation window (shown while Notch island is picked) makes it capturable for demos and screenshots. The island reads it each time it draws, so the switch applies at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hiding waited for Core Animation's completion before ordering the panel out. If that callback were ever lost (sleep mid-shrink), an invisible envelope window would linger at the top of the screen. A backstop now runs the same guarded finish after 1.2 s, past the shrink's settling time. Stress-tested with the real controller: 40 rapid press cycles, show/hide within one frame, hide mid-grow, dictation over a meeting with a call prompt and warning countdown, a two-hour timer, level floods, a display change mid-grow and 300 random state changes: 102/102 checks (window gone after hide, shape settles on its content, click-through outside the island, never off screen), every update under 4 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
startDictation ran its telemetry events and admission checks (~12 ms on the main thread in the logs) before the overlay was asked to show. In Notch island mode the island doesn't need the target field, so it now goes up first and the checks follow; a refused start replaces the dot with its message as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…clipboard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the clipboard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…down ring Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 28, 2026
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.
What
A third Dictation window style in Settings > General: Notch island. It's one black shape that grows out of the MacBook notch and carries dictation, the meeting pill and the call-detected prompt. On a display without a notch it hangs from the top edge as a small tab and is gone when idle. Default stays Near text box, so nothing changes unless you pick it.
How
The three controllers (
FloatingOverlayController,MeetingOverlayController,CapturePillController) keep their state machines, timers, Esc handling and actions. In island mode they skip their own panels and push plain snapshots toNotchIslandController. It composes them with the Foundation-pureNotchIslandPresentation, sizes them withNotchIslandGeometry(notch fromsafeAreaInsets+ the auxiliary top areas), and draws in pure AppKit (NotchIslandView, no SwiftUI hosting).NotchIslandPanelsits at.statusBarlevel, is excluded from screen capture (sharingType = .none), and can never become key, so clicks never pull focus from the app you're dictating into.Motion
Built for a fast first moment. The panel is created at launch and opens at a fixed size, so the island is on screen the same frame as the key press. A continuous-corner mask then springs out of the notch in Core Animation, off the main thread, so it doesn't stutter while the mic starts. On a display without a notch it swells from a small nub at the top edge, on a softer spring. Content sits in place from the first frame and blurs in as the shape uncovers it (~200 ms). When the island resizes, the wings ride the same spring. The window never resizes mid-animation, which avoids a one-frame corner snap. Mouse monitors let clicks through everywhere except over the island. Measured before this: content fully in at ~320 ms after the key press; now fully formed at ~170 ms.
Verification
bash build.sh --no-open: cleanTZ=America/Chicago bash run-tests.sh: 18665/18665 pass. NewNotchIslandPresentationTests/NotchIslandGeometryTests; the panel added to the screen-capture privacy allowlist with a behavioral suite (sharing, focus, level). That suite caught a real bug:isFloatingPanel = truereset the level under the menu bar.check-source-pins --changed-only,check-build-source-lists,bash -non the runner: passNotchIslandControllerthrough dictation → recent insert → meeting → call prompt and checked the window's level and frame.Added: faster, clearer paste-back
Paste standoff (every overlay mode). About 1 in 3 pastes took ~110 ms longer than needed, since at least 2026-09-22. Right after ⌘V, the paste-confirmation loop asked the target over Accessibility whether the text had landed. When that question arrived while the target was mid-paste (blocked on our main thread for the lazily provided string), each side waited on the other until the AX messaging timeouts (2 × 50 ms) ran out. Now nothing is asked over Accessibility until the target has read the clipboard. The text can't have landed before that, so no outcome changes. Found with per-step timing in the confirmation wait: every slow paste was one
checkstep of ~102 ms. On a 14" MacBook Pro, 16 of 44 dictations hit it before the fix and 0 of 20+ after. Paste p95 went from 366 to under 40 ms.Not pasted notice (island only). When a dictation lands on the clipboard instead (no text box, or focus moved), the island shows "Not pasted", the words in quotes (2 lines), "Click where it goes, then press ⌘V.", and Dismiss / Paste. A ring around Dismiss runs down over 15 s and pauses on hover. Pressing ⌘V yourself (the words still on the clipboard) turns it into ✓ Pasted. Paste pastes into the app in front. It never runs by itself, and it sits next to the words, so a user can see whether an ambiguous paste already landed. Other overlay modes keep the plain clipboard notice.
Tests
bash build.sh --no-open,TZ=America/Chicago bash run-tests.sh(18678/18678),bash run-slow-pasteback-smoke.sh(all pass),check-source-pins --changed-only,check-build-source-listsStill to check by hand
🤖 Generated with Claude Code