use std::path::Path; use std::sync::atomic::Ordering::Relaxed; use std::sync::atomic::{AtomicU32, AtomicU64}; use std::time::Duration; use kitty_rc::{KittyError, LaunchCommand}; use niri::socket::Socket; use niri::{Action, Request, Response}; static LAST: AtomicU64 = AtomicU64::new(!0); static KITTY_SOCK: AtomicU32 = AtomicU32::new(!0); pub fn is_running(niri: &mut Socket) -> std::io::Result { let l = LAST.load(Relaxed); if l != !0 { let Ok(Response::Windows(x)) = niri.send(Request::Windows)? else { unreachable!() }; if x.iter().any(|x| x.id == l) { return Ok(true); } // it died :( } Ok(false) } pub async fn launch( x: LaunchCommand, at: &Path, ) -> Result<(), KittyError> { let mut niri = niri::socket::Socket::connect()?; if !is_running(&mut niri)? { runk(&mut niri, at)?; } let mut k = kitty_rc::KittyBuilder::new() .socket_path(format!( "/tmp/kitty-{:x}.sock", KITTY_SOCK.load(Relaxed) )) .connect() .await?; k.execute(&dbg!(x.build()?)).await?; Ok(()) } pub fn runk(niri: &mut Socket, at: &Path) -> std::io::Result<()> { let n: u32 = std::random::random(..); _ = niri.send(Request::Action(Action::Spawn { command: [ "kitty", "--listen-on", &format!("unix:/tmp/kitty-{n:x}.sock"), "-o", "allow_remote_control=yes", "--class", "gratty", at.to_str().unwrap(), ] .map(String::from) .to_vec(), }))?; std::thread::sleep(Duration::from_millis(500)); _ = niri.send(Request::Action(Action::ConsumeOrExpelWindowLeft { id: None, }))?; _ = niri.send(Request::Action(Action::SetWindowHeight { id: None, change: niri::SizeChange::SetFixed(400), }))?; let Ok(Ok(Response::FocusedWindow(Some(ot)))) = niri.send(Request::FocusedWindow) else { unreachable!() }; KITTY_SOCK.store(n, Relaxed); LAST.store(ot.id, Relaxed); Ok(()) } pub fn toggle(at: &Path) -> rootcause::Result<()> { let l = LAST.load(Relaxed); let mut niri = niri::socket::Socket::connect()?; if is_running(&mut niri)? { _ = niri.send(Request::Action(Action::FocusWindow { id: l }))?; // std::thread::sleep(Duration::from_millis(500)); // let Ok(Ok(Response::FocusedWindow(Some(x)))) = niri.send(Request::FocusedWindow) else { unreachable!() }; // dbg!(&x); // if x.layout.window_size.1 < 200 { _ = niri.send(Request::Action(Action::SetColumnDisplay { display: niri::ColumnDisplay::Normal, }))?; _ = niri.send(Request::Action(Action::SetWindowHeight { id: Some(l), change: niri::SizeChange::SetFixed(400), }))?; // } return Ok(()); } // let Ok(Ok(Response::FocusedWindow(Some(focused)))) = // niri.send(Request::FocusedWindow) // else { // unreachable!() // }; runk(&mut niri, at)?; Ok(()) }