ime
This commit is contained in:
parent
2526dcb5a5
commit
8f1174c155
2 changed files with 44 additions and 20 deletions
|
@ -655,6 +655,20 @@ impl X11Client {
|
|||
state.restore_xim(ximc, xim_handler);
|
||||
drop(state);
|
||||
|
||||
// Create IC when IME becomes ready while we already have focus
|
||||
{
|
||||
let s = self.0.borrow();
|
||||
let need_enable = s
|
||||
.xim_handler
|
||||
.as_ref()
|
||||
.map(|h| h.ready && !h.connected && s.keyboard_focused_window.is_some())
|
||||
.unwrap_or(false);
|
||||
drop(s);
|
||||
if need_enable {
|
||||
self.enable_ime();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(event) = xim_callback_event {
|
||||
self.handle_xim_callback_event(event);
|
||||
}
|
||||
|
@ -682,22 +696,25 @@ impl X11Client {
|
|||
let Some((mut ximc, mut xim_handler)) = state.take_xim() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let window_id = state.keyboard_focused_window;
|
||||
if window_id.is_none() {
|
||||
// no focus -> nothing to bind to; put XIM back and bail
|
||||
state.restore_xim(ximc, xim_handler);
|
||||
return;
|
||||
}
|
||||
let window_id = window_id.unwrap();
|
||||
// ensure handler.window is the actual focused window
|
||||
xim_handler.window = window_id;
|
||||
|
||||
let mut ic_attributes = ximc
|
||||
.build_ic_attributes()
|
||||
.push(AttributeName::InputStyle, InputStyle::PREEDIT_CALLBACKS)
|
||||
.push(AttributeName::ClientWindow, xim_handler.window)
|
||||
.push(AttributeName::FocusWindow, xim_handler.window);
|
||||
|
||||
let window_id = state.keyboard_focused_window;
|
||||
drop(state);
|
||||
if let Some(window_id) = window_id {
|
||||
let Some(window) = self.get_window(window_id) else {
|
||||
log::error!("Failed to get window for IME positioning");
|
||||
let mut state = self.0.borrow_mut();
|
||||
state.ximc = Some(ximc);
|
||||
state.xim_handler = Some(xim_handler);
|
||||
return;
|
||||
};
|
||||
if let Some(window) = self.get_window(window_id) {
|
||||
if let Some(area) = window.get_ime_area() {
|
||||
ic_attributes =
|
||||
ic_attributes.nested_list(xim::AttributeName::PreeditAttributes, |b| {
|
||||
|
@ -710,9 +727,17 @@ impl X11Client {
|
|||
);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
log::error!("Failed to get window for IME positioning");
|
||||
}
|
||||
ximc.create_ic(xim_handler.im_id, ic_attributes.build())
|
||||
.ok();
|
||||
|
||||
// if we already have an IC, just rebind its window/spot; else create it
|
||||
if xim_handler.connected {
|
||||
let _ = ximc.set_ic_values(xim_handler.im_id, xim_handler.ic_id, ic_attributes.build());
|
||||
} else {
|
||||
let _ = ximc.create_ic(xim_handler.im_id, ic_attributes.build());
|
||||
}
|
||||
|
||||
let mut state = self.0.borrow_mut();
|
||||
state.restore_xim(ximc, xim_handler);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ pub struct XimHandler {
|
|||
pub im_id: u16,
|
||||
pub ic_id: u16,
|
||||
pub connected: bool,
|
||||
pub ready: bool,
|
||||
pub window: xproto::Window,
|
||||
pub last_callback_event: Option<XimCallbackEvent>,
|
||||
}
|
||||
|
@ -23,6 +24,7 @@ impl XimHandler {
|
|||
im_id: Default::default(),
|
||||
ic_id: Default::default(),
|
||||
connected: false,
|
||||
ready: false,
|
||||
window: Default::default(),
|
||||
last_callback_event: None,
|
||||
}
|
||||
|
@ -42,17 +44,14 @@ impl<C: Client<XEvent = xproto::KeyPressEvent>> ClientHandler<C> for XimHandler
|
|||
|
||||
fn handle_get_im_values(
|
||||
&mut self,
|
||||
client: &mut C,
|
||||
input_method_id: u16,
|
||||
_client: &mut C,
|
||||
_input_method_id: u16,
|
||||
_attributes: AHashMap<AttributeName, Vec<u8>>,
|
||||
) -> Result<(), ClientError> {
|
||||
let ic_attributes = client
|
||||
.build_ic_attributes()
|
||||
.push(AttributeName::InputStyle, InputStyle::PREEDIT_CALLBACKS)
|
||||
.push(AttributeName::ClientWindow, self.window)
|
||||
.push(AttributeName::FocusWindow, self.window)
|
||||
.build();
|
||||
client.create_ic(input_method_id, ic_attributes)
|
||||
// IM is ready, but we don't know the real window yet.
|
||||
// Defer IC creation to client.enable_ime().
|
||||
self.ready = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_create_ic(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue