Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:59:21.042Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

xim_handler.rs

134 lines · 4.1 KB · rust
1use std::default::Default;
2
3use x11rb::protocol::{Event, xproto};
4use xim::{AHashMap, AttributeName, Client, ClientError, ClientHandler, InputStyle};
5
6pub enum XimCallbackEvent {
7    XimXEvent(x11rb::protocol::Event),
8    XimPreeditEvent(xproto::Window, String),
9    XimCommitEvent(xproto::Window, String),
10}
11
12pub struct XimHandler {
13    pub im_id: u16,
14    pub ic_id: u16,
15    pub connected: bool,
16    pub window: xproto::Window,
17    pub last_callback_event: Option<XimCallbackEvent>,
18}
19
20impl XimHandler {
21    pub fn new() -> Self {
22        Self {
23            im_id: Default::default(),
24            ic_id: Default::default(),
25            connected: false,
26            window: Default::default(),
27            last_callback_event: None,
28        }
29    }
30}
31
32impl<C: Client<XEvent = xproto::KeyPressEvent>> ClientHandler<C> for XimHandler {
33    fn handle_connect(&mut self, client: &mut C) -> Result<(), ClientError> {
34        client.open("C")
35    }
36
37    fn handle_open(&mut self, client: &mut C, input_method_id: u16) -> Result<(), ClientError> {
38        self.im_id = input_method_id;
39
40        client.get_im_values(input_method_id, &[AttributeName::QueryInputStyle])
41    }
42
43    fn handle_get_im_values(
44        &mut self,
45        client: &mut C,
46        input_method_id: u16,
47        _attributes: AHashMap<AttributeName, Vec<u8>>,
48    ) -> Result<(), ClientError> {
49        let ic_attributes = client
50            .build_ic_attributes()
51            .push(AttributeName::InputStyle, InputStyle::PREEDIT_CALLBACKS)
52            .push(AttributeName::ClientWindow, self.window)
53            .push(AttributeName::FocusWindow, self.window)
54            .build();
55        client.create_ic(input_method_id, ic_attributes)
56    }
57
58    fn handle_create_ic(
59        &mut self,
60        _client: &mut C,
61        _input_method_id: u16,
62        input_context_id: u16,
63    ) -> Result<(), ClientError> {
64        self.connected = true;
65        self.ic_id = input_context_id;
66        Ok(())
67    }
68
69    fn handle_commit(
70        &mut self,
71        _client: &mut C,
72        _input_method_id: u16,
73        _input_context_id: u16,
74        text: &str,
75    ) -> Result<(), ClientError> {
76        self.last_callback_event = Some(XimCallbackEvent::XimCommitEvent(
77            self.window,
78            String::from(text),
79        ));
80        Ok(())
81    }
82
83    fn handle_forward_event(
84        &mut self,
85        _client: &mut C,
86        _input_method_id: u16,
87        _input_context_id: u16,
88        _flag: xim::ForwardEventFlag,
89        xev: C::XEvent,
90    ) -> Result<(), ClientError> {
91        match xev.response_type {
92            x11rb::protocol::xproto::KEY_PRESS_EVENT => {
93                self.last_callback_event = Some(XimCallbackEvent::XimXEvent(Event::KeyPress(xev)));
94            }
95            x11rb::protocol::xproto::KEY_RELEASE_EVENT => {
96                self.last_callback_event =
97                    Some(XimCallbackEvent::XimXEvent(Event::KeyRelease(xev)));
98            }
99            _ => {}
100        }
101        Ok(())
102    }
103
104    fn handle_close(&mut self, client: &mut C, _input_method_id: u16) -> Result<(), ClientError> {
105        client.disconnect()
106    }
107
108    fn handle_preedit_draw(
109        &mut self,
110        _client: &mut C,
111        _input_method_id: u16,
112        _input_context_id: u16,
113        _caret: i32,
114        _chg_first: i32,
115        _chg_len: i32,
116        _status: xim::PreeditDrawStatus,
117        preedit_string: &str,
118        _feedbacks: Vec<xim::Feedback>,
119    ) -> Result<(), ClientError> {
120        // XIMReverse: 1, XIMPrimary: 8, XIMTertiary: 32: selected text
121        // XIMUnderline: 2, XIMSecondary: 16: underlined text
122        // XIMHighlight: 4: normal text
123        // XIMVisibleToForward: 64, XIMVisibleToBackward: 128, XIMVisibleCenter: 256: text align position
124        // XIMPrimary, XIMHighlight, XIMSecondary, XIMTertiary are not specified,
125        // but interchangeable as above
126        // Currently there's no way to support these.
127        self.last_callback_event = Some(XimCallbackEvent::XimPreeditEvent(
128            self.window,
129            String::from(preedit_string),
130        ));
131        Ok(())
132    }
133}
134
Served at tenant.openagents/omega Member data and write actions are omitted.