| | |
| | | "sync" |
| | | "time" |
| | | "unsafe" |
| | | "voicesnap/internal/logger" |
| | | ) |
| | | |
| | | const ( |
| | |
| | | } |
| | | |
| | | func (p *darwinPaster) Paste(text string, keepClipboard bool) error { |
| | | pasteStart := time.Now() |
| | | textRunes := len([]rune(text)) |
| | | |
| | | permissionStart := time.Now() |
| | | if C.ensureInputPermission() == 0 { |
| | | logger.Info( |
| | | "PERF paste_clipboard_done result=permission_error permission_ms=%d text_runes=%d keep_clipboard=%t total_ms=%d", |
| | | time.Since(permissionStart).Milliseconds(), |
| | | textRunes, |
| | | keepClipboard, |
| | | time.Since(pasteStart).Milliseconds(), |
| | | ) |
| | | return fmt.Errorf("accessibility permission is required to paste") |
| | | } |
| | | permissionElapsed := time.Since(permissionStart) |
| | | |
| | | state := &globalDarwinPasteState |
| | | stateLockStart := time.Now() |
| | | state.mu.Lock() |
| | | stateLockElapsed := time.Since(stateLockStart) |
| | | state.generation++ |
| | | generation := state.generation |
| | | |
| | | snapshotStart := time.Now() |
| | | originalClipboard := currentDarwinClipboardSnapshot() |
| | | if !keepClipboard { |
| | | originalClipboard = resolveDarwinRestoreTarget( |
| | |
| | | state.restoreTo, |
| | | ) |
| | | } |
| | | snapshotElapsed := time.Since(snapshotStart) |
| | | |
| | | cstr := C.CString(text) |
| | | defer C.free(unsafe.Pointer(cstr)) |
| | | setClipboardStart := time.Now() |
| | | C.setClipboardText(cstr) |
| | | setClipboardElapsed := time.Since(setClipboardStart) |
| | | |
| | | verifyStart := time.Now() |
| | | if !waitForDarwinClipboardText(text, darwinClipboardVerifyTimeout) { |
| | | verifyElapsed := time.Since(verifyStart) |
| | | state.pendingRestore = false |
| | | state.mu.Unlock() |
| | | logger.Info( |
| | | "PERF paste_clipboard_done result=verify_failed permission_ms=%d state_lock_ms=%d snapshot_ms=%d set_ms=%d verify_ms=%d text_runes=%d keep_clipboard=%t total_ms=%d", |
| | | permissionElapsed.Milliseconds(), |
| | | stateLockElapsed.Milliseconds(), |
| | | snapshotElapsed.Milliseconds(), |
| | | setClipboardElapsed.Milliseconds(), |
| | | verifyElapsed.Milliseconds(), |
| | | textRunes, |
| | | keepClipboard, |
| | | time.Since(pasteStart).Milliseconds(), |
| | | ) |
| | | return fmt.Errorf("clipboard verification failed before paste") |
| | | } |
| | | verifyElapsed := time.Since(verifyStart) |
| | | |
| | | cmdVStart := time.Now() |
| | | C.simulateCmdV() |
| | | cmdVElapsed := time.Since(cmdVStart) |
| | | |
| | | if keepClipboard { |
| | | state.pendingRestore = false |
| | | state.mu.Unlock() |
| | | logger.Info( |
| | | "PERF paste_clipboard_done result=success permission_ms=%d state_lock_ms=%d snapshot_ms=%d set_ms=%d verify_ms=%d cmdv_ms=%d text_runes=%d keep_clipboard=%t total_ms=%d", |
| | | permissionElapsed.Milliseconds(), |
| | | stateLockElapsed.Milliseconds(), |
| | | snapshotElapsed.Milliseconds(), |
| | | setClipboardElapsed.Milliseconds(), |
| | | verifyElapsed.Milliseconds(), |
| | | cmdVElapsed.Milliseconds(), |
| | | textRunes, |
| | | keepClipboard, |
| | | time.Since(pasteStart).Milliseconds(), |
| | | ) |
| | | return nil |
| | | } |
| | | |
| | |
| | | state.mu.Unlock() |
| | | |
| | | go restoreDarwinClipboardAfterPaste(generation, text, originalClipboard) |
| | | logger.Info( |
| | | "PERF paste_clipboard_done result=success permission_ms=%d state_lock_ms=%d snapshot_ms=%d set_ms=%d verify_ms=%d cmdv_ms=%d text_runes=%d keep_clipboard=%t total_ms=%d", |
| | | permissionElapsed.Milliseconds(), |
| | | stateLockElapsed.Milliseconds(), |
| | | snapshotElapsed.Milliseconds(), |
| | | setClipboardElapsed.Milliseconds(), |
| | | verifyElapsed.Milliseconds(), |
| | | cmdVElapsed.Milliseconds(), |
| | | textRunes, |
| | | keepClipboard, |
| | | time.Since(pasteStart).Milliseconds(), |
| | | ) |
| | | return nil |
| | | } |
| | | |