From 0b75a6b60c63ecee0e55c552c83813e517ad4b5c Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Sun, 7 May 2017 21:16:48 -0700 Subject: [PATCH] Make keyboard input event order consistent All platforms should now receive events in the following order: 1. KeyboardInput(ElementState::Pressed, ..) 2. ReceivedCharacter 3. KeyboardInput(ElementState::Released, ..) cc https://github.com/tomaka/glutin/issues/878 --- src/platform/linux/x11/mod.rs | 34 +++++++++++++++---------------- src/platform/macos/events_loop.rs | 12 +++++------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/platform/linux/x11/mod.rs b/src/platform/linux/x11/mod.rs index d1ed69f6..78eb9586 100644 --- a/src/platform/linux/x11/mod.rs +++ b/src/platform/linux/x11/mod.rs @@ -228,6 +228,23 @@ impl EventsLoop { let mut ev_mods = ModifiersState::default(); + let mut keysym = unsafe { + (self.display.xlib.XKeycodeToKeysym)(self.display.display, xkev.keycode as ffi::KeyCode, 0) + }; + + let vkey = events::keysym_to_element(keysym as libc::c_uint); + + callback(Event::WindowEvent { window_id: wid, event: WindowEvent::KeyboardInput { + // Typical virtual core keyboard ID. xinput2 needs to be used to get a reliable value. + device_id: mkdid(3), + input: KeyboardInput { + state: state, + scancode: xkev.keycode, + virtual_keycode: vkey, + modifiers: ev_mods, + }, + }}); + if state == Pressed { let written = unsafe { use std::str; @@ -267,23 +284,6 @@ impl EventsLoop { callback(Event::WindowEvent { window_id: wid, event: WindowEvent::ReceivedCharacter(chr) }) } } - - let mut keysym = unsafe { - (self.display.xlib.XKeycodeToKeysym)(self.display.display, xkev.keycode as ffi::KeyCode, 0) - }; - - let vkey = events::keysym_to_element(keysym as libc::c_uint); - - callback(Event::WindowEvent { window_id: wid, event: WindowEvent::KeyboardInput { - // Typical virtual core keyboard ID. xinput2 needs to be used to get a reliable value. - device_id: mkdid(3), - input: KeyboardInput { - state: state, - scancode: xkev.keycode, - virtual_keycode: vkey, - modifiers: ev_mods, - }, - }}); } ffi::GenericEvent => { diff --git a/src/platform/macos/events_loop.rs b/src/platform/macos/events_loop.rs index ea24948f..5b075a69 100644 --- a/src/platform/macos/events_loop.rs +++ b/src/platform/macos/events_loop.rs @@ -309,10 +309,6 @@ impl EventsLoop { let mut events = std::collections::VecDeque::new(); let received_c_str = foundation::NSString::UTF8String(ns_event.characters()); let received_str = std::ffi::CStr::from_ptr(received_c_str); - for received_char in std::str::from_utf8(received_str.to_bytes()).unwrap().chars() { - let window_event = WindowEvent::ReceivedCharacter(received_char); - events.push_back(into_event(window_event)); - } let vkey = to_virtual_key_code(NSEvent::keyCode(ns_event)); let state = ElementState::Pressed; @@ -326,10 +322,12 @@ impl EventsLoop { modifiers: event_mods(ns_event), }, }; - events.push_back(into_event(window_event)); - let event = events.pop_front(); + for received_char in std::str::from_utf8(received_str.to_bytes()).unwrap().chars() { + let window_event = WindowEvent::ReceivedCharacter(received_char); + events.push_back(into_event(window_event)); + } self.pending_events.lock().unwrap().extend(events.into_iter()); - event + Some(into_event(window_event)) }, appkit::NSKeyUp => {