diff --git a/espanso/src/cli/daemon/mod.rs b/espanso/src/cli/daemon/mod.rs
index 1a7793b..f770583 100644
--- a/espanso/src/cli/daemon/mod.rs
+++ b/espanso/src/cli/daemon/mod.rs
@@ -35,6 +35,7 @@ use crate::{VERSION, exit_code::{
use super::{CliModule, CliModuleArgs};
mod ipc;
+mod ui;
mod watcher;
pub fn new() -> CliModule {
@@ -55,6 +56,8 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
let config_store = args
.config_store
.expect("missing config store in worker main");
+ let preferences = crate::preferences::get_default(&paths.runtime).expect("unable to obtain preferences");
+ let cli_args = args.cli_args.expect("missing cli_args in daemon main");
// Make sure only one instance of the daemon is running
let lock_file = acquire_daemon_lock(&paths.runtime);
@@ -95,6 +98,10 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
.expect("unable to initialize config watcher thread");
}
+ if cli_args.is_present("show-welcome") {
+ ui::show_welcome_screen(&preferences);
+ }
+
loop {
select! {
recv(watcher_signal) -> _ => {
diff --git a/espanso/src/cli/daemon/ui.rs b/espanso/src/cli/daemon/ui.rs
new file mode 100644
index 0000000..9d0ff5a
--- /dev/null
+++ b/espanso/src/cli/daemon/ui.rs
@@ -0,0 +1,36 @@
+/*
+ * 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 crate::preferences::Preferences;
+
+#[cfg(feature = "modulo")]
+pub fn show_welcome_screen(preferences: &impl Preferences) {
+ if preferences.should_display_welcome() {
+ let espanso_exe_path = std::env::current_exe().expect("unable to determine executable path");
+ let mut command = std::process::Command::new(&espanso_exe_path.to_string_lossy().to_string());
+ command.args(&["modulo", "welcome"]);
+
+ command.spawn().expect("unable to show welcome screen");
+ }
+}
+
+#[cfg(not(feature = "modulo"))]
+pub fn show_welcome_screen(_: &impl Preferences) {
+ // NOOP
+}
\ No newline at end of file
diff --git a/espanso/src/cli/modulo/mod.rs b/espanso/src/cli/modulo/mod.rs
index 4b444c7..753b2ba 100644
--- a/espanso/src/cli/modulo/mod.rs
+++ b/espanso/src/cli/modulo/mod.rs
@@ -23,6 +23,8 @@ use super::{CliModule, CliModuleArgs};
mod form;
#[cfg(feature = "modulo")]
mod search;
+#[cfg(feature = "modulo")]
+mod welcome;
pub fn new() -> CliModule {
#[allow(clippy::needless_update)]
@@ -49,6 +51,10 @@ 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);
+ }
+
0
}
diff --git a/espanso/src/cli/modulo/welcome.rs b/espanso/src/cli/modulo/welcome.rs
new file mode 100644
index 0000000..e559ec4
--- /dev/null
+++ b/espanso/src/cli/modulo/welcome.rs
@@ -0,0 +1,48 @@
+/*
+ * 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 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 {
+ let preferences =
+ crate::preferences::get_default(&paths.runtime).expect("unable to initialize preferences");
+
+ let dont_show_again_handler = Box::new(move |dont_show: bool| {
+ preferences.set_should_display_welcome(!dont_show);
+ });
+
+ espanso_modulo::welcome::show(WelcomeOptions{
+ window_icon_path: icon_paths
+ .wizard_icon
+ .as_ref()
+ .map(|path| path.to_string_lossy().to_string()),
+ tray_image_path: icon_paths
+ .tray_explain_image
+ .as_ref()
+ .map(|path| path.to_string_lossy().to_string()),
+ handlers: WelcomeHandlers {
+ dont_show_again_changed: Some(dont_show_again_handler),
+ },
+ });
+
+ 0
+}
diff --git a/espanso/src/icon.rs b/espanso/src/icon.rs
index 8ae39e5..3ba5e9f 100644
--- a/espanso/src/icon.rs
+++ b/espanso/src/icon.rs
@@ -30,6 +30,8 @@ const WINDOWS_NORMAL_DARK_ICO_BINARY: &[u8] = include_bytes!("res/windows/normal
const WINDOWS_DISABLED_DARK_ICO_BINARY: &[u8] = include_bytes!("res/windows/disabled_dark.ico");
#[cfg(target_os = "windows")]
const WINDOWS_LOGO_ICO_BINARY: &[u8] = include_bytes!("res/windows/logo.ico");
+#[cfg(target_os = "windows")]
+const WINDOWS_TRAY_EXPLAIN_IMAGE: &[u8] = include_bytes!("res/windows/tray_explain_image.png");
#[cfg(target_os = "macos")]
@@ -55,6 +57,7 @@ pub struct IconPaths {
pub accessibility_image_1: Option,
pub accessibility_image_2: Option,
+ pub tray_explain_image: Option,
pub logo: Option,
pub logo_no_background: Option,
@@ -70,6 +73,7 @@ pub fn load_icon_paths(runtime_dir: &Path) -> Result {
tray_icon_disabled: Some(extract_icon(WINDOWS_DISABLED_DARK_ICO_BINARY, &runtime_dir.join("disabled.ico"))?),
logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("icon.png"))?),
logo_no_background: Some(extract_icon(LOGO_NO_BACKGROUND_BINARY, &runtime_dir.join("icon_no_background.png"))?),
+ tray_explain_image: Some(extract_icon(WINDOWS_TRAY_EXPLAIN_IMAGE, &runtime_dir.join("tray_explain_image.png"))?),
..Default::default()
})
}
diff --git a/espanso/src/main.rs b/espanso/src/main.rs
index 4269b7e..7f8f1eb 100644
--- a/espanso/src/main.rs
+++ b/espanso/src/main.rs
@@ -163,6 +163,12 @@ fn main() {
.subcommand(
SubCommand::with_name("daemon")
.setting(AppSettings::Hidden)
+ .arg(
+ Arg::with_name("show-welcome")
+ .long("show-welcome")
+ .required(false)
+ .takes_value(false)
+ )
.about("Start the daemon without spawning a new process."),
)
// .subcommand(SubCommand::with_name("register")
@@ -207,6 +213,10 @@ fn main() {
.takes_value(false)
.help("Interpret the input data as JSON"),
),
+ )
+ .subcommand(
+ SubCommand::with_name("welcome")
+ .about("Display the welcome screen")
),
)
// .subcommand(SubCommand::with_name("start")
diff --git a/espanso/src/preferences/default.rs b/espanso/src/preferences/default.rs
index f58da01..03caf6e 100644
--- a/espanso/src/preferences/default.rs
+++ b/espanso/src/preferences/default.rs
@@ -19,13 +19,13 @@
use espanso_kvs::KVS;
use serde::{de::DeserializeOwned, Serialize};
-use std::path::Path;
use anyhow::Result;
use super::Preferences;
const HAS_COMPLETED_WIZARD_KEY: &str = "has_completed_wizard";
+const SHOULD_DISPLAY_WELCOME_KEY: &str = "should_display_welcome";
#[derive(Clone)]
pub struct DefaultPreferences {
@@ -33,7 +33,7 @@ pub struct DefaultPreferences {
}
impl DefaultPreferences {
- pub fn new(runtime_dir: &Path, kvs: KVSType) -> Result {
+ pub fn new(kvs: KVSType) -> Result {
Ok(Self { kvs })
}
@@ -61,4 +61,12 @@ impl Preferences for DefaultPreferences {
fn set_completed_wizard(&self, value: bool) {
self.set(HAS_COMPLETED_WIZARD_KEY, value);
}
+
+ fn should_display_welcome(&self) -> bool {
+ self.get(SHOULD_DISPLAY_WELCOME_KEY).unwrap_or(true)
+ }
+
+ fn set_should_display_welcome(&self, value: bool) {
+ self.set(SHOULD_DISPLAY_WELCOME_KEY, value);
+ }
}
diff --git a/espanso/src/preferences/mod.rs b/espanso/src/preferences/mod.rs
index bc86a1b..ca19f89 100644
--- a/espanso/src/preferences/mod.rs
+++ b/espanso/src/preferences/mod.rs
@@ -25,9 +25,12 @@ mod default;
pub trait Preferences: Send + Sync + Clone {
fn has_completed_wizard(&self) -> bool;
fn set_completed_wizard(&self, value: bool);
+
+ fn should_display_welcome(&self) -> bool;
+ fn set_should_display_welcome(&self, value: bool);
}
pub fn get_default(runtime_dir: &Path) -> Result {
let kvs = espanso_kvs::get_persistent(runtime_dir)?;
- default::DefaultPreferences::new(runtime_dir, kvs)
+ default::DefaultPreferences::new(kvs)
}
\ No newline at end of file
diff --git a/espanso/src/res/windows/tray_explain_image.png b/espanso/src/res/windows/tray_explain_image.png
new file mode 100644
index 0000000..1750b99
Binary files /dev/null and b/espanso/src/res/windows/tray_explain_image.png differ