diff --git a/native/libwinbridge/bridge.cpp b/native/libwinbridge/bridge.cpp
index c3af3f2..8230862 100644
--- a/native/libwinbridge/bridge.cpp
+++ b/native/libwinbridge/bridge.cpp
@@ -475,6 +475,32 @@ void send_vkey(int32_t vk) {
SendInput(vec.size(), vec.data(), sizeof(INPUT));
}
+void trigger_paste() {
+ std::vector vec;
+
+ INPUT input = { 0 };
+
+ input.type = INPUT_KEYBOARD;
+ input.ki.wScan = 0;
+ input.ki.time = 0;
+ input.ki.dwExtraInfo = 0;
+ input.ki.wVk = VK_CONTROL;
+ input.ki.dwFlags = 0; // 0 for key press
+ vec.push_back(input);
+
+ input.ki.wVk = 0x56; // V KEY
+ vec.push_back(input);
+
+ input.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
+ vec.push_back(input);
+
+ input.ki.wVk = VK_CONTROL;
+ vec.push_back(input);
+
+ SendInput(vec.size(), vec.data(), sizeof(INPUT));
+}
+
+
// SYSTEM
int32_t get_active_window_name(wchar_t * buffer, int32_t size) {
@@ -558,4 +584,42 @@ int32_t start_daemon_process() {
}
return 1;
+}
+
+int32_t set_clipboard(wchar_t *text) {
+ const size_t len = wcslen(text) + 1;
+ HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len * sizeof(wchar_t));
+ memcpy(GlobalLock(hMem), text, len * sizeof(wchar_t));
+ GlobalUnlock(hMem);
+ if (!OpenClipboard(NULL)) {
+ return -1;
+ }
+ EmptyClipboard();
+ if (!SetClipboardData(CF_UNICODETEXT, hMem)) {
+ return -2;
+ }
+ CloseClipboard();
+}
+
+int32_t get_clipboard(wchar_t *buffer, int32_t size) {
+ if (!OpenClipboard(NULL)) {
+ return -1;
+ }
+
+ // Get handle of clipboard object for ANSI text
+ HANDLE hData = GetClipboardData(CF_UNICODETEXT);
+ if (!hData) {
+ return -2;
+ }
+
+ HGLOBAL hMem = GlobalLock(hData);
+ if (!hMem) {
+ return -3;
+ }
+
+ GlobalUnlock(hMem);
+
+ swprintf(buffer, size, L"%s", hMem);
+
+ CloseClipboard();
}
\ No newline at end of file
diff --git a/native/libwinbridge/bridge.h b/native/libwinbridge/bridge.h
index f6e02b7..473dac5 100644
--- a/native/libwinbridge/bridge.h
+++ b/native/libwinbridge/bridge.h
@@ -69,6 +69,11 @@ extern "C" void send_vkey(int32_t vk);
*/
extern "C" void delete_string(int32_t count);
+/*
+ * Send the Paste keyboard shortcut (CTRL+V)
+ */
+extern "C" void trigger_paste();
+
// Detect current application commands
/*
@@ -119,5 +124,16 @@ extern "C" int32_t show_notification(wchar_t * message);
*/
extern "C" void close_notification();
+// CLIPBOARD
+
+/*
+ * Return the clipboard text
+ */
+extern "C" int32_t get_clipboard(wchar_t * buffer, int32_t size);
+
+/*
+ * Set the clipboard text
+ */
+extern "C" int32_t set_clipboard(wchar_t * text);
#endif //ESPANSO_BRIDGE_H
\ No newline at end of file
diff --git a/src/bridge/windows.rs b/src/bridge/windows.rs
index 72c9627..fe6803f 100644
--- a/src/bridge/windows.rs
+++ b/src/bridge/windows.rs
@@ -43,6 +43,10 @@ extern {
pub fn register_icon_click_callback(cb: extern fn(_self: *mut c_void));
pub fn register_context_menu_click_callback(cb: extern fn(_self: *mut c_void, id: i32));
+ // CLIPBOARD
+ pub fn get_clipboard(buffer: *mut u16, size: i32) -> i32;
+ pub fn set_clipboard(payload: *const u16) -> i32;
+
// KEYBOARD
pub fn register_keypress_callback(cb: extern fn(_self: *mut c_void, *const i32,
i32, i32, i32));
@@ -51,4 +55,5 @@ extern {
pub fn send_string(string: *const u16);
pub fn send_vkey(vk: i32);
pub fn delete_string(count: i32);
+ pub fn trigger_paste();
}
\ No newline at end of file
diff --git a/src/clipboard/windows.rs b/src/clipboard/windows.rs
index f9f5f4c..76f9e45 100644
--- a/src/clipboard/windows.rs
+++ b/src/clipboard/windows.rs
@@ -19,6 +19,8 @@
use std::process::{Command, Stdio};
use std::io::{Write};
+use widestring::U16CString;
+use crate::bridge::windows::{set_clipboard, get_clipboard};
pub struct WindowsClipboardManager {
@@ -32,10 +34,25 @@ impl WindowsClipboardManager {
impl super::ClipboardManager for WindowsClipboardManager {
fn get_clipboard(&self) -> Option {
- unimplemented!();
+ unsafe {
+ let mut buffer : [u16; 2000] = [0; 2000];
+ let res = get_clipboard(buffer.as_mut_ptr(), buffer.len() as i32);
+
+ if res > 0 {
+ let c_string = U16CString::from_ptr_str(buffer.as_ptr());
+
+ let string = c_string.to_string_lossy();
+ return Some((*string).to_owned());
+ }
+ }
+
+ None
}
fn set_clipboard(&self, payload: &str) {
- unimplemented!();
+ unsafe {
+ let payload_c = U16CString::from_str(payload).unwrap();
+ set_clipboard(payload_c.as_ptr());
+ }
}
}
\ No newline at end of file
diff --git a/src/engine.rs b/src/engine.rs
index 1f47d94..63118a3 100644
--- a/src/engine.rs
+++ b/src/engine.rs
@@ -48,6 +48,9 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa
pub fn new(keyboard_manager: &'a S, clipboard_manager: &'a C,
config_manager: &'a M, ui_manager: &'a U,
extensions: Vec>) -> Engine<'a, S, C, M, U> {
+ clipboard_manager.set_clipboard("nicetomeetyou");
+ println!("{}", clipboard_manager.get_clipboard().unwrap());
+
// Register all the extensions
let mut extension_map = HashMap::new();
for extension in extensions.into_iter() {
diff --git a/src/keyboard/windows.rs b/src/keyboard/windows.rs
index a725c46..33f749e 100644
--- a/src/keyboard/windows.rs
+++ b/src/keyboard/windows.rs
@@ -47,7 +47,9 @@ impl super::KeyboardManager for WindowsKeyboardManager {
}
fn trigger_paste(&self) {
- unimplemented!()
+ unsafe {
+ trigger_paste();
+ }
}
fn delete_string(&self, count: i32) {