aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.rs14
-rw-r--r--src/main.rs2
-rw-r--r--src/term/mod.rs7
-rw-r--r--src/window.rs32
4 files changed, 54 insertions, 1 deletions
diff --git a/src/display.rs b/src/display.rs
index 0f2c526f..d1af5411 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -331,4 +331,18 @@ impl Display {
pub fn get_window_id(&self) -> Option<usize> {
self.window.get_window_id()
}
+
+ /// Adjust the XIM editor position according to the new location of the cursor
+ pub fn update_ime_position(&mut self, terminal: &Term) {
+ use index::{Point, Line, Column};
+ use term::SizeInfo;
+ let Point{line: Line(row), col: Column(col)} = terminal.cursor().point;
+ let SizeInfo{cell_width: cw,
+ cell_height: ch,
+ padding_x: px,
+ padding_y: py, ..} = *terminal.size_info();
+ let nspot_y = (py + (row + 1) as f32 * ch) as i16;
+ let nspot_x = (px + col as f32 * cw) as i16;
+ self.window().send_xim_spot(nspot_x, nspot_y);
+ }
}
diff --git a/src/main.rs b/src/main.rs
index 9db5ce58..472e4144 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -172,6 +172,8 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// Maybe draw the terminal
if terminal.needs_draw() {
+ // Try to update the position of the input method editor
+ display.update_ime_position(&terminal);
// Handle pending resize events
//
// The second argument is a list of types that want to be notified
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 64541b33..0a51aac3 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -490,7 +490,7 @@ impl IndexMut<CharsetIndex> for Charsets {
#[derive(Default, Copy, Clone)]
pub struct Cursor {
/// The location of this cursor
- point: Point,
+ pub point: Point,
/// Template cell when using this cursor
template: Cell,
@@ -1054,6 +1054,11 @@ impl Term {
&self.mode
}
+ #[inline]
+ pub fn cursor(&self) -> &Cursor {
+ &self.cursor
+ }
+
pub fn swap_alt(&mut self) {
if self.alt {
let template = self.empty_cell;
diff --git a/src/window.rs b/src/window.rs
index 4fbe8631..8126454d 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -183,6 +183,8 @@ impl Window {
title: &str
) -> Result<Window> {
let event_loop = EventsLoop::new();
+
+ Window::platform_window_init();
let window = WindowBuilder::new()
.with_title(title);
let context = ContextBuilder::new()
@@ -282,6 +284,36 @@ impl Window {
}
}
+ #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
+ pub fn platform_window_init() {
+ /// Set up env to make XIM work correctly
+ use x11_dl::xlib;
+ use libc::{setlocale, LC_CTYPE};
+ let xlib = xlib::Xlib::open().expect("get xlib");
+ unsafe {
+ /// Use empty c string to fallback to LC_CTYPE in environment variables
+ setlocale(LC_CTYPE, b"\0".as_ptr() as *const _);
+ /// Use empty c string for implementation dependent behavior,
+ /// which might be the XMODIFIERS set in env
+ (xlib.XSetLocaleModifiers)(b"\0".as_ptr() as *const _);
+ }
+ }
+
+ /// TODO: change this directive when adding functions for other platforms
+ #[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))]
+ pub fn platform_window_init() {
+ }
+
+ #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
+ pub fn send_xim_spot(&self, x: i16, y: i16) {
+ use glutin::os::unix::WindowExt;
+ self.window.send_xim_spot(x, y);
+ }
+
+ #[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))]
+ pub fn send_xim_spot(&self, x: i16, y: i16) {
+ }
+
#[cfg(not(target_os = "macos"))]
pub fn get_window_id(&self) -> Option<usize> {
use glutin::os::unix::WindowExt;