diff --git a/src/platform/linux/x11/mod.rs b/src/platform/linux/x11/mod.rs index 414362be..cddbd265 100644 --- a/src/platform/linux/x11/mod.rs +++ b/src/platform/linux/x11/mod.rs @@ -290,13 +290,26 @@ impl EventsLoop { let written = unsafe { use std::str; + const INIT_BUFF_SIZE: usize = 16; let mut windows = self.windows.lock().unwrap(); let window_data = windows.get_mut(&WindowId(xwindow)).unwrap(); - let mut buffer: [u8; 16] = [mem::uninitialized(); 16]; - let mut keysym = 0; - let count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev, + /* buffer allocated on heap instead of stack, due to the possible + * reallocation */ + let mut buffer: Vec = vec![mem::uninitialized(); INIT_BUFF_SIZE]; + let mut keysym: ffi::KeySym = 0; + let mut status: ffi::Status = 0; + let mut count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev, mem::transmute(buffer.as_mut_ptr()), - buffer.len() as libc::c_int, &mut keysym, ptr::null_mut()); + buffer.len() as libc::c_int, + &mut keysym, &mut status); + /* buffer overflowed, dynamically reallocate */ + if status == ffi::XBufferOverflow { + buffer = vec![mem::uninitialized(); count as usize]; + count = (self.display.xlib.Xutf8LookupString)(window_data.ic, xkev, + mem::transmute(buffer.as_mut_ptr()), + buffer.len() as libc::c_int, + &mut keysym, &mut status); + } { // Translate x event state to mods @@ -451,10 +464,20 @@ impl EventsLoop { } ffi::XI_FocusIn => { let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) }; + unsafe { + let mut windows = self.windows.lock().unwrap(); + let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); + (self.display.xlib.XSetICFocus)(window_data.ic); + } callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(true) }) } ffi::XI_FocusOut => { let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) }; + unsafe { + let mut windows = self.windows.lock().unwrap(); + let window_data = windows.get_mut(&WindowId(xev.event)).unwrap(); + (self.display.xlib.XUnsetICFocus)(window_data.ic); + } callback(Event::WindowEvent { window_id: mkwid(xev.event), event: Focused(false) }) }