Refactor and improve

timeout_old
Tassilo Horn 4 years ago
parent e942037931
commit 12f8da1bb0
  1. 7
      rustfmt.toml
  2. 5
      src/bin/swayrd.rs
  3. 30
      src/client.rs
  4. 7
      src/demon.rs
  5. 21
      src/ipc.rs
  6. 8
      src/util.rs
  7. 54
      src/window.rs

@ -0,0 +1,7 @@
max_width = 80
newline_style = "Unix"
use_try_shorthand = true
use_field_init_shorthand = true
# format_code_in_doc_comments = true
# report_todo = "Always"
# report_fixme = "Always"

@ -13,8 +13,9 @@ fn main() {
Arc::new(RwLock::new(HashMap::new())); Arc::new(RwLock::new(HashMap::new()));
let win_props_for_ev_handler = win_props.clone(); let win_props_for_ev_handler = win_props.clone();
let subscriber_handle = let subscriber_handle = thread::spawn(move || {
thread::spawn(move || demon::monitor_window_events(win_props_for_ev_handler)); demon::monitor_window_events(win_props_for_ev_handler)
});
match demon::serve_client_requests(win_props) { match demon::serve_client_requests(win_props) {
Ok(()) => { Ok(()) => {

@ -1,37 +1,15 @@
use crate::ipc; use crate::ipc;
use crate::util; use crate::util;
use crate::window; use crate::window;
use std::collections::HashMap;
use std::os::unix::net::UnixStream;
fn get_window_props() -> Result<HashMap<ipc::Id, ipc::WindowProps>, serde_json::Error> {
if let Ok(sock) = UnixStream::connect(util::get_swayr_socket_path()) {
serde_json::from_reader(sock)
} else {
panic!("Could not connect to socket!")
}
}
fn get_windows(root_node: &ipc::Node) -> std::vec::Vec<window::Window> {
let win_props = match get_window_props() {
Ok(win_props) => Some(win_props),
Err(e) => {
eprintln!("Got no win_props: {:?}", e);
None
}
};
window::get_windows(&root_node, win_props.unwrap_or(HashMap::new()))
}
pub fn switch_window() { pub fn switch_window() {
let root_node = get_tree(); let root_node = get_tree();
let mut windows = get_windows(&root_node); let mut windows = window::get_windows(&root_node);
windows.sort(); windows.sort();
if let Some(window) = util::select_window("Switch to window", &windows) { if let Some(window) = util::select_window("Switch to window", &windows) {
util::swaymsg(vec![ util::swaymsg(vec![
format!("[con_id={}]", window.node.id).as_str(), format!("[con_id={}]", window.get_id()).as_str(),
"focus", "focus",
]); ]);
} }
@ -39,12 +17,12 @@ pub fn switch_window() {
pub fn quit_window() { pub fn quit_window() {
let root_node = get_tree(); let root_node = get_tree();
let mut windows = get_windows(&root_node); let mut windows = window::get_windows(&root_node);
windows.sort_by(|a, b| a.cmp(b).reverse()); windows.sort_by(|a, b| a.cmp(b).reverse());
if let Some(window) = util::select_window("Quit window", &windows) { if let Some(window) = util::select_window("Quit window", &windows) {
util::swaymsg(vec![ util::swaymsg(vec![
format!("[con_id={}]", window.node.id).as_str(), format!("[con_id={}]", window.get_id()).as_str(),
"kill", "kill",
]); ]);
} }

@ -10,7 +10,9 @@ use std::sync::RwLock;
use std::thread; use std::thread;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
pub fn monitor_window_events(win_props: Arc<RwLock<HashMap<ipc::Id, ipc::WindowProps>>>) { pub fn monitor_window_events(
win_props: Arc<RwLock<HashMap<ipc::Id, ipc::WindowProps>>>,
) {
let child = proc::Command::new("swaymsg") let child = proc::Command::new("swaymsg")
.arg("--monitor") .arg("--monitor")
.arg("--raw") .arg("--raw")
@ -21,7 +23,8 @@ pub fn monitor_window_events(win_props: Arc<RwLock<HashMap<ipc::Id, ipc::WindowP
.spawn() .spawn()
.expect("Failed to subscribe to window events"); .expect("Failed to subscribe to window events");
let stdout: std::process::ChildStdout = child.stdout.unwrap(); let stdout: std::process::ChildStdout = child.stdout.unwrap();
let stream = Deserializer::from_reader(stdout).into_iter::<ipc::WindowEvent>(); let stream =
Deserializer::from_reader(stdout).into_iter::<ipc::WindowEvent>();
for res in stream { for res in stream {
match res { match res {
Ok(win_ev) => handle_window_event(win_ev, win_props.clone()), Ok(win_ev) => handle_window_event(win_ev, win_props.clone()),

@ -126,6 +126,27 @@ impl Node {
pub fn iter(&self) -> NodeIter { pub fn iter(&self) -> NodeIter {
NodeIter::new(self) NodeIter::new(self)
} }
pub fn windows(&self) -> Vec<&Node> {
self.iter()
.filter(|n| {
(n.r#type == NodeType::Con || n.r#type == NodeType::FloatingCon)
&& n.name.is_some()
})
.collect()
}
pub fn workspaces(&self) -> Vec<&Node> {
self.iter()
.filter(|n| n.r#type == NodeType::Workspace)
.collect()
}
pub fn outputs(&self) -> Vec<&Node> {
self.iter()
.filter(|n| n.r#type == NodeType::Output)
.collect()
}
} }
pub struct NodeIter<'a> { pub struct NodeIter<'a> {

@ -1,4 +1,5 @@
use crate::window; use crate::window;
use std::collections::HashMap;
use std::io::Write; use std::io::Write;
use std::process as proc; use std::process as proc;
@ -34,11 +35,14 @@ pub fn select_window<'a>(
wofi_select(prompt, windows) wofi_select(prompt, windows)
} }
pub fn wofi_select<'a, 'b, TS>(prompt: &'a str, choices: &'b Vec<TS>) -> Option<&'b TS> pub fn wofi_select<'a, 'b, TS>(
prompt: &'a str,
choices: &'b Vec<TS>,
) -> Option<&'b TS>
where where
TS: std::fmt::Display + Sized, TS: std::fmt::Display + Sized,
{ {
let mut map: std::collections::HashMap<String, &TS> = std::collections::HashMap::new(); let mut map: HashMap<String, &TS> = HashMap::new();
let mut strs: Vec<String> = vec![]; let mut strs: Vec<String> = vec![];
for c in choices { for c in choices {
let s = format!("{}", c); let s = format!("{}", c);

@ -1,10 +1,14 @@
use crate::ipc; use crate::ipc;
use crate::util;
use std::cmp; use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt;
use std::os::unix::net::UnixStream;
#[derive(Debug)] #[derive(Debug)]
pub struct Window<'a> { pub struct Window<'a> {
pub node: &'a ipc::Node, node: &'a ipc::Node,
workspace: &'a ipc::Node,
win_props: Option<ipc::WindowProps>, win_props: Option<ipc::WindowProps>,
} }
@ -54,8 +58,10 @@ impl Ord for Window<'_> {
} else if !self.node.focused && other.node.focused { } else if !self.node.focused && other.node.focused {
std::cmp::Ordering::Less std::cmp::Ordering::Less
} else { } else {
let lru_a = self.win_props.as_ref().map_or(0, |wp| wp.last_focus_time); let lru_a =
let lru_b = other.win_props.as_ref().map_or(0, |wp| wp.last_focus_time); self.win_props.as_ref().map_or(0, |wp| wp.last_focus_time);
let lru_b =
other.win_props.as_ref().map_or(0, |wp| wp.last_focus_time);
lru_a.cmp(&lru_b).reverse() lru_a.cmp(&lru_b).reverse()
} }
} }
@ -68,37 +74,61 @@ impl PartialOrd for Window<'_> {
} }
impl<'a> std::fmt::Display for Window<'a> { impl<'a> std::fmt::Display for Window<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!( write!(
f, f,
"<span font_weight=\"bold\" {}>{}</span> — {} [{}]", "<span font_weight=\"bold\" {}>{}</span> \
<i>{}</i> \
on workspace <b>{}</b> \
<span alpha=\"20000\">id {}</span>", // Almost hide ID!
if self.node.urgent { if self.node.urgent {
" background=\"darkred\" foreground=\"white\"" " background=\"darkred\" foreground=\"white\""
} else { } else {
"" ""
}, },
self.get_app_name(),
self.get_title(), self.get_title(),
self.get_app_name(),
self.workspace.name.as_ref().unwrap(),
self.get_id() self.get_id()
) )
} }
} }
/// Gets all application windows of the tree. fn build_windows(
pub fn get_windows(
tree: &ipc::Node, tree: &ipc::Node,
mut win_props: HashMap<ipc::Id, ipc::WindowProps>, mut win_props: HashMap<ipc::Id, ipc::WindowProps>,
) -> Vec<Window> { ) -> Vec<Window> {
let mut v = vec![]; let mut v = vec![];
for n in tree.iter() { for workspace in tree.workspaces() {
if n.name.is_some() for n in workspace.windows() {
&& (n.r#type == ipc::NodeType::Con || n.r#type == ipc::NodeType::FloatingCon)
{
v.push(Window { v.push(Window {
node: &n, node: &n,
win_props: win_props.remove(&n.id), win_props: win_props.remove(&n.id),
workspace: &workspace,
}) })
} }
} }
v v
} }
fn get_window_props(
) -> Result<HashMap<ipc::Id, ipc::WindowProps>, serde_json::Error> {
if let Ok(sock) = UnixStream::connect(util::get_swayr_socket_path()) {
serde_json::from_reader(sock)
} else {
panic!("Could not connect to socket!")
}
}
/// Gets all application windows of the tree.
pub fn get_windows(root_node: &ipc::Node) -> Vec<Window> {
let win_props = match get_window_props() {
Ok(win_props) => Some(win_props),
Err(e) => {
eprintln!("Got no win_props: {:?}", e);
None
}
};
build_windows(&root_node, win_props.unwrap_or(HashMap::new()))
}

Loading…
Cancel
Save