From d166175d12c8e87904e5954f9c0ba26072482cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=B0=AC?= Date: Sat, 11 Apr 2026 09:23:04 +0900 Subject: [PATCH] =?UTF-8?q?fix(desktop):=20macOS=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=99=EC=97=AC=EB=84=A3=EA=B8=B0=20=E2=80=94=20?= =?UTF-8?q?Cmd+V=EB=A1=9C=20=EB=B6=84=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 증상: - 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 짧은 지연 추가 (앱이 클립보드 변화 인식 시간) --- .../src/main/services/TextInsertService.ts | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/apps/desktop/src/main/services/TextInsertService.ts b/apps/desktop/src/main/services/TextInsertService.ts index 52fdc69..0179fac 100644 --- a/apps/desktop/src/main/services/TextInsertService.ts +++ b/apps/desktop/src/main/services/TextInsertService.ts @@ -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 { // 1. 기존 클립보드 저장 @@ -134,24 +135,22 @@ class TextInsertService extends EventEmitter { // 2. 클립보드에 텍스트 설정 clipboard.writeText(text) - // 3. Ctrl+V 시뮬레이션 + // 짧은 지연: 일부 앱이 클립보드 변경을 받아들일 시간 필요 + await this._sleep(20) + + // 3. Paste 단축키 시뮬레이션 — 플랫폼별 modifier const nut = await this._ensureNut() - await nut.pressKey(nut.Key.LeftControl, nut.Key.V) - await nut.releaseKey(nut.Key.LeftControl, nut.Key.V) + const pasteModKey = + process.platform === 'darwin' ? nut.Key.LeftSuper : nut.Key.LeftControl - // 4. 붙여넣기 완료 대기 - await this._sleep(150) + await nut.pressKey(pasteModKey, nut.Key.V) + await nut.releaseKey(nut.Key.V, pasteModKey) - // 4.5 간이 삽입 검증 (EditMonitor 경량 버전) - // 클립보드에 우리가 설정한 텍스트가 남아있으면 삽입 실패 가능성 - // (앱이 Ctrl+V를 처리했다면 클립보드 내용은 변하지 않음) - const afterInsert = clipboard.readText() - if (afterInsert === text) { - // 클립보드가 그대로 → 정상 (앱이 붙여넣기함) - logger.debug('Insert verification: clipboard unchanged (normal)') - } + // 4. 붙여넣기 완료 대기 — 앱이 paste 이벤트를 처리할 시간 + // macOS는 비동기 처리가 좀 더 느린 경우가 있어 250ms로 잡음 + await this._sleep(process.platform === 'darwin' ? 250 : 150) - // 5. 클립보드 복원 + // 5. 클립보드 복원 (원래 내용으로 되돌림) this.restoreClipboard(snapshot) this.emit('clipboard-restored', {}) } catch (error) {