Refactor and improve

timeout_old
Tassilo Horn 3 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()));
let win_props_for_ev_handler = win_props.clone();
let subscriber_handle =
thread::spawn(move || demon::monitor_window_events(win_props_for_ev_handler));
let subscriber_handle = thread::spawn(move || {
demon::monitor_window_events(win_props_for_ev_handler)
});
match demon::serve_client_requests(win_props) {
Ok(()) => {

@ -1,37 +1,15 @@
use crate::ipc;
use crate::util;
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() {
let root_node = get_tree();
let mut windows = get_windows(&root_node);
let mut windows = window::get_windows(&root_node);
windows.sort();
if let Some(window) = util::select_window("Switch to window", &windows) {
util::swaymsg(vec![
format!("[con_id={}]", window.node.id).as_str(),
format!("[con_id={}]", window.get_id()).as_str(),
"focus",
]);
}
@ -39,12 +17,12 @@ pub fn switch_window() {
pub fn quit_window() {
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());
if let Some(window) = util::select_window("Quit window", &windows) {
util::swaymsg(vec![
format!("[con_id={}]", window.node.id).as_str(),
format!("[con_id={}]", window.get_id()).as_str(),
"kill",
]);
}

@ -10,7 +10,9 @@ use std::sync::RwLock;
use std::thread;
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")
.arg("--monitor")
.arg("--raw")
@ -21,7 +23,8 @@ pub fn monitor_window_events(win_props: Arc<RwLock<HashMap<ipc::Id, ipc::WindowP
.spawn()
.expect("Failed to subscribe to window events");
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 {
match res {
Ok(win_ev) => handle_window_event(win_ev, win_props.clone()),

@ -126,6 +126,27 @@ impl Node {
pub fn iter(&self) -> NodeIter {
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> {

@ -1,4 +1,5 @@
use crate::window;
use std::collections::HashMap;
use std::io::Write;
use std::process as proc;
@ -34,11 +35,14 @@ pub fn select_window<'a>(
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
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![];
for c in choices {
let s = format!("{}", c);

@ -1,10 +1,14 @@
use crate::ipc;
use crate::util;
use std::cmp;
use std::collections::HashMap;
use std::fmt;
use std::os::unix::net::UnixStream;
#[derive(Debug)]
pub struct Window<'a> {
pub node: &'a ipc::Node,
node: &'a ipc::Node,
workspace: &'a ipc::Node,
win_props: Option<ipc::WindowProps>,
}
@ -54,8 +58,10 @@ impl Ord for Window<'_> {
} else if !self.node.focused && other.node.focused {
std::cmp::Ordering::Less
} else {
let lru_a = 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);
let lru_a =
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()
}
}
@ -68,37 +74,61 @@ impl PartialOrd for Window<'_> {
}
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!(
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 {
" background=\"darkred\" foreground=\"white\""
} else {
""
},
self.get_app_name(),
self.get_title(),
self.get_app_name(),
self.workspace.name.as_ref().unwrap(),
self.get_id()
)
}
}
/// Gets all application windows of the tree.
pub fn get_windows(
fn build_windows(
tree: &ipc::Node,
mut win_props: HashMap<ipc::Id, ipc::WindowProps>,
) -> Vec<Window> {
let mut v = vec![];
for n in tree.iter() {
if n.name.is_some()
&& (n.r#type == ipc::NodeType::Con || n.r#type == ipc::NodeType::FloatingCon)
{
for workspace in tree.workspaces() {
for n in workspace.windows() {
v.push(Window {
node: &n,
win_props: win_props.remove(&n.id),
workspace: &workspace,
})
}
}
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