Created
August 20, 2022 15:08
-
-
Save diocletiann/946e917cd7bfcf46407fb05129e6b3f1 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::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