C.W.K.
Stream
Lesson 02 of 05 · published

Four Rungs, Each Failing Gracefully

~12 min · ladder, insertion-methods, graceful-degradation, cgevent

Level 0Unlit
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"There is no one way to put text in every app. There are four ways, and a plan for when each one gives up."

Why a Ladder and Not a Method

macOS has no single reliable "insert this text into the focused field" call that works everywhere. Different apps expose different surfaces, so insertion is a ladder: try the best method that applies, and fall to the next rung when it can't. Each rung trades cleanliness for breadth.

The Four Rungs

1. AX replace         cleanest, no clipboard touched
   |  (only where the app exposes a reliable editable value + range)
   v  fails -> 
2. Pasteboard + Cmd+V  broad default for most apps and large text
   |  (touches the clipboard; needs save/restore etiquette)
   v  fails / hostile ->
3. Unicode key events  synthesize keystrokes, no clipboard side effect
   |  (slower; good for short text or paste-hostile targets)
   v  fails ->
4. Clipboard only      last resort: copy + notify "paste manually"

Rung 1, AX replace: if the focused element reliably exposes an editable value and selection range, replace through Accessibility — no clipboard touched, cleanest possible. Use it only in apps proven reliable. Rung 2, pasteboard + synthetic Cmd+V: the broad default for large text and most apps; it works almost everywhere but touches the clipboard, so it owes the pasteboard etiquette we'll cover. Rung 3, Unicode key events: synthesize the characters via CGEvent — no pasteboard side effect, but slower; good for short text or paste-hostile targets. Rung 4, clipboard-only: when nothing else applies, copy the text and tell the user to paste it.

Degrade, Don't Fail

The point of the ladder is that insertion never simply fails — it degrades. Even the worst case (clipboard + notify) leaves the user one keystroke from their text, with a clear message about what happened. Compare that to a single-method design: pick AX-only and you break in every app that doesn't expose it; pick paste-only and you're stuck when a target rejects paste. The ladder means there's always a rung that works, and the user always ends up with their words.

For an operation with no universal method, build a ladder with a guaranteed floor. When the ideal approach only works sometimes, don't gate the whole feature on it. Order methods best-to-broadest and make the last rung a can't-fail fallback (here, clipboard + notify). Every user reaches some rung; nobody hits a dead end.
Choose the rung from the target category, not by trying blindly. The snapshot's category (browser, editor, terminal, unknown) already tells you which rung is likely to work, so you can start at the right height instead of failing down from the top every time. A known-reliable editor might start at AX; an unknown app might start at paste; a terminal takes its own profile entirely.

Code

The ladder: try each rung, guarantee a floor·swift
func insert(_ text: String, into t: TargetSnapshot) async -> InsertOutcome {
    // Rung 1 — cleanest, only where AX is proven reliable.
    if t.category.axReliable, await axReplace(text, in: t.focusedElement) { return .inserted(.ax) }

    // Rung 2 — broad default; touches the clipboard (etiquette owed).
    if await pasteInsert(text, into: t) { return .inserted(.paste) }

    // Rung 3 — synthesize keystrokes; no clipboard side effect, slower.
    if await keyEventInsert(text, into: t) { return .inserted(.keyEvents) }

    // Rung 4 — can't-fail floor: copy + tell the user.
    clipboard.copy(text)
    notify("Couldn't insert — text copied. Paste with Cmd+V.")
    return .clipboardOnly
}

External links

Exercise

Pick an operation in your own work that has no single method that works everywhere (rendering a file type, exporting to a format, connecting to a device). Order your available methods from cleanest to broadest, and define the can't-fail floor. What does the user experience at the floor, and is it acceptable?
Hint
A good floor is unglamorous but reliable and honest — for insertion it's 'copied to clipboard, paste manually.' The test is whether the floor still leaves the user able to accomplish the goal with minimal effort and a clear explanation. If your floor is 'error, nothing happened,' you don't have a ladder yet; you have a method that sometimes fails.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.