support forking
This commit is contained in:
parent
45a97e86d1
commit
7f96889803
2 changed files with 62 additions and 23 deletions
|
@ -1,11 +1,12 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::{env, fs};
|
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::{env, fs};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||||
|
@ -177,10 +178,11 @@ impl FromStr for KeyDetectionType {
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Parser)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Parser)]
|
||||||
#[clap(about = "Worf is a wofi clone written in rust, it aims to be a drop-in replacement")]
|
#[clap(about = "Worf is a wofi clone written in rust, it aims to be a drop-in replacement")]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
#[allow(clippy::struct_excessive_bools)] // it's fine for config
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Forks the menu so you can close the terminal
|
/// Forks the menu so you can close the terminal
|
||||||
#[clap(short = 'f', long = "fork")]
|
#[clap(long = "fork")]
|
||||||
fork: Option<bool>, // todo support fork
|
fork: bool,
|
||||||
|
|
||||||
/// Selects a config file to use
|
/// Selects a config file to use
|
||||||
#[clap(short = 'c', long = "conf")]
|
#[clap(short = 'c', long = "conf")]
|
||||||
|
@ -225,7 +227,8 @@ pub struct Config {
|
||||||
|
|
||||||
/// Set to 'false' to disable images, defaults to true
|
/// Set to 'false' to disable images, defaults to true
|
||||||
#[clap(short = 'I', long = "allow-images")]
|
#[clap(short = 'I', long = "allow-images")]
|
||||||
allow_images: Option<bool>,
|
#[serde(default = "default_true")]
|
||||||
|
allow_images: bool,
|
||||||
|
|
||||||
/// If `true` pango markup is parsed
|
/// If `true` pango markup is parsed
|
||||||
#[clap(short = 'm', long = "allow-markup")]
|
#[clap(short = 'm', long = "allow-markup")]
|
||||||
|
@ -335,16 +338,16 @@ pub struct Config {
|
||||||
// todo re-add this
|
// todo re-add this
|
||||||
// #[serde(flatten)]
|
// #[serde(flatten)]
|
||||||
// key_custom: Option<HashMap<String, String>>,
|
// key_custom: Option<HashMap<String, String>>,
|
||||||
global_coords: Option<bool>, // todo support this
|
global_coords: bool, // todo support this
|
||||||
|
|
||||||
/// If set to `true` the search field will be hidden.
|
/// If set to `true` the search field willOption<> be hidden.
|
||||||
#[clap(long = "hide-search")]
|
#[clap(long = "hide-search")]
|
||||||
hide_search: Option<bool>,
|
hide_search: bool,
|
||||||
dynamic_lines: Option<bool>, // todo support this
|
dynamic_lines: bool, // todo support this
|
||||||
layer: Option<String>, // todo support this
|
layer: Option<String>, // todo support this
|
||||||
copy_exec: Option<String>, // todo support this
|
copy_exec: Option<String>, // todo support this
|
||||||
single_click: Option<bool>, // todo support this
|
single_click: bool, // todo support this
|
||||||
pre_display_exec: Option<bool>, // todo support this
|
pre_display_exec: bool, // todo support this
|
||||||
|
|
||||||
/// Minimum score for a fuzzy search to be shown
|
/// Minimum score for a fuzzy search to be shown
|
||||||
#[clap(long = "fuzzy-min-score")]
|
#[clap(long = "fuzzy-min-score")]
|
||||||
|
@ -359,13 +362,18 @@ pub struct Config {
|
||||||
|
|
||||||
/// Display only icon in emoji mode
|
/// Display only icon in emoji mode
|
||||||
#[clap(long = "emoji-hide-string")]
|
#[clap(long = "emoji-hide-string")]
|
||||||
emoji_hide_label: Option<bool>,
|
emoji_hide_label: bool,
|
||||||
|
|
||||||
#[clap(long = "keyboard-detection-type")]
|
#[clap(long = "keyboard-detection-type")]
|
||||||
key_detection_type: Option<KeyDetectionType>,
|
key_detection_type: Option<KeyDetectionType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
#[must_use]
|
||||||
|
pub fn fork(&self) -> bool {
|
||||||
|
self.fork
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn image_size(&self) -> u16 {
|
pub fn image_size(&self) -> u16 {
|
||||||
self.image_size.unwrap_or(32)
|
self.image_size.unwrap_or(32)
|
||||||
|
@ -469,7 +477,7 @@ impl Config {
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn allow_images(&self) -> bool {
|
pub fn allow_images(&self) -> bool {
|
||||||
self.allow_images.unwrap_or(true)
|
self.allow_images
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -513,7 +521,7 @@ impl Config {
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn hide_search(&self) -> bool {
|
pub fn hide_search(&self) -> bool {
|
||||||
self.hide_search.unwrap_or(false)
|
self.hide_search
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -543,7 +551,7 @@ impl Config {
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn emoji_hide_label(&self) -> bool {
|
pub fn emoji_hide_label(&self) -> bool {
|
||||||
self.emoji_hide_label.unwrap_or(false)
|
self.emoji_hide_label
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -558,9 +566,9 @@ fn default_false() -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn default_true() -> bool {
|
fn default_true() -> bool {
|
||||||
// true
|
true
|
||||||
// }
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// // TODO
|
// // TODO
|
||||||
|
@ -774,3 +782,32 @@ fn merge_json(a: &mut Value, b: &Value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fork into background if configured
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if preexec and or setsid do not work
|
||||||
|
pub fn fork_if_configured(config: &Config) {
|
||||||
|
let fork_env_var = "WORF_PROCESS_IS_FORKED";
|
||||||
|
if config.fork() && env::var(fork_env_var).is_err() {
|
||||||
|
let mut cmd = Command::new(env::current_exe().expect("Failed to get current executable"));
|
||||||
|
|
||||||
|
for arg in env::args().skip(1) {
|
||||||
|
cmd.arg(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.env(fork_env_var, "1");
|
||||||
|
cmd.stdin(Stdio::null())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
cmd.pre_exec(|| {
|
||||||
|
libc::setsid();
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.spawn().expect("Failed to fork to background");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use worf_lib::config::Mode;
|
use worf_lib::config::{Mode, fork_if_configured};
|
||||||
use worf_lib::{Error, config, modes};
|
use worf_lib::{Error, config, modes};
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
|
@ -13,6 +13,8 @@ fn main() -> anyhow::Result<()> {
|
||||||
let args = config::parse_args();
|
let args = config::parse_args();
|
||||||
let config = config::load_config(Some(&args)).unwrap_or(args);
|
let config = config::load_config(Some(&args)).unwrap_or(args);
|
||||||
|
|
||||||
|
fork_if_configured(&config);
|
||||||
|
|
||||||
if let Some(show) = &config.show() {
|
if let Some(show) = &config.show() {
|
||||||
let result = match show {
|
let result = match show {
|
||||||
Mode::Run => modes::run::show(&config),
|
Mode::Run => modes::run::show(&config),
|
||||||
|
|
Loading…
Add table
Reference in a new issue