Implement filter bindings for Windows and moved extern in bridge. Fix #13
This commit is contained in:
parent
d04bd9d7f6
commit
cd2c159696
|
@ -247,4 +247,29 @@ void send_vkey(int32_t vk) {
|
|||
vec.push_back(input);
|
||||
|
||||
SendInput(vec.size(), vec.data(), sizeof(INPUT));
|
||||
}
|
||||
|
||||
// SYSTEM
|
||||
|
||||
int32_t get_active_window_name(wchar_t * buffer, int32_t size) {
|
||||
HWND hwnd = GetForegroundWindow();
|
||||
|
||||
return GetWindowText(hwnd, buffer, size);
|
||||
}
|
||||
|
||||
int32_t get_active_window_executable(wchar_t * buffer, int32_t size) {
|
||||
HWND hwnd = GetForegroundWindow();
|
||||
|
||||
// Extract the window PID
|
||||
DWORD windowPid;
|
||||
GetWindowThreadProcessId(hwnd, &windowPid);
|
||||
|
||||
DWORD dsize = (DWORD) size;
|
||||
|
||||
// Extract the process executable file path
|
||||
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, windowPid);
|
||||
int res = QueryFullProcessImageNameW(process, 0, buffer, &dsize);
|
||||
CloseHandle(process);
|
||||
|
||||
return res;
|
||||
}
|
|
@ -44,4 +44,14 @@ extern "C" void send_vkey(int32_t vk);
|
|||
*/
|
||||
extern "C" void delete_string(int32_t count);
|
||||
|
||||
/*
|
||||
* Return the active windows's title
|
||||
*/
|
||||
extern "C" int32_t get_active_window_name(wchar_t * buffer, int32_t size);
|
||||
|
||||
/*
|
||||
* Return the active windows's executable path
|
||||
*/
|
||||
extern "C" int32_t get_active_window_executable(wchar_t * buffer, int32_t size);
|
||||
|
||||
#endif //ESPANSO_BRIDGE_H
|
17
src/bridge/windows.rs
Normal file
17
src/bridge/windows.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use std::os::raw::{c_void};
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
#[link(name="winbridge", kind="static")]
|
||||
extern {
|
||||
pub fn get_active_window_name(buffer: *mut u16, size: i32) -> i32;
|
||||
pub fn get_active_window_executable(buffer: *mut u16, size: i32) -> i32;
|
||||
|
||||
pub fn register_keypress_callback(s: *const c_void,
|
||||
cb: extern fn(_self: *mut c_void, *const i32,
|
||||
i32, i32, i32));
|
||||
pub fn initialize_window();
|
||||
pub fn eventloop();
|
||||
pub fn send_string(string: *const u16);
|
||||
pub fn send_vkey(vk: i32);
|
||||
pub fn delete_string(count: i32);
|
||||
}
|
|
@ -19,4 +19,12 @@ pub fn get_manager() -> impl ClipboardManager {
|
|||
let manager = linux::LinuxClipboardManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
||||
|
||||
// WINDOWS IMPLEMENTATION
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_manager() -> impl ClipboardManager {
|
||||
let manager = windows::WindowsClipboardManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
24
src/clipboard/windows.rs
Normal file
24
src/clipboard/windows.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use std::process::{Command, Stdio};
|
||||
use std::io::{Write};
|
||||
|
||||
pub struct WindowsClipboardManager {
|
||||
|
||||
}
|
||||
|
||||
impl super::ClipboardManager for WindowsClipboardManager {
|
||||
fn initialize(&self) {
|
||||
// TODO: check if xclip is present and log an error otherwise.
|
||||
}
|
||||
|
||||
fn get_clipboard(&self) -> Option<String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_clipboard(&self, payload: &str) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowsClipboardManager {
|
||||
|
||||
}
|
|
@ -203,9 +203,13 @@ impl <S: SystemManager> ConfigManager for RuntimeConfigManager<S> {
|
|||
fn active_config(&self) -> &Configs {
|
||||
// TODO: optimize performance by avoiding some of these checks if no Configs use the filters
|
||||
|
||||
debug!("Requested config for window:");
|
||||
|
||||
let active_title = self.system_manager.get_current_window_title();
|
||||
|
||||
if let Some(title) = active_title {
|
||||
debug!("=> Title: '{}'", title);
|
||||
|
||||
for (i, regex) in self.title_regexps.iter().enumerate() {
|
||||
if let Some(regex) = regex {
|
||||
if regex.is_match(&title) {
|
||||
|
@ -218,6 +222,24 @@ impl <S: SystemManager> ConfigManager for RuntimeConfigManager<S> {
|
|||
}
|
||||
}
|
||||
|
||||
let active_executable = self.system_manager.get_current_window_executable();
|
||||
|
||||
if let Some(executable) = active_executable {
|
||||
debug!("=> Executable: '{}'", executable);
|
||||
|
||||
// TODO
|
||||
/*for (i, regex) in self.title_regexps.iter().enumerate() {
|
||||
if let Some(regex) = regex {
|
||||
if regex.is_match(&title) {
|
||||
debug!("Matched 'filter_title' for '{}' config, using custom settings.",
|
||||
self.set.specific[i].name);
|
||||
|
||||
return &self.set.specific[i]
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// No matches, return the default mapping
|
||||
debug!("No matches for custom configs, using default settings.");
|
||||
&self.set.default
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::os::raw::{c_void};
|
|||
use std::ffi::CString;
|
||||
use crate::keyboard::{KeyEvent, KeyModifier};
|
||||
use crate::keyboard::KeyModifier::*;
|
||||
|
||||
use crate::bridge::linux::*;
|
||||
|
||||
#[repr(C)]
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use std::sync::mpsc;
|
||||
use std::os::raw::{c_void};
|
||||
use widestring::{U16CString};
|
||||
use crate::keyboard::{KeyEvent, KeyModifier};
|
||||
use crate::keyboard::KeyModifier::*;
|
||||
use crate::bridge::windows::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WindowsKeyboardInterceptor {
|
||||
|
@ -11,7 +13,8 @@ pub struct WindowsKeyboardInterceptor {
|
|||
impl super::KeyboardInterceptor for WindowsKeyboardInterceptor {
|
||||
fn initialize(&self) {
|
||||
unsafe {
|
||||
register_keypress_callback(self,keypress_callback);
|
||||
let self_ptr = self as *const WindowsKeyboardInterceptor as *const c_void;
|
||||
register_keypress_callback(self_ptr,keypress_callback);
|
||||
initialize_window();
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +50,10 @@ impl super::KeyboardSender for WindowsKeyboardSender {
|
|||
}
|
||||
}
|
||||
|
||||
fn trigger_paste(&self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn delete_string(&self, count: i32) {
|
||||
unsafe {
|
||||
delete_string(count)
|
||||
|
@ -56,9 +63,11 @@ impl super::KeyboardSender for WindowsKeyboardSender {
|
|||
|
||||
// Native bridge code
|
||||
|
||||
extern fn keypress_callback(_self: *mut WindowsKeyboardInterceptor, raw_buffer: *const i32, len: i32,
|
||||
extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const i32, len: i32,
|
||||
is_modifier: i32, key_code: i32) {
|
||||
unsafe {
|
||||
let _self = _self as *mut WindowsKeyboardInterceptor;
|
||||
|
||||
if is_modifier == 0 { // Char event
|
||||
// Convert the received buffer to a character
|
||||
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
||||
|
@ -83,17 +92,4 @@ extern fn keypress_callback(_self: *mut WindowsKeyboardInterceptor, raw_buffer:
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
#[link(name="winbridge", kind="static")]
|
||||
extern {
|
||||
fn register_keypress_callback(s: *const WindowsKeyboardInterceptor,
|
||||
cb: extern fn(_self: *mut WindowsKeyboardInterceptor, *const i32,
|
||||
i32, i32, i32));
|
||||
fn initialize_window();
|
||||
fn eventloop();
|
||||
fn send_string(string: *const u16);
|
||||
fn send_vkey(vk: i32);
|
||||
fn delete_string(count: i32);
|
||||
}
|
|
@ -20,4 +20,12 @@ pub fn get_manager() -> impl SystemManager {
|
|||
let manager = linux::LinuxSystemManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
||||
|
||||
// WINDOWS IMPLEMENTATION
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_manager() -> impl SystemManager {
|
||||
let manager = windows::WindowsSystemManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
54
src/system/windows.rs
Normal file
54
src/system/windows.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use widestring::U16CString;
|
||||
use crate::bridge::windows::*;
|
||||
|
||||
pub struct WindowsSystemManager {
|
||||
|
||||
}
|
||||
|
||||
impl super::SystemManager for WindowsSystemManager {
|
||||
fn initialize(&self) {
|
||||
|
||||
}
|
||||
|
||||
fn get_current_window_title(&self) -> Option<String> {
|
||||
unsafe {
|
||||
let mut buffer : [u16; 100] = [0; 100];
|
||||
let res = get_active_window_name(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 get_current_window_class(&self) -> Option<String> {
|
||||
self.get_current_window_executable()
|
||||
}
|
||||
|
||||
fn get_current_window_executable(&self) -> Option<String> {
|
||||
unsafe {
|
||||
let mut buffer : [u16; 250] = [0; 250];
|
||||
let res = get_active_window_executable(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
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for WindowsSystemManager {}
|
||||
|
||||
impl WindowsSystemManager {
|
||||
|
||||
}
|
|
@ -26,4 +26,12 @@ pub fn get_uimanager() -> impl UIManager {
|
|||
let manager = linux::LinuxUIManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
||||
|
||||
// WINDOWS IMPLEMENTATION
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_uimanager() -> impl UIManager {
|
||||
let manager = windows::WindowsUIManager{};
|
||||
manager.initialize();
|
||||
manager
|
||||
}
|
19
src/ui/windows.rs
Normal file
19
src/ui/windows.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use std::process::Command;
|
||||
|
||||
pub struct WindowsUIManager {
|
||||
|
||||
}
|
||||
|
||||
impl super::UIManager for WindowsUIManager {
|
||||
fn initialize(&self) {
|
||||
// TODO: check if notify-send is present and log an error otherwise.
|
||||
}
|
||||
|
||||
fn notify(&self, message: &str) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowsUIManager {
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user