fix(core): improve handling of conflicting pressed modifiers
This commit is contained in:
parent
2eef404d6c
commit
e049ba51fb
|
@ -32,6 +32,11 @@ use crate::engine::process::ModifierStatusProvider;
|
||||||
/// after a while.
|
/// after a while.
|
||||||
const MAXIMUM_MODIFIERS_PRESS_TIME_RECORD: Duration = Duration::from_secs(30);
|
const MAXIMUM_MODIFIERS_PRESS_TIME_RECORD: Duration = Duration::from_secs(30);
|
||||||
|
|
||||||
|
// TODO: should we add also Shift on Linux to avoid any conflict in the expansion process? Investigate
|
||||||
|
/// These are the modifiers that might conflict with the expansion process. For example,
|
||||||
|
/// if espanso injects some texts while Alt or Ctrl are pressed, strange things might happen.
|
||||||
|
const CONFLICTING_MODIFIERS: &[Modifier] = &[Modifier::Ctrl, Modifier::Alt, Modifier::Meta];
|
||||||
|
|
||||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||||
pub enum Modifier {
|
pub enum Modifier {
|
||||||
Ctrl,
|
Ctrl,
|
||||||
|
@ -52,7 +57,7 @@ impl ModifierStateStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_any_modifier_pressed(&self) -> bool {
|
pub fn is_any_conflicting_modifier_pressed(&self) -> bool {
|
||||||
let mut state = self.state.lock().expect("unable to obtain modifier state");
|
let mut state = self.state.lock().expect("unable to obtain modifier state");
|
||||||
let mut is_any_modifier_pressed = false;
|
let mut is_any_modifier_pressed = false;
|
||||||
for (modifier, status) in &mut state.modifiers {
|
for (modifier, status) in &mut state.modifiers {
|
||||||
|
@ -64,7 +69,7 @@ impl ModifierStateStore {
|
||||||
status.release();
|
status.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.is_pressed() {
|
if status.is_pressed() && CONFLICTING_MODIFIERS.contains(modifier) {
|
||||||
is_any_modifier_pressed = true;
|
is_any_modifier_pressed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +136,7 @@ impl ModifierStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModifierStatusProvider for ModifierStateStore {
|
impl ModifierStatusProvider for ModifierStateStore {
|
||||||
fn is_any_modifier_pressed(&self) -> bool {
|
fn is_any_conflicting_modifier_pressed(&self) -> bool {
|
||||||
self.is_any_modifier_pressed()
|
self.is_any_conflicting_modifier_pressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use crate::engine::event::{Event, EventType};
|
||||||
const MODIFIER_DELAY_TIMEOUT: Duration = Duration::from_secs(3);
|
const MODIFIER_DELAY_TIMEOUT: Duration = Duration::from_secs(3);
|
||||||
|
|
||||||
pub trait ModifierStatusProvider {
|
pub trait ModifierStatusProvider {
|
||||||
fn is_any_modifier_pressed(&self) -> bool;
|
fn is_any_conflicting_modifier_pressed(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This middleware is used to delay the injection of text until
|
/// This middleware is used to delay the injection of text until
|
||||||
|
@ -58,11 +58,14 @@ impl <'a> Middleware for DelayForModifierReleaseMiddleware<'a> {
|
||||||
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
|
fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
|
||||||
if is_injection_event(&event.etype) {
|
if is_injection_event(&event.etype) {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
while self.provider.is_any_modifier_pressed() {
|
while self.provider.is_any_conflicting_modifier_pressed() {
|
||||||
if Instant::now().duration_since(start) > MODIFIER_DELAY_TIMEOUT {
|
if Instant::now().duration_since(start) > MODIFIER_DELAY_TIMEOUT {
|
||||||
warn!("injection delay has timed out, please release the modifier keys (SHIFT, CTRL, ALT, CMD) to trigger an expansion");
|
warn!("injection delay has timed out, please release the modifier keys (SHIFT, CTRL, ALT, CMD) to trigger an expansion");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: here we might show a popup window to tell the users to release those keys
|
||||||
|
|
||||||
trace!("delaying injection event as some modifiers are pressed");
|
trace!("delaying injection event as some modifiers are pressed");
|
||||||
std::thread::sleep(Duration::from_millis(100));
|
std::thread::sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user