Flush high surrogate if not followed by low surrogate (#1166)

* Flush high surrogate if not followed by low surrogate

* Remove transmute from WM_CHAR handler

* Fix window_state being locked while dispatching ReceivedCharacter for surrogate codepoints.

* Format
This commit is contained in:
Osspial 2019-09-16 14:26:56 -04:00 committed by GitHub
parent c03ef852a4
commit 3716f13d8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1031,16 +1031,18 @@ unsafe extern "system" fn public_window_callback<T>(
winuser::WM_CHAR => { winuser::WM_CHAR => {
use crate::event::WindowEvent::ReceivedCharacter; use crate::event::WindowEvent::ReceivedCharacter;
let high_surrogate = 0xD800 <= wparam && wparam <= 0xDBFF; use std::char;
let low_surrogate = 0xDC00 <= wparam && wparam <= 0xDFFF; let is_high_surrogate = 0xD800 <= wparam && wparam <= 0xDBFF;
let is_low_surrogate = 0xDC00 <= wparam && wparam <= 0xDFFF;
if high_surrogate { if is_high_surrogate {
subclass_input.window_state.lock().high_surrogate = Some(wparam as u16); subclass_input.window_state.lock().high_surrogate = Some(wparam as u16);
} else if low_surrogate { } else if is_low_surrogate {
let mut window_state = subclass_input.window_state.lock(); let high_surrogate = subclass_input.window_state.lock().high_surrogate.take();
if let Some(high_surrogate) = window_state.high_surrogate.take() {
if let Some(high_surrogate) = high_surrogate {
let pair = [high_surrogate, wparam as u16]; let pair = [high_surrogate, wparam as u16];
if let Some(Ok(chr)) = std::char::decode_utf16(pair.iter().copied()).next() { if let Some(Ok(chr)) = char::decode_utf16(pair.iter().copied()).next() {
subclass_input.send_event(Event::WindowEvent { subclass_input.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
event: ReceivedCharacter(chr), event: ReceivedCharacter(chr),
@ -1048,11 +1050,14 @@ unsafe extern "system" fn public_window_callback<T>(
} }
} }
} else { } else {
let chr: char = mem::transmute(wparam as u32); subclass_input.window_state.lock().high_surrogate = None;
subclass_input.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), if let Some(chr) = char::from_u32(wparam as u32) {
event: ReceivedCharacter(chr), subclass_input.send_event(Event::WindowEvent {
}); window_id: RootWindowId(WindowId(window)),
event: ReceivedCharacter(chr),
});
}
} }
0 0
} }