Add clipboard support on Windows. Fix #8
This commit is contained in:
parent
30cc0d3fe0
commit
14268b1bc7
|
@ -475,6 +475,32 @@ void send_vkey(int32_t vk) {
|
||||||
SendInput(vec.size(), vec.data(), sizeof(INPUT));
|
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
|
// SYSTEM
|
||||||
|
|
||||||
int32_t get_active_window_name(wchar_t * buffer, int32_t size) {
|
int32_t get_active_window_name(wchar_t * buffer, int32_t size) {
|
||||||
|
@ -559,3 +585,41 @@ int32_t start_daemon_process() {
|
||||||
|
|
||||||
return 1;
|
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();
|
||||||
|
}
|
|
@ -69,6 +69,11 @@ extern "C" void send_vkey(int32_t vk);
|
||||||
*/
|
*/
|
||||||
extern "C" void delete_string(int32_t count);
|
extern "C" void delete_string(int32_t count);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the Paste keyboard shortcut (CTRL+V)
|
||||||
|
*/
|
||||||
|
extern "C" void trigger_paste();
|
||||||
|
|
||||||
// Detect current application commands
|
// Detect current application commands
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -119,5 +124,16 @@ extern "C" int32_t show_notification(wchar_t * message);
|
||||||
*/
|
*/
|
||||||
extern "C" void close_notification();
|
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
|
#endif //ESPANSO_BRIDGE_H
|
|
@ -43,6 +43,10 @@ extern {
|
||||||
pub fn register_icon_click_callback(cb: extern fn(_self: *mut c_void));
|
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));
|
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
|
// KEYBOARD
|
||||||
pub fn register_keypress_callback(cb: extern fn(_self: *mut c_void, *const i32,
|
pub fn register_keypress_callback(cb: extern fn(_self: *mut c_void, *const i32,
|
||||||
i32, i32, i32));
|
i32, i32, i32));
|
||||||
|
@ -51,4 +55,5 @@ extern {
|
||||||
pub fn send_string(string: *const u16);
|
pub fn send_string(string: *const u16);
|
||||||
pub fn send_vkey(vk: i32);
|
pub fn send_vkey(vk: i32);
|
||||||
pub fn delete_string(count: i32);
|
pub fn delete_string(count: i32);
|
||||||
|
pub fn trigger_paste();
|
||||||
}
|
}
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::io::{Write};
|
use std::io::{Write};
|
||||||
|
use widestring::U16CString;
|
||||||
|
use crate::bridge::windows::{set_clipboard, get_clipboard};
|
||||||
|
|
||||||
pub struct WindowsClipboardManager {
|
pub struct WindowsClipboardManager {
|
||||||
|
|
||||||
|
@ -32,10 +34,25 @@ impl WindowsClipboardManager {
|
||||||
|
|
||||||
impl super::ClipboardManager for WindowsClipboardManager {
|
impl super::ClipboardManager for WindowsClipboardManager {
|
||||||
fn get_clipboard(&self) -> Option<String> {
|
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) {
|
fn set_clipboard(&self, payload: &str) {
|
||||||
unimplemented!();
|
unsafe {
|
||||||
|
let payload_c = U16CString::from_str(payload).unwrap();
|
||||||
|
set_clipboard(payload_c.as_ptr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
pub fn new(keyboard_manager: &'a S, clipboard_manager: &'a C,
|
||||||
config_manager: &'a M, ui_manager: &'a U,
|
config_manager: &'a M, ui_manager: &'a U,
|
||||||
extensions: Vec<Box<dyn Extension>>) -> Engine<'a, S, C, M, 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
|
// Register all the extensions
|
||||||
let mut extension_map = HashMap::new();
|
let mut extension_map = HashMap::new();
|
||||||
for extension in extensions.into_iter() {
|
for extension in extensions.into_iter() {
|
||||||
|
|
|
@ -47,7 +47,9 @@ impl super::KeyboardManager for WindowsKeyboardManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger_paste(&self) {
|
fn trigger_paste(&self) {
|
||||||
unimplemented!()
|
unsafe {
|
||||||
|
trigger_paste();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_string(&self, count: i32) {
|
fn delete_string(&self, count: i32) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user