consume.rs (1245B)
1 use crate::client::Client; 2 use crate::util::BuildIdHasher; 3 4 use winsys::connection::Pid; 5 use winsys::window::Window; 6 7 use std::collections::HashMap; 8 use std::fs; 9 10 fn get_parent_pid(pid: Pid) -> Option<Pid> { 11 if let Ok(stat) = fs::read_to_string(format!("/proc/{}/stat", pid)) { 12 let stat = stat.split(" ").collect::<Vec<&str>>(); 13 return stat.get(3).and_then(|ppid| ppid.parse::<Pid>().ok()); 14 } 15 16 None 17 } 18 19 pub fn get_spawner_pid( 20 pid: Pid, 21 wm_pid: Pid, 22 pid_map: &HashMap<Pid, Window>, 23 client_map: &HashMap<Window, Client, BuildIdHasher>, 24 ) -> Option<Pid> { 25 let mut ppid = get_parent_pid(pid); 26 27 while ppid.is_some() { 28 let ppid_new = get_parent_pid(ppid.unwrap()); 29 30 let mut is_consumer = false; 31 if let Some(ppid_new) = ppid_new { 32 if let Some(window) = pid_map.get(&ppid_new) { 33 if let Some(client) = client_map.get(&window) { 34 is_consumer = client.is_consuming(); 35 } 36 } 37 }; 38 39 if is_consumer { 40 return ppid_new; 41 } 42 43 if ppid_new == Some(wm_pid) { 44 return if ppid == Some(pid) { None } else { ppid }; 45 } 46 47 ppid = ppid_new; 48 } 49 50 None 51 }