use super::*;
use swayipc::{Connection, EventType};
struct LuaI3Event(EventType);
impl LuaUserData for LuaI3Event {}
pub struct I3;
impl Module for I3 {
fn load(&self, state: &mut State) -> Result<(), LuaError> {
let module = state.lua.create_table()?;
module.set("EVENT_WORKSPACE", LuaI3Event(EventType::Workspace))?;
module.set("EVENT_OUTPUT", LuaI3Event(EventType::Output))?;
module.set("EVENT_MODE", LuaI3Event(EventType::Mode))?;
module.set("EVENT_WINDOW", LuaI3Event(EventType::Window))?;
module.set(
"EVENT_BARCONFIG_UPDATE",
LuaI3Event(EventType::BarConfigUpdate),
)?;
module.set("EVENT_BINDING", LuaI3Event(EventType::Binding))?;
module.set("EVENT_SHUTDOWN", LuaI3Event(EventType::Shutdown))?;
module.set("EVENT_TICK", LuaI3Event(EventType::Tick))?;
module.set(
"EVENT_BARSTATE_UPDATE",
LuaI3Event(EventType::BarStateUpdate),
)?;
module.set("EVENT_INPUT", LuaI3Event(EventType::Input))?;
module.set(
"run_command",
state.lua.create_function(|_, command: String| {
match Connection::new() {
Ok(mut c) => match c.run_command(command) {
Ok(_) => {}
Err(_) => return Ok(LuaValue::Boolean(false)),
},
Err(_) => return Ok(LuaValue::Boolean(false)),
}
Ok(LuaValue::Boolean(true))
})?,
)?;
module.set(
"get_workspaces",
state.lua.create_function(|lua, _: ()| {
let mut jsons: Vec<String> = vec![];
if let Ok(mut c) = Connection::new() {
if let Ok(ws) = c.get_workspaces() {
for w in ws {
if let Ok(s) = serde_json::to_string(&w) {
jsons.push(s)
};
}
}
};
Ok(jsons.into_lua(lua))
})?,
)?;
module.set(
"get_outputs",
state.lua.create_function(|lua, _: ()| {
let mut jsons: Vec<String> = vec![];
if let Ok(mut c) = Connection::new() {
if let Ok(ws) = c.get_outputs() {
for w in ws {
if let Ok(s) = serde_json::to_string(&w) {
jsons.push(s)
};
}
}
};
Ok(jsons.into_lua(lua))
})?,
)?;
module.set(
"get_tree",
state.lua.create_function(|lua, _: ()| {
if let Ok(mut c) = Connection::new() {
if let Ok(ws) = c.get_tree() {
if let Ok(s) = serde_json::to_string(&ws) {
return s.into_lua(lua);
};
}
};
Ok(LuaValue::Nil)
})?,
)?;
module.set(
"get_seats",
state.lua.create_function(|lua, _: ()| {
if let Ok(mut c) = Connection::new() {
if let Ok(ws) = c.get_seats() {
if let Ok(s) = serde_json::to_string(&ws) {
return s.into_lua(lua);
}
}
};
Ok(LuaValue::Nil)
})?,
)?;
module.set(
"get_inputs",
state.lua.create_function(|lua, _: ()| {
if let Ok(mut c) = Connection::new() {
if let Ok(ws) = c.get_inputs() {
if let Ok(s) = serde_json::to_string(&ws) {
return s.into_lua(lua);
}
}
};
Ok(LuaValue::Nil)
})?
)?;
module.set(
"subscribe_event",
state.lua.create_function(
|_, (event_type, callback): (LuaAnyUserData, LuaFunction)| {
let event_type = if event_type.is::<LuaI3Event>() {
event_type.take::<LuaI3Event>()?
} else {
return Ok(LuaValue::Boolean(false));
};
let c = match Connection::new() {
Ok(c) => c,
Err(_) => return Ok(LuaValue::Boolean(false)),
};
let stream = match c.subscribe(vec![event_type.0]) {
Ok(s) => s,
Err(_) => return Ok(LuaValue::Boolean(false)),
};
for r_event in stream {
let event = match r_event {
Ok(e) => e,
Err(_) => continue,
};
match event.event_type() {
e if e == event_type.0 => {
match serde_json::to_string(&event) {
Ok(s) => callback.call::<LuaValue>(s)?,
Err(_) => callback.call::<LuaValue>(LuaValue::Nil)?,
};
}
_ => {}
}
}
Ok(LuaValue::Nil)
},
)?,
)?;
create_module(&state.lua, "autosway.i3", module)?;
Ok(())
}
}