diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b6f47e..f4cd72ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ - On Windows, add touch pressure information for touch events. - On macOS, differentiate between `CursorIcon::Grab` and `CursorIcon::Grabbing`. - On Wayland, fix event processing sometimes stalling when using OpenGL with vsync. -- Officially remove the Emscripten backend +- Officially remove the Emscripten backend. +- On Windows, fix handling of surrogate pairs when dispatching `ReceivedCharacter`. - On macOS 10.15, fix freeze upon exiting exclusive fullscreen mode. # 0.20.0 Alpha 3 (2019-08-14) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 57e51b21..f6e3f503 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1031,11 +1031,29 @@ unsafe extern "system" fn public_window_callback( winuser::WM_CHAR => { use crate::event::WindowEvent::ReceivedCharacter; - let chr: char = mem::transmute(wparam as u32); - subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), - event: ReceivedCharacter(chr), - }); + let high_surrogate = 0xD800 <= wparam && wparam <= 0xDBFF; + let low_surrogate = 0xDC00 <= wparam && wparam <= 0xDFFF; + + if high_surrogate { + subclass_input.window_state.lock().high_surrogate = Some(wparam as u16); + } else if low_surrogate { + let mut window_state = subclass_input.window_state.lock(); + if let Some(high_surrogate) = window_state.high_surrogate.take() { + let pair = [high_surrogate, wparam as u16]; + if let Some(Ok(chr)) = std::char::decode_utf16(pair.iter().copied()).next() { + subclass_input.send_event(Event::WindowEvent { + window_id: RootWindowId(WindowId(window)), + event: ReceivedCharacter(chr), + }); + } + } + } else { + let chr: char = mem::transmute(wparam as u32); + subclass_input.send_event(Event::WindowEvent { + window_id: RootWindowId(WindowId(window)), + event: ReceivedCharacter(chr), + }); + } 0 } diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 5979f777..51bf45b8 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -32,6 +32,7 @@ pub struct WindowState { /// Used to supress duplicate redraw attempts when calling `request_redraw` multiple /// times in `EventsCleared`. pub queued_out_of_band_redraw: bool, + pub high_surrogate: Option, window_flags: WindowFlags, } @@ -114,6 +115,7 @@ impl WindowState { fullscreen: None, queued_out_of_band_redraw: false, + high_surrogate: None, window_flags: WindowFlags::empty(), } }