More, more, more...

timeout_old
Tassilo Horn 4 years ago
parent aa1fadd6fd
commit 7184747a5f
  1. 55
      src/client.rs
  2. 32
      src/ipc.rs
  3. 16
      src/util.rs
  4. 82
      src/window.rs

@ -13,26 +13,10 @@ fn get_window_props() -> Result<HashMap<ipc::Id, ipc::WindowProps>, serde_json::
}
pub fn switch_window() {
let root_node = ipc::get_tree();
let root_node = get_tree();
let mut windows = window::get_windows(&root_node);
if let Ok(win_props) = get_window_props() {
windows.sort_unstable_by(|a, b| {
if a.node.focused {
std::cmp::Ordering::Greater
} else if b.node.focused {
std::cmp::Ordering::Less
} else {
let lru_a = win_props
.get(&a.node.id)
.map(|p| p.last_focus_time)
.unwrap_or(0);
let lru_b = win_props
.get(&b.node.id)
.map(|p| p.last_focus_time)
.unwrap_or(0);
lru_a.cmp(&lru_b).reverse()
}
});
window::sort_windows(&mut windows, win_props);
}
if let Some(window) = util::select_window(&windows) {
@ -42,3 +26,38 @@ pub fn switch_window() {
]);
}
}
pub fn get_tree() -> ipc::Node {
let output = util::swaymsg(vec!["-t", "get_tree"]);
let result = serde_json::from_str(output.as_str());
match result {
Ok(node) => node,
Err(e) => {
eprintln!("Error: {}", e);
panic!()
}
}
}
#[test]
fn test_get_tree() {
let tree = get_tree();
println!("Those IDs are in get_tree():");
for n in tree.iter() {
println!(" id: {}, type: {:?}", n.id, n.r#type);
}
}
#[test]
fn test_get_windows() {
let tree = get_tree();
let cons = window::get_windows(&tree);
println!("There are {} cons.", cons.len());
for c in cons {
println!(" {}", c);
}
}

@ -3,7 +3,6 @@ extern crate serde_json;
extern crate users;
use serde::{Deserialize, Serialize};
use std::process as proc;
pub type Id = u32;
pub type Dim = u16;
@ -154,37 +153,6 @@ impl<'a> Iterator for NodeIter<'a> {
}
}
pub fn get_tree() -> Node {
let output = proc::Command::new("swaymsg")
.arg("-t")
.arg("get_tree")
.output()
.expect("Error running swaymsg!");
let result = serde_json::from_str(
String::from_utf8(output.stdout)
.expect("Wrong string data!")
.as_str(),
);
match result {
Ok(node) => node,
Err(e) => {
eprintln!("Error: {}", e);
panic!()
}
}
}
#[test]
fn test_get_tree() {
let tree = get_tree();
println!("Those IDs are in get_tree():");
for n in tree.iter() {
println!(" id: {}, type: {:?}", n.id, n.r#type);
}
}
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
pub enum WindowEventType {

@ -7,7 +7,18 @@ pub fn is_debug() -> bool {
}
pub fn get_swayr_socket_path() -> String {
format!("/run/user/{}/swayr-sock", users::get_current_uid())
let wayland_display = std::env::var("WAYLAND_DISPLAY");
format!(
"/run/user/{}/swayr-{}.sock",
users::get_current_uid(),
match wayland_display {
Ok(val) => val,
Err(_e) => {
eprintln!("Couldn't get WAYLAND_DISPLAY!");
String::from("unknown")
}
}
)
}
pub fn swaymsg(args: Vec<&str>) -> String {
@ -35,6 +46,9 @@ where
let mut wofi = proc::Command::new("wofi")
.arg("--show=dmenu")
.arg("--allow-markup")
.arg("--allow-images")
.arg("--insensitive")
.arg("--prompt")
.arg(prompt)
.stdin(proc::Stdio::piped())

@ -1,22 +1,44 @@
use crate::ipc;
use std::collections::HashMap;
#[derive(Debug)]
pub struct Window<'a> {
// TODO: Drop all fields except for node!
app_id: Option<&'a str>,
name: &'a str,
id: ipc::Id,
pub node: &'a ipc::Node,
}
impl Window<'_> {
pub fn get_id(&self) -> ipc::Id {
self.node.id
}
pub fn get_app_name(&self) -> &str {
if let Some(app_id) = &self.node.app_id {
app_id
} else if let Some(wp_class) = self
.node
.window_properties
.as_ref()
.and_then(|wp| wp.class.as_ref())
{
wp_class
} else {
"<Unknown>"
}
}
pub fn get_title(&self) -> &str {
self.node.name.as_ref().unwrap()
}
}
impl<'a> std::fmt::Display for Window<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"{} — {} <{}>",
self.app_id.unwrap_or(""),
self.name,
self.id
"<b>{}</b> — {} [{}]",
self.get_app_name(),
self.get_title(),
self.get_id()
)
}
}
@ -28,29 +50,35 @@ pub fn get_windows(tree: &ipc::Node) -> Vec<Window> {
if n.name.is_some()
&& (n.r#type == ipc::NodeType::Con || n.r#type == ipc::NodeType::FloatingCon)
{
v.push(Window {
name: &n.name.as_ref().unwrap(),
id: n.id,
app_id: match &n.app_id {
Some(s) => Some(s.as_ref()),
// TODO: Use n.window_properties.class instead!
None => None,
},
node: &n,
})
v.push(Window { node: &n })
}
}
v
}
#[test]
fn test_get_windows() {
let tree = ipc::get_tree();
let cons = get_windows(&tree);
println!("There are {} cons.", cons.len());
for c in cons {
println!(" {}", c);
/// Sorts windows so that urgent windows come first, the currently focused
/// window comes last, and otherwise windows are sorted in last-recently-used
/// order.
pub fn sort_windows(windows: &mut Vec<Window>, win_props: HashMap<ipc::Id, ipc::WindowProps>) {
windows.sort_unstable_by(|a, b| {
if a.node.urgent && !b.node.urgent {
std::cmp::Ordering::Less
} else if !a.node.urgent && b.node.urgent {
std::cmp::Ordering::Greater
} else if a.node.focused {
std::cmp::Ordering::Greater
} else if b.node.focused {
std::cmp::Ordering::Less
} else {
let lru_a = win_props
.get(&a.node.id)
.map(|p| p.last_focus_time)
.unwrap_or(0);
let lru_b = win_props
.get(&b.node.id)
.map(|p| p.last_focus_time)
.unwrap_or(0);
lru_a.cmp(&lru_b).reverse()
}
});
}

Loading…
Cancel
Save