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.
186 lines
4.4 KiB
Rust
186 lines
4.4 KiB
Rust
#![cfg(windows_platform)]
|
|
|
|
use smol_str::SmolStr;
|
|
use windows_sys::Win32::{
|
|
Foundation::{HANDLE, HWND},
|
|
UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX},
|
|
};
|
|
|
|
pub(crate) use self::{
|
|
event_loop::{
|
|
EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes,
|
|
},
|
|
icon::WinIcon,
|
|
monitor::{MonitorHandle, VideoMode},
|
|
window::Window,
|
|
};
|
|
|
|
pub use self::icon::WinIcon as PlatformIcon;
|
|
pub(self) use crate::platform_impl::Fullscreen;
|
|
|
|
use crate::event::DeviceId as RootDeviceId;
|
|
use crate::icon::Icon;
|
|
use crate::keyboard::Key;
|
|
|
|
#[derive(Clone)]
|
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
|
pub owner: Option<HWND>,
|
|
pub menu: Option<HMENU>,
|
|
pub taskbar_icon: Option<Icon>,
|
|
pub no_redirection_bitmap: bool,
|
|
pub drag_and_drop: bool,
|
|
pub skip_taskbar: bool,
|
|
pub decoration_shadow: bool,
|
|
}
|
|
|
|
impl Default for PlatformSpecificWindowBuilderAttributes {
|
|
fn default() -> Self {
|
|
Self {
|
|
owner: None,
|
|
menu: None,
|
|
taskbar_icon: None,
|
|
no_redirection_bitmap: false,
|
|
drag_and_drop: true,
|
|
skip_taskbar: false,
|
|
decoration_shadow: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
|
|
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}
|
|
|
|
// Cursor name in UTF-16. Used to set cursor in `WM_SETCURSOR`.
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Cursor(pub *const u16);
|
|
unsafe impl Send for Cursor {}
|
|
unsafe impl Sync for Cursor {}
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct DeviceId(u32);
|
|
|
|
impl DeviceId {
|
|
pub const unsafe fn dummy() -> Self {
|
|
DeviceId(0)
|
|
}
|
|
}
|
|
|
|
impl DeviceId {
|
|
pub fn persistent_identifier(&self) -> Option<String> {
|
|
if self.0 != 0 {
|
|
raw_input::get_raw_input_device_name(self.0 as HANDLE)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
// Constant device ID, to be removed when this backend is updated to report real device IDs.
|
|
const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId(0));
|
|
|
|
fn wrap_device_id(id: u32) -> RootDeviceId {
|
|
RootDeviceId(DeviceId(id))
|
|
}
|
|
|
|
pub type OsError = std::io::Error;
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
pub struct KeyEventExtra {
|
|
pub text_with_all_modifers: Option<SmolStr>,
|
|
pub key_without_modifiers: Key,
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct WindowId(HWND);
|
|
unsafe impl Send for WindowId {}
|
|
unsafe impl Sync for WindowId {}
|
|
|
|
impl WindowId {
|
|
pub const unsafe fn dummy() -> Self {
|
|
WindowId(0)
|
|
}
|
|
}
|
|
|
|
impl From<WindowId> for u64 {
|
|
fn from(window_id: WindowId) -> Self {
|
|
window_id.0 as u64
|
|
}
|
|
}
|
|
|
|
impl From<WindowId> for HWND {
|
|
fn from(window_id: WindowId) -> Self {
|
|
window_id.0
|
|
}
|
|
}
|
|
|
|
impl From<u64> for WindowId {
|
|
fn from(raw_id: u64) -> Self {
|
|
Self(raw_id as HWND)
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn get_xbutton_wparam(x: u32) -> u16 {
|
|
hiword(x)
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn get_x_lparam(x: u32) -> i16 {
|
|
loword(x) as _
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn get_y_lparam(x: u32) -> i16 {
|
|
hiword(x) as _
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) const fn primarylangid(lgid: u16) -> u16 {
|
|
lgid & 0x3FF
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub(crate) const fn loword(x: u32) -> u16 {
|
|
(x & 0xFFFF) as u16
|
|
}
|
|
|
|
#[inline(always)]
|
|
const fn hiword(x: u32) -> u16 {
|
|
((x >> 16) & 0xFFFF) as u16
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {
|
|
#[cfg(target_pointer_width = "64")]
|
|
return windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, nindex);
|
|
#[cfg(target_pointer_width = "32")]
|
|
return windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, nindex) as isize;
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn set_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX, dwnewlong: isize) -> isize {
|
|
#[cfg(target_pointer_width = "64")]
|
|
return windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, nindex, dwnewlong);
|
|
#[cfg(target_pointer_width = "32")]
|
|
return windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongW(
|
|
hwnd,
|
|
nindex,
|
|
dwnewlong as i32,
|
|
) as isize;
|
|
}
|
|
|
|
#[macro_use]
|
|
mod util;
|
|
mod dark_mode;
|
|
mod definitions;
|
|
mod dpi;
|
|
mod drop_handler;
|
|
mod event_loop;
|
|
mod icon;
|
|
mod ime;
|
|
mod keyboard;
|
|
mod keyboard_layout;
|
|
mod monitor;
|
|
mod raw_input;
|
|
mod window;
|
|
mod window_state;
|