fix(desktop): macOS 텍스트 붙여넣기 — Cmd+V로 분기

증상:
- STT 전사는 정상 ('그럼 이제는 되는 건가요?')
- 로그상 'Text inserted (14 chars, 851ms)' 성공으로 보임
- 그런데 실제로 활성 앱에 텍스트가 안 들어감

원인:
- TextInsertService._insertViaClipboard가 nut.Key.LeftControl + V로 하드코딩
  - macOS는 Cmd+V (LeftSuper+V)가 표준 paste 단축키
  - Ctrl+V는 macOS에서 동작 안 함 (앱마다 다르지만 보통 noop)
- 클립보드 검증 로직도 거짓 양성:
  - paste 후 clipboard.readText() === text면 '정상'으로 판단
  - macOS에서는 Ctrl+V가 클립보드를 안 건드리므로 항상 일치 → 항상 'success' 로그

수정:
- pasteModKey = process.platform === 'darwin' ? LeftSuper : LeftControl
- pressKey/releaseKey 시 동적 modifier 사용
- releaseKey는 V → mod 순으로 release (modifier last 권장)
- 잘못된 검증 로직 제거 (의미 없는 로그였음)
- macOS는 paste 후 sleep 250ms (Win/Linux 150ms) — 일부 앱의 비동기 처리 여유
- clipboard write 후 20ms 짧은 지연 추가 (앱이 클립보드 변화 인식 시간)
This commit is contained in:
윤찬 2026-04-11 09:23:04 +09:00
parent d7405a4203
commit d166175d12

View file

@ -123,7 +123,8 @@ class TextInsertService extends EventEmitter {
} }
/** /**
* 방식: save set Ctrl+V restore (Speakly ) * 방식: save set Cmd/Ctrl+V restore (Speakly )
* macOS는 +V, Windows/Linux는 Ctrl+V로 .
*/ */
private async _insertViaClipboard(text: string): Promise<void> { private async _insertViaClipboard(text: string): Promise<void> {
// 1. 기존 클립보드 저장 // 1. 기존 클립보드 저장
@ -134,24 +135,22 @@ class TextInsertService extends EventEmitter {
// 2. 클립보드에 텍스트 설정 // 2. 클립보드에 텍스트 설정
clipboard.writeText(text) clipboard.writeText(text)
// 3. Ctrl+V 시뮬레이션 // 짧은 지연: 일부 앱이 클립보드 변경을 받아들일 시간 필요
await this._sleep(20)
// 3. Paste 단축키 시뮬레이션 — 플랫폼별 modifier
const nut = await this._ensureNut() const nut = await this._ensureNut()
await nut.pressKey(nut.Key.LeftControl, nut.Key.V) const pasteModKey =
await nut.releaseKey(nut.Key.LeftControl, nut.Key.V) process.platform === 'darwin' ? nut.Key.LeftSuper : nut.Key.LeftControl
// 4. 붙여넣기 완료 대기 await nut.pressKey(pasteModKey, nut.Key.V)
await this._sleep(150) await nut.releaseKey(nut.Key.V, pasteModKey)
// 4.5 간이 삽입 검증 (EditMonitor 경량 버전) // 4. 붙여넣기 완료 대기 — 앱이 paste 이벤트를 처리할 시간
// 클립보드에 우리가 설정한 텍스트가 남아있으면 삽입 실패 가능성 // macOS는 비동기 처리가 좀 더 느린 경우가 있어 250ms로 잡음
// (앱이 Ctrl+V를 처리했다면 클립보드 내용은 변하지 않음) await this._sleep(process.platform === 'darwin' ? 250 : 150)
const afterInsert = clipboard.readText()
if (afterInsert === text) {
// 클립보드가 그대로 → 정상 (앱이 붙여넣기함)
logger.debug('Insert verification: clipboard unchanged (normal)')
}
// 5. 클립보드 복원 // 5. 클립보드 복원 (원래 내용으로 되돌림)
this.restoreClipboard(snapshot) this.restoreClipboard(snapshot)
this.emit('clipboard-restored', {}) this.emit('clipboard-restored', {})
} catch (error) { } catch (error) {