diff --git a/src/terminal_box.rs b/src/terminal_box.rs index e070498..8eac907 100644 --- a/src/terminal_box.rs +++ b/src/terminal_box.rs @@ -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>, autoscroll: DragAutoscroll, + preedit: Option, } 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, } } }