Split into modules/files

timeout_old
Tassilo Horn 4 years ago
parent c060d05a23
commit a4a435de54
  1. 47
      src/con.rs
  2. 175
      src/ipc.rs
  3. 219
      src/lib.rs
  4. 7
      src/main.rs

@ -0,0 +1,47 @@
use crate::ipc;
#[allow(dead_code)]
pub struct Con<'a> {
name: &'a str,
id: ipc::Id,
app_id: Option<&'a str>,
}
impl<'a> std::fmt::Display for Con<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{} — {}", self.app_id.unwrap_or(""), self.name)
}
}
/// Gets all cons (aka, application windows) of the tree.
pub fn get_cons<'a>(tree: &'a ipc::Node) -> Vec<Con<'a>> {
let mut v = vec![];
for n in tree.iter() {
if n.r#type == ipc::NodeType::Con || n.r#type == ipc::NodeType::FloatingCon {
v.push(Con {
name: &n
.name
.as_ref()
.expect(format!("Con without name. id = {}", n.id).as_str()),
id: n.id,
app_id: match &n.app_id {
Some(s) => Some(s.as_ref()),
None => None,
},
})
}
}
v
}
#[test]
fn test_get_cons() {
let tree = ipc::get_tree();
let cons = get_cons(&tree);
println!("There are {} cons.", cons.len());
for c in cons {
println!(" {}", c);
}
}

@ -0,0 +1,175 @@
extern crate serde;
extern crate serde_json;
use serde::Deserialize;
use std::process as proc;
pub type Id = u32;
pub type Dim = u16;
pub type Pid = u16;
#[derive(Deserialize)]
#[allow(dead_code)]
pub struct Rect {
pub x: Dim,
pub y: Dim,
pub width: Dim,
pub height: Dim,
}
// TODO: Maybe there are more?
#[derive(Deserialize)]
pub enum Border {
#[serde(rename = "none")]
None,
#[serde(rename = "pixel")]
Pixel,
#[serde(rename = "csd")]
Csd,
}
// TODO: Maybe there are more?
#[derive(Deserialize)]
pub enum Layout {
#[serde(rename = "splith")]
SplitH,
#[serde(rename = "splitv")]
SplitV,
#[serde(rename = "tabbed")]
Tabbed,
#[serde(rename = "stacked")]
Stacked,
#[serde(rename = "output")]
Output,
#[serde(rename = "none")]
None,
}
#[derive(Deserialize)]
pub enum Orientation {
#[serde(rename = "horizontal")]
Horizontal,
#[serde(rename = "vertical")]
Vertical,
#[serde(rename = "none")]
None,
}
#[derive(Deserialize, PartialEq, Debug)]
pub enum NodeType {
#[serde(rename = "root")]
Root,
#[serde(rename = "workspace")]
Workspace,
#[serde(rename = "output")]
Output,
#[serde(rename = "con")]
Con,
#[serde(rename = "floating_con")]
FloatingCon,
}
#[derive(Deserialize)]
pub enum ShellType {
#[serde(rename = "xdg_shell")]
XdgShell,
#[serde(rename = "xwayland")]
XWayland,
}
#[derive(Deserialize)]
#[allow(dead_code)]
pub struct Node {
pub id: Id,
pub name: Option<String>,
pub rect: Rect,
pub focused: bool,
pub focus: Vec<Id>,
pub border: Border,
pub current_border_width: Dim,
pub layout: Layout,
pub orientation: Orientation,
pub percent: Option<f64>,
pub window_rect: Rect,
pub deco_rect: Rect,
pub geometry: Rect,
pub window: Option<Id>,
pub urgent: bool,
pub marks: Vec<String>,
pub fullscreen_mode: u8, // TODO: actually, it's 0 or 1, i.e., a bool
pub nodes: Vec<Node>,
pub floating_nodes: Vec<Node>,
pub sticky: bool,
pub r#type: NodeType,
pub app_id: Option<String>,
pub visible: Option<bool>,
pub max_render_time: Option<i32>,
pub pid: Option<Pid>,
pub shell: Option<ShellType>,
}
impl Node {
pub fn iter(&self) -> PreOrderNodeIter {
PreOrderNodeIter::new(self)
}
}
pub struct PreOrderNodeIter<'a> {
stack: Vec<&'a Node>,
}
impl<'a> PreOrderNodeIter<'a> {
fn new(node: &'a Node) -> PreOrderNodeIter {
PreOrderNodeIter { stack: vec![node] }
}
}
impl<'a> Iterator for PreOrderNodeIter<'a> {
type Item = &'a Node;
fn next(&mut self) -> Option<Self::Item> {
if let Some(node) = self.stack.pop() {
for n in &node.floating_nodes {
self.stack.push(&n);
}
for n in &node.nodes {
self.stack.push(&n);
}
Some(node)
} else {
None
}
}
}
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);
}
}

@ -1,217 +1,2 @@
extern crate serde; pub mod con;
extern crate serde_json; pub mod ipc;
use serde::Deserialize;
use std::process as proc;
pub type Id = u32;
pub type Dim = u16;
pub type Pid = u16;
#[derive(Deserialize)]
#[allow(dead_code)]
pub struct Rect {
x: Dim,
y: Dim,
width: Dim,
height: Dim,
}
// TODO: Maybe there are more?
#[derive(Deserialize)]
pub enum Border {
#[serde(rename = "none")]
None,
#[serde(rename = "pixel")]
Pixel,
#[serde(rename = "csd")]
Csd,
}
// TODO: Maybe there are more?
#[derive(Deserialize)]
pub enum Layout {
#[serde(rename = "splith")]
SplitH,
#[serde(rename = "splitv")]
SplitV,
#[serde(rename = "tabbed")]
Tabbed,
#[serde(rename = "stacked")]
Stacked,
#[serde(rename = "output")]
Output,
#[serde(rename = "none")]
None,
}
#[derive(Deserialize)]
pub enum Orientation {
#[serde(rename = "horizontal")]
Horizontal,
#[serde(rename = "vertical")]
Vertical,
#[serde(rename = "none")]
None,
}
#[derive(Deserialize, PartialEq)]
pub enum NodeType {
#[serde(rename = "root")]
Root,
#[serde(rename = "workspace")]
Workspace,
#[serde(rename = "output")]
Output,
#[serde(rename = "con")]
Con,
#[serde(rename = "floating_con")]
FloatingCon,
}
#[derive(Deserialize)]
pub enum ShellType {
#[serde(rename = "xdg_shell")]
XdgShell,
#[serde(rename = "xwayland")]
XWayland,
}
#[derive(Deserialize)]
#[allow(dead_code)]
pub struct Node {
id: Id,
name: Option<String>,
rect: Rect,
focused: bool,
focus: Vec<Id>,
border: Border,
current_border_width: Dim,
layout: Layout,
orientation: Orientation,
percent: Option<f64>,
window_rect: Rect,
deco_rect: Rect,
geometry: Rect,
window: Option<Id>,
urgent: bool,
marks: Vec<String>,
fullscreen_mode: u8, // TODO: actually, it's 0 or 1, i.e., a bool
nodes: Vec<Node>,
floating_nodes: Vec<Node>,
sticky: bool,
r#type: NodeType,
app_id: Option<String>,
visible: Option<bool>,
max_render_time: Option<i32>,
pid: Option<Pid>,
shell: Option<ShellType>,
}
impl Node {
fn iter(&self) -> PreOrderNodeIter {
PreOrderNodeIter::new(self)
}
}
struct PreOrderNodeIter<'a> {
stack: Vec<&'a Node>,
}
impl<'a> PreOrderNodeIter<'a> {
fn new(node: &'a Node) -> PreOrderNodeIter {
PreOrderNodeIter { stack: vec![node] }
}
}
impl<'a> Iterator for PreOrderNodeIter<'a> {
type Item = &'a Node;
fn next(&mut self) -> Option<Self::Item> {
if let Some(node) = self.stack.pop() {
for n in &node.nodes {
self.stack.push(&n);
}
for n in &node.floating_nodes {
self.stack.push(&n);
}
Some(node)
} else {
None
}
}
}
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!()
}
}
}
#[allow(dead_code)]
pub struct Con<'a> {
name: &'a str,
id: Id,
app_id: Option<&'a str>,
}
impl<'a> std::fmt::Display for Con<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{} — {}", self.app_id.unwrap_or(""), self.name)
}
}
/// Gets all cons (aka, application windows) of the tree.
pub fn get_cons<'a>(tree: &'a Node) -> Vec<Con<'a>> {
let mut v = vec![];
for n in tree.iter() {
if n.r#type == NodeType::Con || n.r#type == NodeType::FloatingCon {
v.push(Con {
name: &n
.name
.as_ref()
.expect(format!("Con without name. id = {}", n.id).as_str()),
id: n.id,
app_id: match &n.app_id {
Some(s) => Some(s.as_ref()),
None => None,
},
})
}
}
v
}
#[test]
fn test_get_cons() {
let tree = get_tree();
println!("Those IDs are in get_tree():");
for n in tree.iter() {
println!(" id: {}", n.id);
}
let cons = get_cons(&tree);
println!("There are {} cons.", cons.len());
for c in cons {
println!("{}", c);
}
}

@ -1,6 +1,9 @@
use swayr::con;
use swayr::ipc;
fn main() { fn main() {
let root_node = swayr::get_tree(); let root_node = ipc::get_tree();
for con in swayr::get_cons(&root_node) { for con in con::get_cons(&root_node) {
println!("{}", con); println!("{}", con);
} }
println!("Yes!") println!("Yes!")

Loading…
Cancel
Save