feat(detect): add option to lower the windows keyboard layout cache interval, #745
This commit is contained in:
parent
21bc75bc31
commit
92645e0987
|
@ -66,6 +66,12 @@ pub struct SourceCreationOptions {
|
|||
// those from espanso, but might need to be disabled when using some software-level keyboards.
|
||||
// Disabling this option might conflict with the undo feature.
|
||||
pub win32_exclude_orphan_events: bool,
|
||||
|
||||
// The maximum interval (in milliseconds) for which a keyboard layout
|
||||
// can be cached. If switching often between different layouts, you
|
||||
// could lower this amount to avoid the "lost detection" effect described
|
||||
// in this issue: https://github.com/federico-terzi/espanso/issues/745
|
||||
pub win32_keyboard_layout_cache_interval: i64,
|
||||
}
|
||||
|
||||
// This struct identifies the keyboard layout that
|
||||
|
@ -87,6 +93,7 @@ impl Default for SourceCreationOptions {
|
|||
evdev_keyboard_rmlvo: None,
|
||||
hotkeys: Vec::new(),
|
||||
win32_exclude_orphan_events: true,
|
||||
win32_keyboard_layout_cache_interval: 2000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +104,7 @@ pub fn get_source(options: SourceCreationOptions) -> Result<Box<dyn Source>> {
|
|||
Ok(Box::new(win32::Win32Source::new(
|
||||
&options.hotkeys,
|
||||
options.win32_exclude_orphan_events,
|
||||
options.win32_keyboard_layout_cache_interval,
|
||||
)))
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::os::raw::c_long;
|
||||
use std::{convert::TryInto, ffi::c_void};
|
||||
|
||||
use lazycell::LazyCell;
|
||||
|
@ -79,10 +80,19 @@ pub struct RawHotKey {
|
|||
pub flags: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct InitOptions {
|
||||
pub keyboard_layout_cache_interval: c_long,
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
#[link(name = "espansodetect", kind = "static")]
|
||||
extern "C" {
|
||||
pub fn detect_initialize(_self: *const Win32Source, error_code: *mut i32) -> *mut c_void;
|
||||
pub fn detect_initialize(
|
||||
_self: *const Win32Source,
|
||||
options: *const InitOptions,
|
||||
error_code: *mut i32,
|
||||
) -> *mut c_void;
|
||||
pub fn detect_register_hotkey(window: *const c_void, hotkey: RawHotKey) -> i32;
|
||||
|
||||
pub fn detect_eventloop(
|
||||
|
@ -99,24 +109,35 @@ pub struct Win32Source {
|
|||
hotkeys: Vec<HotKey>,
|
||||
|
||||
exclude_orphan_events: bool,
|
||||
keyboard_layout_cache_interval: i64,
|
||||
}
|
||||
|
||||
#[allow(clippy::new_without_default)]
|
||||
impl Win32Source {
|
||||
pub fn new(hotkeys: &[HotKey], exclude_orphan_events: bool) -> Win32Source {
|
||||
pub fn new(
|
||||
hotkeys: &[HotKey],
|
||||
exclude_orphan_events: bool,
|
||||
keyboard_layout_cache_interval: i64,
|
||||
) -> Win32Source {
|
||||
Self {
|
||||
handle: std::ptr::null_mut(),
|
||||
callback: LazyCell::new(),
|
||||
hotkeys: hotkeys.to_vec(),
|
||||
exclude_orphan_events,
|
||||
keyboard_layout_cache_interval,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for Win32Source {
|
||||
fn initialize(&mut self) -> Result<()> {
|
||||
let options = InitOptions {
|
||||
keyboard_layout_cache_interval: self.keyboard_layout_cache_interval.try_into().unwrap(),
|
||||
};
|
||||
|
||||
let mut error_code = 0;
|
||||
let handle = unsafe { detect_initialize(self as *const Win32Source, &mut error_code) };
|
||||
let handle =
|
||||
unsafe { detect_initialize(self as *const Win32Source, &options, &mut error_code) };
|
||||
|
||||
if handle.is_null() {
|
||||
let error = match error_code {
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include <strsafe.h>
|
||||
#include <Windows.h>
|
||||
|
||||
// How many milliseconds must pass between events before refreshing the keyboard layout
|
||||
const long DETECT_REFRESH_KEYBOARD_LAYOUT_INTERVAL = 2000;
|
||||
const wchar_t *const DETECT_WINCLASS = L"EspansoDetect";
|
||||
const USHORT MOUSE_DOWN_FLAGS = RI_MOUSE_LEFT_BUTTON_DOWN | RI_MOUSE_RIGHT_BUTTON_DOWN | RI_MOUSE_MIDDLE_BUTTON_DOWN |
|
||||
RI_MOUSE_BUTTON_1_DOWN | RI_MOUSE_BUTTON_2_DOWN | RI_MOUSE_BUTTON_3_DOWN |
|
||||
|
@ -52,6 +50,8 @@ const USHORT MOUSE_UP_FLAGS = RI_MOUSE_LEFT_BUTTON_UP | RI_MOUSE_RIGHT_BUTTON_UP
|
|||
typedef struct {
|
||||
HKL current_keyboard_layout;
|
||||
DWORD last_key_press_tick;
|
||||
// How many milliseconds must pass between events before refreshing the keyboard layout
|
||||
long keyboard_layout_cache_interval;
|
||||
|
||||
// Rust interop
|
||||
void * rust_instance;
|
||||
|
@ -130,7 +130,7 @@ LRESULT CALLBACK detect_window_procedure(HWND window, unsigned int msg, WPARAM w
|
|||
DWORD currentTick = GetTickCount();
|
||||
|
||||
// If enough time has passed between the last keypress and now, refresh the keyboard layout
|
||||
if ((currentTick - variables->last_key_press_tick) > DETECT_REFRESH_KEYBOARD_LAYOUT_INTERVAL)
|
||||
if ((currentTick - variables->last_key_press_tick) > variables->keyboard_layout_cache_interval)
|
||||
{
|
||||
|
||||
// Because keyboard layouts on windows are Window-specific, to get the current
|
||||
|
@ -269,7 +269,7 @@ LRESULT CALLBACK detect_window_procedure(HWND window, unsigned int msg, WPARAM w
|
|||
}
|
||||
}
|
||||
|
||||
void * detect_initialize(void *_self, int32_t *error_code)
|
||||
void * detect_initialize(void *_self, InitOptions * options, int32_t *error_code)
|
||||
{
|
||||
HWND window = NULL;
|
||||
|
||||
|
@ -297,6 +297,7 @@ void * detect_initialize(void *_self, int32_t *error_code)
|
|||
|
||||
// Initialize the default keyboard layout
|
||||
variables->current_keyboard_layout = GetKeyboardLayout(0);
|
||||
variables->keyboard_layout_cache_interval = options->keyboard_layout_cache_interval;
|
||||
|
||||
// Docs: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw
|
||||
window = CreateWindowEx(
|
||||
|
|
|
@ -76,9 +76,12 @@ typedef struct {
|
|||
|
||||
typedef void (*EventCallback)(void * rust_istance, InputEvent data);
|
||||
|
||||
typedef struct {
|
||||
long keyboard_layout_cache_interval;
|
||||
} InitOptions;
|
||||
|
||||
// Initialize the Raw Input API and the Window.
|
||||
extern "C" void * detect_initialize(void * rust_istance, int32_t *error_code);
|
||||
extern "C" void * detect_initialize(void * rust_istance, InitOptions * options, int32_t *error_code);
|
||||
|
||||
// Register the given hotkey, return a non-zero code if successful
|
||||
extern "C" int32_t detect_register_hotkey(void * window, HotKey hotkey);
|
||||
|
|
Loading…
Reference in New Issue
Block a user