Add clipboard support on Windows. Fix #8

This commit is contained in:
Federico Terzi 2019-09-16 11:35:05 +02:00
parent 30cc0d3fe0
commit 14268b1bc7
6 changed files with 110 additions and 3 deletions

View File

@ -475,6 +475,32 @@ void send_vkey(int32_t vk) {
SendInput(vec.size(), vec.data(), sizeof(INPUT));
}
void trigger_paste() {
std::vector<INPUT> 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) {
@ -559,3 +585,41 @@ 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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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<String> {
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());
}
}
}

View File

@ -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<Box<dyn Extension>>) -> 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() {

View File

@ -47,7 +47,9 @@ impl super::KeyboardManager for WindowsKeyboardManager {
}
fn trigger_paste(&self) {
unimplemented!()
unsafe {
trigger_paste();
}
}
fn delete_string(&self, count: i32) {