Skip to content

Instantly share code, notes, and snippets.

@diocletiann
Created August 20, 2022 15:08
Show Gist options
  • Save diocletiann/946e917cd7bfcf46407fb05129e6b3f1 to your computer and use it in GitHub Desktop.
Save diocletiann/946e917cd7bfcf46407fb05129e6b3f1 to your computer and use it in GitHub Desktop.
use compact_str::ToCompactString;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixStream;
use crate::mover::Mover;
use crate::yabai::{send, CmdError, Display, Window, ADDR, QWW, STACKED_BORDER, UNSTACKED_BORDER};
pub async fn border_color() -> anyhow::Result<()> {
// println!("running border_color");
let mut socket = UnixStream::connect(ADDR).await?;
socket.write_all(QWW.as_bytes()).await?;
let mut buf = String::with_capacity(768);
socket.read_to_string(&mut buf).await?;
let v = gjson::get(&buf, "stack-index").u8();
if v == 0 {
send(&[UNSTACKED_BORDER]).await?;
} else {
send(&[STACKED_BORDER]).await?;
}
Ok(())
}
pub async fn focus_window(input_dir: &str) -> Result<(), anyhow::Error> {
match send(&["window", "--focus", input_dir]).await {
Ok(..) => border_color().await?, // TODO: fix error propagation
Err(err) => {
// try focusing local window
if matches!(err, CmdError::CommandFailed(_)) {
focus_other(input_dir).await?;
}
cycle_stack(input_dir).await?;
}
}
Ok(())
}
pub async fn focus_other(input_dir: &str) -> Result<(), anyhow::Error> {
if input_dir == "east" {
return match send(&["display", "--focus", input_dir]).await {
Ok(..) => {
send(&["window", "--focus", "first"]).await?; // focus closest window in adjacent display
border_color().await?; // TODO: fix error propagation
Ok(())
}
Err(_err) => Ok(()), // TODO: add state to prevent queries if there's no target display
};
} else if input_dir == "west" {
return match send(&["display", "--focus", input_dir]).await {
Ok(..) => {
send(&["window", "--focus", "last"]).await?; // focus closest window in adjacent display
border_color().await?; // TODO: fix error propagation
Ok(())
}
Err(_err) => Ok(()), // TODO: add state to prevent queries if there's no target display
};
}
Ok(())
}
async fn cycle_stack(input_dir: &str) -> Result<(), CmdError> {
if input_dir == "north" {
if let Err(_err) = send(&["window", "--focus", "stack.prev"]).await {
send(&["window", "--focus", "stack.last"]).await?;
}
} else if input_dir == "south" {
if let Err(_err) = send(&["window", "--focus", "stack.next"]).await {
send(&["window", "--focus", "stack.first"]).await?;
}
}
Ok(())
}
pub async fn start_move(input_dir: &str) -> anyhow::Result<()> {
let input_dir_copy = input_dir.to_compact_string();
let source_win_handle = tokio::spawn(async {
Window::get_source().await.unwrap() // this is required
});
let target_win_handle =
tokio::spawn(async move { Window::get_target(input_dir_copy.as_str()).await.unwrap_or_default() });
let source_disp_handle = tokio::spawn(async {
Display::get_source().await.unwrap() // this is required
});
let td = Display::get_target(input_dir).await.unwrap_or_default();
let sw = source_win_handle.await?;
let tw = target_win_handle.await?;
let sd = source_disp_handle.await?;
let m = Mover::move_setup(input_dir, &sw, &tw, &sd, &td);
m.move_window().await?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment