swaykbswitch/
lib.rs

1extern crate swayipc;
2
3use std::ffi::{CStr, CString};
4
5use std::os::raw::c_char;
6
7use swayipc::{Connection, Input};
8
9#[derive(Debug)]
10enum Error {
11    InconsistentLayouts,
12    NoKeyboards,
13}
14
15#[no_mangle]
16pub extern "C" fn Xkb_Switch_getXkbLayout() -> *const c_char {
17    let mut conn = Connection::new().unwrap();
18    let layout = get_cur_layout(&mut conn).unwrap();
19    // let _ = UnixStream::from(conn).shutdown(Shutdown::Both);
20    CString::new(layout).unwrap().into_raw()
21}
22
23fn get_cur_layout(conn: &mut Connection) -> Result<String, Error> {
24    let mut layouts: Vec<String> = get_keyboards(conn)
25        .drain(..)
26        .filter_map(|kb| kb.xkb_active_layout_name)
27        .collect();
28    layouts.dedup();
29    match layouts.leak() {
30        [] => Err(Error::NoKeyboards),
31        [layout] => Ok(layout.to_string()),
32        _ => Err(Error::InconsistentLayouts),
33    }
34}
35
36fn get_keyboards(conn: &mut Connection) -> Vec<Input> {
37    let mut all_inputs = conn.get_inputs().unwrap_or_default();
38    all_inputs.retain(|input_device| input_device.input_type == "keyboard");
39    all_inputs
40}
41
42#[no_mangle]
43pub extern "C" fn Xkb_Switch_setXkbLayout(layout_ptr: *const c_char) {
44    match Connection::new() {
45        Ok(mut conn) => {
46            let layout = unsafe { CStr::from_ptr(layout_ptr).to_string_lossy().to_string() };
47            switch_layout(&mut conn, &layout);
48            // let _ = UnixStream::from(conn).shutdown(Shutdown::Both);
49        }
50        Err(_) => (),
51    };
52}
53
54fn switch_layout(conn: &mut Connection, layout: &String) {
55    get_keyboards(conn).iter().for_each(|kb| {
56        let layout_index = kb
57            .xkb_layout_names
58            .iter()
59            .position(|x| x == layout)
60            .unwrap();
61
62        let _ = conn.run_command(format!(
63            "input {} xkb_switch_layout {}",
64            kb.identifier, layout_index
65        ));
66        // .unwrap();
67    });
68}