From 340508ca5799205e6bfc65f2b09825c5a30c816a Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 11 Nov 2022 22:27:05 +0100 Subject: [PATCH] Update application --- Cargo.lock | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/gui.rs | 76 ++++++++++++++++++++++++++++++++-- 3 files changed, 190 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0fdc24..ee0f31a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,6 +291,49 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossfont" version = "0.5.1" @@ -481,6 +524,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + [[package]] name = "emath" version = "0.19.0" @@ -727,6 +776,15 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1036,6 +1094,25 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.5.7" @@ -1210,6 +1287,30 @@ dependencies = [ "cty", ] +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1248,6 +1349,7 @@ dependencies = [ "eframe", "egui", "serde", + "sysinfo", "toml", ] @@ -1411,6 +1513,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sysinfo" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.37" diff --git a/Cargo.toml b/Cargo.toml index f47f5a6..d5b5352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ egui = "0.19.0" eframe = { version = "0.19.0", features = ["persistence"] } serde = { version = "1.0", features = ["derive"] } toml = "0.5.9" +sysinfo = "0.26.7" [profile.dev.package."*"] opt-level = 2 diff --git a/src/gui.rs b/src/gui.rs index 7a1ab1e..19a5674 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,4 +1,5 @@ use serde::{Serialize, Deserialize}; +use sysinfo::{System, SystemExt, ProcessExt, Pid, Process, Uid}; use eframe::App; @@ -6,14 +7,26 @@ use eframe::App; #[serde(default)] pub struct Application { - label: String + label: String, + #[serde(skip)] + info: System, + #[serde(skip)] + current_pid: Option, + #[serde(skip)] + kill_current: bool, + #[serde(skip)] + this_user_id: Option, } impl Default for Application { fn default() -> Self { Self { - label: "Example".to_owned() + label: "Example".to_owned(), + info: System::new(), + current_pid: None, + kill_current: false, + this_user_id: None } } } @@ -30,6 +43,10 @@ impl Application { } } +pub fn get_process_display_name(process: &Process) -> &str { + *process.exe().to_str().unwrap().split("/").collect::>().last().unwrap() +} + impl App for Application { fn save(&mut self, storage: &mut dyn eframe::Storage) { eframe::set_value(storage, eframe::APP_KEY, self); @@ -46,9 +63,60 @@ impl App for Application { }); }); + self.info.refresh_all(); + + if self.this_user_id.is_none() { + let current_process_or_none = self.info.process(sysinfo::get_current_pid().unwrap()); + self.this_user_id = Some(current_process_or_none.unwrap().user_id().unwrap().to_owned()) + } + + if self.current_pid.is_some() { + let process_or_none = self.info.process(Pid::from(self.current_pid.unwrap())); + if process_or_none.is_none() { + self.current_pid = None + } else { + let process = process_or_none.unwrap(); + egui::TopBottomPanel::bottom("process_bottom_panel").show(ctx, |ui| { + ui.horizontal(|ui| { + ui.label(format!("{}: {}", i32::try_from(process.pid()).unwrap_or(-1), process.exe().to_str().unwrap())); + if ui.button("End Process").clicked() { + self.kill_current = true + } + if ui.button("Close").clicked() { + self.kill_current = false; + self.current_pid = None + } + }); + }); + if self.kill_current { + egui::Window::new("Confirm").collapsible(true).show(ctx, |ui| { + ui.label(format!("Are you sure you want to end the process {}?", get_process_display_name(process))); + if ui.button("End Process").clicked() { + process.kill_with(sysinfo::Signal::Term); + self.current_pid = None; + self.kill_current = false + } + if ui.button("Cancel").clicked() { + self.kill_current = false + } + }); + } + } + } + egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("Hello, world!"); - egui::warn_if_debug_build(ui); + ui.heading(format!("Total memory: {} bytes", self.info.total_memory())); + ui.heading(format!("Free memory: {} bytes", self.info.free_memory())); + egui::ScrollArea::vertical().show(ui, |ui| { + let mut values = Vec::from_iter(self.info.processes().values()); + values.sort_by(|a, b| a.user_id().unwrap().cmp(b.user_id().unwrap())); + let processes= values.iter().filter(|proc| proc.exe().exists()).filter(|proc| proc.user_id().unwrap() == self.this_user_id.as_ref().expect("User id should have already been loaded")); + for process in processes { + if ui.selectable_label(false, format!("{}", get_process_display_name(*process))).clicked() { + self.current_pid = Some(process.pid()); + } + } + }); }); } } \ No newline at end of file