diff --git a/espanso/src/cli/worker/engine/executor/key_injector.rs b/espanso/src/cli/worker/engine/executor/key_injector.rs
new file mode 100644
index 0000000..ba160af
--- /dev/null
+++ b/espanso/src/cli/worker/engine/executor/key_injector.rs
@@ -0,0 +1,84 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso. If not, see .
+ */
+
+use espanso_inject::Injector;
+
+use crate::engine::dispatch::KeyInjector;
+
+pub struct KeyInjectorAdapter<'a> {
+ injector: &'a dyn Injector,
+}
+
+impl<'a> KeyInjectorAdapter<'a> {
+ pub fn new(injector: &'a dyn Injector) -> Self {
+ Self { injector }
+ }
+}
+
+impl<'a> KeyInjector for KeyInjectorAdapter<'a> {
+ fn inject_sequence(&self, keys: &[crate::engine::event::keyboard::Key]) -> anyhow::Result<()> {
+ let converted_keys: Vec<_> = keys.iter().map(convert_to_inject_key).collect();
+ self.injector.send_keys(&converted_keys, Default::default()) // TODO: handle options
+ }
+}
+
+fn convert_to_inject_key(key: &crate::engine::event::keyboard::Key) -> espanso_inject::keys::Key {
+ match key {
+ crate::engine::event::keyboard::Key::Alt => espanso_inject::keys::Key::Alt,
+ crate::engine::event::keyboard::Key::CapsLock => espanso_inject::keys::Key::CapsLock,
+ crate::engine::event::keyboard::Key::Control => espanso_inject::keys::Key::Control,
+ crate::engine::event::keyboard::Key::Meta => espanso_inject::keys::Key::Meta,
+ crate::engine::event::keyboard::Key::NumLock => espanso_inject::keys::Key::NumLock,
+ crate::engine::event::keyboard::Key::Shift => espanso_inject::keys::Key::Shift,
+ crate::engine::event::keyboard::Key::Enter => espanso_inject::keys::Key::Enter,
+ crate::engine::event::keyboard::Key::Tab => espanso_inject::keys::Key::Tab,
+ crate::engine::event::keyboard::Key::Space => espanso_inject::keys::Key::Space,
+ crate::engine::event::keyboard::Key::ArrowDown => espanso_inject::keys::Key::ArrowDown,
+ crate::engine::event::keyboard::Key::ArrowLeft => espanso_inject::keys::Key::ArrowLeft,
+ crate::engine::event::keyboard::Key::ArrowRight => espanso_inject::keys::Key::ArrowRight,
+ crate::engine::event::keyboard::Key::ArrowUp => espanso_inject::keys::Key::ArrowUp,
+ crate::engine::event::keyboard::Key::End => espanso_inject::keys::Key::End,
+ crate::engine::event::keyboard::Key::Home => espanso_inject::keys::Key::Home,
+ crate::engine::event::keyboard::Key::PageDown => espanso_inject::keys::Key::PageDown,
+ crate::engine::event::keyboard::Key::PageUp => espanso_inject::keys::Key::PageUp,
+ crate::engine::event::keyboard::Key::Escape => espanso_inject::keys::Key::Escape,
+ crate::engine::event::keyboard::Key::Backspace => espanso_inject::keys::Key::Backspace,
+ crate::engine::event::keyboard::Key::F1 => espanso_inject::keys::Key::F1,
+ crate::engine::event::keyboard::Key::F2 => espanso_inject::keys::Key::F2,
+ crate::engine::event::keyboard::Key::F3 => espanso_inject::keys::Key::F3,
+ crate::engine::event::keyboard::Key::F4 => espanso_inject::keys::Key::F4,
+ crate::engine::event::keyboard::Key::F5 => espanso_inject::keys::Key::F5,
+ crate::engine::event::keyboard::Key::F6 => espanso_inject::keys::Key::F6,
+ crate::engine::event::keyboard::Key::F7 => espanso_inject::keys::Key::F7,
+ crate::engine::event::keyboard::Key::F8 => espanso_inject::keys::Key::F8,
+ crate::engine::event::keyboard::Key::F9 => espanso_inject::keys::Key::F9,
+ crate::engine::event::keyboard::Key::F10 => espanso_inject::keys::Key::F10,
+ crate::engine::event::keyboard::Key::F11 => espanso_inject::keys::Key::F11,
+ crate::engine::event::keyboard::Key::F12 => espanso_inject::keys::Key::F12,
+ crate::engine::event::keyboard::Key::F13 => espanso_inject::keys::Key::F13,
+ crate::engine::event::keyboard::Key::F14 => espanso_inject::keys::Key::F14,
+ crate::engine::event::keyboard::Key::F15 => espanso_inject::keys::Key::F15,
+ crate::engine::event::keyboard::Key::F16 => espanso_inject::keys::Key::F16,
+ crate::engine::event::keyboard::Key::F17 => espanso_inject::keys::Key::F17,
+ crate::engine::event::keyboard::Key::F18 => espanso_inject::keys::Key::F18,
+ crate::engine::event::keyboard::Key::F19 => espanso_inject::keys::Key::F19,
+ crate::engine::event::keyboard::Key::F20 => espanso_inject::keys::Key::F20,
+ crate::engine::event::keyboard::Key::Other(raw) => espanso_inject::keys::Key::Raw(*raw),
+ }
+}
diff --git a/espanso/src/cli/worker/engine/executor/mod.rs b/espanso/src/cli/worker/engine/executor/mod.rs
index 93435fd..025aa56 100644
--- a/espanso/src/cli/worker/engine/executor/mod.rs
+++ b/espanso/src/cli/worker/engine/executor/mod.rs
@@ -17,4 +17,5 @@
* along with espanso. If not, see .
*/
-pub mod text_injector;
\ No newline at end of file
+pub mod text_injector;
+pub mod key_injector;
\ No newline at end of file
diff --git a/espanso/src/cli/worker/engine/executor/text_injector.rs b/espanso/src/cli/worker/engine/executor/text_injector.rs
index 2a5bc84..4b65800 100644
--- a/espanso/src/cli/worker/engine/executor/text_injector.rs
+++ b/espanso/src/cli/worker/engine/executor/text_injector.rs
@@ -17,21 +17,25 @@
* along with espanso. If not, see .
*/
+use espanso_inject::Injector;
+
use crate::engine::dispatch::TextInjector;
-pub struct TextInjectorAdapter {}
+pub struct TextInjectorAdapter<'a> {
+ injector: &'a dyn Injector,
+}
-impl TextInjectorAdapter {
- pub fn new() -> Self {
- Self {}
+impl <'a> TextInjectorAdapter<'a> {
+ pub fn new(injector: &'a dyn Injector) -> Self {
+ Self {
+ injector
+ }
}
}
-impl TextInjector for TextInjectorAdapter {
- fn inject(&self, text: &str) -> anyhow::Result<()> {
- // TODO: implement
- println!("INJECT: {}", text);
-
- Ok(())
+impl <'a> TextInjector for TextInjectorAdapter<'a> {
+ fn inject_text(&self, text: &str) -> anyhow::Result<()> {
+ // TODO: handle injection options
+ self.injector.send_string(text, Default::default())
}
}
diff --git a/espanso/src/cli/worker/mod.rs b/espanso/src/cli/worker/mod.rs
index 2d15c1a..44c79c6 100644
--- a/espanso/src/cli/worker/mod.rs
+++ b/espanso/src/cli/worker/mod.rs
@@ -63,8 +63,11 @@ fn worker_main(args: CliModuleArgs) {
let mut processor = process::default(&matchers, &config_manager, &selector, &multiplexer, &renderer_adapter);
- let text_injector = engine::executor::text_injector::TextInjectorAdapter::new();
- let dispatcher = dispatch::default(&text_injector);
+ let injector = espanso_inject::get_injector(Default::default()).expect("failed to initialize injector module"); // TODO: handle the options
+
+ let text_injector = engine::executor::text_injector::TextInjectorAdapter::new(&*injector);
+ let key_injector = engine::executor::key_injector::KeyInjectorAdapter::new(&*injector);
+ let dispatcher = dispatch::default(&text_injector, &key_injector);
let mut engine = Engine::new(&funnel, &mut processor, &dispatcher);
engine.run();
diff --git a/espanso/src/engine/dispatch/default.rs b/espanso/src/engine/dispatch/default.rs
index 3c8646b..0867ad2 100644
--- a/espanso/src/engine/dispatch/default.rs
+++ b/espanso/src/engine/dispatch/default.rs
@@ -17,7 +17,7 @@
* along with espanso. If not, see .
*/
-use super::{Dispatcher, Executor, TextInjector};
+use super::{Dispatcher, Executor, KeyInjector, TextInjector};
use super::Event;
pub struct DefaultDispatcher<'a> {
@@ -25,10 +25,11 @@ pub struct DefaultDispatcher<'a> {
}
impl <'a> DefaultDispatcher<'a> {
- pub fn new(text_injector: &'a dyn TextInjector) -> Self {
+ pub fn new(text_injector: &'a dyn TextInjector, key_injector: &'a dyn KeyInjector) -> Self {
Self {
executors: vec![
Box::new(super::executor::text_inject::TextInjectExecutor::new(text_injector)),
+ Box::new(super::executor::key_inject::KeyInjectExecutor::new(key_injector)),
]
}
}
diff --git a/espanso/src/engine/dispatch/executor/key_inject.rs b/espanso/src/engine/dispatch/executor/key_inject.rs
new file mode 100644
index 0000000..3182a38
--- /dev/null
+++ b/espanso/src/engine/dispatch/executor/key_inject.rs
@@ -0,0 +1,44 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso. If not, see .
+ */
+
+use super::super::{Event, Executor, KeyInjector};
+use log::error;
+
+pub struct KeyInjectExecutor<'a> {
+ injector: &'a dyn KeyInjector,
+}
+
+impl<'a> KeyInjectExecutor<'a> {
+ pub fn new(injector: &'a dyn KeyInjector) -> Self {
+ Self { injector }
+ }
+}
+
+impl<'a> Executor for KeyInjectExecutor<'a> {
+ fn execute(&self, event: &Event) -> bool {
+ if let Event::KeySequenceInject(inject_event) = event {
+ if let Err(error) = self.injector.inject_sequence(&inject_event.keys) {
+ error!("key injector reported an error: {}", error);
+ }
+ return true;
+ }
+
+ false
+ }
+}
diff --git a/espanso/src/engine/dispatch/executor/mod.rs b/espanso/src/engine/dispatch/executor/mod.rs
index 05c1a2f..9631006 100644
--- a/espanso/src/engine/dispatch/executor/mod.rs
+++ b/espanso/src/engine/dispatch/executor/mod.rs
@@ -17,4 +17,5 @@
* along with espanso. If not, see .
*/
-pub mod text_inject;
\ No newline at end of file
+pub mod text_inject;
+pub mod key_inject;
\ No newline at end of file
diff --git a/espanso/src/engine/dispatch/executor/text_inject.rs b/espanso/src/engine/dispatch/executor/text_inject.rs
index ca5da46..30e6ffb 100644
--- a/espanso/src/engine/dispatch/executor/text_inject.rs
+++ b/espanso/src/engine/dispatch/executor/text_inject.rs
@@ -18,7 +18,7 @@
*/
use super::super::{Event, Executor, TextInjector};
-use crate::engine::event::inject::TextInjectMode;
+use crate::engine::event::text::TextInjectMode;
use log::error;
pub struct TextInjectExecutor<'a> {
@@ -35,7 +35,7 @@ impl<'a> Executor for TextInjectExecutor<'a> {
fn execute(&self, event: &Event) -> bool {
if let Event::TextInject(inject_event) = event {
if let Some(TextInjectMode::Keys) = inject_event.force_mode {
- if let Err(error) = self.injector.inject(&inject_event.text) {
+ if let Err(error) = self.injector.inject_text(&inject_event.text) {
error!("text injector reported an error: {:?}", error);
}
return true;
diff --git a/espanso/src/engine/dispatch/mod.rs b/espanso/src/engine/dispatch/mod.rs
index 542e054..03a2cb6 100644
--- a/espanso/src/engine/dispatch/mod.rs
+++ b/espanso/src/engine/dispatch/mod.rs
@@ -18,7 +18,7 @@
*/
use anyhow::Result;
-use super::Event;
+use super::{Event, event::keyboard::Key};
mod executor;
mod default;
@@ -32,11 +32,16 @@ pub trait Dispatcher {
}
pub trait TextInjector {
- fn inject(&self, text: &str) -> Result<()>;
+ fn inject_text(&self, text: &str) -> Result<()>;
}
-pub fn default<'a>(text_injector: &'a dyn TextInjector) -> impl Dispatcher + 'a {
+pub trait KeyInjector {
+ fn inject_sequence(&self, keys: &[Key]) -> Result<()>;
+}
+
+pub fn default<'a>(text_injector: &'a dyn TextInjector, key_injector: &'a dyn KeyInjector) -> impl Dispatcher + 'a {
default::DefaultDispatcher::new(
text_injector,
+ key_injector,
)
}
\ No newline at end of file
diff --git a/espanso/src/engine/event/keyboard.rs b/espanso/src/engine/event/keyboard.rs
index 05fb0a8..da2d819 100644
--- a/espanso/src/engine/event/keyboard.rs
+++ b/espanso/src/engine/event/keyboard.rs
@@ -37,6 +37,11 @@ pub struct KeyboardEvent {
pub variant: Option,
}
+#[derive(Debug)]
+pub struct KeySequenceInjectRequest {
+ pub keys: Vec,
+}
+
#[derive(Debug, Clone, PartialEq)]
pub enum Key {
// Modifiers
diff --git a/espanso/src/engine/event/mod.rs b/espanso/src/engine/event/mod.rs
index a55f080..3bfc01c 100644
--- a/espanso/src/engine/event/mod.rs
+++ b/espanso/src/engine/event/mod.rs
@@ -18,7 +18,7 @@
*/
pub mod keyboard;
-pub mod inject;
+pub mod text;
pub mod matches;
pub mod render;
@@ -38,5 +38,6 @@ pub enum Event {
Rendered(render::RenderedEvent),
// Effects
- TextInject(inject::TextInjectRequest),
+ KeySequenceInject(keyboard::KeySequenceInjectRequest),
+ TextInject(text::TextInjectRequest),
}
\ No newline at end of file
diff --git a/espanso/src/engine/event/inject.rs b/espanso/src/engine/event/text.rs
similarity index 97%
rename from espanso/src/engine/event/inject.rs
rename to espanso/src/engine/event/text.rs
index 1edc09a..79db95c 100644
--- a/espanso/src/engine/event/inject.rs
+++ b/espanso/src/engine/event/text.rs
@@ -19,7 +19,6 @@
#[derive(Debug)]
pub struct TextInjectRequest {
- pub delete_count: i32,
pub text: String,
pub force_mode: Option,
}
@@ -28,4 +27,5 @@ pub struct TextInjectRequest {
pub enum TextInjectMode {
Keys,
Clipboard,
-}
\ No newline at end of file
+}
+
diff --git a/espanso/src/engine/process/default.rs b/espanso/src/engine/process/default.rs
index 988e965..e38132f 100644
--- a/espanso/src/engine/process/default.rs
+++ b/espanso/src/engine/process/default.rs
@@ -22,7 +22,7 @@ use log::trace;
use super::{
middleware::{
match_select::MatchSelectMiddleware, matcher::MatchMiddleware, multiplex::MultiplexMiddleware,
- render::RenderMiddleware,
+ render::RenderMiddleware, action::ActionMiddleware,
},
Event, MatchFilter, MatchSelector, Matcher, Middleware, Multiplexer, Processor, Renderer,
};
@@ -48,6 +48,7 @@ impl<'a> DefaultProcessor<'a> {
Box::new(MatchSelectMiddleware::new(match_filter, match_selector)),
Box::new(MultiplexMiddleware::new(multiplexer)),
Box::new(RenderMiddleware::new(renderer)),
+ Box::new(ActionMiddleware::new()),
],
}
}
@@ -57,7 +58,7 @@ impl<'a> DefaultProcessor<'a> {
let mut current_event = event;
let mut current_queue = VecDeque::new();
- let dispatch = |event: Event| {
+ let mut dispatch = |event: Event| {
trace!("dispatched event: {:?}", event);
current_queue.push_front(event);
};
@@ -65,7 +66,7 @@ impl<'a> DefaultProcessor<'a> {
for middleware in self.middleware.iter() {
trace!("middleware received event: {:?}", current_event);
- current_event = middleware.next(current_event, &dispatch);
+ current_event = middleware.next(current_event, &mut dispatch);
trace!("middleware produced event: {:?}", current_event);
}
diff --git a/espanso/src/engine/process/middleware/action.rs b/espanso/src/engine/process/middleware/action.rs
new file mode 100644
index 0000000..a81c030
--- /dev/null
+++ b/espanso/src/engine/process/middleware/action.rs
@@ -0,0 +1,57 @@
+/*
+ * This file is part of espanso.
+ *
+ * Copyright (C) 2019-2021 Federico Terzi
+ *
+ * espanso is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * espanso is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with espanso. If not, see .
+ */
+
+use log::{debug, error};
+
+use super::super::Middleware;
+use crate::engine::{event::{Event, keyboard::{Key, KeySequenceInjectRequest}, matches::MatchSelectedEvent, text::{TextInjectMode, TextInjectRequest}}, process::{MatchFilter, MatchSelector, Multiplexer}};
+
+pub struct ActionMiddleware {
+}
+
+impl ActionMiddleware {
+ pub fn new() -> Self {
+ Self {}
+ }
+}
+
+impl Middleware for ActionMiddleware {
+ fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event {
+ if let Event::Rendered(m_event) = &event {
+ let delete_count = m_event.trigger.len();
+ let delete_sequence: Vec<_> = (0..delete_count).map(|_| Key::Backspace).collect();
+
+ dispatch(Event::TextInject(TextInjectRequest {
+ text: m_event.body.clone(),
+ force_mode: Some(TextInjectMode::Keys), // TODO: determine this one dynamically
+ }));
+
+ // This is executed before the dispatched event
+ return Event::KeySequenceInject(KeySequenceInjectRequest {
+ keys: delete_sequence
+ })
+ }
+
+ // TODO: handle images
+
+ event
+ }
+}
+
+// TODO: test
diff --git a/espanso/src/engine/process/middleware/match_select.rs b/espanso/src/engine/process/middleware/match_select.rs
index 146ad0b..6edb5b6 100644
--- a/espanso/src/engine/process/middleware/match_select.rs
+++ b/espanso/src/engine/process/middleware/match_select.rs
@@ -43,7 +43,7 @@ impl<'a> MatchSelectMiddleware<'a> {
}
impl<'a> Middleware for MatchSelectMiddleware<'a> {
- fn next(&self, event: Event, _: &dyn FnMut(Event)) -> Event {
+ fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
if let Event::MatchesDetected(m_event) = event {
let matches_ids: Vec = m_event.matches.iter().map(|m| m.id).collect();
diff --git a/espanso/src/engine/process/middleware/matcher.rs b/espanso/src/engine/process/middleware/matcher.rs
index f9a5dfd..862c7fb 100644
--- a/espanso/src/engine/process/middleware/matcher.rs
+++ b/espanso/src/engine/process/middleware/matcher.rs
@@ -41,7 +41,7 @@ impl<'a, State> MatchMiddleware<'a, State> {
}
impl<'a, State> Middleware for MatchMiddleware<'a, State> {
- fn next(&self, event: Event, _: &dyn FnMut(Event)) -> Event {
+ fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
let mut matcher_states = self.matcher_states.borrow_mut();
let prev_states = if !matcher_states.is_empty() {
matcher_states.get(matcher_states.len() - 1)
diff --git a/espanso/src/engine/process/middleware/mod.rs b/espanso/src/engine/process/middleware/mod.rs
index e449e1a..082bb0f 100644
--- a/espanso/src/engine/process/middleware/mod.rs
+++ b/espanso/src/engine/process/middleware/mod.rs
@@ -17,6 +17,7 @@
* along with espanso. If not, see .
*/
+pub mod action;
pub mod render;
pub mod matcher;
pub mod multiplex;
diff --git a/espanso/src/engine/process/middleware/multiplex.rs b/espanso/src/engine/process/middleware/multiplex.rs
index 9e9235b..890e91c 100644
--- a/espanso/src/engine/process/middleware/multiplex.rs
+++ b/espanso/src/engine/process/middleware/multiplex.rs
@@ -20,7 +20,7 @@
use log::{debug, error};
use super::super::Middleware;
-use crate::engine::{event::{Event, inject::{TextInjectRequest, TextInjectMode}, matches::MatchSelectedEvent}, process::{MatchFilter, MatchSelector, Multiplexer}};
+use crate::engine::{event::{Event, text::{TextInjectRequest, TextInjectMode}, matches::MatchSelectedEvent}, process::{MatchFilter, MatchSelector, Multiplexer}};
pub struct MultiplexMiddleware<'a> {
multiplexer: &'a dyn Multiplexer,
@@ -33,7 +33,7 @@ impl<'a> MultiplexMiddleware<'a> {
}
impl<'a> Middleware for MultiplexMiddleware<'a> {
- fn next(&self, event: Event, _: &dyn FnMut(Event)) -> Event {
+ fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
if let Event::MatchSelected(m_event) = event {
return match self.multiplexer.convert(m_event.chosen.id, m_event.chosen.trigger, m_event.chosen.args) {
Some(event) => event,
diff --git a/espanso/src/engine/process/middleware/render.rs b/espanso/src/engine/process/middleware/render.rs
index cb31040..d9ddce8 100644
--- a/espanso/src/engine/process/middleware/render.rs
+++ b/espanso/src/engine/process/middleware/render.rs
@@ -20,7 +20,7 @@
use log::{debug, error};
use super::super::Middleware;
-use crate::engine::{event::{Event, inject::{TextInjectRequest, TextInjectMode}, matches::MatchSelectedEvent, render::RenderedEvent}, process::{MatchFilter, MatchSelector, Renderer, RendererError}};
+use crate::engine::{event::{Event, text::{TextInjectRequest, TextInjectMode}, matches::MatchSelectedEvent, render::RenderedEvent}, process::{MatchFilter, MatchSelector, Renderer, RendererError}};
pub struct RenderMiddleware<'a> {
renderer: &'a dyn Renderer<'a>,
@@ -33,7 +33,7 @@ impl<'a> RenderMiddleware<'a> {
}
impl<'a> Middleware for RenderMiddleware<'a> {
- fn next(&self, event: Event, _: &dyn FnMut(Event)) -> Event {
+ fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event {
if let Event::RenderingRequested(m_event) = event {
match self.renderer.render(m_event.match_id, m_event.trigger_args) {
Ok(body) => {
diff --git a/espanso/src/engine/process/mod.rs b/espanso/src/engine/process/mod.rs
index 9258869..490e3b4 100644
--- a/espanso/src/engine/process/mod.rs
+++ b/espanso/src/engine/process/mod.rs
@@ -26,7 +26,7 @@ mod default;
mod middleware;
pub trait Middleware {
- fn next(&self, event: Event, dispatch: &dyn FnMut(Event)) -> Event;
+ fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event;
}
pub trait Processor {