Created
August 20, 2022 15:08
-
-
Save diocletiann/af57c17f8c657fde086bf20aac6141df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use compact_str::{CompactString, ToCompactString}; | |
use tokio::task::JoinHandle; | |
use crate::yabai::{ | |
send, send_async, CmdError, Display, Space, Window, STACKED_BORDER, UNFOCUSED_BORDER, UNSTACKED_BORDER, | |
}; | |
#[derive(Default)] | |
pub struct Mover { | |
input_dir: CompactString, | |
// playing with crates | |
sw_id: u32, | |
sw_id_str: CompactString, | |
tw_id: u32, | |
uw_id: u32, | |
td_id: u8, | |
sw_is_stacked: bool, | |
sw_full_height: bool, | |
// tw_full_height: bool, | |
sw_is_top_row: bool, | |
similar_h: bool, | |
similar_w: bool, | |
} | |
// enum Direction { | |
// North(&'static str), | |
// South(&'static str), | |
// East(&'static str), | |
// West(&'static str), | |
// } | |
impl Mover { | |
pub fn move_setup(input_dir: &str, sw: &Window, tw: &Window, sd: &Display, td: &Display) -> Self { | |
// let m = Self { | |
Self { | |
input_dir: input_dir.to_compact_string(), | |
sw_id: sw.id, | |
sw_id_str: sw.id.to_compact_string(), | |
tw_id: tw.id, | |
uw_id: sw.id_below, | |
td_id: td.id, | |
sw_is_stacked: sw.stack_index > 0, | |
sw_full_height: (sd.frame.h - sw.frame.h) < 40_f32, | |
// tw_full_height: (td.frame.h - tw.frame.h) < 40_f32, | |
sw_is_top_row: (sw.frame.y - sd.frame.y) < 40_f32, | |
similar_h: (sw.frame.h - tw.frame.h).abs() < 20_f32, // TODO: find way to query notch height | |
similar_w: (sw.frame.w - tw.frame.w).abs() < 20_f32, | |
} | |
// m.move_window().await?; | |
// Ok(()) | |
} | |
pub async fn move_window(&self) -> anyhow::Result<()> { | |
if !self.sw_is_stacked && self.sw_full_height && self.tw_id == 0 && self.td_id == 0 { | |
if self.input_dir == "east" || self.input_dir == "west" { | |
return Ok(()); | |
} else if self.input_dir == "north" || self.input_dir == "south" { | |
self.rotate().await?; | |
return Ok(()); | |
} | |
} | |
if !self.sw_is_stacked && self.sw_full_height && self.tw_id == 0 && self.td_id > 0 { | |
self.move_to_display().await?; | |
return Ok(()); | |
} | |
if self.sw_is_stacked && self.tw_id == 0 { | |
self.unstack().await?; | |
return Ok(()); | |
} | |
if self.similar_h && self.similar_w { | |
self.stack().await?; | |
return Ok(()); | |
} | |
if self.sw_is_top_row { | |
if self.tw_id == 0 && self.td_id == 0 && (self.input_dir == "north" || self.input_dir == "south") { | |
return Ok(()); | |
} else if self.tw_id == 0 { | |
self.insert_warp("south", &self.input_dir).await?; | |
return Ok(()); | |
} | |
self.insert_warp(&self.input_dir, "north").await?; | |
return Ok(()); | |
} | |
if self.tw_id == 0 && self.td_id == 0 && (self.input_dir == "north" || self.input_dir == "south") { | |
return Ok(()); | |
} | |
if self.tw_id == 0 { | |
self.insert_warp("north", &self.input_dir).await?; | |
return Ok(()); | |
} | |
self.insert_warp(&self.input_dir, "south").await?; | |
Ok(()) | |
} | |
async fn rotate(&self) -> anyhow::Result<()> { | |
let s = Space::get_source().await?; | |
if self.sw_id == s.first_window { | |
self.insert_warp("east", &self.input_dir).await?; | |
} else if self.sw_id == s.last_window { | |
self.insert_warp("west", &self.input_dir).await?; | |
} | |
Ok(()) | |
} | |
async fn stack(&self) -> anyhow::Result<()> { | |
let h1 = send_async(&["window", &self.input_dir, "--stack", &self.sw_id_str]).await?; | |
let h2 = send_async(&["window", "--focus", "stack.prev"]).await?; | |
let h3 = send_async(&["window", "--focus", "stack.next"]).await?; | |
let h4 = send_async(&[STACKED_BORDER]).await?; | |
h1.await.unwrap()?; | |
h2.await.unwrap()?; | |
h3.await.unwrap()?; | |
h4.await.unwrap()?; | |
Ok(()) | |
} | |
async fn unstack(&self) -> anyhow::Result<()> { | |
let h1 = send_async(&["window", &self.sw_id_str, "--toggle", "float"]).await?; | |
let h2 = send_async(&["window", &self.uw_id.to_compact_string(), "--insert", &self.input_dir]).await?; | |
let h3 = send_async(&["window", &self.sw_id_str, "--toggle", "float"]).await?; | |
let h4 = send_async(&[UNSTACKED_BORDER]).await?; | |
h1.await.unwrap()?; | |
h2.await.unwrap()?; | |
h3.await.unwrap()?; | |
h4.await.unwrap()?; | |
Ok(()) | |
} | |
async fn insert_warp(&self, target: &str, side: &str) -> anyhow::Result<()> { | |
let h = send_async(&["window", target, "--insert", side]).await?; | |
send(&["window", "--warp", target]).await?; | |
h.await.unwrap()?; | |
Ok(()) | |
} | |
async fn move_to_display(&self) -> anyhow::Result<()> { | |
let spaces = Space::get_target_all(&self.input_dir).await?; | |
let mut h1: Option<JoinHandle<Result<(), CmdError>>> = None; | |
let mut h2: Option<JoinHandle<Result<(), CmdError>>> = None; | |
for s in spaces { | |
if s.is_visible { | |
send(&[UNFOCUSED_BORDER]).await?; | |
if s.first_window == 0 { | |
// move directly to empty space | |
h1 = Some(send_async(&["window", "--display", &self.input_dir]).await?); | |
send(&["window", "--focus", &self.sw_id_str]).await?; | |
} else { | |
// insert into nearest window | |
if self.input_dir == "east" { | |
h1 = Some( | |
send_async(&["window", &s.first_window.to_compact_string(), "--insert", "west"]).await?, | |
); | |
} else if self.input_dir == "west" { | |
h1 = Some( | |
send_async(&["window", &s.last_window.to_compact_string(), "--insert", "east"]).await?, | |
); | |
} | |
h2 = Some(send_async(&["window", "--display", &self.input_dir]).await?); | |
send(&["window", "--focus", &self.sw_id_str]).await?; | |
} | |
} | |
} | |
send(&[UNSTACKED_BORDER]).await?; | |
if let Some(h1) = h1 { | |
h1.await.unwrap()?; | |
} | |
if let Some(h2) = h2 { | |
h2.await.unwrap()?; | |
} | |
Ok(()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment