* Bracket `fn()` with modifier press/release. `pressed` tracks which presses * actually landed, so a mid-press throw only releases what was pressed — no * stuck modifiers. The finally covers both press-phase and fn() throws. * * Caller must already be inside drainRunLoop() — key() dispatches to
( input: Input, mods: string[], fn: () => Promise<T>, )
| 205 | * main queue and needs the pump to resolve. |
| 206 | */ |
| 207 | async function withModifiers<T>( |
| 208 | input: Input, |
| 209 | mods: string[], |
| 210 | fn: () => Promise<T>, |
| 211 | ): Promise<T> { |
| 212 | const pressed: string[] = [] |
| 213 | try { |
| 214 | for (const m of mods) { |
| 215 | await input.key(m, 'press') |
| 216 | pressed.push(m) |
| 217 | } |
| 218 | return await fn() |
| 219 | } finally { |
| 220 | await releasePressed(input, pressed) |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * Port of Cowork's `typeViaClipboard`. Sequence: |
no test coverage detected