Overhaul the keyboard API in winit to mimic the W3C specification
to achieve better crossplatform parity. The `KeyboardInput` event
is now uses `KeyEvent` which consists of:
- `physical_key` - a cross platform way to refer to scancodes;
- `logical_key` - keysym value, which shows your key respecting the
layout;
- `text` - the text produced by this keypress;
- `location` - the location of the key on the keyboard;
- `repeat` - whether the key was produced by the repeat.
And also a `platform_specific` field which encapsulates extra
information on desktop platforms, like key without modifiers
and text with all modifiers.
The `Modifiers` were also slightly reworked as in, the information
whether the left or right modifier is pressed is now also exposed
on platforms where it could be queried reliably. The support was
also added for the web and orbital platforms finishing the API
change.
This change made the `OptionAsAlt` API on macOS redundant thus it
was removed all together.
Co-authored-by: Artúr Kovács <kovacs.artur.barnabas@gmail.com>
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
Co-authored-by: daxpedda <daxpedda@gmail.com>
Fixes: #2631.
Fixes: #2055.
Fixes: #2032.
Fixes: #1904.
Fixes: #1810.
Fixes: #1700.
Fixes: #1443.
Fixes: #1343.
Fixes: #1208.
Fixes: #1151.
Fixes: #812.
Fixes: #600.
Fixes: #361.
Fixes: #343.
67 lines
2.1 KiB
Rust
67 lines
2.1 KiB
Rust
use std::sync::{
|
|
atomic::{AtomicBool, Ordering::Relaxed},
|
|
Mutex,
|
|
};
|
|
|
|
use winapi::{
|
|
shared::{
|
|
minwindef::{LPARAM, WPARAM},
|
|
windef::HWND,
|
|
},
|
|
um::winuser,
|
|
};
|
|
|
|
use crate::platform_impl::platform::{event_loop::ProcResult, keyboard::next_kbd_msg};
|
|
|
|
pub struct MinimalIme {
|
|
// True if we're currently receiving messages belonging to a finished IME session.
|
|
getting_ime_text: AtomicBool,
|
|
|
|
utf16parts: Mutex<Vec<u16>>,
|
|
}
|
|
impl Default for MinimalIme {
|
|
fn default() -> Self {
|
|
MinimalIme {
|
|
getting_ime_text: AtomicBool::new(false),
|
|
utf16parts: Mutex::new(Vec::with_capacity(16)),
|
|
}
|
|
}
|
|
}
|
|
impl MinimalIme {
|
|
pub(crate) fn process_message(
|
|
&self,
|
|
hwnd: HWND,
|
|
msg_kind: u32,
|
|
wparam: WPARAM,
|
|
_lparam: LPARAM,
|
|
result: &mut ProcResult,
|
|
) -> Option<String> {
|
|
match msg_kind {
|
|
winuser::WM_IME_ENDCOMPOSITION => {
|
|
self.getting_ime_text.store(true, Relaxed);
|
|
}
|
|
winuser::WM_CHAR | winuser::WM_SYSCHAR => {
|
|
if self.getting_ime_text.load(Relaxed) {
|
|
*result = ProcResult::Value(0);
|
|
self.utf16parts.lock().unwrap().push(wparam as u16);
|
|
// It's important that we push the new character and release the lock
|
|
// before getting the next message
|
|
let next_msg = next_kbd_msg(hwnd);
|
|
let more_char_coming = next_msg
|
|
.map(|m| matches!(m.message, winuser::WM_CHAR | winuser::WM_SYSCHAR))
|
|
.unwrap_or(false);
|
|
if !more_char_coming {
|
|
let mut utf16parts = self.utf16parts.lock().unwrap();
|
|
let result = String::from_utf16(&utf16parts).ok();
|
|
utf16parts.clear();
|
|
self.getting_ime_text.store(false, Relaxed);
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
_ => (),
|
|
}
|
|
|
|
None
|
|
}
|
|
}
|