Add windows support for modifiers
This commit is contained in:
parent
5d51b856b3
commit
e81e168f4f
|
@ -17,11 +17,11 @@ HWND window;
|
||||||
|
|
||||||
const wchar_t* const winclass = L"Espanso";
|
const wchar_t* const winclass = L"Espanso";
|
||||||
|
|
||||||
keypress_callback keypressCallback;
|
KeypressCallback keypress_callback;
|
||||||
void * interceptor_instance;
|
void * interceptor_instance;
|
||||||
|
|
||||||
void register_keypress_callback(void * self, keypress_callback callback) {
|
void register_keypress_callback(void * self, KeypressCallback callback) {
|
||||||
keypressCallback = callback;
|
keypress_callback = callback;
|
||||||
interceptor_instance = self;
|
interceptor_instance = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +92,14 @@ LRESULT CALLBACK window_worker_procedure(HWND window, unsigned int msg, WPARAM w
|
||||||
std::array<WCHAR, 4> buffer;
|
std::array<WCHAR, 4> buffer;
|
||||||
int result = ToUnicodeEx(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, lpKeyState.data(), buffer.data(), buffer.size(), 0, currentKeyboardLayout);
|
int result = ToUnicodeEx(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, lpKeyState.data(), buffer.data(), buffer.size(), 0, currentKeyboardLayout);
|
||||||
|
|
||||||
// If a result is available, invoke the callback
|
//std::cout << result << " " << buffer[0] << " " << raw->data.keyboard.VKey << std::endl;
|
||||||
if (result >= 1) {
|
|
||||||
//std::cout << buffer[0] << " " << buffer[1] << " res=" << result << " vk=" << raw->data.keyboard.VKey << " rsc=" << raw->data.keyboard.MakeCode << std::endl;
|
// We need to call the callback in two different ways based on the type of key
|
||||||
keypressCallback(interceptor_instance, reinterpret_cast<int32_t*>(buffer.data()), buffer.size());
|
// The only modifier we use that has a result > 0 is the BACKSPACE, so we have to consider it.
|
||||||
|
if (result >= 1 && raw->data.keyboard.VKey != VK_BACK) {
|
||||||
|
keypress_callback(interceptor_instance, reinterpret_cast<int32_t*>(buffer.data()), buffer.size(), 0, raw->data.keyboard.VKey);
|
||||||
|
}else{
|
||||||
|
keypress_callback(interceptor_instance, nullptr, 0, 1, raw->data.keyboard.VKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
* Called when a new keypress is made, the first argument is an int array,
|
* Called when a new keypress is made, the first argument is an int array,
|
||||||
* while the second is the size of the array.
|
* while the second is the size of the array.
|
||||||
*/
|
*/
|
||||||
typedef void (*keypress_callback)(void * self, int32_t *buffer, int32_t len);
|
typedef void (*KeypressCallback)(void * self, int32_t *buffer, int32_t len, int32_t is_modifier, int32_t key_code);
|
||||||
|
|
||||||
extern keypress_callback keypressCallback;
|
extern KeypressCallback keypress_callback;
|
||||||
extern void * interceptor_instance;
|
extern void * interceptor_instance;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the callback that will be called when a keypress was made
|
* Register the callback that will be called when a keypress was made
|
||||||
*/
|
*/
|
||||||
extern "C" void register_keypress_callback(void *self, keypress_callback callback);
|
extern "C" void register_keypress_callback(void *self, KeypressCallback callback);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the Windows worker's parameters
|
* Initialize the Windows worker's parameters
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use widestring::{U16CString};
|
use widestring::{U16CString};
|
||||||
use crate::keyboard::KeyEvent;
|
use crate::keyboard::{KeyEvent, KeyModifier};
|
||||||
|
use crate::keyboard::KeyModifier::*;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct WindowsKeyboardInterceptor {
|
pub struct WindowsKeyboardInterceptor {
|
||||||
|
@ -12,16 +13,14 @@ impl super::KeyboardInterceptor for WindowsKeyboardInterceptor {
|
||||||
fn initialize(&self) {
|
fn initialize(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
register_keypress_callback(self,keypress_callback);
|
register_keypress_callback(self,keypress_callback);
|
||||||
|
initialize_window();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
thread::spawn(|| {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
initialize_window();
|
|
||||||
eventloop();
|
eventloop();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,21 +50,41 @@ impl super::KeyboardSender for WindowsKeyboardSender {
|
||||||
|
|
||||||
// Native bridge code
|
// Native bridge code
|
||||||
|
|
||||||
extern fn keypress_callback(_self: *mut WindowsKeyboardInterceptor, raw_buffer: *const i32, len: i32) {
|
extern fn keypress_callback(_self: *mut WindowsKeyboardInterceptor, raw_buffer: *const i32, len: i32,
|
||||||
|
is_modifier: i32, key_code: i32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
if is_modifier == 0 { // Char event
|
||||||
// Convert the received buffer to a character
|
// Convert the received buffer to a character
|
||||||
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
||||||
let r = std::char::from_u32(buffer[0] as u32).unwrap();
|
let r = std::char::from_u32(buffer[0] as u32);
|
||||||
|
|
||||||
// Send the char through the channel
|
// Send the char through the channel
|
||||||
(*_self).sender.send(r).unwrap();
|
if let Some(c) = r {
|
||||||
|
(*_self).sender.send(KeyEvent::Char(c)).unwrap();
|
||||||
|
}
|
||||||
|
}else{ // Modifier event
|
||||||
|
let modifier: Option<KeyModifier> = match key_code {
|
||||||
|
0x5B | 0x5C => Some(META),
|
||||||
|
0x10 => Some(SHIFT),
|
||||||
|
0x12 => Some(ALT),
|
||||||
|
0x11 => Some(CTRL),
|
||||||
|
0x08 => Some(BACKSPACE),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(modifier) = modifier {
|
||||||
|
(*_self).sender.send(KeyEvent::Modifier(modifier)).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
#[link(name="winbridge", kind="static")]
|
#[link(name="winbridge", kind="static")]
|
||||||
extern {
|
extern {
|
||||||
fn register_keypress_callback(s: *const WindowsKeyboardInterceptor, cb: extern fn(_self: *mut WindowsKeyboardInterceptor, *const i32, i32));
|
fn register_keypress_callback(s: *const WindowsKeyboardInterceptor,
|
||||||
|
cb: extern fn(_self: *mut WindowsKeyboardInterceptor, *const i32,
|
||||||
|
i32, i32, i32));
|
||||||
fn initialize_window();
|
fn initialize_window();
|
||||||
fn eventloop();
|
fn eventloop();
|
||||||
fn send_string(string: *const u16);
|
fn send_string(string: *const u16);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user