feat(core): add support for Disable/Enable
This commit is contained in:
parent
d193cb749b
commit
5abea19016
|
@ -61,6 +61,10 @@ impl<'a> ConfigManager<'a> {
|
|||
let match_paths = config.match_paths();
|
||||
(config, self.match_store.query(&match_paths))
|
||||
}
|
||||
|
||||
pub fn default(&self) -> &'a dyn Config {
|
||||
self.config_store.default()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test
|
||||
|
|
46
espanso/src/cli/worker/engine/executor/icon.rs
Normal file
46
espanso/src/cli/worker/engine/executor/icon.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use espanso_ui::{UIRemote, icons::TrayIcon};
|
||||
|
||||
use crate::engine::{dispatch::IconHandler, event::ui::IconStatus};
|
||||
|
||||
pub struct IconHandlerAdapter<'a> {
|
||||
remote: &'a dyn UIRemote,
|
||||
}
|
||||
|
||||
impl<'a> IconHandlerAdapter<'a> {
|
||||
pub fn new(remote: &'a dyn UIRemote) -> Self {
|
||||
Self { remote }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IconHandler for IconHandlerAdapter<'a> {
|
||||
fn update_icon(&self, status: &IconStatus) -> anyhow::Result<()> {
|
||||
let icon = match status {
|
||||
IconStatus::Enabled => TrayIcon::Normal,
|
||||
IconStatus::Disabled => TrayIcon::Disabled,
|
||||
IconStatus::SecureInputDisabled => TrayIcon::SystemDisabled,
|
||||
};
|
||||
|
||||
self.remote.update_tray_icon(icon);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -20,4 +20,5 @@
|
|||
pub mod clipboard_injector;
|
||||
pub mod context_menu;
|
||||
pub mod event_injector;
|
||||
pub mod icon;
|
||||
pub mod key_injector;
|
|
@ -34,6 +34,7 @@ pub mod match_cache;
|
|||
pub mod matcher;
|
||||
pub mod multiplex;
|
||||
pub mod path;
|
||||
pub mod process;
|
||||
pub mod render;
|
||||
pub mod source;
|
||||
pub mod ui;
|
||||
|
@ -118,6 +119,8 @@ pub fn initialize_and_spawn(
|
|||
super::engine::render::RendererAdapter::new(&match_cache, &config_manager, &renderer);
|
||||
let path_provider = PathProviderAdapter::new(&paths);
|
||||
|
||||
let disable_options = process::middleware::disable::extract_disable_options(config_manager.default());
|
||||
|
||||
let mut processor = crate::engine::process::default(
|
||||
&matchers,
|
||||
&config_manager,
|
||||
|
@ -128,6 +131,7 @@ pub fn initialize_and_spawn(
|
|||
&modifier_state_store,
|
||||
&sequencer,
|
||||
&path_provider,
|
||||
disable_options,
|
||||
);
|
||||
|
||||
let event_injector =
|
||||
|
@ -140,6 +144,7 @@ pub fn initialize_and_spawn(
|
|||
);
|
||||
let key_injector = super::engine::executor::key_injector::KeyInjectorAdapter::new(&*injector);
|
||||
let context_menu_adapter = super::engine::executor::context_menu::ContextMenuHandlerAdapter::new(&*ui_remote);
|
||||
let icon_adapter = super::engine::executor::icon::IconHandlerAdapter::new(&*ui_remote);
|
||||
let dispatcher = crate::engine::dispatch::default(
|
||||
&event_injector,
|
||||
&clipboard_injector,
|
||||
|
@ -148,6 +153,7 @@ pub fn initialize_and_spawn(
|
|||
&clipboard_injector,
|
||||
&clipboard_injector,
|
||||
&context_menu_adapter,
|
||||
&icon_adapter,
|
||||
);
|
||||
|
||||
let mut engine = crate::engine::Engine::new(&funnel, &mut processor, &dispatcher);
|
||||
|
|
49
espanso/src/cli/worker/engine/process/middleware/disable.rs
Normal file
49
espanso/src/cli/worker/engine/process/middleware/disable.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::engine::{event::input::{Key, Variant}, process::DisableOptions};
|
||||
use espanso_config::config::Config;
|
||||
|
||||
pub fn extract_disable_options(config: &dyn Config) -> DisableOptions {
|
||||
let (toggle_key, variant) = match config.toggle_key() {
|
||||
Some(key) => match key {
|
||||
espanso_config::config::ToggleKey::Ctrl => (Some(Key::Control), None),
|
||||
espanso_config::config::ToggleKey::Meta => (Some(Key::Meta), None),
|
||||
espanso_config::config::ToggleKey::Alt => (Some(Key::Alt), None),
|
||||
espanso_config::config::ToggleKey::Shift => (Some(Key::Shift), None),
|
||||
espanso_config::config::ToggleKey::RightCtrl => (Some(Key::Control), Some(Variant::Right)),
|
||||
espanso_config::config::ToggleKey::RightAlt => (Some(Key::Alt), Some(Variant::Right)),
|
||||
espanso_config::config::ToggleKey::RightShift => (Some(Key::Shift), Some(Variant::Right)),
|
||||
espanso_config::config::ToggleKey::RightMeta => (Some(Key::Meta), Some(Variant::Right)),
|
||||
espanso_config::config::ToggleKey::LeftCtrl => (Some(Key::Control), Some(Variant::Left)),
|
||||
espanso_config::config::ToggleKey::LeftAlt => (Some(Key::Alt), Some(Variant::Left)),
|
||||
espanso_config::config::ToggleKey::LeftShift => (Some(Key::Shift), Some(Variant::Left)),
|
||||
espanso_config::config::ToggleKey::LeftMeta => (Some(Key::Meta), Some(Variant::Left)),
|
||||
},
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
DisableOptions {
|
||||
toggle_key,
|
||||
toggle_key_variant: variant,
|
||||
toggle_key_maximum_window: Duration::from_millis(1000),
|
||||
}
|
||||
}
|
20
espanso/src/cli/worker/engine/process/middleware/mod.rs
Normal file
20
espanso/src/cli/worker/engine/process/middleware/mod.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
pub mod disable;
|
20
espanso/src/cli/worker/engine/process/mod.rs
Normal file
20
espanso/src/cli/worker/engine/process/mod.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
pub mod middleware;
|
|
@ -17,7 +17,7 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::{ContextMenuHandler, Event, ImageInjector};
|
||||
use super::{ContextMenuHandler, Event, IconHandler, ImageInjector};
|
||||
use super::{ModeProvider, Dispatcher, Executor, KeyInjector, TextInjector, HtmlInjector};
|
||||
|
||||
pub struct DefaultDispatcher<'a> {
|
||||
|
@ -33,6 +33,7 @@ impl<'a> DefaultDispatcher<'a> {
|
|||
html_injector: &'a dyn HtmlInjector,
|
||||
image_injector: &'a dyn ImageInjector,
|
||||
context_menu_handler: &'a dyn ContextMenuHandler,
|
||||
icon_handler: &'a dyn IconHandler,
|
||||
) -> Self {
|
||||
Self {
|
||||
executors: vec![
|
||||
|
@ -52,6 +53,9 @@ impl<'a> DefaultDispatcher<'a> {
|
|||
)),
|
||||
Box::new(super::executor::context_menu::ContextMenuExecutor::new(
|
||||
context_menu_handler,
|
||||
)),
|
||||
Box::new(super::executor::icon_update::IconUpdateExecutor::new(
|
||||
icon_handler,
|
||||
))
|
||||
],
|
||||
}
|
||||
|
|
53
espanso/src/engine/dispatch/executor/icon_update.rs
Normal file
53
espanso/src/engine/dispatch/executor/icon_update.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::super::{Event, Executor};
|
||||
use crate::engine::event::{EventType, ui::{IconStatus}};
|
||||
use anyhow::Result;
|
||||
use log::error;
|
||||
|
||||
pub trait IconHandler {
|
||||
fn update_icon(&self, status: &IconStatus) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct IconUpdateExecutor<'a> {
|
||||
handler: &'a dyn IconHandler,
|
||||
}
|
||||
|
||||
impl<'a> IconUpdateExecutor<'a> {
|
||||
pub fn new(handler: &'a dyn IconHandler) -> Self {
|
||||
Self { handler }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Executor for IconUpdateExecutor<'a> {
|
||||
fn execute(&self, event: &Event) -> bool {
|
||||
if let EventType::IconStatusChange(m_event) = &event.etype {
|
||||
if let Err(error) = self.handler.update_icon(&m_event.status) {
|
||||
error!("icon handler reported an error: {:?}", error);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
pub mod context_menu;
|
||||
pub mod icon_update;
|
||||
pub mod image_inject;
|
||||
pub mod html_inject;
|
||||
pub mod key_inject;
|
||||
|
|
|
@ -37,6 +37,7 @@ pub use executor::html_inject::HtmlInjector;
|
|||
pub use executor::text_inject::{Mode, ModeProvider, TextInjector};
|
||||
pub use executor::image_inject::{ImageInjector};
|
||||
pub use executor::context_menu::{ContextMenuHandler};
|
||||
pub use executor::icon_update::IconHandler;
|
||||
|
||||
// TODO: move into module
|
||||
pub trait KeyInjector {
|
||||
|
@ -51,6 +52,7 @@ pub fn default<'a>(
|
|||
html_injector: &'a dyn HtmlInjector,
|
||||
image_injector: &'a dyn ImageInjector,
|
||||
context_menu_handler: &'a dyn ContextMenuHandler,
|
||||
icon_handler: &'a dyn IconHandler,
|
||||
) -> impl Dispatcher + 'a {
|
||||
default::DefaultDispatcher::new(
|
||||
event_injector,
|
||||
|
@ -60,5 +62,6 @@ pub fn default<'a>(
|
|||
html_injector,
|
||||
image_injector,
|
||||
context_menu_handler,
|
||||
icon_handler,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -70,6 +70,11 @@ pub enum EventType {
|
|||
MatchInjected,
|
||||
DiscardPrevious(internal::DiscardPreviousEvent),
|
||||
|
||||
Disabled,
|
||||
Enabled,
|
||||
SecureInputEnabled,
|
||||
SecureInputDisabled,
|
||||
|
||||
// Effects
|
||||
TriggerCompensation(effect::TriggerCompensationEvent),
|
||||
CursorHintCompensation(effect::CursorHintCompensationEvent),
|
||||
|
@ -82,6 +87,7 @@ pub enum EventType {
|
|||
|
||||
// UI
|
||||
ShowContextMenu(ui::ShowContextMenuEvent),
|
||||
IconStatusChange(ui::IconStatusChangeEvent),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -40,3 +40,15 @@ pub struct SubMenuItem {
|
|||
pub label: String,
|
||||
pub items: Vec<MenuItem>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct IconStatusChangeEvent {
|
||||
pub status: IconStatus
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum IconStatus {
|
||||
Enabled,
|
||||
Disabled,
|
||||
SecureInputDisabled,
|
||||
}
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
use log::trace;
|
||||
|
||||
use super::{MatchFilter, MatchInfoProvider, MatchSelector, Matcher, Middleware, Multiplexer, PathProvider, Processor, Renderer, middleware::{
|
||||
use super::{DisableOptions, MatchFilter, MatchInfoProvider, MatchSelector, Matcher, Middleware, Multiplexer, PathProvider, Processor, Renderer, middleware::{
|
||||
match_select::MatchSelectMiddleware, matcher::MatcherMiddleware, multiplex::MultiplexMiddleware,
|
||||
render::RenderMiddleware, action::{ActionMiddleware, EventSequenceProvider}, cursor_hint::CursorHintMiddleware, cause::CauseCompensateMiddleware,
|
||||
delay_modifiers::{DelayForModifierReleaseMiddleware, ModifierStatusProvider}, markdown::MarkdownMiddleware,
|
||||
past_discard::PastEventsDiscardMiddleware,
|
||||
}};
|
||||
use crate::engine::{event::{Event, EventType}, process::middleware::{context_menu::ContextMenuMiddleware, exit::ExitMiddleware, image_resolve::ImageResolverMiddleware}};
|
||||
use crate::engine::{event::{Event, EventType}, process::middleware::{context_menu::ContextMenuMiddleware, disable::DisableMiddleware, exit::ExitMiddleware, icon_status::IconStatusMiddleware, image_resolve::ImageResolverMiddleware}};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct DefaultProcessor<'a> {
|
||||
|
@ -44,11 +44,14 @@ impl<'a> DefaultProcessor<'a> {
|
|||
modifier_status_provider: &'a dyn ModifierStatusProvider,
|
||||
event_sequence_provider: &'a dyn EventSequenceProvider,
|
||||
path_provider: &'a dyn PathProvider,
|
||||
disable_options: DisableOptions,
|
||||
) -> DefaultProcessor<'a> {
|
||||
Self {
|
||||
event_queue: VecDeque::new(),
|
||||
middleware: vec![
|
||||
Box::new(PastEventsDiscardMiddleware::new()),
|
||||
Box::new(DisableMiddleware::new(disable_options)),
|
||||
Box::new(IconStatusMiddleware::new()),
|
||||
Box::new(MatcherMiddleware::new(matchers)),
|
||||
Box::new(ContextMenuMiddleware::new()),
|
||||
Box::new(MatchSelectMiddleware::new(match_filter, match_selector)),
|
||||
|
|
125
espanso/src/engine/process/middleware/disable.rs
Normal file
125
espanso/src/engine/process/middleware/disable.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use log::{info};
|
||||
|
||||
use super::super::Middleware;
|
||||
use crate::engine::{event::{Event, EventType, input::{Key, KeyboardEvent, Status, Variant}}};
|
||||
|
||||
pub struct DisableOptions {
|
||||
pub toggle_key: Option<Key>,
|
||||
pub toggle_key_variant: Option<Variant>,
|
||||
pub toggle_key_maximum_window: Duration,
|
||||
|
||||
// TODO: toggle shortcut?
|
||||
}
|
||||
|
||||
pub struct DisableMiddleware {
|
||||
enabled: RefCell<bool>,
|
||||
last_toggle_press: RefCell<Option<Instant>>,
|
||||
options: DisableOptions,
|
||||
}
|
||||
|
||||
impl DisableMiddleware {
|
||||
pub fn new(options: DisableOptions) -> Self {
|
||||
Self {
|
||||
enabled: RefCell::new(true),
|
||||
last_toggle_press: RefCell::new(None),
|
||||
options,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Middleware for DisableMiddleware {
|
||||
fn name(&self) -> &'static str {
|
||||
"disable"
|
||||
}
|
||||
|
||||
fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event {
|
||||
let mut has_status_changed = false;
|
||||
let mut enabled = self.enabled.borrow_mut();
|
||||
|
||||
if let EventType::Keyboard(m_event) = &event.etype {
|
||||
if is_toggle_key(m_event, &self.options) {
|
||||
let mut last_toggle_press = self.last_toggle_press.borrow_mut();
|
||||
if let Some(previous_press) = *last_toggle_press {
|
||||
if previous_press.elapsed() < self.options.toggle_key_maximum_window {
|
||||
*enabled = !*enabled;
|
||||
*last_toggle_press = None;
|
||||
has_status_changed = true;
|
||||
} else {
|
||||
*last_toggle_press = Some(Instant::now());
|
||||
}
|
||||
} else {
|
||||
*last_toggle_press = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if has_status_changed {
|
||||
info!("toggled enabled state, is_enabled = {}", *enabled);
|
||||
dispatch(Event::caused_by(
|
||||
event.source_id,
|
||||
if *enabled {
|
||||
EventType::Enabled
|
||||
} else {
|
||||
EventType::Disabled
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
// Block keyboard events when disabled
|
||||
if let EventType::Keyboard(_) = &event.etype {
|
||||
if !*enabled {
|
||||
return Event::caused_by(event.source_id, EventType::NOOP);
|
||||
}
|
||||
}
|
||||
// TODO: also ignore hotkey and mouse events
|
||||
|
||||
event
|
||||
}
|
||||
}
|
||||
|
||||
fn is_toggle_key(event: &KeyboardEvent, options: &DisableOptions) -> bool {
|
||||
if event.status != Status::Released {
|
||||
return false;
|
||||
}
|
||||
|
||||
if options
|
||||
.toggle_key
|
||||
.as_ref()
|
||||
.map(|key| key == &event.key)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
if let (Some(variant), Some(e_variant)) = (&options.toggle_key_variant, &event.variant) {
|
||||
variant == e_variant
|
||||
} else {
|
||||
true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test
|
79
espanso/src/engine/process/middleware/icon_status.rs
Normal file
79
espanso/src/engine/process/middleware/icon_status.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
};
|
||||
|
||||
use super::super::Middleware;
|
||||
use crate::engine::event::{Event, EventType, ui::{IconStatus, IconStatusChangeEvent}};
|
||||
|
||||
pub struct IconStatusMiddleware {
|
||||
enabled: RefCell<bool>,
|
||||
secure_input_enabled: RefCell<bool>,
|
||||
}
|
||||
|
||||
impl IconStatusMiddleware {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
enabled: RefCell::new(true),
|
||||
secure_input_enabled: RefCell::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Middleware for IconStatusMiddleware {
|
||||
fn name(&self) -> &'static str {
|
||||
"icon_status"
|
||||
}
|
||||
|
||||
fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event {
|
||||
let mut enabled = self.enabled.borrow_mut();
|
||||
let mut secure_input_enabled = self.secure_input_enabled.borrow_mut();
|
||||
|
||||
let mut did_update = true;
|
||||
match &event.etype {
|
||||
EventType::Enabled => *enabled = true,
|
||||
EventType::Disabled => *enabled = false,
|
||||
EventType::SecureInputEnabled => *secure_input_enabled = true,
|
||||
EventType::SecureInputDisabled => *secure_input_enabled = false,
|
||||
_ => did_update = false,
|
||||
}
|
||||
|
||||
if did_update {
|
||||
let status = if *enabled {
|
||||
if *secure_input_enabled {
|
||||
IconStatus::SecureInputDisabled
|
||||
} else {
|
||||
IconStatus::Enabled
|
||||
}
|
||||
} else {
|
||||
IconStatus::Disabled
|
||||
};
|
||||
|
||||
dispatch(Event::caused_by(event.source_id, EventType::IconStatusChange(IconStatusChangeEvent {
|
||||
status,
|
||||
})));
|
||||
}
|
||||
|
||||
event
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test
|
|
@ -22,7 +22,9 @@ pub mod cause;
|
|||
pub mod context_menu;
|
||||
pub mod cursor_hint;
|
||||
pub mod delay_modifiers;
|
||||
pub mod disable;
|
||||
pub mod exit;
|
||||
pub mod icon_status;
|
||||
pub mod image_resolve;
|
||||
pub mod match_select;
|
||||
pub mod matcher;
|
||||
|
|
|
@ -95,6 +95,7 @@ pub enum RendererError {
|
|||
pub use middleware::action::{MatchInfoProvider, EventSequenceProvider};
|
||||
pub use middleware::delay_modifiers::ModifierStatusProvider;
|
||||
pub use middleware::image_resolve::PathProvider;
|
||||
pub use middleware::disable::DisableOptions;
|
||||
|
||||
pub fn default<'a, MatcherState>(
|
||||
matchers: &'a [&'a dyn Matcher<'a, MatcherState>],
|
||||
|
@ -106,6 +107,7 @@ pub fn default<'a, MatcherState>(
|
|||
modifier_status_provider: &'a dyn ModifierStatusProvider,
|
||||
event_sequence_provider: &'a dyn EventSequenceProvider,
|
||||
path_provider: &'a dyn PathProvider,
|
||||
disable_options: DisableOptions,
|
||||
) -> impl Processor + 'a {
|
||||
default::DefaultProcessor::new(
|
||||
matchers,
|
||||
|
@ -117,5 +119,6 @@ pub fn default<'a, MatcherState>(
|
|||
modifier_status_provider,
|
||||
event_sequence_provider,
|
||||
path_provider,
|
||||
disable_options,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user