Add minimal support CJK input method to terminal box excepts IME cursor positioning which is a bit tricky

This commit is contained in:
KENZ 2025-04-27 12:54:46 +09:00 committed by KENZ
parent faa61d1692
commit 18462517f0

View file

@ -13,6 +13,7 @@ use cosmic::{
iced::core::{
Border, Shell,
clipboard::Clipboard,
input_method::{self, InputMethod},
keyboard::key::Named,
layout::{self, Layout},
renderer::{self, Quad, Renderer as _},
@ -233,6 +234,18 @@ where
self.disabled = disabled;
self
}
fn input_method<'b>(&self, state: &'b State, layout: Layout<'_>) -> InputMethod<&'b str> {
if !state.is_focused {
return InputMethod::Disabled;
}
InputMethod::Enabled {
cursor: Rectangle::default(),
purpose: input_method::Purpose::Normal,
preedit: state.preedit.as_ref().map(input_method::Preedit::as_ref),
}
}
}
pub fn terminal_box<'a, Message>(
@ -879,6 +892,7 @@ where
shell.request_redraw();
}
}
shell.request_input_method(&self.input_method(state, layout));
}
cosmic::iced::window::Event::Unfocused => {
state.is_focused = false;
@ -1160,6 +1174,30 @@ where
}
}
}
Event::InputMethod(event) => match event {
input_method::Event::Opened | input_method::Event::Closed => {
state.preedit = matches!(event, input_method::Event::Opened).then(|| {
let preedit = input_method::Preedit::new();
preedit
});
}
input_method::Event::Preedit(content, selection) => {
if state.is_focused {
let metrics = terminal.with_buffer(|buffer| buffer.metrics());
state.preedit = Some(input_method::Preedit {
content: content.to_owned(),
selection: selection.clone(),
text_size: Some(metrics.font_size.into()),
})
}
}
input_method::Event::Commit(text) => {
if state.is_focused {
terminal.paste(text.to_string());
shell.capture_event();
}
}
},
Event::Mouse(MouseEvent::ButtonPressed(button)) => {
if let Some(p) = cursor_position.position_in(layout.bounds()) {
let x = p.x - self.padding.left;
@ -1867,6 +1905,7 @@ pub struct State {
scroll_pixels: f32,
scrollbar_rect: Cell<Rectangle<f32>>,
autoscroll: DragAutoscroll,
preedit: Option<input_method::Preedit>,
}
impl State {
@ -1880,6 +1919,7 @@ impl State {
scroll_pixels: 0.0,
scrollbar_rect: Cell::new(Rectangle::default()),
autoscroll: DragAutoscroll::new(AUTOSCROLL_INTERVAL),
preedit: None,
}
}
}