A simple CPU rendered GUI IDE experience.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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<bool> {
    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(())
}