feat(core): add support for linux capabilities
This commit is contained in:
parent
c381da94f9
commit
72d7c19e9f
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -132,6 +132,17 @@ dependencies = [
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "caps"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c088f2dddef283f86b023ab1ebe2301c653326834996458b2f48d29b804e9540"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.66"
|
version = "1.0.66"
|
||||||
|
@ -412,11 +423,33 @@ dependencies = [
|
||||||
"syn 1.0.67",
|
"syn 1.0.67",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe"
|
||||||
|
dependencies = [
|
||||||
|
"errno-dragonfly",
|
||||||
|
"libc",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno-dragonfly"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
||||||
|
dependencies = [
|
||||||
|
"gcc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "espanso"
|
name = "espanso"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"caps",
|
||||||
"clap",
|
"clap",
|
||||||
"colored",
|
"colored",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
|
@ -774,6 +807,12 @@ dependencies = [
|
||||||
"new_debug_unreachable",
|
"new_debug_unreachable",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gcc"
|
||||||
|
version = "0.3.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
|
|
|
@ -66,4 +66,7 @@ widestring = "0.4.3"
|
||||||
libc = "0.2.98"
|
libc = "0.2.98"
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
espanso-mac-utils = { path = "../espanso-mac-utils" }
|
espanso-mac-utils = { path = "../espanso-mac-utils" }
|
||||||
|
|
||||||
|
[target.'cfg(target_os="linux")'.dependencies]
|
||||||
|
caps = "0.5.2"
|
32
espanso/src/capabilities/fallback.rs
Normal file
32
espanso/src/capabilities/fallback.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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 anyhow::Result;
|
||||||
|
|
||||||
|
pub fn can_use_capabilities() -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grant_capabilities() -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_capabilities() -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
42
espanso/src/capabilities/linux.rs
Normal file
42
espanso/src/capabilities/linux.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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 anyhow::Result;
|
||||||
|
use caps::{CapSet, Capability};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
pub fn can_use_capabilities() -> bool {
|
||||||
|
match caps::has_cap(None, CapSet::Permitted, Capability::CAP_DAC_OVERRIDE) {
|
||||||
|
Ok(has_cap) => has_cap,
|
||||||
|
Err(err) => {
|
||||||
|
error!("error while checking if capabilities are enabled: {}", err);
|
||||||
|
false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grant_capabilities() -> Result<()> {
|
||||||
|
caps::raise(None, CapSet::Effective, Capability::CAP_DAC_OVERRIDE)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_capabilities() -> Result<()> {
|
||||||
|
caps::clear(None, CapSet::Effective)?;
|
||||||
|
caps::clear(None, CapSet::Permitted)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
29
espanso/src/capabilities/mod.rs
Normal file
29
espanso/src/capabilities/mod.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod linux;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub use linux::*;
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
mod fallback;
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
pub use fallback::*;
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub struct CliModule {
|
||||||
pub requires_config: bool,
|
pub requires_config: bool,
|
||||||
pub subcommand: String,
|
pub subcommand: String,
|
||||||
pub show_in_dock: bool,
|
pub show_in_dock: bool,
|
||||||
|
pub requires_linux_capabilities: bool,
|
||||||
pub entry: fn(CliModuleArgs)->i32,
|
pub entry: fn(CliModuleArgs)->i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ impl Default for CliModule {
|
||||||
requires_config: false,
|
requires_config: false,
|
||||||
subcommand: "".to_string(),
|
subcommand: "".to_string(),
|
||||||
show_in_dock: false,
|
show_in_dock: false,
|
||||||
|
requires_linux_capabilities: false,
|
||||||
entry: |_| {0},
|
entry: |_| {0},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use espanso_detect::event::{InputEvent, KeyboardEvent, Status};
|
use espanso_detect::{SourceCreationOptions, event::{InputEvent, KeyboardEvent, Status}};
|
||||||
use log::{error};
|
use log::{error};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
@ -33,8 +33,7 @@ pub mod secure_input;
|
||||||
pub mod sequencer;
|
pub mod sequencer;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
// TODO: pass options
|
pub fn init_and_spawn(source_options: SourceCreationOptions) -> Result<(DetectSource, ModifierStateStore, Sequencer)> {
|
||||||
pub fn init_and_spawn() -> Result<(DetectSource, ModifierStateStore, Sequencer)> {
|
|
||||||
let (sender, receiver) = crossbeam::channel::unbounded();
|
let (sender, receiver) = crossbeam::channel::unbounded();
|
||||||
let (init_tx, init_rx) = crossbeam::channel::unbounded();
|
let (init_tx, init_rx) = crossbeam::channel::unbounded();
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ pub fn init_and_spawn() -> Result<(DetectSource, ModifierStateStore, Sequencer)>
|
||||||
if let Err(error) = std::thread::Builder::new()
|
if let Err(error) = std::thread::Builder::new()
|
||||||
.name("detect thread".to_string())
|
.name("detect thread".to_string())
|
||||||
.spawn(
|
.spawn(
|
||||||
move || match espanso_detect::get_source(Default::default()) {
|
move || match espanso_detect::get_source(source_options) {
|
||||||
Ok(mut source) => {
|
Ok(mut source) => {
|
||||||
if source.initialize().is_err() {
|
if source.initialize().is_err() {
|
||||||
init_tx
|
init_tx
|
||||||
|
|
|
@ -22,18 +22,39 @@ use std::thread::JoinHandle;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossbeam::channel::Receiver;
|
use crossbeam::channel::Receiver;
|
||||||
use espanso_config::{config::ConfigStore, matches::store::MatchStore};
|
use espanso_config::{config::ConfigStore, matches::store::MatchStore};
|
||||||
|
use espanso_detect::SourceCreationOptions;
|
||||||
|
use espanso_inject::InjectorCreationOptions;
|
||||||
use espanso_path::Paths;
|
use espanso_path::Paths;
|
||||||
use espanso_ui::{event::UIEvent, UIRemote};
|
use espanso_ui::{event::UIEvent, UIRemote};
|
||||||
use log::info;
|
use log::{debug, error, info, warn};
|
||||||
|
|
||||||
use crate::{cli::worker::{engine::{dispatch::executor::{
|
use crate::{
|
||||||
|
cli::worker::{
|
||||||
|
engine::{
|
||||||
|
dispatch::executor::{
|
||||||
clipboard_injector::ClipboardInjectorAdapter, context_menu::ContextMenuHandlerAdapter,
|
clipboard_injector::ClipboardInjectorAdapter, context_menu::ContextMenuHandlerAdapter,
|
||||||
event_injector::EventInjectorAdapter, icon::IconHandlerAdapter,
|
event_injector::EventInjectorAdapter, icon::IconHandlerAdapter,
|
||||||
key_injector::KeyInjectorAdapter,
|
key_injector::KeyInjectorAdapter,
|
||||||
}, process::middleware::{image_resolve::PathProviderAdapter, match_select::MatchSelectorAdapter, matcher::{convert::MatchConverter, regex::{RegexMatcherAdapter, RegexMatcherAdapterOptions}, rolling::{RollingMatcherAdapter, RollingMatcherAdapterOptions}}, multiplex::MultiplexAdapter, render::{
|
},
|
||||||
|
process::middleware::{
|
||||||
|
image_resolve::PathProviderAdapter,
|
||||||
|
match_select::MatchSelectorAdapter,
|
||||||
|
matcher::{
|
||||||
|
convert::MatchConverter,
|
||||||
|
regex::{RegexMatcherAdapter, RegexMatcherAdapterOptions},
|
||||||
|
rolling::{RollingMatcherAdapter, RollingMatcherAdapterOptions},
|
||||||
|
},
|
||||||
|
multiplex::MultiplexAdapter,
|
||||||
|
render::{
|
||||||
extension::{clipboard::ClipboardAdapter, form::FormProviderAdapter},
|
extension::{clipboard::ClipboardAdapter, form::FormProviderAdapter},
|
||||||
RendererAdapter,
|
RendererAdapter,
|
||||||
}}}, match_cache::MatchCache}, engine::event::ExitMode};
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
match_cache::MatchCache,
|
||||||
|
},
|
||||||
|
engine::event::ExitMode,
|
||||||
|
};
|
||||||
|
|
||||||
use super::secure_input::SecureInputEvent;
|
use super::secure_input::SecureInputEvent;
|
||||||
|
|
||||||
|
@ -41,6 +62,7 @@ pub mod dispatch;
|
||||||
pub mod funnel;
|
pub mod funnel;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn initialize_and_spawn(
|
pub fn initialize_and_spawn(
|
||||||
paths: Paths,
|
paths: Paths,
|
||||||
config_store: Box<dyn ConfigStore>,
|
config_store: Box<dyn ConfigStore>,
|
||||||
|
@ -49,6 +71,7 @@ pub fn initialize_and_spawn(
|
||||||
exit_signal: Receiver<ExitMode>,
|
exit_signal: Receiver<ExitMode>,
|
||||||
ui_event_receiver: Receiver<UIEvent>,
|
ui_event_receiver: Receiver<UIEvent>,
|
||||||
secure_input_receiver: Receiver<SecureInputEvent>,
|
secure_input_receiver: Receiver<SecureInputEvent>,
|
||||||
|
use_evdev_backend: bool,
|
||||||
) -> Result<JoinHandle<ExitMode>> {
|
) -> Result<JoinHandle<ExitMode>> {
|
||||||
let handle = std::thread::Builder::new()
|
let handle = std::thread::Builder::new()
|
||||||
.name("engine thread".to_string())
|
.name("engine thread".to_string())
|
||||||
|
@ -66,18 +89,35 @@ pub fn initialize_and_spawn(
|
||||||
let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager);
|
let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager);
|
||||||
let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager);
|
let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager);
|
||||||
|
|
||||||
|
let has_granted_capabilities = grant_linux_capabilities(use_evdev_backend);
|
||||||
|
|
||||||
|
// TODO: pass all the options
|
||||||
let (detect_source, modifier_state_store, sequencer) =
|
let (detect_source, modifier_state_store, sequencer) =
|
||||||
super::engine::funnel::init_and_spawn().expect("failed to initialize detector module");
|
super::engine::funnel::init_and_spawn(SourceCreationOptions {
|
||||||
|
use_evdev: use_evdev_backend,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.expect("failed to initialize detector module");
|
||||||
let exit_source = super::engine::funnel::exit::ExitSource::new(exit_signal, &sequencer);
|
let exit_source = super::engine::funnel::exit::ExitSource::new(exit_signal, &sequencer);
|
||||||
let ui_source = super::engine::funnel::ui::UISource::new(ui_event_receiver, &sequencer);
|
let ui_source = super::engine::funnel::ui::UISource::new(ui_event_receiver, &sequencer);
|
||||||
let secure_input_source = super::engine::funnel::secure_input::SecureInputSource::new(secure_input_receiver, &sequencer);
|
let secure_input_source = super::engine::funnel::secure_input::SecureInputSource::new(
|
||||||
let sources: Vec<&dyn crate::engine::funnel::Source> =
|
secure_input_receiver,
|
||||||
vec![&detect_source, &exit_source, &ui_source, &secure_input_source];
|
&sequencer,
|
||||||
|
);
|
||||||
|
let sources: Vec<&dyn crate::engine::funnel::Source> = vec![
|
||||||
|
&detect_source,
|
||||||
|
&exit_source,
|
||||||
|
&ui_source,
|
||||||
|
&secure_input_source,
|
||||||
|
];
|
||||||
let funnel = crate::engine::funnel::default(&sources);
|
let funnel = crate::engine::funnel::default(&sources);
|
||||||
|
|
||||||
let rolling_matcher = RollingMatcherAdapter::new(&match_converter.get_rolling_matches(), RollingMatcherAdapterOptions {
|
let rolling_matcher = RollingMatcherAdapter::new(
|
||||||
char_word_separators: config_manager.default().word_separators(),
|
&match_converter.get_rolling_matches(),
|
||||||
});
|
RollingMatcherAdapterOptions {
|
||||||
|
char_word_separators: config_manager.default().word_separators(),
|
||||||
|
},
|
||||||
|
);
|
||||||
let regex_matcher = RegexMatcherAdapter::new(
|
let regex_matcher = RegexMatcherAdapter::new(
|
||||||
&match_converter.get_regex_matches(),
|
&match_converter.get_regex_matches(),
|
||||||
&RegexMatcherAdapterOptions {
|
&RegexMatcherAdapterOptions {
|
||||||
|
@ -92,8 +132,11 @@ pub fn initialize_and_spawn(
|
||||||
let selector = MatchSelectorAdapter::new(&modulo_search_ui, &match_cache);
|
let selector = MatchSelectorAdapter::new(&modulo_search_ui, &match_cache);
|
||||||
let multiplexer = MultiplexAdapter::new(&match_cache);
|
let multiplexer = MultiplexAdapter::new(&match_cache);
|
||||||
|
|
||||||
let injector = espanso_inject::get_injector(Default::default())
|
let injector = espanso_inject::get_injector(InjectorCreationOptions {
|
||||||
.expect("failed to initialize injector module"); // TODO: handle the options
|
use_evdev: use_evdev_backend,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.expect("failed to initialize injector module"); // TODO: handle the options
|
||||||
let clipboard = espanso_clipboard::get_clipboard(Default::default())
|
let clipboard = espanso_clipboard::get_clipboard(Default::default())
|
||||||
.expect("failed to initialize clipboard module"); // TODO: handle options
|
.expect("failed to initialize clipboard module"); // TODO: handle options
|
||||||
|
|
||||||
|
@ -161,6 +204,13 @@ pub fn initialize_and_spawn(
|
||||||
&icon_adapter,
|
&icon_adapter,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Disable previously granted linux capabilities if not needed anymore
|
||||||
|
if has_granted_capabilities {
|
||||||
|
if let Err(err) = crate::capabilities::clear_capabilities() {
|
||||||
|
error!("unable to revoke linux capabilities: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut engine = crate::engine::Engine::new(&funnel, &mut processor, &dispatcher);
|
let mut engine = crate::engine::Engine::new(&funnel, &mut processor, &dispatcher);
|
||||||
let exit_mode = engine.run();
|
let exit_mode = engine.run();
|
||||||
|
|
||||||
|
@ -172,3 +222,30 @@ pub fn initialize_and_spawn(
|
||||||
|
|
||||||
Ok(handle)
|
Ok(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn grant_linux_capabilities(use_evdev_backend: bool) -> bool {
|
||||||
|
if use_evdev_backend {
|
||||||
|
if crate::capabilities::can_use_capabilities() {
|
||||||
|
debug!("using linux capabilities to grant permissions needed by EVDEV backend");
|
||||||
|
if let Err(err) = crate::capabilities::grant_capabilities() {
|
||||||
|
error!("unable to grant CAP_DAC_OVERRIDE capability: {}", err);
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
debug!("successfully granted permissions using capabilities");
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!("EVDEV backend is being used, but without enabling linux capabilities.");
|
||||||
|
warn!(" Although you CAN run espanso EVDEV backend as root, it's not recommended due");
|
||||||
|
warn!(
|
||||||
|
" to security reasons. Espanso supports linux capabilities to limit the attack surface"
|
||||||
|
);
|
||||||
|
warn!(" area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with");
|
||||||
|
warn!(" /dev/input/* devices to detect and inject text) and disabling it as soon as the");
|
||||||
|
warn!(" initial setup is completed.");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn new() -> CliModule {
|
||||||
CliModule {
|
CliModule {
|
||||||
requires_paths: true,
|
requires_paths: true,
|
||||||
requires_config: true,
|
requires_config: true,
|
||||||
|
requires_linux_capabilities: true,
|
||||||
enable_logs: true,
|
enable_logs: true,
|
||||||
log_mode: super::LogMode::AppendOnly,
|
log_mode: super::LogMode::AppendOnly,
|
||||||
subcommand: "worker".to_string(),
|
subcommand: "worker".to_string(),
|
||||||
|
@ -81,6 +82,12 @@ fn worker_main(args: CliModuleArgs) -> i32 {
|
||||||
|
|
||||||
// TODO: show config loading errors in a GUI, if any
|
// TODO: show config loading errors in a GUI, if any
|
||||||
|
|
||||||
|
let use_evdev_backend = if cfg!(feature = "wayland") {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
std::env::var("USE_EVDEV").unwrap_or_else(|_| "false".to_string()) == "true"
|
||||||
|
};
|
||||||
|
|
||||||
let icon_paths =
|
let icon_paths =
|
||||||
crate::icon::load_icon_paths(&paths.runtime).expect("unable to initialize icons");
|
crate::icon::load_icon_paths(&paths.runtime).expect("unable to initialize icons");
|
||||||
|
|
||||||
|
@ -112,6 +119,7 @@ fn worker_main(args: CliModuleArgs) -> i32 {
|
||||||
engine_exit_receiver,
|
engine_exit_receiver,
|
||||||
engine_ui_event_receiver,
|
engine_ui_event_receiver,
|
||||||
engine_secure_input_receiver,
|
engine_secure_input_receiver,
|
||||||
|
use_evdev_backend,
|
||||||
)
|
)
|
||||||
.expect("unable to initialize engine");
|
.expect("unable to initialize engine");
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ use simplelog::{
|
||||||
|
|
||||||
use crate::cli::{LogMode, PathsOverrides};
|
use crate::cli::{LogMode, PathsOverrides};
|
||||||
|
|
||||||
|
mod capabilities;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod config;
|
mod config;
|
||||||
mod engine;
|
mod engine;
|
||||||
|
@ -401,6 +402,13 @@ fn main() {
|
||||||
log_panics::init();
|
log_panics::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the process doesn't require linux capabilities, disable them
|
||||||
|
if !handler.requires_linux_capabilities {
|
||||||
|
if let Err(err) = crate::capabilities::clear_capabilities() {
|
||||||
|
error!("unable to clear linux capabilities: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If explicitly requested, we show the Dock icon on macOS
|
// If explicitly requested, we show the Dock icon on macOS
|
||||||
// We need to enable this selectively, otherwise we would end up with multiple
|
// We need to enable this selectively, otherwise we would end up with multiple
|
||||||
// dock icons due to the multi-process nature of espanso.
|
// dock icons due to the multi-process nature of espanso.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user