1use std::sync::Arc;
2use xcb_imdkit::{ImeClient, InputStyle};
3
4fn create_window(connection: Arc<xcb::Connection>, screen: &xcb::Screen) -> u32 {
5 let w = connection.generate_id();
6 let mask = xcb::EVENT_MASK_KEY_PRESS
7 | xcb::EVENT_MASK_KEY_RELEASE
8 | xcb::EVENT_MASK_FOCUS_CHANGE
9 | xcb::EVENT_MASK_VISIBILITY_CHANGE
10 | xcb::EVENT_MASK_STRUCTURE_NOTIFY;
11 let values = [
12 (xcb::CW_BACK_PIXEL, screen.white_pixel()),
13 (xcb::CW_EVENT_MASK, mask),
14 ];
15 xcb::create_window(
16 &connection,
17 xcb::COPY_FROM_PARENT as u8,
18 w,
19 screen.root(),
20 0,
21 0,
22 400,
23 400,
24 10,
25 xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
26 screen.root_visual(),
27 &values,
28 );
29 xcb::map_window(&connection, w);
30 unsafe {
31 xcb::ffi::xcb_flush(connection.get_raw_conn());
32 }
33 w
34}
35
36fn main() {
37 let (connection, screen_default_nbr) = xcb::Connection::connect(None).unwrap();
38 let connection = Arc::new(connection);
39 let screen = connection
40 .get_setup()
41 .roots()
42 .nth(screen_default_nbr as usize)
43 .unwrap();
44
45 ImeClient::set_logger(|msg| println!("Log: {}", msg));
46 let mut ime = ImeClient::new(
47 connection.clone(),
48 screen_default_nbr,
49 InputStyle::PREEDIT_CALLBACKS,
50 None,
51 );
52 ime.set_commit_string_cb(|win, input| println!("Win {}, got: {}", win, input));
53 ime.set_forward_event_cb(|win, e| {
54 dbg!(
55 win,
56 e.response_type(),
57 e.detail(),
58 e.time(),
59 e.root(),
60 e.event(),
61 e.child(),
62 e.root_x(),
63 e.root_y(),
64 e.event_x(),
65 e.event_y(),
66 e.state(),
67 e.same_screen(),
68 );
69 });
70 ime.set_preedit_draw_cb(|win, info| {
71 dbg!(win, info);
72 });
73
74 let mut wins = vec![];
75 for _ in 0..3 {
76 wins.push(create_window(connection.clone(), &screen));
77 }
78
79 let mut focus_win = wins[0];
80 let mut n = 0;
81 loop {
82 let event = connection.wait_for_event();
83 if event.is_none() {
84 break;
85 }
86 let event = event.unwrap();
87 dbg!(event.response_type());
88
89 let event_type = event.response_type() & !0x80;
90 if xcb::FOCUS_IN == event_type {
91 let event: &xcb::FocusInEvent = unsafe { xcb::cast_event(&event) };
92 focus_win = event.event();
93 ime.update_pos(focus_win, 0, 0);
94 }
95
96 if xcb::CONFIGURE_NOTIFY == event_type {
97 ime.update_pos(focus_win, 0, 0);
98 }
99
100 println!(">>>>{}>>>>", n);
101 ime.process_event(&event);
102 println!("<<<<{}<<<<", n);
103 n += 1;
104 }
105}