diff --git a/src/shell.rs b/src/shell.rs index 96e1b5e..f992adb 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -262,6 +262,26 @@ impl State { Continue(false) }); } + + fn set_im_location(&self) { + if let Some(line_height) = self.line_height { + if let Some(char_width) = self.char_width { + let (row, col) = self.model.get_cursor(); + + let (x, y, width, height) = + ModelRect::point(col, row).to_area(line_height, char_width); + + self.im_context.set_cursor_location(&gdk::Rectangle { + x, + y, + width, + height, + }); + } + } + + self.im_context.reset(); + } } pub struct UiState { @@ -420,13 +440,21 @@ impl Shell { let ref_state = self.state.clone(); state.drawing_area.connect_realize(move |w| { - ref_state.borrow().im_context.set_client_window( - w.get_window().as_ref(), - ) + let ref_state = ref_state.clone(); + let w = w.clone(); + // sometime set_client_window does not work without idle_add + // and looks like not enabled im_context + gtk::idle_add(move || { + ref_state.borrow().im_context.set_client_window( + w.get_window().as_ref(), + ); + Continue(false) + }); }); let ref_state = self.state.clone(); state.im_context.connect_commit(move |_, ch| { + println!("commit"); ref_state.borrow().im_commit(ch) }); @@ -501,6 +529,7 @@ impl Deref for Shell { fn gtk_focus_in(state: &mut State) -> Inhibit { state.im_context.focus_in(); + println!("focus in"); state.cursor.as_mut().unwrap().enter_focus(); let point = state.model.cur_point(); state.on_redraw(&RepaintMode::Area(point)); @@ -509,6 +538,7 @@ fn gtk_focus_in(state: &mut State) -> Inhibit { fn gtk_focus_out(state: &mut State) -> Inhibit { state.im_context.focus_out(); + println!("focus out"); state.cursor.as_mut().unwrap().leave_focus(); let point = state.model.cur_point(); state.on_redraw(&RepaintMode::Area(point)); @@ -992,7 +1022,9 @@ fn try_nvim_resize(state: &Arc>) { impl RedrawEvents for State { fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode { - RepaintMode::AreaList(self.model.set_cursor(row as usize, col as usize)) + let repaint_area = self.model.set_cursor(row as usize, col as usize); + self.set_im_location(); + RepaintMode::AreaList(repaint_area) } fn on_put(&mut self, text: &str) -> RepaintMode {