use x11rb::{
connection::Connection,
protocol::{
xproto::{self, ConnectionExt},
Event,
},
rust_connection::RustConnection,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let (conn, screen) = RustConnection::connect(None)?;
let root = conn.setup().roots[screen].root;
let background = conn.setup().roots[screen].white_pixel;
let window = conn.generate_id()?;
conn.create_window(
x11rb::COPY_DEPTH_FROM_PARENT,
window,
root,
0,
0,
100,
100,
0,
xproto::WindowClass::INPUT_OUTPUT,
0,
&xproto::CreateWindowAux::new()
.background_pixel(background)
.event_mask(xproto::EventMask::KEY_PRESS),
)?
.ignore_error();
let (wm_protocols, wm_delete_window) = {
let wmp_tok = conn.intern_atom(false, b"WM_PROTOCOLS")?;
let wmdw_tok = conn.intern_atom(false, b"WM_DELETE_WINDOW")?;
let wmp = wmp_tok.reply()?;
let wmdw = wmdw_tok.reply()?;
(wmp.atom, wmdw.atom)
};
conn.change_property(
xproto::PropMode::REPLACE,
window,
wm_protocols,
xproto::AtomEnum::ATOM,
32,
1,
bytemuck::bytes_of(&wm_delete_window),
)?
.ignore_error();
conn.map_window(window)?.ignore_error();
let mapping = conn
.get_keyboard_mapping(
conn.setup().min_keycode,
conn.setup().max_keycode - conn.setup().min_keycode + 1,
)?
.reply()?;
let name = b"Type to see keyboard symbols";
conn.change_property(
xproto::PropMode::REPLACE,
window,
xproto::AtomEnum::WM_NAME,
xproto::AtomEnum::STRING,
8,
name.len() as u32,
name,
)?
.ignore_error();
loop {
let event = conn.wait_for_event()?;
match event {
Event::ClientMessage(cme) => {
if cme.type_ == wm_protocols
&& cme.format == 32
&& cme.data.as_data32()[0] == wm_delete_window
{
break;
}
}
Event::KeyPress(kpe) => {
let keycode = kpe.detail;
let keysym = xkeysym::keysym(
keycode.into(),
0,
conn.setup().min_keycode.into(),
mapping.keysyms_per_keycode,
mapping.keysyms.as_slice(),
);
match keysym.and_then(xkeysym::Keysym::name) {
Some(name) => println!("{name}"),
None => println!("Unknown keysym"),
}
}
_ => {}
}
}
Ok(())
}