diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/macos.md | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/docs/macos.md b/docs/macos.md index 2d9fb1cc..3c02de8a 100644 --- a/docs/macos.md +++ b/docs/macos.md @@ -177,14 +177,14 @@ marks the view dirty. acme wants three mouse buttons — 1 selects, 2 executes, 3 looks — and the machine this runs on has a glass rectangle. So the rectangle is taught to speak -the vocabulary, and the mapping is the one macOS itself already suggests: +the vocabulary, cheapest gesture to commonest verb: | gesture | button | verb | | --- | --- | --- | | one finger | 1 | select | -| two fingers | 3 | Look | +| two fingers | 2 | Exec | | three fingers | 2 | Exec | -| a deep press | 2 | Exec | +| a deep press | 3 | Look | | two fingers twisted | — | `n` / `N` | **The finger count decides, not the button stream.** This is the part that only @@ -192,8 +192,9 @@ real hardware could teach, and it is worth spelling out because the obvious implementation is wrong. macOS's secondary click is "click or tap with **two or more** fingers", so with that setting on — the default — a *three*-finger click is delivered as `rightMouseDown` exactly like a two-finger one. A view that -trusts the stream cannot tell them apart and quietly does Look for both. The -trace that caught it, from a real trackpad: +trusts the stream cannot tell them apart and quietly does Look for both, which +is the one thing a multi-finger click here must NOT do. The trace that caught +it, from a real trackpad: ``` pardes: rightMouseDown: resting=2 @@ -205,10 +206,18 @@ button from the fingers first and falls back to the stream only when there are no fingers to count — which is exactly the real-mouse case, where right is Look and the middle button is Exec. +Two and three fingers landing on the same verb is therefore not a wasted +gesture, it is the hardware refusing to distinguish them under the default +setting. Look is the deep press instead: on a trackpad it is the one gesture +the system does not overload, and it wants "Force Click and haptic feedback" +on in System Settings — which nothing in this process can read, so a Mac with +that off (or a trackpad with no force sensor) reaches Look through a real +mouse's right button and the `Look` builtin, keyboard Enter included. + The count comes from `event.touches(matching: .touching, in: nil)`, with `nil` rather than the view because that argument filters on touch/view association and an association that fails does not raise, it returns zero fingers — a -two-finger Look silently degrading into a select. Belt and braces: the view also +two-finger Exec silently degrading into a select. Belt and braces: the view also keeps a running `restingFingers` from the four `touchesXxx` callbacks, because the touch set hanging off a *mouse* event is an accident of how the click was produced and can come back empty. The mouse event's own set wins when it has @@ -220,21 +229,21 @@ core tracks a drag keyed by button, and answering a press of 3 with a release of A deep press arrives as `pressureChange` reaching stage 2, and only the transition counts — AppKit repeats stage 2 for as long as the finger stays down. -By then a press has already gone out, so it is *released* before the middle one -is sent. That ordering is not tidiness: a middle press arriving while the core -holds a left select-drag is acme's 1-2 chord, which is **Cut**. The release +By then a press has already gone out, so it is *released* before the right one +is sent. That ordering is not tidiness: a right press arriving while the core +holds a left select-drag is acme's 1-3 chord, which is **Paste**. The release costs a cursor move at the click point, which is what clicking there would have -done anyway. +done anyway; a multi-finger press released this way fires the Exec its fingers +already asked for. Which press gets upgraded is deliberately not restricted to the left one, and that too came from the trace: on a Force Touch trackpad the deep press usually rides a click that already went out on the *right* stream, so gating on a latched left button meant the conversion never fired at all — the log showed `pressure: stage=2 latched=nil` and nothing else. Any in-flight click upgrades; -already-Exec is the only case with nothing to do. The view also needs +already-Look is the only case with nothing to do. The view also needs `NSPressureConfiguration(pressureBehavior: .primaryDeepClick)` or stage 2 is the -system's business and never arrives — and the user needs "Force Click and -haptic feedback" on in System Settings, which nothing in this process can read. +system's business and never arrives. Twisting two fingers is a dial, and a dial over a list of look-able places is `n`. A notch moves the SELECTION one place along and opens nothing; Enter opens @@ -388,11 +397,11 @@ layer here; everything pardes binds lives on the other four. All three verbs are cheap to mistake for broken, because acme's verbs are about the *word under the pointer* and most words resolve to nothing: -- **Look** (two fingers) on a filename opens it; on a word that names no file +- **Look** (a deep press) on a filename opens it; on a word that names no file and matches nothing else on screen, it searches, finds where it already is, and the screen does not move. The pulse still fires — the gesture worked. -- **Exec** (three fingers) on a builtin name runs it. On ordinary prose it types - that word at a shell, which needs a terminal pane to type into. +- **Exec** (two or three fingers) on a builtin name runs it. On ordinary prose + it types that word at a shell, which needs a terminal pane to type into. - **`n`/`N`** (twist) moves the SELECTION to the next look-able place and opens nothing; Enter opens what it landed on. It walks a ring across panes — the ones a Look came from first, then the output buffers none has — so a twist |
