diff --git a/Cargo.lock b/Cargo.lock index a2ec4f9..ccb9280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,6 +456,28 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +[[package]] +name = "clipboard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" +dependencies = [ + "clipboard-win", + "objc", + "objc-foundation", + "objc_id", + "x11-clipboard", +] + +[[package]] +name = "clipboard-win" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" +dependencies = [ + "winapi", +] + [[package]] name = "cocoa" version = "0.22.0" @@ -705,6 +727,7 @@ dependencies = [ "async-openai", "async-std", "clap", + "clipboard", "cpal", "dotenvy", "enigo", @@ -1606,6 +1629,26 @@ dependencies = [ "malloc_buf", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "object" version = "0.36.5" @@ -2852,6 +2895,25 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11-clipboard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" +dependencies = [ + "xcb", +] + +[[package]] +name = "xcb" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +dependencies = [ + "libc", + "log", +] + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index d9f6483..26a60b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ anyhow = "1.0.75" async-openai = "0.14.3" async-std = "1.12.0" clap = { version = "4.4.6", features = ["derive"] } +clipboard = "0.5.0" cpal = "0.15.2" dotenvy = "0.15.7" enigo = "0.1.3" diff --git a/src/main.rs b/src/main.rs index ecbec12..ccb2164 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,17 +5,20 @@ use enigo::{Enigo, KeyboardControllable}; use std::env; use tempfile::tempdir; mod transcribe; -use std::thread; +use std::thread::{self, sleep}; use transcribe::trans; mod record; use async_std::future; use clap::{Parser, Subcommand}; +use clipboard::ClipboardContext; +use clipboard::ClipboardProvider; use cpal::traits::{DeviceTrait, HostTrait}; use rdev::{listen, Event}; use record::rec; use std::error::Error; use std::time::Duration; mod easy_rdev_key; +use crate::easy_rdev_key::PTTKey; #[derive(Parser, Debug)] #[command(version)] @@ -30,7 +33,7 @@ struct Opt { /// The push to talk key #[arg(short, long)] - ptt_key: Option, + ptt_key: Option, /// The push to talk key. /// Use this if you want to use a key that is not supported by the PTTKey enum. @@ -53,6 +56,8 @@ fn main() -> Result<(), Box> { let opt = Opt::parse(); let _ = dotenv(); + let mut clipboard: ClipboardContext = ClipboardProvider::new().unwrap(); + match opt.subcommands { Some(subcommand) => { match subcommand { @@ -73,6 +78,9 @@ fn main() -> Result<(), Box> { SubCommands::ListDevices => { let host = cpal::default_host(); + let test = host.default_output_device().unwrap(); + + println!("default output_device: {:?}", test.name()); // Set up the input device and stream with the default input config. host.default_input_device(); let devices = host @@ -131,7 +139,7 @@ fn main() -> Result<(), Box> { let runtime = tokio::runtime::Runtime::new() .context("Failed to create tokio runtime") .unwrap(); - let mut enigo = Enigo::new(); + // let mut enigo = Enigo::new(); let tmp_dir = tempdir().unwrap(); // println!("{:?}", tmp_dir.path()); @@ -221,7 +229,40 @@ fn main() -> Result<(), Box> { println!("No transcription"); } - enigo.key_sequence(&transcription); + // enigo.key_sequence(&transcription); + // paste from clipboard + + // get the clipboard contents so we can restore it later + let clip_tmp_result = clipboard.get_contents(); + + // Set and paste Clipboard Contents + match clipboard.set_contents(transcription) { + Ok(_) => { + Enigo.key_sequence_parse("{+CTRL}"); + sleep(Duration::from_millis(100)); + Enigo.key_sequence_parse("v"); + sleep(Duration::from_millis(100)); + Enigo.key_sequence_parse("{-CTRL}"); + sleep(Duration::from_millis(100)); + + // restore the clipboard contents + if let Ok(clip_tmp) = clip_tmp_result { + if let Err(err) = clipboard.set_contents(clip_tmp) { + println!( + "Error restoring clipboard contents: {}", + err + ); + } + } + } + Err(err) => { + println!( + "Error: Failed to set clipboard contents: {:?}", + err + ); + continue; + } + } } else { println!("Recording too short"); }