From 42907b898273246ca2b1b615da5cfe781121d9d8 Mon Sep 17 00:00:00 2001 From: Armin Friedl Date: Sat, 23 Oct 2021 09:34:02 +0200 Subject: [PATCH] App execution --- Cargo.lock | 24 ++++++++++++---- Cargo.toml | 3 +- src/sources/apps.rs | 68 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db29fcd..df08eab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,7 +110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42dcfbd723aa6eff9f024cfd5ad08b11144d79b2d8d37b4a31a006ceab255c77" dependencies = [ "log", - "nix", + "nix 0.22.0", ] [[package]] @@ -801,6 +801,19 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nix" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + [[package]] name = "nom" version = "6.2.1" @@ -1077,6 +1090,7 @@ dependencies = [ "fuzzy-matcher", "log", "mlua", + "nix 0.23.0", "rayon", "walkdir", "winit", @@ -1141,7 +1155,7 @@ dependencies = [ "lazy_static", "log", "memmap2", - "nix", + "nix 0.22.0", "pkg-config", "wayland-client", "wayland-cursor", @@ -1358,7 +1372,7 @@ dependencies = [ "bitflags", "downcast-rs", "libc", - "nix", + "nix 0.22.0", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -1371,7 +1385,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6377fc0efc620da05cb78c5dc846420940e7b2c471aa2faf59c58e063c2b7" dependencies = [ - "nix", + "nix 0.22.0", "once_cell", "smallvec", "wayland-sys", @@ -1383,7 +1397,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf9197a26e00b5e282b57ea9b620e4305ea5682f55f0b1ad862e388abf2d2bb5" dependencies = [ - "nix", + "nix 0.22.0", "wayland-client", "xcursor", ] diff --git a/Cargo.toml b/Cargo.toml index f59e069..9b80172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,5 @@ fuzzy-matcher = "0.3.7" walkdir = "2.3.2" freedesktop_entry_parser = "1.2.0" -mlua = { version = "0.6", features = ["lua54", "vendored"] } \ No newline at end of file +mlua = { version = "0.6", features = ["lua54", "vendored"] } +nix = "0.23.0" \ No newline at end of file diff --git a/src/sources/apps.rs b/src/sources/apps.rs index 03de961..39c6e76 100644 --- a/src/sources/apps.rs +++ b/src/sources/apps.rs @@ -1,6 +1,9 @@ +use std::{os::unix::prelude::CommandExt, process::{Child, Command, Stdio}}; + use freedesktop_entry_parser as parser; -use log::debug; +use log::{debug, error}; use walkdir::WalkDir; +use nix::unistd::{getpid, setpgid}; use crate::roftl::{Action, Entry, Source}; @@ -10,6 +13,52 @@ struct App { command: String, } +fn with_term<'a>(term_cmd: &'a Option, exec: &'a str,) { + if let Some(term) = term_cmd { + let mut args: Vec<&str> = + term.split(' ').chain(exec.split(' ')).collect(); + let term = args.remove(0).to_owned(); + } else { + let term = std::env::var("TERM").unwrap(); + let mut args: Vec<&str> = exec.split(' ').collect(); + args.insert(0, "-e"); + } +} + +pub fn parse_command_string<'a>(exec: &'a str) -> (String, Vec<&'a str>) { + let mut iter = exec.split(' '); + let cmd = iter.next().expect("Empty Exec").to_owned(); + let args = iter.collect(); + (cmd, args) +} + +pub fn run_bg(mut command: Command) { + command.stdout(Stdio::null()).stderr(Stdio::null()); + unsafe { + command.pre_exec(|| { + let pid = getpid(); + if let Err(e) = setpgid(pid, pid) { + error!{"Failed to set pgid of child process with pid {}", pid}; + } + Ok(()) + }); + } + + debug!{"Running command {:?}", command} + command.spawn().unwrap(); +} + +impl App { + pub fn run(&self, term_cmd: &Option) { + debug!("Exec: `{}`", self.command); + let(cmd, args) = parse_command_string(&self.command); + debug!("Running `{} {}`", cmd, args.join(" ")); + let mut command = Command::new(&cmd); + command.args(&args); + let _ = run_bg(command); + } +} + impl From<&App> for Entry { fn from(app: &App) -> Self { @@ -20,6 +69,8 @@ impl From<&App> for Entry identifier: 0 } } + + } #[derive(Default, Debug)] @@ -40,7 +91,7 @@ impl<'a> AppBuilder<'a> Some ( App { name: self.name.unwrap().into(), - command: self.exec.unwrap().into() + command: strip_entry_args(self.exec.unwrap()).into(), }) } } @@ -56,6 +107,17 @@ impl Apps { } } +fn strip_entry_args(exec: &str) -> String { + debug!{"Stripping {}", exec} + let iter = exec.split(' '); + let result = iter.filter(|item| !item.starts_with('%')) + .collect::>() + .join(" "); + + debug!{"Stripped into {}", result} + result +} + impl Source for Apps { fn name(&self) -> &'static str { "apps" @@ -89,6 +151,7 @@ impl Source for Apps { { "Name" => app_builder.name = attr.value, "Exec" => app_builder.exec = attr.value, + "NoDisplay" => app_builder.hidden = attr.value, "Hidden" => app_builder.hidden = attr.value, _ => () } @@ -116,5 +179,6 @@ impl Source for Apps { debug!{"Apps has entries {:?}", self.entries} let app = self.entries.get(entry.identifier as usize).unwrap(); debug!{"Doing primary action {} for {}", app.name, app.command} + app.run(&Some("/bin/bash".into())); } }