diff --git a/src/os/unix.rs b/src/os/unix.rs index 7abac2de..b7c4dfb9 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -39,6 +39,8 @@ pub trait WindowExt { fn get_xlib_screen_id(&self) -> Option<*mut libc::c_void>; fn get_xlib_xconnection(&self) -> Option>; + + fn send_xim_spot(&self, x: i16, y: i16); /// This function returns the underlying `xcb_connection_t` of an xlib `Display`. /// @@ -100,6 +102,12 @@ impl WindowExt for Window { } } + fn send_xim_spot(&self, x: i16, y: i16) { + if let LinuxWindow::X(ref w) = self.window { + w.send_xim_spot(x, y); + } + } + #[inline] fn get_wayland_surface(&self) -> Option<*mut libc::c_void> { use wayland_client::Proxy; diff --git a/src/platform/linux/x11/mod.rs b/src/platform/linux/x11/mod.rs index 66fee12a..86458547 100644 --- a/src/platform/linux/x11/mod.rs +++ b/src/platform/linux/x11/mod.rs @@ -699,6 +699,7 @@ impl Window2 { x_events_loop.windows.lock().unwrap().insert(win.id(), WindowData { im: im, ic: ic, + ic_spot: ffi::XPoint {x: 0, y: 0}, config: None, multitouch: window.multitouch, cursor_pos: None, @@ -715,6 +716,26 @@ impl Window2 { pub fn id(&self) -> WindowId { self.window.id() } + + #[inline] + pub fn send_xim_spot(&self, x: i16, y: i16) { + if let (Some(windows), Some(display)) = (self.windows.upgrade(), self.display.upgrade()) { + let nspot = ffi::XPoint{x: x, y: y}; + let mut windows = windows.lock().unwrap(); + let mut w = windows.get_mut(&self.window.id()).unwrap(); + if w.ic_spot.x == x && w.ic_spot.y == y { + return + } + w.ic_spot = nspot; + unsafe { + let preedit_attr = (display.xlib.XVaCreateNestedList) + (0, b"spotLocation\0", &nspot, ptr::null::<()>()); + (display.xlib.XSetICValues)(w.ic, b"preeditAttributes\0", + preedit_attr, ptr::null::<()>()); + (display.xlib.XFree)(preedit_attr); + } + } + } } impl Drop for Window2 { @@ -736,6 +757,7 @@ struct WindowData { config: Option, im: ffi::XIM, ic: ffi::XIC, + ic_spot: ffi::XPoint, multitouch: bool, cursor_pos: Option<(f64, f64)>, }