From d7a8db6a07f088ec4f758e11538d8b1e74cba29d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 30 Jan 2024 18:23:57 +0000 Subject: [PATCH] app_list: Use libcosmic desktop helpers --- Cargo.lock | 48 +++--- Cargo.toml | 2 +- cosmic-app-list/Cargo.toml | 3 - cosmic-app-list/src/app.rs | 275 ++++++++++----------------------- cosmic-app-list/src/main.rs | 1 - cosmic-app-list/src/process.rs | 31 ---- 6 files changed, 112 insertions(+), 248 deletions(-) delete mode 100644 cosmic-app-list/src/process.rs diff --git a/Cargo.lock b/Cargo.lock index 32ca2a0d..4ae7c3e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -792,8 +792,6 @@ dependencies = [ "anyhow", "cosmic-client-toolkit", "cosmic-protocols", - "freedesktop-desktop-entry", - "freedesktop-icons", "futures", "futures-util", "i18n-embed 0.13.9", @@ -808,7 +806,6 @@ dependencies = [ "rust-embed 6.8.1", "rust-embed-utils 7.8.1", "serde", - "shlex", "tokio", "tracing", "tracing-log", @@ -1036,7 +1033,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1044,17 +1041,19 @@ dependencies = [ "dirs 5.0.1", "futures-util", "iced_futures", + "known-folders", "notify", "once_cell", "ron", "serde", + "xdg", "zbus", ] [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "quote", "syn 1.0.109", @@ -1164,7 +1163,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "almost", "cosmic-config", @@ -2689,7 +2688,7 @@ dependencies = [ [[package]] name = "iced" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "iced_accessibility", "iced_core", @@ -2704,7 +2703,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "accesskit", "accesskit_unix", @@ -2713,7 +2712,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "bitflags 1.3.2", "iced_accessibility", @@ -2731,7 +2730,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "futures", "iced_core", @@ -2744,7 +2743,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2767,7 +2766,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2780,7 +2779,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "iced_accessibility", "iced_core", @@ -2792,7 +2791,7 @@ dependencies = [ [[package]] name = "iced_sctk" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "enum-repr", "float-cmp", @@ -2816,7 +2815,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "iced_core", "once_cell", @@ -2826,7 +2825,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "bytemuck", "cosmic-text", @@ -2844,7 +2843,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2864,7 +2863,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "iced_renderer", "iced_runtime", @@ -3070,6 +3069,15 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "known-folders" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4397c789f2709d23cfcb703b316e0766a8d4b17db2d47b0ab096ef6047cae1d8" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -3120,7 +3128,7 @@ checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#912e8b0a4478e67ad4b3ce46e327c70dbe9887d8" +source = "git+https://github.com/pop-os/libcosmic#bf0508816b7e7098cfcc6eb16ee288207ef0cc31" dependencies = [ "apply", "ashpd", @@ -3132,6 +3140,7 @@ dependencies = [ "css-color", "derive_setters", "fraction", + "freedesktop-desktop-entry", "freedesktop-icons", "iced", "iced_core", @@ -3147,6 +3156,7 @@ dependencies = [ "palette", "rfd", "ron", + "shlex", "slotmap", "taffy", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 0aae1ab7..fdc64e75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = fa "applet-token", "tokio", "wayland", - "process", + "desktop", "dbus-config" ] } zbus = { version = "3.14", default-features = false, features = ["tokio"] } diff --git a/cosmic-app-list/Cargo.toml b/cosmic-app-list/Cargo.toml index b6f03d59..d51e58b0 100644 --- a/cosmic-app-list/Cargo.toml +++ b/cosmic-app-list/Cargo.toml @@ -18,14 +18,11 @@ tracing-subscriber.workspace = true tracing-log.workspace = true tracing.workspace = true nix = "0.26" -shlex = "1.3.0" anyhow = "1.0" serde = { version = "1.0", features = ["derive"] } log = "0.4" tokio = { version = "1.17.0", features = ["sync", "rt", "rt-multi-thread", "macros", "process"] } itertools = "*" -freedesktop-desktop-entry = "0.5.0" -freedesktop-icons = "0.2.4" i18n-embed = { version = "0.13", features = ["fluent-system", "desktop-requester"] } i18n-embed-fl = "0.6" rust-embed = "6.3" diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index 57b8c176..1620e469 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -12,6 +12,7 @@ use cctk::toplevel_info::ToplevelInfo; use cctk::wayland_client::protocol::wl_data_device_manager::DndAction; use cctk::wayland_client::protocol::wl_seat::WlSeat; use cosmic::cosmic_config::{self, Config, CosmicConfigEntry}; +use cosmic::desktop::{load_applications_for_app_ids, DesktopEntryData}; use cosmic::iced; use cosmic::iced::event::listen_with; use cosmic::iced::wayland::actions::data_device::DataFromMimeType; @@ -24,7 +25,6 @@ use cosmic::iced::widget::vertical_space; use cosmic::iced::widget::{column, dnd_source, mouse_area, row, Column, Row}; use cosmic::iced::Color; use cosmic::iced::{window, Subscription}; -use cosmic::iced_core::window::Icon; use cosmic::iced_runtime::core::alignment::Horizontal; use cosmic::iced_runtime::core::event; use cosmic::iced_sctk::commands::data_device::accept_mime_type; @@ -44,7 +44,6 @@ use cosmic::{ }; use cosmic::{Element, Theme}; use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1; -use freedesktop_desktop_entry::DesktopEntry; use futures::future::pending; use iced::widget::container; use iced::Alignment; @@ -52,9 +51,7 @@ use iced::Background; use iced::Length; use itertools::Itertools; use rand::{thread_rng, Rng}; -use std::borrow::Cow; use std::collections::HashMap; -use std::path::Path; use std::path::PathBuf; use std::str::FromStr; use std::time::Duration; @@ -71,14 +68,14 @@ pub fn run() -> cosmic::iced::Result { struct DockItem { id: u32, toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo)>, - desktop_info: DesktopInfo, + desktop_info: DesktopEntryData, } impl DataFromMimeType for DockItem { fn from_mime_type(&self, mime_type: &str) -> Option> { - if mime_type == MIME_TYPE { + if mime_type == MIME_TYPE && self.desktop_info.path.is_some() { Some( - Url::from_file_path(self.desktop_info.path.clone()) + Url::from_file_path(self.desktop_info.path.as_deref().unwrap()) .ok()? .to_string() .as_bytes() @@ -94,7 +91,7 @@ impl DockItem { fn new( id: u32, toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo)>, - desktop_info: DesktopInfo, + desktop_info: DesktopEntryData, ) -> Self { Self { id, @@ -167,11 +164,11 @@ impl DockItem { dnd_source( mouse_area( icon_button - .on_press( + .on_press_maybe( toplevels .first() .map(|t| Message::Activate(t.0.clone())) - .unwrap_or_else(|| Message::Exec(desktop_info.exec.clone())), + .or_else(|| desktop_info.exec.clone().map(Message::Exec)), ) .width(Length::Shrink) .height(Length::Shrink), @@ -202,7 +199,7 @@ struct DndOffer { #[derive(Clone, Default)] struct CosmicAppList { core: cosmic::app::Core, - popup: Option<(window::Id, DockItem)>, + popup: Option<(window::Id, u32)>, subscription_ctr: u32, item_ctr: u32, active_list: Vec, @@ -246,109 +243,6 @@ enum Message { ConfigUpdated(AppListConfig), } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum IconSource { - Name(String), - Path(PathBuf), -} - -impl IconSource { - fn from_unknown(icon: &str) -> Self { - let icon_path = Path::new(icon); - if icon_path.is_absolute() && icon_path.exists() { - Self::Path(icon_path.into()) - } else { - Self::Name(icon.into()) - } - } - - fn as_cosmic_icon(&self) -> cosmic::widget::icon::Icon { - match self { - Self::Name(name) => cosmic::widget::icon::from_name(name.as_str()) - .size(128) - .fallback(Some(cosmic::widget::icon::IconFallback::Names(vec![ - "application-default".into(), - "application-x-executable".into(), - ]))) - .into(), - Self::Path(path) => cosmic::widget::icon(cosmic::widget::icon::from_path(path.clone())), - } - } -} - -impl Default for IconSource { - fn default() -> Self { - Self::Name("application-default".to_string()) - } -} - -#[derive(Debug, Clone, Default)] -struct DesktopInfo { - id: String, - wm_class: Option, - icon: IconSource, - exec: String, - name: String, - path: PathBuf, -} - -fn desktop_info_for_app_ids(mut app_ids: Vec) -> Vec { - let app_ids_clone = app_ids.clone(); - let mut ret = freedesktop_desktop_entry::Iter::new(freedesktop_desktop_entry::default_paths()) - .filter_map(|path| { - std::fs::read_to_string(&path).ok().and_then(|input| { - DesktopEntry::decode(&path, &input).ok().and_then(|de| { - if let Some(i) = app_ids.iter().position(|s| { - s == de.appid || s.eq(&de.startup_wm_class().unwrap_or_default()) - }) { - // check if absolute path exists and otherwise treat it as a name - let icon = de.icon().unwrap_or(de.appid); - let icon_path = Path::new(icon); - let icon = if icon_path.is_absolute() && icon_path.exists() { - IconSource::Path(icon_path.into()) - } else { - IconSource::Name(icon.into()) - }; - app_ids.remove(i); - - Some(DesktopInfo { - id: de.appid.to_string(), - wm_class: de.startup_wm_class().map(ToString::to_string), - icon, - exec: de.exec().unwrap_or_default().to_string(), - name: de.name(None).unwrap_or_default().to_string(), - path: path.clone(), - }) - } else { - None - } - }) - }) - }) - .collect_vec(); - ret.append( - &mut app_ids - .into_iter() - .map(|id| DesktopInfo { - id, - icon: IconSource::default(), - ..Default::default() - }) - .collect_vec(), - ); - ret.sort_by(|a, b| { - app_ids_clone - .iter() - .position(|id| id == &a.id || Some(id) == a.wm_class.as_ref()) - .cmp( - &app_ids_clone - .iter() - .position(|id| id == &b.id || Some(id) == b.wm_class.as_ref()), - ) - }); - ret -} - fn index_in_list( mut list_len: usize, item_size: f32, @@ -404,15 +298,19 @@ impl cosmic::Application for CosmicAppList { .unwrap_or_default(); let mut self_ = Self { core, - favorite_list: desktop_info_for_app_ids(config.favorites.clone()) - .into_iter() - .enumerate() - .map(|(favorite_ctr, e)| DockItem { - id: favorite_ctr as u32, - toplevels: Default::default(), - desktop_info: e, - }) - .collect(), + favorite_list: load_applications_for_app_ids( + None, + config.favorites.iter().map(|s| &**s), + true, + ) + .into_iter() + .enumerate() + .map(|(favorite_ctr, e)| DockItem { + id: favorite_ctr as u32, + toplevels: Default::default(), + desktop_info: e, + }) + .collect(), config, ..Default::default() }; @@ -450,7 +348,7 @@ impl cosmic::Application for CosmicAppList { }; let new_id = window::Id::unique(); - self.popup = Some((new_id, toplevel_group.clone())); + self.popup = Some((new_id, toplevel_group.id.clone())); let mut popup_settings = self.core.applet.get_popup_settings( window::Id::MAIN, @@ -511,12 +409,12 @@ impl cosmic::Application for CosmicAppList { } } Message::Activate(handle) => { - if let Some(p) = self.popup.take() { - return destroy_popup(p.0); - } if let Some(tx) = self.wayland_sender.as_ref() { let _ = tx.send(WaylandRequest::Toplevel(ToplevelRequest::Activate(handle))); } + if let Some(p) = self.popup.take() { + return destroy_popup(p.0); + } } Message::Quit(id) => { if let Some(toplevel_group) = self @@ -649,18 +547,7 @@ impl cosmic::Application for CosmicAppList { } Message::DndData(file_path) => { if let Some(DndOffer { dock_item, .. }) = self.dnd_offer.as_mut() { - if let Some(di) = std::fs::read_to_string(&file_path).ok().and_then(|input| { - DesktopEntry::decode(&file_path, &input) - .ok() - .map(|de| DesktopInfo { - id: de.id().to_string(), - wm_class: de.startup_wm_class().map(ToString::to_string), - icon: IconSource::from_unknown(de.icon().unwrap_or(de.appid)), - exec: de.exec().unwrap_or_default().to_string(), - name: de.name(None).unwrap_or_default().to_string(), - path: file_path.clone(), - }) - }) { + if let Some(di) = cosmic::desktop::load_desktop_file(None, &file_path) { self.item_ctr += 1; *dock_item = Some(DockItem::new(self.item_ctr, Vec::new(), di)); } @@ -758,17 +645,14 @@ impl cosmic::Application for CosmicAppList { info.app_id = format!("Unknown Application {}", self.item_ctr); } self.item_ctr += 1; - let desktop_info = - desktop_info_for_app_ids(vec![info.app_id.clone()]) - .pop() - .unwrap_or_else(|| DesktopInfo { - id: info.app_id.clone(), - wm_class: None, - icon: IconSource::default(), - exec: String::new(), - name: info.app_id.clone(), - path: PathBuf::new(), - }); + let desktop_info = load_applications_for_app_ids( + None, + std::iter::once(&*info.app_id), + true, + ) + .into_iter() + .next() + .unwrap(); self.active_list.push(DockItem { id: self.item_ctr, toplevels: vec![(handle, info)], @@ -806,23 +690,13 @@ impl cosmic::Application for CosmicAppList { } }, WaylandUpdate::ActivationToken { token, exec } => { - let mut exec = shlex::Shlex::new(&exec); - let mut cmd = match exec.next() { - Some(cmd) if !cmd.contains('=') => std::process::Command::new(cmd), - _ => return Command::none(), - }; - for arg in exec { - // TODO handle "%" args here if necessary? - if !arg.starts_with('%') { - cmd.arg(arg); - } - } + let mut envs = Vec::new(); if let Some(token) = token { - cmd.env("XDG_ACTIVATION_TOKEN", &token); - cmd.env("DESKTOP_STARTUP_ID", &token); + envs.push(("XDG_ACTIVATION_TOKEN", token.clone())); + envs.push(("DESKTOP_STARTUP_ID", token)); } tokio::task::spawn_blocking(|| { - crate::process::spawn(cmd); + cosmic::desktop::spawn_desktop_exec(exec, envs); }); } } @@ -872,25 +746,29 @@ impl cosmic::Application for CosmicAppList { } // pull back configured items into the favorites list - self.favorite_list = desktop_info_for_app_ids(self.config.favorites.clone()) - .into_iter() - .map(|new_dock_item| { - if let Some(p) = self - .active_list - .iter() - .position(|dock_item| dock_item.desktop_info.id == new_dock_item.id) - { - self.active_list.remove(p) - } else { - self.item_ctr += 1; - DockItem { - id: self.item_ctr, - toplevels: Default::default(), - desktop_info: new_dock_item, - } + self.favorite_list = load_applications_for_app_ids( + None, + self.config.favorites.iter().map(|s| &**s), + true, + ) + .into_iter() + .map(|new_dock_item| { + if let Some(p) = self + .active_list + .iter() + .position(|dock_item| dock_item.desktop_info.id == new_dock_item.id) + { + self.active_list.remove(p) + } else { + self.item_ctr += 1; + DockItem { + id: self.item_ctr, + toplevels: Default::default(), + desktop_info: new_dock_item, } - }) - .collect(); + } + }) + .collect(); } Message::CloseRequested(id) => { if Some(id) == self.popup.as_ref().map(|p| p.0) { @@ -1051,15 +929,20 @@ impl cosmic::Application for CosmicAppList { .as_cosmic_icon() .size(self.core.applet.suggested_size().0) .into() - } else if let Some(( - _popup_id, - DockItem { + } else if let Some((_popup_id, id)) = self.popup.as_ref().filter(|p| id == p.0) { + let Some(DockItem { toplevels, desktop_info, .. - }, - )) = self.popup.as_ref().filter(|p| id == p.0) - { + }) = self + .favorite_list + .iter() + .chain(self.active_list.iter()) + .find(|i| i.id == *id) + else { + return iced::widget::text("").into(); + }; + let is_favorite = self.config.favorites.contains(&desktop_info.id) || desktop_info .wm_class @@ -1068,13 +951,20 @@ impl cosmic::Application for CosmicAppList { let mut content = column![ iced::widget::text(&desktop_info.name).horizontal_alignment(Horizontal::Center), - cosmic::widget::button(iced::widget::text(fl!("new-window"))) - .style(Button::Text) - .on_press(Message::Exec(desktop_info.exec.clone())), ] .padding(8) .spacing(4) .align_items(Alignment::Center); + + if let Some(exec) = desktop_info.exec.clone() { + content = content.push( + cosmic::widget::button(iced::widget::text(fl!("new-window"))) + .style(Button::Text) + .on_press(Message::Exec(exec)), + ); + content = content.push(divider::horizontal::default()); + } + if !toplevels.is_empty() { let mut list_col = column![]; for (handle, info) in toplevels { @@ -1089,10 +979,9 @@ impl cosmic::Application for CosmicAppList { .on_press(Message::Activate(handle.clone())), ); } - content = content.push(divider::horizontal::default()); content = content.push(list_col); + content = content.push(divider::horizontal::default()); } - content = content.push(divider::horizontal::default()); content = content.push(if is_favorite { cosmic::widget::button(iced::widget::text(fl!("unfavorite"))) .style(Button::Text) diff --git a/cosmic-app-list/src/main.rs b/cosmic-app-list/src/main.rs index ad175a8e..0d17a245 100644 --- a/cosmic-app-list/src/main.rs +++ b/cosmic-app-list/src/main.rs @@ -2,7 +2,6 @@ mod app; mod config; mod localize; -mod process; mod wayland_handler; mod wayland_subscription; diff --git a/cosmic-app-list/src/process.rs b/cosmic-app-list/src/process.rs deleted file mode 100644 index 1f58531a..00000000 --- a/cosmic-app-list/src/process.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::process::{exit, Command, Stdio}; - -use nix::sys::wait::waitpid; -use nix::unistd::{fork, ForkResult}; - -/// Performs a double fork with setsid to spawn and detach a command. -pub fn spawn(mut command: Command) { - command - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()); - - unsafe { - match fork() { - Ok(ForkResult::Parent { child }) => { - let _res = waitpid(Some(child), None); - } - - Ok(ForkResult::Child) => { - let _res = nix::unistd::setsid(); - let _res = command.spawn(); - - exit(0); - } - - Err(why) => { - println!("failed to fork and spawn command: {}", why.desc()); - } - } - } -}