diff --git a/native/libwinbridge/bridge.cpp b/native/libwinbridge/bridge.cpp index 6a57002..ede2528 100644 --- a/native/libwinbridge/bridge.cpp +++ b/native/libwinbridge/bridge.cpp @@ -663,6 +663,25 @@ void trigger_copy() { SendInput(vec.size(), vec.data(), sizeof(INPUT)); } +int32_t are_modifiers_pressed() { + short ctrl_pressed = GetAsyncKeyState(VK_CONTROL); + short enter_pressed = GetAsyncKeyState(VK_RETURN); + short alt_pressed = GetAsyncKeyState(VK_MENU); + short shift_pressed = GetAsyncKeyState(VK_SHIFT); + short meta_pressed = GetAsyncKeyState(VK_LWIN); + short rmeta_pressed = GetAsyncKeyState(VK_RWIN); + if (((ctrl_pressed & 0x8000) + + (enter_pressed & 0x8000) + + (alt_pressed & 0x8000) + + (shift_pressed & 0x8000) + + (meta_pressed & 0x8000) + + (rmeta_pressed & 0x8000)) != 0) { + return 1; + } + + return 0; +} + // SYSTEM diff --git a/native/libwinbridge/bridge.h b/native/libwinbridge/bridge.h index 7db802a..ae57213 100644 --- a/native/libwinbridge/bridge.h +++ b/native/libwinbridge/bridge.h @@ -97,6 +97,11 @@ extern "C" void trigger_shift_paste(); */ extern "C" void trigger_copy(); +/* + * Check whether keyboard modifiers (CTRL, CMD, SHIFT, ecc) are pressed + */ +extern "C" int32_t are_modifiers_pressed(); + // Detect current application commands /* diff --git a/src/bridge/windows.rs b/src/bridge/windows.rs index dd7ed32..554056f 100644 --- a/src/bridge/windows.rs +++ b/src/bridge/windows.rs @@ -69,6 +69,7 @@ extern "C" { pub fn trigger_paste(); pub fn trigger_shift_paste(); pub fn trigger_copy(); + pub fn are_modifiers_pressed() -> i32; // PROCESSES diff --git a/src/extension/form.rs b/src/extension/form.rs index c0a3361..00ac091 100644 --- a/src/extension/form.rs +++ b/src/extension/form.rs @@ -74,7 +74,7 @@ impl super::Extension for FormExtension { .manager .invoke(&["form", "-i", "-"], &serialized_config); - // On macOS, after the form closes we have to wait until the user releases the modifier keys + // On macOS and Windows, after the form closes we have to wait until the user releases the modifier keys on_form_close(); if let Some(output) = output { @@ -95,9 +95,17 @@ impl super::Extension for FormExtension { } } -#[cfg(not(target_os = "macos"))] +#[cfg(target_os = "linux")] fn on_form_close() { - // NOOP on Windows and Linux + // NOOP on Linux +} + +#[cfg(target_os = "windows")] +fn on_form_close() { + let released = crate::keyboard::windows::wait_for_modifiers_release(); + if !released { + warn!("Wait for modifiers release timed out! Please after closing the form, release your modifiers keys (CTRL, CMD, ALT, SHIFT)"); + } } #[cfg(target_os = "macos")] diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index dece480..7a5c2ca 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -21,7 +21,7 @@ use crate::config::Configs; use serde::{Deserialize, Serialize}; #[cfg(target_os = "windows")] -mod windows; +pub mod windows; #[cfg(target_os = "linux")] mod linux; diff --git a/src/keyboard/windows.rs b/src/keyboard/windows.rs index be2cbb2..55b1b1d 100644 --- a/src/keyboard/windows.rs +++ b/src/keyboard/windows.rs @@ -78,3 +78,15 @@ impl super::KeyboardManager for WindowsKeyboardManager { } } } + +pub fn wait_for_modifiers_release() -> bool { + let start = std::time::SystemTime::now(); + while start.elapsed().unwrap_or_default().as_millis() < 3000 { + let pressed = unsafe { crate::bridge::windows::are_modifiers_pressed() }; + if pressed == 0 { + return true; + } + std::thread::sleep(std::time::Duration::from_millis(100)); + } + false +} \ No newline at end of file