diff --git a/espanso/src/cli/launcher/daemon.rs b/espanso/src/cli/launcher/daemon.rs index a4fc895..0ea8697 100644 --- a/espanso/src/cli/launcher/daemon.rs +++ b/espanso/src/cli/launcher/daemon.rs @@ -25,10 +25,14 @@ use thiserror::Error; use crate::cli::PathsOverrides; use crate::cli::util::CommandExt; -pub fn launch_daemon(paths_overrides: &PathsOverrides) -> Result<()> { +pub fn launch_daemon(paths_overrides: &PathsOverrides, show_welcome: bool) -> Result<()> { let espanso_exe_path = std::env::current_exe()?; let mut command = Command::new(&espanso_exe_path.to_string_lossy().to_string()); - command.args(&["daemon", "--show-welcome"]); + let mut args = vec!["daemon"]; + if show_welcome { + args.push("--show-welcome"); + } + command.args(&args); command.with_paths_overrides(paths_overrides); let mut child = command.spawn()?; diff --git a/espanso/src/cli/launcher/mod.rs b/espanso/src/cli/launcher/mod.rs index 79182a8..a8234e0 100644 --- a/espanso/src/cli/launcher/mod.rs +++ b/espanso/src/cli/launcher/mod.rs @@ -18,7 +18,7 @@ */ use self::util::MigrationError; -use crate::exit_code::{LAUNCHER_CONFIG_DIR_POPULATION_FAILURE, LAUNCHER_SUCCESS}; +use crate::{exit_code::{LAUNCHER_ALREADY_RUNNING, LAUNCHER_CONFIG_DIR_POPULATION_FAILURE, LAUNCHER_SUCCESS}, lock::acquire_daemon_lock}; use crate::preferences::Preferences; use log::error; @@ -45,10 +45,18 @@ pub fn new() -> CliModule { #[cfg(feature = "modulo")] fn launcher_main(args: CliModuleArgs) -> i32 { use espanso_modulo::wizard::{MigrationResult, WizardHandlers, WizardOptions}; + let paths = args.paths.expect("missing paths in launcher main"); // TODO: should we create a non-gui wizard? We can also use it for the non-modulo versions of espanso - let paths = args.paths.expect("missing paths in launcher main"); + // If espanso is already running, show a warning + let lock_file = acquire_daemon_lock(&paths.runtime); + if lock_file.is_none() { + util::show_already_running_warning().expect("unable to show already running warning"); + return LAUNCHER_ALREADY_RUNNING; + } + drop(lock_file); + let paths_overrides = args .paths_overrides .expect("missing paths overrides in launcher main"); @@ -56,6 +64,7 @@ fn launcher_main(args: CliModuleArgs) -> i32 { let preferences = crate::preferences::get_default(&paths.runtime).expect("unable to initialize preferences"); + let is_first_start = !preferences.has_completed_wizard(); let is_welcome_page_enabled = !preferences.has_completed_wizard(); @@ -175,7 +184,7 @@ fn launcher_main(args: CliModuleArgs) -> i32 { espanso_mac_utils::convert_to_background_app(); } - daemon::launch_daemon(&paths_overrides).expect("failed to launch daemon"); + daemon::launch_daemon(&paths_overrides, is_first_start).expect("failed to launch daemon"); } LAUNCHER_SUCCESS diff --git a/espanso/src/cli/launcher/util.rs b/espanso/src/cli/launcher/util.rs index 020c661..9eb867d 100644 --- a/espanso/src/cli/launcher/util.rs +++ b/espanso/src/cli/launcher/util.rs @@ -96,4 +96,14 @@ pub fn add_espanso_to_path() -> Result<()> { pub enum AddToPathError { #[error("unexpected error, 'espanso env-path register' returned a non-zero exit code.")] NonZeroExitCode, -} \ No newline at end of file +} + +pub fn show_already_running_warning() -> Result<()> { + let espanso_exe_path = std::env::current_exe()?; + let mut command = Command::new(&espanso_exe_path.to_string_lossy().to_string()); + command.args(&["modulo", "welcome", "--already-running"]); + + let mut child = command.spawn()?; + child.wait()?; + Ok(()) +} diff --git a/espanso/src/cli/modulo/mod.rs b/espanso/src/cli/modulo/mod.rs index bcd5918..9ee9fde 100644 --- a/espanso/src/cli/modulo/mod.rs +++ b/espanso/src/cli/modulo/mod.rs @@ -53,8 +53,8 @@ fn modulo_main(args: CliModuleArgs) -> i32 { return search::search_main(matches, &icon_paths); } - if let Some(_) = cli_args.subcommand_matches("welcome") { - return welcome::welcome_main(&paths, &icon_paths); + if let Some(matches) = cli_args.subcommand_matches("welcome") { + return welcome::welcome_main(matches, &paths, &icon_paths); } if let Some(_) = cli_args.subcommand_matches("troubleshoot") { diff --git a/espanso/src/cli/modulo/welcome.rs b/espanso/src/cli/modulo/welcome.rs index e559ec4..1a08c27 100644 --- a/espanso/src/cli/modulo/welcome.rs +++ b/espanso/src/cli/modulo/welcome.rs @@ -17,12 +17,13 @@ * along with espanso. If not, see . */ +use clap::{ArgMatches}; use crate::icon::IconPaths; use crate::preferences::Preferences; use espanso_modulo::welcome::*; use espanso_path::Paths; -pub fn welcome_main(paths: &Paths, icon_paths: &IconPaths) -> i32 { +pub fn welcome_main(matches: &ArgMatches, paths: &Paths, icon_paths: &IconPaths) -> i32 { let preferences = crate::preferences::get_default(&paths.runtime).expect("unable to initialize preferences"); @@ -30,6 +31,8 @@ pub fn welcome_main(paths: &Paths, icon_paths: &IconPaths) -> i32 { preferences.set_should_display_welcome(!dont_show); }); + let is_already_running = matches.is_present("already-running"); + espanso_modulo::welcome::show(WelcomeOptions{ window_icon_path: icon_paths .wizard_icon @@ -39,6 +42,7 @@ pub fn welcome_main(paths: &Paths, icon_paths: &IconPaths) -> i32 { .tray_explain_image .as_ref() .map(|path| path.to_string_lossy().to_string()), + is_already_running, handlers: WelcomeHandlers { dont_show_again_changed: Some(dont_show_again_handler), }, diff --git a/espanso/src/exit_code.rs b/espanso/src/exit_code.rs index f5cbac0..26e5125 100644 --- a/espanso/src/exit_code.rs +++ b/espanso/src/exit_code.rs @@ -43,6 +43,7 @@ pub const ADD_TO_PATH_FAILURE: i32 = 1; pub const LAUNCHER_SUCCESS: i32 = 0; pub const LAUNCHER_CONFIG_DIR_POPULATION_FAILURE: i32 = 1; +pub const LAUNCHER_ALREADY_RUNNING: i32 = 2; pub const SERVICE_SUCCESS: i32 = 0; pub const SERVICE_FAILURE: i32 = 1; diff --git a/espanso/src/main.rs b/espanso/src/main.rs index 0f94232..7ed9ac1 100644 --- a/espanso/src/main.rs +++ b/espanso/src/main.rs @@ -222,7 +222,15 @@ fn main() { ), ) .subcommand(SubCommand::with_name("troubleshoot").about("Display the troubleshooting GUI")) - .subcommand(SubCommand::with_name("welcome").about("Display the welcome screen")), + .subcommand( + SubCommand::with_name("welcome") + .about("Display the welcome screen") + .arg( + Arg::with_name("already-running") + .long("already-running") + .takes_value(false), + ), + ), ) // .subcommand(SubCommand::with_name("start") // .about("Start the daemon spawning a new process in the background."))