diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f9cc8b7..8223ffac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,17 @@ jobs: - name: Check Formatting run: cargo fmt -- --check + docsrs: + name: Check building on docs.rs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@nightly + - name: Check Formatting + run: cargo doc --no-deps --features=rwh_04,rwh_05,rwh_06,serde,mint,android-native-activity + env: + RUSTDOCFLAGS: '--cfg=docsrs --deny=warnings' + tests: name: Test ${{ matrix.toolchain }} ${{ matrix.platform.name }} runs-on: ${{ matrix.platform.os }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 18f87ca2..eab253a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ Unreleased` header. - On Web, add the ability to toggle calling `Event.preventDefault()` on `Window`. - **Breaking:** Remove `WindowAttributes::fullscreen()` and expose as field directly. - **Breaking:** Rename `VideoMode` to `VideoModeHandle` to represent that it doesn't hold static data. +- **Breaking:** No longer export `platform::x11::XNotSupported`. +- **Breaking:** Renamed `platform::x11::XWindowType` to `platform::x11::WindowType`. # 0.29.8 diff --git a/Cargo.toml b/Cargo.toml index c20438db..b7628d7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ features = [ "rwh_05", "rwh_06", "serde", + "mint", # Enabled to get docs to compile "android-native-activity", ] diff --git a/src/lib.rs b/src/lib.rs index 78701c7a..99aa888a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -154,7 +154,11 @@ #![deny(unsafe_op_in_unsafe_fn)] #![cfg_attr(feature = "cargo-clippy", deny(warnings))] // Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc -#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr( + docsrs, + feature(doc_auto_cfg, doc_cfg_hide), + doc(cfg_hide(doc, docsrs)) +)] #![allow(clippy::missing_safety_doc)] #[cfg(feature = "rwh_06")] diff --git a/src/platform/android.rs b/src/platform/android.rs index b5fde4ad..88b24103 100644 --- a/src/platform/android.rs +++ b/src/platform/android.rs @@ -3,7 +3,7 @@ use crate::{ window::{Window, WindowBuilder}, }; -use android_activity::{AndroidApp, ConfigurationRef, Rect}; +use self::activity::{AndroidApp, ConfigurationRef, Rect}; /// Additional methods on [`EventLoop`] that are specific to Android. pub trait EventLoopExtAndroid {} @@ -89,5 +89,16 @@ pub mod activity { // feature enabled, so we avoid inlining it so that they're forced to view // it on the crate's own docs.rs page. #[doc(no_inline)] + #[cfg(android_platform)] pub use android_activity::*; + + #[cfg(not(android_platform))] + #[doc(hidden)] + pub struct Rect; + #[cfg(not(android_platform))] + #[doc(hidden)] + pub struct ConfigurationRef; + #[cfg(not(android_platform))] + #[doc(hidden)] + pub struct AndroidApp; } diff --git a/src/platform/ios.rs b/src/platform/ios.rs index 2cb07044..f0f83cba 100644 --- a/src/platform/ios.rs +++ b/src/platform/ios.rs @@ -1,8 +1,5 @@ use std::os::raw::c_void; -use icrate::Foundation::MainThreadMarker; -use objc2::rc::Id; - use crate::{ event_loop::EventLoop, monitor::{MonitorHandle, VideoModeHandle}, @@ -240,8 +237,8 @@ impl MonitorHandleExtIOS for MonitorHandle { #[inline] fn ui_screen(&self) -> *mut c_void { // SAFETY: The marker is only used to get the pointer of the screen - let mtm = unsafe { MainThreadMarker::new_unchecked() }; - Id::as_ptr(self.inner.ui_screen(mtm)) as *mut c_void + let mtm = unsafe { icrate::Foundation::MainThreadMarker::new_unchecked() }; + objc2::rc::Id::as_ptr(self.inner.ui_screen(mtm)) as *mut c_void } #[inline] diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 8a069611..b043f477 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -1,7 +1,5 @@ use std::os::raw::c_void; -use icrate::Foundation::MainThreadMarker; -use objc2::rc::Id; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -369,8 +367,10 @@ impl MonitorHandleExtMacOS for MonitorHandle { fn ns_screen(&self) -> Option<*mut c_void> { // SAFETY: We only use the marker to get a pointer - let mtm = unsafe { MainThreadMarker::new_unchecked() }; - self.inner.ns_screen(mtm).map(|s| Id::as_ptr(&s) as _) + let mtm = unsafe { icrate::Foundation::MainThreadMarker::new_unchecked() }; + self.inner + .ns_screen(mtm) + .map(|s| objc2::rc::Id::as_ptr(&s) as _) } } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index dbf1cbba..94dcec65 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,38 +1,24 @@ //! Contains traits with platform-specific methods in them. //! -//! Contains the follow OS-specific modules: -//! -//! - `android` -//! - `ios` -//! - `macos` -//! - `unix` -//! - `windows` -//! - `web` -//! -//! And the following platform-specific modules: -//! -//! - `run_on_demand` (available on `windows`, `unix`, `macos`, `android`) -//! - `pump_events` (available on `windows`, `unix`, `macos`, `android`) -//! -//! However only the module corresponding to the platform you're compiling to will be available. +//! Only the modules corresponding to the platform you're compiling to will be available. -#[cfg(android_platform)] +#[cfg(any(android_platform, docsrs))] pub mod android; -#[cfg(ios_platform)] +#[cfg(any(ios_platform, docsrs))] pub mod ios; -#[cfg(macos_platform)] +#[cfg(any(macos_platform, docsrs))] pub mod macos; -#[cfg(orbital_platform)] +#[cfg(any(orbital_platform, docsrs))] pub mod orbital; -#[cfg(any(x11_platform, wayland_platform))] +#[cfg(any(x11_platform, wayland_platform, docsrs))] pub mod startup_notify; -#[cfg(wayland_platform)] +#[cfg(any(wayland_platform, docsrs))] pub mod wayland; -#[cfg(wasm_platform)] +#[cfg(any(wasm_platform, docsrs))] pub mod web; -#[cfg(windows_platform)] +#[cfg(any(windows_platform, docsrs))] pub mod windows; -#[cfg(x11_platform)] +#[cfg(any(x11_platform, docsrs))] pub mod x11; #[cfg(any( @@ -40,7 +26,8 @@ pub mod x11; macos_platform, android_platform, x11_platform, - wayland_platform + wayland_platform, + docsrs, ))] pub mod run_on_demand; @@ -49,9 +36,25 @@ pub mod run_on_demand; macos_platform, android_platform, x11_platform, - wayland_platform + wayland_platform, + docsrs, ))] pub mod pump_events; +#[cfg(any( + windows_platform, + macos_platform, + x11_platform, + wayland_platform, + docsrs +))] pub mod modifier_supplement; + +#[cfg(any( + windows_platform, + macos_platform, + x11_platform, + wayland_platform, + docsrs +))] pub mod scancode; diff --git a/src/platform/modifier_supplement.rs b/src/platform/modifier_supplement.rs index 2b0302bf..651ba7f3 100644 --- a/src/platform/modifier_supplement.rs +++ b/src/platform/modifier_supplement.rs @@ -1,5 +1,4 @@ -#![cfg(any(windows_platform, macos_platform, x11_platform, wayland_platform))] - +use crate::event::KeyEvent; use crate::keyboard::Key; /// Additional methods for the `KeyEvent` which cannot be implemented on all @@ -22,3 +21,18 @@ pub trait KeyEventExtModifierSupplement { /// cannot be `Dead`. fn key_without_modifiers(&self) -> Key; } + +impl KeyEventExtModifierSupplement for KeyEvent { + #[inline] + fn text_with_all_modifiers(&self) -> Option<&str> { + self.platform_specific + .text_with_all_modifiers + .as_ref() + .map(|s| s.as_str()) + } + + #[inline] + fn key_without_modifiers(&self) -> Key { + self.platform_specific.key_without_modifiers.clone() + } +} diff --git a/src/platform/scancode.rs b/src/platform/scancode.rs index 1173d98b..35d101da 100644 --- a/src/platform/scancode.rs +++ b/src/platform/scancode.rs @@ -1,5 +1,3 @@ -#![cfg(any(windows_platform, macos_platform, x11_platform, wayland_platform))] - use crate::keyboard::{KeyCode, PhysicalKey}; // TODO: Describe what this value contains for each platform @@ -29,17 +27,24 @@ pub trait PhysicalKeyExtScancode { fn from_scancode(scancode: u32) -> PhysicalKey; } -impl PhysicalKeyExtScancode for KeyCode -where - PhysicalKey: PhysicalKeyExtScancode, -{ - #[inline] - fn from_scancode(scancode: u32) -> PhysicalKey { - ::from_scancode(scancode) +impl PhysicalKeyExtScancode for PhysicalKey { + fn to_scancode(self) -> Option { + crate::platform_impl::physicalkey_to_scancode(self) } + fn from_scancode(scancode: u32) -> PhysicalKey { + crate::platform_impl::scancode_to_physicalkey(scancode) + } +} + +impl PhysicalKeyExtScancode for KeyCode { #[inline] fn to_scancode(self) -> Option { ::to_scancode(PhysicalKey::Code(self)) } + + #[inline] + fn from_scancode(scancode: u32) -> PhysicalKey { + ::from_scancode(scancode) + } } diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index ba876518..b58d929d 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -4,8 +4,6 @@ use crate::{ window::{Window, WindowBuilder}, }; -use crate::platform_impl::{ApplicationName, Backend}; - pub use crate::window::Theme; /// Additional methods on [`EventLoopWindowTarget`] that are specific to Wayland. @@ -36,7 +34,7 @@ pub trait EventLoopBuilderExtWayland { impl EventLoopBuilderExtWayland for EventLoopBuilder { #[inline] fn with_wayland(&mut self) -> &mut Self { - self.platform_specific.forced_backend = Some(Backend::Wayland); + self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::Wayland); self } @@ -67,7 +65,10 @@ pub trait WindowBuilderExtWayland { impl WindowBuilderExtWayland for WindowBuilder { #[inline] fn with_name(mut self, general: impl Into, instance: impl Into) -> Self { - self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into())); + self.platform_specific.name = Some(crate::platform_impl::ApplicationName::new( + general.into(), + instance.into(), + )); self } } diff --git a/src/platform/web.rs b/src/platform/web.rs index baab78cf..f24eb512 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -35,8 +35,13 @@ use crate::platform_impl::PlatformCustomCursorBuilder; use crate::window::CustomCursor; use crate::window::{Window, WindowBuilder}; +#[cfg(wasm_platform)] use web_sys::HtmlCanvasElement; +#[cfg(not(wasm_platform))] +#[doc(hidden)] +pub struct HtmlCanvasElement; + pub trait WindowExtWebSys { /// Only returns the canvas if called from inside the window context (the /// main thread). @@ -80,6 +85,11 @@ pub trait WindowBuilderExtWebSys { /// In any case, the canvas won't be automatically inserted into the web page. /// /// [`None`] by default. + #[cfg_attr( + not(wasm_platform), + doc = "", + doc = "[`HtmlCanvasElement`]: #only-available-on-wasm" + )] fn with_canvas(self, canvas: Option) -> Self; /// Sets whether `event.preventDefault()` should be called on events on the diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 8e101579..e59946f1 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -2,12 +2,9 @@ use std::{ffi::c_void, path::Path}; use crate::{ dpi::PhysicalSize, - event::{DeviceId, KeyEvent}, + event::DeviceId, event_loop::EventLoopBuilder, - keyboard::Key, monitor::MonitorHandle, - platform::modifier_supplement::KeyEventExtModifierSupplement, - platform_impl::WinIcon, window::{BadIcon, Icon, Window, WindowBuilder}, }; @@ -185,7 +182,14 @@ pub trait WindowBuilderExtWindows { /// Note: Dark mode cannot be supported for win32 menus, it's simply not possible to change how the menus look. /// If you use this, it is recommended that you combine it with `with_theme(Some(Theme::Light))` to avoid a jarring effect. /// - /// [`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu + #[cfg_attr( + platform_windows, + doc = "[`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu" + )] + #[cfg_attr( + not(platform_windows), + doc = "[`CreateMenu`]: #only-available-on-windows" + )] fn with_menu(self, menu: HMENU) -> Self; /// This sets `ICON_BIG`. A good ceiling here is 256x256. @@ -328,27 +332,12 @@ impl IconExtWindows for Icon { path: P, size: Option>, ) -> Result { - let win_icon = WinIcon::from_path(path, size)?; + let win_icon = crate::platform_impl::WinIcon::from_path(path, size)?; Ok(Icon { inner: win_icon }) } fn from_resource(ordinal: u16, size: Option>) -> Result { - let win_icon = WinIcon::from_resource(ordinal, size)?; + let win_icon = crate::platform_impl::WinIcon::from_resource(ordinal, size)?; Ok(Icon { inner: win_icon }) } } - -impl KeyEventExtModifierSupplement for KeyEvent { - #[inline] - fn text_with_all_modifiers(&self) -> Option<&str> { - self.platform_specific - .text_with_all_modifers - .as_ref() - .map(|s| s.as_str()) - } - - #[inline] - fn key_without_modifiers(&self) -> Key { - self.platform_specific.key_without_modifiers.clone() - } -} diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 5cbd2fe3..c481e937 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + use crate::{ event_loop::{EventLoopBuilder, EventLoopWindowTarget}, monitor::MonitorHandle, @@ -5,9 +8,50 @@ use crate::{ }; use crate::dpi::Size; -use crate::platform_impl::{ApplicationName, Backend, XLIB_ERROR_HOOKS}; -pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported}; +/// X window type. Maps directly to +/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html). +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum WindowType { + /// A desktop feature. This can include a single window containing desktop icons with the same dimensions as the + /// screen, allowing the desktop environment to have full control of the desktop, without the need for proxying + /// root window clicks. + Desktop, + /// A dock or panel feature. Typically a Window Manager would keep such windows on top of all other windows. + Dock, + /// Toolbar windows. "Torn off" from the main application. + Toolbar, + /// Pinnable menu windows. "Torn off" from the main application. + Menu, + /// A small persistent utility window, such as a palette or toolbox. + Utility, + /// The window is a splash screen displayed as an application is starting up. + Splash, + /// This is a dialog window. + Dialog, + /// A dropdown menu that usually appears when the user clicks on an item in a menu bar. + /// This property is typically used on override-redirect windows. + DropdownMenu, + /// A popup menu that usually appears when the user right clicks on an object. + /// This property is typically used on override-redirect windows. + PopupMenu, + /// A tooltip window. Usually used to show additional information when hovering over an object with the cursor. + /// This property is typically used on override-redirect windows. + Tooltip, + /// The window is a notification. + /// This property is typically used on override-redirect windows. + Notification, + /// This should be used on the windows that are popped up by combo boxes. + /// This property is typically used on override-redirect windows. + Combo, + /// This indicates the the window is being dragged. + /// This property is typically used on override-redirect windows. + Dnd, + /// This is a normal, top-level window. + #[default] + Normal, +} /// The first argument in the provided hook will be the pointer to `XDisplay` /// and the second one the pointer to [`XErrorEvent`]. The returned `bool` is an @@ -38,7 +82,10 @@ pub type XWindow = u32; pub fn register_xlib_error_hook(hook: XlibErrorHook) { // Append new hook. unsafe { - XLIB_ERROR_HOOKS.lock().unwrap().push(hook); + crate::platform_impl::XLIB_ERROR_HOOKS + .lock() + .unwrap() + .push(hook); } } @@ -70,7 +117,7 @@ pub trait EventLoopBuilderExtX11 { impl EventLoopBuilderExtX11 for EventLoopBuilder { #[inline] fn with_x11(&mut self) -> &mut Self { - self.platform_specific.forced_backend = Some(Backend::X); + self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::X); self } @@ -102,13 +149,13 @@ pub trait WindowBuilderExtX11 { /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id) fn with_name(self, general: impl Into, instance: impl Into) -> Self; - /// Build window with override-redirect flag; defaults to false. Only relevant on X11. + /// Build window with override-redirect flag; defaults to false. fn with_override_redirect(self, override_redirect: bool) -> Self; - /// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. Only relevant on X11. - fn with_x11_window_type(self, x11_window_type: Vec) -> Self; + /// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. + fn with_x11_window_type(self, x11_window_type: Vec) -> Self; - /// Build window with base size hint. Only implemented on X11. + /// Build window with base size hint. /// /// ``` /// # use winit::dpi::{LogicalSize, PhysicalSize}; @@ -155,7 +202,10 @@ impl WindowBuilderExtX11 for WindowBuilder { #[inline] fn with_name(mut self, general: impl Into, instance: impl Into) -> Self { - self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into())); + self.platform_specific.name = Some(crate::platform_impl::ApplicationName::new( + general.into(), + instance.into(), + )); self } @@ -166,7 +216,7 @@ impl WindowBuilderExtX11 for WindowBuilder { } #[inline] - fn with_x11_window_type(mut self, x11_window_types: Vec) -> Self { + fn with_x11_window_type(mut self, x11_window_types: Vec) -> Self { self.platform_specific.x11.x11_window_types = x11_window_types; self } diff --git a/src/platform_impl/linux/common/keymap.rs b/src/platform_impl/linux/common/keymap.rs index fa9c496e..2fc3979b 100644 --- a/src/platform_impl/linux/common/keymap.rs +++ b/src/platform_impl/linux/common/keymap.rs @@ -6,13 +6,13 @@ use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyC /// /// X11-style keycodes are offset by 8 from the keycodes the Linux kernel uses. pub fn raw_keycode_to_physicalkey(keycode: u32) -> PhysicalKey { - scancode_to_keycode(keycode.saturating_sub(8)) + scancode_to_physicalkey(keycode.saturating_sub(8)) } /// Map the linux scancode to Keycode. /// /// Both X11 and Wayland use keys with `+ 8` offset to linux scancode. -pub fn scancode_to_keycode(scancode: u32) -> PhysicalKey { +pub fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey { // The keycode values are taken from linux/include/uapi/linux/input-event-codes.h, as // libxkbcommon's documentation seems to suggest that the keycode values we're interested in // are defined by the Linux kernel. If Winit programs end up being run on other Unix-likes, diff --git a/src/platform_impl/linux/common/xkb_state.rs b/src/platform_impl/linux/common/xkb_state.rs index 83abd79e..1f926b3c 100644 --- a/src/platform_impl/linux/common/xkb_state.rs +++ b/src/platform_impl/linux/common/xkb_state.rs @@ -398,8 +398,8 @@ impl KbdState { let text_with_all_modifiers = event.text_with_all_modifiers(); let platform_specific = KeyEventExtra { - key_without_modifiers, text_with_all_modifiers, + key_without_modifiers, }; KeyEvent { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 6a68fab0..7f310fb4 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -15,41 +15,36 @@ use once_cell::sync::Lazy; use smol_str::SmolStr; #[cfg(x11_platform)] -use crate::platform::x11::XlibErrorHook; +use self::x11::{X11Error, XConnection, XError, XNotSupported}; +#[cfg(x11_platform)] +use crate::platform::x11::{WindowType as XWindowType, XlibErrorHook}; use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError}, - event::KeyEvent, event_loop::{ AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW, }, icon::Icon, - keyboard::{Key, PhysicalKey}, - platform::{ - modifier_supplement::KeyEventExtModifierSupplement, pump_events::PumpStatus, - scancode::PhysicalKeyExtScancode, - }, + keyboard::Key, + platform::pump_events::PumpStatus, window::{ ActivationToken, Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes, WindowButtons, WindowLevel, }, }; -#[cfg(x11_platform)] -pub use x11::XNotSupported; -#[cfg(x11_platform)] -use x11::{util::WindowType as XWindowType, X11Error, XConnection, XError}; +pub(crate) use self::common::keymap::{physicalkey_to_scancode, scancode_to_physicalkey}; pub(crate) use crate::cursor::OnlyCursorImage as PlatformCustomCursor; pub(crate) use crate::cursor::OnlyCursorImageBuilder as PlatformCustomCursorBuilder; pub(crate) use crate::icon::RgbaIcon as PlatformIcon; pub(crate) use crate::platform_impl::Fullscreen; -pub mod common; +pub(crate) mod common; #[cfg(wayland_platform)] -pub mod wayland; +pub(crate) mod wayland; #[cfg(x11_platform)] -pub mod x11; +pub(crate) mod x11; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub(crate) enum Backend { @@ -640,33 +635,8 @@ impl Window { #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct KeyEventExtra { - pub key_without_modifiers: Key, pub text_with_all_modifiers: Option, -} - -impl KeyEventExtModifierSupplement for KeyEvent { - #[inline] - fn text_with_all_modifiers(&self) -> Option<&str> { - self.platform_specific - .text_with_all_modifiers - .as_ref() - .map(|s| s.as_str()) - } - - #[inline] - fn key_without_modifiers(&self) -> Key { - self.platform_specific.key_without_modifiers.clone() - } -} - -impl PhysicalKeyExtScancode for PhysicalKey { - fn from_scancode(scancode: u32) -> PhysicalKey { - common::keymap::scancode_to_keycode(scancode) - } - - fn to_scancode(self) -> Option { - common::keymap::physicalkey_to_scancode(self) - } + pub key_without_modifiers: Key, } /// Hooks for X11 errors. diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 29e7ba81..395668c3 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -14,11 +14,9 @@ mod xdisplay; pub(crate) use self::{ monitor::{MonitorHandle, VideoModeHandle}, window::UnownedWindow, - xdisplay::XConnection, + xdisplay::{XConnection, XError, XNotSupported}, }; -pub use self::xdisplay::{XError, XNotSupported}; - use calloop::generic::Generic; use calloop::EventLoop as Loop; use calloop::{ping::Ping, Readiness}; diff --git a/src/platform_impl/linux/x11/util/hint.rs b/src/platform_impl/linux/x11/util/hint.rs index d8c2bb95..ae95ea12 100644 --- a/src/platform_impl/linux/x11/util/hint.rs +++ b/src/platform_impl/linux/x11/util/hint.rs @@ -1,8 +1,6 @@ +use crate::platform::x11::WindowType; use std::sync::Arc; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - use super::*; #[derive(Debug)] @@ -23,50 +21,6 @@ impl From for StateOperation { } } -/// X window type. Maps directly to -/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html). -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum WindowType { - /// A desktop feature. This can include a single window containing desktop icons with the same dimensions as the - /// screen, allowing the desktop environment to have full control of the desktop, without the need for proxying - /// root window clicks. - Desktop, - /// A dock or panel feature. Typically a Window Manager would keep such windows on top of all other windows. - Dock, - /// Toolbar windows. "Torn off" from the main application. - Toolbar, - /// Pinnable menu windows. "Torn off" from the main application. - Menu, - /// A small persistent utility window, such as a palette or toolbox. - Utility, - /// The window is a splash screen displayed as an application is starting up. - Splash, - /// This is a dialog window. - Dialog, - /// A dropdown menu that usually appears when the user clicks on an item in a menu bar. - /// This property is typically used on override-redirect windows. - DropdownMenu, - /// A popup menu that usually appears when the user right clicks on an object. - /// This property is typically used on override-redirect windows. - PopupMenu, - /// A tooltip window. Usually used to show additional information when hovering over an object with the cursor. - /// This property is typically used on override-redirect windows. - Tooltip, - /// The window is a notification. - /// This property is typically used on override-redirect windows. - Notification, - /// This should be used on the windows that are popped up by combo boxes. - /// This property is typically used on override-redirect windows. - Combo, - /// This indicates the the window is being dragged. - /// This property is typically used on override-redirect windows. - Dnd, - /// This is a normal, top-level window. - #[default] - Normal, -} - impl WindowType { pub(crate) fn as_atom(&self, xconn: &Arc) -> xproto::Atom { use self::WindowType::*; diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 3bbac07e..ddf96542 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -26,6 +26,7 @@ use crate::{ error::{ExternalError, NotSupportedError, OsError as RootOsError}, event::{Event, InnerSizeWriter, WindowEvent}, event_loop::AsyncRequestSerial, + platform::x11::WindowType, platform_impl::{ x11::{ atoms::*, xinput_fp1616_to_float, MonitorHandle as X11MonitorHandle, WakeSender, @@ -635,10 +636,7 @@ impl UnownedWindow { flusher.map(Some) } - fn set_window_types( - &self, - window_types: Vec, - ) -> Result, X11Error> { + fn set_window_types(&self, window_types: Vec) -> Result, X11Error> { let atoms = self.xconn.atoms(); let hint_atom = atoms[_NET_WM_WINDOW_TYPE]; let atoms: Vec<_> = window_types diff --git a/src/platform_impl/linux/x11/xdisplay.rs b/src/platform_impl/linux/x11/xdisplay.rs index 02fb5ecd..718e5e17 100644 --- a/src/platform_impl/linux/x11/xdisplay.rs +++ b/src/platform_impl/linux/x11/xdisplay.rs @@ -260,7 +260,7 @@ impl fmt::Display for XError { /// Error returned if this system doesn't have XLib or can't create an X connection. #[derive(Clone, Debug)] -pub enum XNotSupported { +pub(crate) enum XNotSupported { /// Failed to load one or several shared libraries. LibraryOpenError(ffi::OpenError), diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index e2c18385..b4124ee0 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -19,9 +19,6 @@ use crate::{ Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode, PhysicalKey, }, - platform::{ - modifier_supplement::KeyEventExtModifierSupplement, scancode::PhysicalKeyExtScancode, - }, platform_impl::platform::ffi, }; @@ -31,19 +28,6 @@ pub struct KeyEventExtra { pub key_without_modifiers: Key, } -impl KeyEventExtModifierSupplement for KeyEvent { - fn text_with_all_modifiers(&self) -> Option<&str> { - self.platform_specific - .text_with_all_modifiers - .as_ref() - .map(|s| s.as_str()) - } - - fn key_without_modifiers(&self) -> Key { - self.platform_specific.key_without_modifiers.clone() - } -} - pub fn get_modifierless_char(scancode: u16) -> Key { let mut string = [0; 16]; let input_source; @@ -127,8 +111,7 @@ pub(crate) fn create_key_event( let state = if is_press { Pressed } else { Released }; let scancode = unsafe { ns_event.keyCode() }; - let mut physical_key = - key_override.unwrap_or_else(|| PhysicalKey::from_scancode(scancode as u32)); + let mut physical_key = key_override.unwrap_or_else(|| scancode_to_physicalkey(scancode as u32)); let text_with_all_modifiers: Option = if key_override.is_some() { None @@ -189,8 +172,8 @@ pub(crate) fn create_key_event( state, text, platform_specific: KeyEventExtra { - key_without_modifiers, text_with_all_modifiers, + key_without_modifiers, }, } } @@ -415,268 +398,266 @@ pub(super) fn dummy_event() -> Option> { } } -impl PhysicalKeyExtScancode for PhysicalKey { - fn to_scancode(self) -> Option { - let code = match self { - PhysicalKey::Code(code) => code, - PhysicalKey::Unidentified(_) => return None, - }; +pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option { + let code = match physical_key { + PhysicalKey::Code(code) => code, + PhysicalKey::Unidentified(_) => return None, + }; - match code { - KeyCode::KeyA => Some(0x00), - KeyCode::KeyS => Some(0x01), - KeyCode::KeyD => Some(0x02), - KeyCode::KeyF => Some(0x03), - KeyCode::KeyH => Some(0x04), - KeyCode::KeyG => Some(0x05), - KeyCode::KeyZ => Some(0x06), - KeyCode::KeyX => Some(0x07), - KeyCode::KeyC => Some(0x08), - KeyCode::KeyV => Some(0x09), - KeyCode::KeyB => Some(0x0b), - KeyCode::KeyQ => Some(0x0c), - KeyCode::KeyW => Some(0x0d), - KeyCode::KeyE => Some(0x0e), - KeyCode::KeyR => Some(0x0f), - KeyCode::KeyY => Some(0x10), - KeyCode::KeyT => Some(0x11), - KeyCode::Digit1 => Some(0x12), - KeyCode::Digit2 => Some(0x13), - KeyCode::Digit3 => Some(0x14), - KeyCode::Digit4 => Some(0x15), - KeyCode::Digit6 => Some(0x16), - KeyCode::Digit5 => Some(0x17), - KeyCode::Equal => Some(0x18), - KeyCode::Digit9 => Some(0x19), - KeyCode::Digit7 => Some(0x1a), - KeyCode::Minus => Some(0x1b), - KeyCode::Digit8 => Some(0x1c), - KeyCode::Digit0 => Some(0x1d), - KeyCode::BracketRight => Some(0x1e), - KeyCode::KeyO => Some(0x1f), - KeyCode::KeyU => Some(0x20), - KeyCode::BracketLeft => Some(0x21), - KeyCode::KeyI => Some(0x22), - KeyCode::KeyP => Some(0x23), - KeyCode::Enter => Some(0x24), - KeyCode::KeyL => Some(0x25), - KeyCode::KeyJ => Some(0x26), - KeyCode::Quote => Some(0x27), - KeyCode::KeyK => Some(0x28), - KeyCode::Semicolon => Some(0x29), - KeyCode::Backslash => Some(0x2a), - KeyCode::Comma => Some(0x2b), - KeyCode::Slash => Some(0x2c), - KeyCode::KeyN => Some(0x2d), - KeyCode::KeyM => Some(0x2e), - KeyCode::Period => Some(0x2f), - KeyCode::Tab => Some(0x30), - KeyCode::Space => Some(0x31), - KeyCode::Backquote => Some(0x32), - KeyCode::Backspace => Some(0x33), - KeyCode::Escape => Some(0x35), - KeyCode::SuperRight => Some(0x36), - KeyCode::SuperLeft => Some(0x37), - KeyCode::ShiftLeft => Some(0x38), - KeyCode::AltLeft => Some(0x3a), - KeyCode::ControlLeft => Some(0x3b), - KeyCode::ShiftRight => Some(0x3c), - KeyCode::AltRight => Some(0x3d), - KeyCode::ControlRight => Some(0x3e), - KeyCode::F17 => Some(0x40), - KeyCode::NumpadDecimal => Some(0x41), - KeyCode::NumpadMultiply => Some(0x43), - KeyCode::NumpadAdd => Some(0x45), - KeyCode::NumLock => Some(0x47), - KeyCode::AudioVolumeUp => Some(0x49), - KeyCode::AudioVolumeDown => Some(0x4a), - KeyCode::NumpadDivide => Some(0x4b), - KeyCode::NumpadEnter => Some(0x4c), - KeyCode::NumpadSubtract => Some(0x4e), - KeyCode::F18 => Some(0x4f), - KeyCode::F19 => Some(0x50), - KeyCode::NumpadEqual => Some(0x51), - KeyCode::Numpad0 => Some(0x52), - KeyCode::Numpad1 => Some(0x53), - KeyCode::Numpad2 => Some(0x54), - KeyCode::Numpad3 => Some(0x55), - KeyCode::Numpad4 => Some(0x56), - KeyCode::Numpad5 => Some(0x57), - KeyCode::Numpad6 => Some(0x58), - KeyCode::Numpad7 => Some(0x59), - KeyCode::F20 => Some(0x5a), - KeyCode::Numpad8 => Some(0x5b), - KeyCode::Numpad9 => Some(0x5c), - KeyCode::IntlYen => Some(0x5d), - KeyCode::F5 => Some(0x60), - KeyCode::F6 => Some(0x61), - KeyCode::F7 => Some(0x62), - KeyCode::F3 => Some(0x63), - KeyCode::F8 => Some(0x64), - KeyCode::F9 => Some(0x65), - KeyCode::F11 => Some(0x67), - KeyCode::F13 => Some(0x69), - KeyCode::F16 => Some(0x6a), - KeyCode::F14 => Some(0x6b), - KeyCode::F10 => Some(0x6d), - KeyCode::F12 => Some(0x6f), - KeyCode::F15 => Some(0x71), - KeyCode::Insert => Some(0x72), - KeyCode::Home => Some(0x73), - KeyCode::PageUp => Some(0x74), - KeyCode::Delete => Some(0x75), - KeyCode::F4 => Some(0x76), - KeyCode::End => Some(0x77), - KeyCode::F2 => Some(0x78), - KeyCode::PageDown => Some(0x79), - KeyCode::F1 => Some(0x7a), - KeyCode::ArrowLeft => Some(0x7b), - KeyCode::ArrowRight => Some(0x7c), - KeyCode::ArrowDown => Some(0x7d), - KeyCode::ArrowUp => Some(0x7e), - _ => None, - } - } - - fn from_scancode(scancode: u32) -> PhysicalKey { - PhysicalKey::Code(match scancode { - 0x00 => KeyCode::KeyA, - 0x01 => KeyCode::KeyS, - 0x02 => KeyCode::KeyD, - 0x03 => KeyCode::KeyF, - 0x04 => KeyCode::KeyH, - 0x05 => KeyCode::KeyG, - 0x06 => KeyCode::KeyZ, - 0x07 => KeyCode::KeyX, - 0x08 => KeyCode::KeyC, - 0x09 => KeyCode::KeyV, - //0x0a => World 1, - 0x0b => KeyCode::KeyB, - 0x0c => KeyCode::KeyQ, - 0x0d => KeyCode::KeyW, - 0x0e => KeyCode::KeyE, - 0x0f => KeyCode::KeyR, - 0x10 => KeyCode::KeyY, - 0x11 => KeyCode::KeyT, - 0x12 => KeyCode::Digit1, - 0x13 => KeyCode::Digit2, - 0x14 => KeyCode::Digit3, - 0x15 => KeyCode::Digit4, - 0x16 => KeyCode::Digit6, - 0x17 => KeyCode::Digit5, - 0x18 => KeyCode::Equal, - 0x19 => KeyCode::Digit9, - 0x1a => KeyCode::Digit7, - 0x1b => KeyCode::Minus, - 0x1c => KeyCode::Digit8, - 0x1d => KeyCode::Digit0, - 0x1e => KeyCode::BracketRight, - 0x1f => KeyCode::KeyO, - 0x20 => KeyCode::KeyU, - 0x21 => KeyCode::BracketLeft, - 0x22 => KeyCode::KeyI, - 0x23 => KeyCode::KeyP, - 0x24 => KeyCode::Enter, - 0x25 => KeyCode::KeyL, - 0x26 => KeyCode::KeyJ, - 0x27 => KeyCode::Quote, - 0x28 => KeyCode::KeyK, - 0x29 => KeyCode::Semicolon, - 0x2a => KeyCode::Backslash, - 0x2b => KeyCode::Comma, - 0x2c => KeyCode::Slash, - 0x2d => KeyCode::KeyN, - 0x2e => KeyCode::KeyM, - 0x2f => KeyCode::Period, - 0x30 => KeyCode::Tab, - 0x31 => KeyCode::Space, - 0x32 => KeyCode::Backquote, - 0x33 => KeyCode::Backspace, - //0x34 => unknown, - 0x35 => KeyCode::Escape, - 0x36 => KeyCode::SuperRight, - 0x37 => KeyCode::SuperLeft, - 0x38 => KeyCode::ShiftLeft, - 0x39 => KeyCode::CapsLock, - 0x3a => KeyCode::AltLeft, - 0x3b => KeyCode::ControlLeft, - 0x3c => KeyCode::ShiftRight, - 0x3d => KeyCode::AltRight, - 0x3e => KeyCode::ControlRight, - 0x3f => KeyCode::Fn, - 0x40 => KeyCode::F17, - 0x41 => KeyCode::NumpadDecimal, - //0x42 -> unknown, - 0x43 => KeyCode::NumpadMultiply, - //0x44 => unknown, - 0x45 => KeyCode::NumpadAdd, - //0x46 => unknown, - 0x47 => KeyCode::NumLock, - //0x48 => KeyCode::NumpadClear, - - // TODO: (Artur) for me, kVK_VolumeUp is 0x48 - // macOS 10.11 - // /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h - 0x49 => KeyCode::AudioVolumeUp, - 0x4a => KeyCode::AudioVolumeDown, - 0x4b => KeyCode::NumpadDivide, - 0x4c => KeyCode::NumpadEnter, - //0x4d => unknown, - 0x4e => KeyCode::NumpadSubtract, - 0x4f => KeyCode::F18, - 0x50 => KeyCode::F19, - 0x51 => KeyCode::NumpadEqual, - 0x52 => KeyCode::Numpad0, - 0x53 => KeyCode::Numpad1, - 0x54 => KeyCode::Numpad2, - 0x55 => KeyCode::Numpad3, - 0x56 => KeyCode::Numpad4, - 0x57 => KeyCode::Numpad5, - 0x58 => KeyCode::Numpad6, - 0x59 => KeyCode::Numpad7, - 0x5a => KeyCode::F20, - 0x5b => KeyCode::Numpad8, - 0x5c => KeyCode::Numpad9, - 0x5d => KeyCode::IntlYen, - //0x5e => JIS Ro, - //0x5f => unknown, - 0x60 => KeyCode::F5, - 0x61 => KeyCode::F6, - 0x62 => KeyCode::F7, - 0x63 => KeyCode::F3, - 0x64 => KeyCode::F8, - 0x65 => KeyCode::F9, - //0x66 => JIS Eisuu (macOS), - 0x67 => KeyCode::F11, - //0x68 => JIS Kanna (macOS), - 0x69 => KeyCode::F13, - 0x6a => KeyCode::F16, - 0x6b => KeyCode::F14, - //0x6c => unknown, - 0x6d => KeyCode::F10, - //0x6e => unknown, - 0x6f => KeyCode::F12, - //0x70 => unknown, - 0x71 => KeyCode::F15, - 0x72 => KeyCode::Insert, - 0x73 => KeyCode::Home, - 0x74 => KeyCode::PageUp, - 0x75 => KeyCode::Delete, - 0x76 => KeyCode::F4, - 0x77 => KeyCode::End, - 0x78 => KeyCode::F2, - 0x79 => KeyCode::PageDown, - 0x7a => KeyCode::F1, - 0x7b => KeyCode::ArrowLeft, - 0x7c => KeyCode::ArrowRight, - 0x7d => KeyCode::ArrowDown, - 0x7e => KeyCode::ArrowUp, - //0x7f => unknown, - - // 0xA is the caret (^) an macOS's German QERTZ layout. This key is at the same location as - // backquote (`) on Windows' US layout. - 0xa => KeyCode::Backquote, - _ => return PhysicalKey::Unidentified(NativeKeyCode::MacOS(scancode as u16)), - }) + match code { + KeyCode::KeyA => Some(0x00), + KeyCode::KeyS => Some(0x01), + KeyCode::KeyD => Some(0x02), + KeyCode::KeyF => Some(0x03), + KeyCode::KeyH => Some(0x04), + KeyCode::KeyG => Some(0x05), + KeyCode::KeyZ => Some(0x06), + KeyCode::KeyX => Some(0x07), + KeyCode::KeyC => Some(0x08), + KeyCode::KeyV => Some(0x09), + KeyCode::KeyB => Some(0x0b), + KeyCode::KeyQ => Some(0x0c), + KeyCode::KeyW => Some(0x0d), + KeyCode::KeyE => Some(0x0e), + KeyCode::KeyR => Some(0x0f), + KeyCode::KeyY => Some(0x10), + KeyCode::KeyT => Some(0x11), + KeyCode::Digit1 => Some(0x12), + KeyCode::Digit2 => Some(0x13), + KeyCode::Digit3 => Some(0x14), + KeyCode::Digit4 => Some(0x15), + KeyCode::Digit6 => Some(0x16), + KeyCode::Digit5 => Some(0x17), + KeyCode::Equal => Some(0x18), + KeyCode::Digit9 => Some(0x19), + KeyCode::Digit7 => Some(0x1a), + KeyCode::Minus => Some(0x1b), + KeyCode::Digit8 => Some(0x1c), + KeyCode::Digit0 => Some(0x1d), + KeyCode::BracketRight => Some(0x1e), + KeyCode::KeyO => Some(0x1f), + KeyCode::KeyU => Some(0x20), + KeyCode::BracketLeft => Some(0x21), + KeyCode::KeyI => Some(0x22), + KeyCode::KeyP => Some(0x23), + KeyCode::Enter => Some(0x24), + KeyCode::KeyL => Some(0x25), + KeyCode::KeyJ => Some(0x26), + KeyCode::Quote => Some(0x27), + KeyCode::KeyK => Some(0x28), + KeyCode::Semicolon => Some(0x29), + KeyCode::Backslash => Some(0x2a), + KeyCode::Comma => Some(0x2b), + KeyCode::Slash => Some(0x2c), + KeyCode::KeyN => Some(0x2d), + KeyCode::KeyM => Some(0x2e), + KeyCode::Period => Some(0x2f), + KeyCode::Tab => Some(0x30), + KeyCode::Space => Some(0x31), + KeyCode::Backquote => Some(0x32), + KeyCode::Backspace => Some(0x33), + KeyCode::Escape => Some(0x35), + KeyCode::SuperRight => Some(0x36), + KeyCode::SuperLeft => Some(0x37), + KeyCode::ShiftLeft => Some(0x38), + KeyCode::AltLeft => Some(0x3a), + KeyCode::ControlLeft => Some(0x3b), + KeyCode::ShiftRight => Some(0x3c), + KeyCode::AltRight => Some(0x3d), + KeyCode::ControlRight => Some(0x3e), + KeyCode::F17 => Some(0x40), + KeyCode::NumpadDecimal => Some(0x41), + KeyCode::NumpadMultiply => Some(0x43), + KeyCode::NumpadAdd => Some(0x45), + KeyCode::NumLock => Some(0x47), + KeyCode::AudioVolumeUp => Some(0x49), + KeyCode::AudioVolumeDown => Some(0x4a), + KeyCode::NumpadDivide => Some(0x4b), + KeyCode::NumpadEnter => Some(0x4c), + KeyCode::NumpadSubtract => Some(0x4e), + KeyCode::F18 => Some(0x4f), + KeyCode::F19 => Some(0x50), + KeyCode::NumpadEqual => Some(0x51), + KeyCode::Numpad0 => Some(0x52), + KeyCode::Numpad1 => Some(0x53), + KeyCode::Numpad2 => Some(0x54), + KeyCode::Numpad3 => Some(0x55), + KeyCode::Numpad4 => Some(0x56), + KeyCode::Numpad5 => Some(0x57), + KeyCode::Numpad6 => Some(0x58), + KeyCode::Numpad7 => Some(0x59), + KeyCode::F20 => Some(0x5a), + KeyCode::Numpad8 => Some(0x5b), + KeyCode::Numpad9 => Some(0x5c), + KeyCode::IntlYen => Some(0x5d), + KeyCode::F5 => Some(0x60), + KeyCode::F6 => Some(0x61), + KeyCode::F7 => Some(0x62), + KeyCode::F3 => Some(0x63), + KeyCode::F8 => Some(0x64), + KeyCode::F9 => Some(0x65), + KeyCode::F11 => Some(0x67), + KeyCode::F13 => Some(0x69), + KeyCode::F16 => Some(0x6a), + KeyCode::F14 => Some(0x6b), + KeyCode::F10 => Some(0x6d), + KeyCode::F12 => Some(0x6f), + KeyCode::F15 => Some(0x71), + KeyCode::Insert => Some(0x72), + KeyCode::Home => Some(0x73), + KeyCode::PageUp => Some(0x74), + KeyCode::Delete => Some(0x75), + KeyCode::F4 => Some(0x76), + KeyCode::End => Some(0x77), + KeyCode::F2 => Some(0x78), + KeyCode::PageDown => Some(0x79), + KeyCode::F1 => Some(0x7a), + KeyCode::ArrowLeft => Some(0x7b), + KeyCode::ArrowRight => Some(0x7c), + KeyCode::ArrowDown => Some(0x7d), + KeyCode::ArrowUp => Some(0x7e), + _ => None, } } + +pub(crate) fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey { + PhysicalKey::Code(match scancode { + 0x00 => KeyCode::KeyA, + 0x01 => KeyCode::KeyS, + 0x02 => KeyCode::KeyD, + 0x03 => KeyCode::KeyF, + 0x04 => KeyCode::KeyH, + 0x05 => KeyCode::KeyG, + 0x06 => KeyCode::KeyZ, + 0x07 => KeyCode::KeyX, + 0x08 => KeyCode::KeyC, + 0x09 => KeyCode::KeyV, + //0x0a => World 1, + 0x0b => KeyCode::KeyB, + 0x0c => KeyCode::KeyQ, + 0x0d => KeyCode::KeyW, + 0x0e => KeyCode::KeyE, + 0x0f => KeyCode::KeyR, + 0x10 => KeyCode::KeyY, + 0x11 => KeyCode::KeyT, + 0x12 => KeyCode::Digit1, + 0x13 => KeyCode::Digit2, + 0x14 => KeyCode::Digit3, + 0x15 => KeyCode::Digit4, + 0x16 => KeyCode::Digit6, + 0x17 => KeyCode::Digit5, + 0x18 => KeyCode::Equal, + 0x19 => KeyCode::Digit9, + 0x1a => KeyCode::Digit7, + 0x1b => KeyCode::Minus, + 0x1c => KeyCode::Digit8, + 0x1d => KeyCode::Digit0, + 0x1e => KeyCode::BracketRight, + 0x1f => KeyCode::KeyO, + 0x20 => KeyCode::KeyU, + 0x21 => KeyCode::BracketLeft, + 0x22 => KeyCode::KeyI, + 0x23 => KeyCode::KeyP, + 0x24 => KeyCode::Enter, + 0x25 => KeyCode::KeyL, + 0x26 => KeyCode::KeyJ, + 0x27 => KeyCode::Quote, + 0x28 => KeyCode::KeyK, + 0x29 => KeyCode::Semicolon, + 0x2a => KeyCode::Backslash, + 0x2b => KeyCode::Comma, + 0x2c => KeyCode::Slash, + 0x2d => KeyCode::KeyN, + 0x2e => KeyCode::KeyM, + 0x2f => KeyCode::Period, + 0x30 => KeyCode::Tab, + 0x31 => KeyCode::Space, + 0x32 => KeyCode::Backquote, + 0x33 => KeyCode::Backspace, + //0x34 => unknown, + 0x35 => KeyCode::Escape, + 0x36 => KeyCode::SuperRight, + 0x37 => KeyCode::SuperLeft, + 0x38 => KeyCode::ShiftLeft, + 0x39 => KeyCode::CapsLock, + 0x3a => KeyCode::AltLeft, + 0x3b => KeyCode::ControlLeft, + 0x3c => KeyCode::ShiftRight, + 0x3d => KeyCode::AltRight, + 0x3e => KeyCode::ControlRight, + 0x3f => KeyCode::Fn, + 0x40 => KeyCode::F17, + 0x41 => KeyCode::NumpadDecimal, + //0x42 -> unknown, + 0x43 => KeyCode::NumpadMultiply, + //0x44 => unknown, + 0x45 => KeyCode::NumpadAdd, + //0x46 => unknown, + 0x47 => KeyCode::NumLock, + //0x48 => KeyCode::NumpadClear, + + // TODO: (Artur) for me, kVK_VolumeUp is 0x48 + // macOS 10.11 + // /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h + 0x49 => KeyCode::AudioVolumeUp, + 0x4a => KeyCode::AudioVolumeDown, + 0x4b => KeyCode::NumpadDivide, + 0x4c => KeyCode::NumpadEnter, + //0x4d => unknown, + 0x4e => KeyCode::NumpadSubtract, + 0x4f => KeyCode::F18, + 0x50 => KeyCode::F19, + 0x51 => KeyCode::NumpadEqual, + 0x52 => KeyCode::Numpad0, + 0x53 => KeyCode::Numpad1, + 0x54 => KeyCode::Numpad2, + 0x55 => KeyCode::Numpad3, + 0x56 => KeyCode::Numpad4, + 0x57 => KeyCode::Numpad5, + 0x58 => KeyCode::Numpad6, + 0x59 => KeyCode::Numpad7, + 0x5a => KeyCode::F20, + 0x5b => KeyCode::Numpad8, + 0x5c => KeyCode::Numpad9, + 0x5d => KeyCode::IntlYen, + //0x5e => JIS Ro, + //0x5f => unknown, + 0x60 => KeyCode::F5, + 0x61 => KeyCode::F6, + 0x62 => KeyCode::F7, + 0x63 => KeyCode::F3, + 0x64 => KeyCode::F8, + 0x65 => KeyCode::F9, + //0x66 => JIS Eisuu (macOS), + 0x67 => KeyCode::F11, + //0x68 => JIS Kanna (macOS), + 0x69 => KeyCode::F13, + 0x6a => KeyCode::F16, + 0x6b => KeyCode::F14, + //0x6c => unknown, + 0x6d => KeyCode::F10, + //0x6e => unknown, + 0x6f => KeyCode::F12, + //0x70 => unknown, + 0x71 => KeyCode::F15, + 0x72 => KeyCode::Insert, + 0x73 => KeyCode::Home, + 0x74 => KeyCode::PageUp, + 0x75 => KeyCode::Delete, + 0x76 => KeyCode::F4, + 0x77 => KeyCode::End, + 0x78 => KeyCode::F2, + 0x79 => KeyCode::PageDown, + 0x7a => KeyCode::F1, + 0x7b => KeyCode::ArrowLeft, + 0x7c => KeyCode::ArrowRight, + 0x7d => KeyCode::ArrowDown, + 0x7e => KeyCode::ArrowUp, + //0x7f => unknown, + + // 0xA is the caret (^) an macOS's German QERTZ layout. This key is at the same location as + // backquote (`) on Windows' US layout. + 0xa => KeyCode::Backquote, + _ => return PhysicalKey::Unidentified(NativeKeyCode::MacOS(scancode as u16)), + }) +} diff --git a/src/platform_impl/macos/mod.rs b/src/platform_impl/macos/mod.rs index 8dbc981e..13cd8d27 100644 --- a/src/platform_impl/macos/mod.rs +++ b/src/platform_impl/macos/mod.rs @@ -18,7 +18,7 @@ mod window_delegate; use std::fmt; pub(crate) use self::{ - event::KeyEventExtra, + event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra}, event_loop::{ EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, }, diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index e1a86e36..585950e7 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -22,15 +22,15 @@ use objc2::{ use super::cursor::{default_cursor, invisible_cursor}; use super::event::{code_to_key, code_to_location}; use super::event::{lalt_pressed, ralt_pressed}; +use crate::platform_impl::scancode_to_physicalkey; use crate::{ dpi::{LogicalPosition, LogicalSize}, event::{ DeviceEvent, ElementState, Event, Ime, Modifiers, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent, }, - keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey, PhysicalKey}, + keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey}, platform::macos::{OptionAsAlt, WindowExtMacOS}, - platform::scancode::PhysicalKeyExtScancode, platform_impl::platform::{ app_state::AppState, event::{create_key_event, event_mods}, @@ -915,7 +915,7 @@ impl WinitView { 'send_event: { if is_flags_changed_event && unsafe { ns_event.keyCode() } != 0 { let scancode = unsafe { ns_event.keyCode() }; - let physical_key = PhysicalKey::from_scancode(scancode as u32); + let physical_key = scancode_to_physicalkey(scancode as u32); // We'll correct the `is_press` later. let mut event = create_key_event(ns_event, false, false, Some(physical_key)); diff --git a/src/platform_impl/windows/keyboard.rs b/src/platform_impl/windows/keyboard.rs index 6a63f343..05d108ea 100644 --- a/src/platform_impl/windows/keyboard.rs +++ b/src/platform_impl/windows/keyboard.rs @@ -39,7 +39,6 @@ use unicode_segmentation::UnicodeSegmentation; use crate::{ event::{ElementState, KeyEvent}, keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyCode, PhysicalKey}, - platform::scancode::PhysicalKeyExtScancode, platform_impl::platform::{ event_loop::ProcResult, keyboard_layout::{Layout, LayoutCache, WindowsModifiers, LAYOUT_CACHE}, @@ -455,7 +454,7 @@ impl KeyEventBuilder { return None; } let scancode = scancode as ExScancode; - let physical_key = PhysicalKey::from_scancode(scancode as u32); + let physical_key = scancode_to_physicalkey(scancode as u32); let mods = if caps_lock_on { WindowsModifiers::CAPS_LOCK } else { @@ -484,7 +483,7 @@ impl KeyEventBuilder { let mut event = event_info.finalize(); event.logical_key = logical_key; - event.platform_specific.text_with_all_modifers = text; + event.platform_specific.text_with_all_modifiers = text; Some(MessageAsKeyEvent { event, is_synthetic: true, @@ -545,7 +544,7 @@ impl PartialKeyEventInfo { } else { new_ex_scancode(lparam_struct.scancode, lparam_struct.extended) }; - let physical_key = PhysicalKey::from_scancode(scancode as u32); + let physical_key = scancode_to_physicalkey(scancode as u32); let location = get_location(scancode, layout.hkl as HKL); let kbd_state = get_kbd_state(); @@ -666,7 +665,7 @@ impl PartialKeyEventInfo { state: self.key_state, repeat: self.is_repeat, platform_specific: KeyEventExtra { - text_with_all_modifers: char_with_all_modifiers, + text_with_all_modifiers: char_with_all_modifiers, key_without_modifiers: self.key_without_modifiers, }, } @@ -943,345 +942,343 @@ fn get_location(scancode: ExScancode, hkl: HKL) -> KeyLocation { } } -impl PhysicalKeyExtScancode for PhysicalKey { - fn to_scancode(self) -> Option { - // See `from_scancode` for more info +pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option { + // See `scancode_to_physicalkey` for more info - let hkl = unsafe { GetKeyboardLayout(0) }; + let hkl = unsafe { GetKeyboardLayout(0) }; - let primary_lang_id = primarylangid(loword(hkl as u32)); - let is_korean = primary_lang_id as u32 == LANG_KOREAN; + let primary_lang_id = primarylangid(loword(hkl as u32)); + let is_korean = primary_lang_id as u32 == LANG_KOREAN; - let code = match self { - PhysicalKey::Code(code) => code, - PhysicalKey::Unidentified(code) => { - return match code { - NativeKeyCode::Windows(scancode) => Some(scancode as u32), - _ => None, - }; - } - }; - - match code { - KeyCode::Backquote => Some(0x0029), - KeyCode::Backslash => Some(0x002B), - KeyCode::Backspace => Some(0x000E), - KeyCode::BracketLeft => Some(0x001A), - KeyCode::BracketRight => Some(0x001B), - KeyCode::Comma => Some(0x0033), - KeyCode::Digit0 => Some(0x000B), - KeyCode::Digit1 => Some(0x0002), - KeyCode::Digit2 => Some(0x0003), - KeyCode::Digit3 => Some(0x0004), - KeyCode::Digit4 => Some(0x0005), - KeyCode::Digit5 => Some(0x0006), - KeyCode::Digit6 => Some(0x0007), - KeyCode::Digit7 => Some(0x0008), - KeyCode::Digit8 => Some(0x0009), - KeyCode::Digit9 => Some(0x000A), - KeyCode::Equal => Some(0x000D), - KeyCode::IntlBackslash => Some(0x0056), - KeyCode::IntlRo => Some(0x0073), - KeyCode::IntlYen => Some(0x007D), - KeyCode::KeyA => Some(0x001E), - KeyCode::KeyB => Some(0x0030), - KeyCode::KeyC => Some(0x002E), - KeyCode::KeyD => Some(0x0020), - KeyCode::KeyE => Some(0x0012), - KeyCode::KeyF => Some(0x0021), - KeyCode::KeyG => Some(0x0022), - KeyCode::KeyH => Some(0x0023), - KeyCode::KeyI => Some(0x0017), - KeyCode::KeyJ => Some(0x0024), - KeyCode::KeyK => Some(0x0025), - KeyCode::KeyL => Some(0x0026), - KeyCode::KeyM => Some(0x0032), - KeyCode::KeyN => Some(0x0031), - KeyCode::KeyO => Some(0x0018), - KeyCode::KeyP => Some(0x0019), - KeyCode::KeyQ => Some(0x0010), - KeyCode::KeyR => Some(0x0013), - KeyCode::KeyS => Some(0x001F), - KeyCode::KeyT => Some(0x0014), - KeyCode::KeyU => Some(0x0016), - KeyCode::KeyV => Some(0x002F), - KeyCode::KeyW => Some(0x0011), - KeyCode::KeyX => Some(0x002D), - KeyCode::KeyY => Some(0x0015), - KeyCode::KeyZ => Some(0x002C), - KeyCode::Minus => Some(0x000C), - KeyCode::Period => Some(0x0034), - KeyCode::Quote => Some(0x0028), - KeyCode::Semicolon => Some(0x0027), - KeyCode::Slash => Some(0x0035), - KeyCode::AltLeft => Some(0x0038), - KeyCode::AltRight => Some(0xE038), - KeyCode::CapsLock => Some(0x003A), - KeyCode::ContextMenu => Some(0xE05D), - KeyCode::ControlLeft => Some(0x001D), - KeyCode::ControlRight => Some(0xE01D), - KeyCode::Enter => Some(0x001C), - KeyCode::SuperLeft => Some(0xE05B), - KeyCode::SuperRight => Some(0xE05C), - KeyCode::ShiftLeft => Some(0x002A), - KeyCode::ShiftRight => Some(0x0036), - KeyCode::Space => Some(0x0039), - KeyCode::Tab => Some(0x000F), - KeyCode::Convert => Some(0x0079), - KeyCode::Lang1 => { - if is_korean { - Some(0xE0F2) - } else { - Some(0x0072) - } - } - KeyCode::Lang2 => { - if is_korean { - Some(0xE0F1) - } else { - Some(0x0071) - } - } - KeyCode::KanaMode => Some(0x0070), - KeyCode::NonConvert => Some(0x007B), - KeyCode::Delete => Some(0xE053), - KeyCode::End => Some(0xE04F), - KeyCode::Home => Some(0xE047), - KeyCode::Insert => Some(0xE052), - KeyCode::PageDown => Some(0xE051), - KeyCode::PageUp => Some(0xE049), - KeyCode::ArrowDown => Some(0xE050), - KeyCode::ArrowLeft => Some(0xE04B), - KeyCode::ArrowRight => Some(0xE04D), - KeyCode::ArrowUp => Some(0xE048), - KeyCode::NumLock => Some(0xE045), - KeyCode::Numpad0 => Some(0x0052), - KeyCode::Numpad1 => Some(0x004F), - KeyCode::Numpad2 => Some(0x0050), - KeyCode::Numpad3 => Some(0x0051), - KeyCode::Numpad4 => Some(0x004B), - KeyCode::Numpad5 => Some(0x004C), - KeyCode::Numpad6 => Some(0x004D), - KeyCode::Numpad7 => Some(0x0047), - KeyCode::Numpad8 => Some(0x0048), - KeyCode::Numpad9 => Some(0x0049), - KeyCode::NumpadAdd => Some(0x004E), - KeyCode::NumpadComma => Some(0x007E), - KeyCode::NumpadDecimal => Some(0x0053), - KeyCode::NumpadDivide => Some(0xE035), - KeyCode::NumpadEnter => Some(0xE01C), - KeyCode::NumpadEqual => Some(0x0059), - KeyCode::NumpadMultiply => Some(0x0037), - KeyCode::NumpadSubtract => Some(0x004A), - KeyCode::Escape => Some(0x0001), - KeyCode::F1 => Some(0x003B), - KeyCode::F2 => Some(0x003C), - KeyCode::F3 => Some(0x003D), - KeyCode::F4 => Some(0x003E), - KeyCode::F5 => Some(0x003F), - KeyCode::F6 => Some(0x0040), - KeyCode::F7 => Some(0x0041), - KeyCode::F8 => Some(0x0042), - KeyCode::F9 => Some(0x0043), - KeyCode::F10 => Some(0x0044), - KeyCode::F11 => Some(0x0057), - KeyCode::F12 => Some(0x0058), - KeyCode::F13 => Some(0x0064), - KeyCode::F14 => Some(0x0065), - KeyCode::F15 => Some(0x0066), - KeyCode::F16 => Some(0x0067), - KeyCode::F17 => Some(0x0068), - KeyCode::F18 => Some(0x0069), - KeyCode::F19 => Some(0x006A), - KeyCode::F20 => Some(0x006B), - KeyCode::F21 => Some(0x006C), - KeyCode::F22 => Some(0x006D), - KeyCode::F23 => Some(0x006E), - KeyCode::F24 => Some(0x0076), - KeyCode::PrintScreen => Some(0xE037), - //KeyCode::PrintScreen => Some(0x0054), // Alt + PrintScreen - KeyCode::ScrollLock => Some(0x0046), - KeyCode::Pause => Some(0x0045), - //KeyCode::Pause => Some(0xE046), // Ctrl + Pause - KeyCode::BrowserBack => Some(0xE06A), - KeyCode::BrowserFavorites => Some(0xE066), - KeyCode::BrowserForward => Some(0xE069), - KeyCode::BrowserHome => Some(0xE032), - KeyCode::BrowserRefresh => Some(0xE067), - KeyCode::BrowserSearch => Some(0xE065), - KeyCode::BrowserStop => Some(0xE068), - KeyCode::LaunchApp1 => Some(0xE06B), - KeyCode::LaunchApp2 => Some(0xE021), - KeyCode::LaunchMail => Some(0xE06C), - KeyCode::MediaPlayPause => Some(0xE022), - KeyCode::MediaSelect => Some(0xE06D), - KeyCode::MediaStop => Some(0xE024), - KeyCode::MediaTrackNext => Some(0xE019), - KeyCode::MediaTrackPrevious => Some(0xE010), - KeyCode::Power => Some(0xE05E), - KeyCode::AudioVolumeDown => Some(0xE02E), - KeyCode::AudioVolumeMute => Some(0xE020), - KeyCode::AudioVolumeUp => Some(0xE030), - _ => None, + let code = match physical_key { + PhysicalKey::Code(code) => code, + PhysicalKey::Unidentified(code) => { + return match code { + NativeKeyCode::Windows(scancode) => Some(scancode as u32), + _ => None, + }; } - } + }; - fn from_scancode(scancode: u32) -> PhysicalKey { - // See: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html - // and: https://www.w3.org/TR/uievents-code/ - // and: The widget/NativeKeyToDOMCodeName.h file in the firefox source - - PhysicalKey::Code(match scancode { - 0x0029 => KeyCode::Backquote, - 0x002B => KeyCode::Backslash, - 0x000E => KeyCode::Backspace, - 0x001A => KeyCode::BracketLeft, - 0x001B => KeyCode::BracketRight, - 0x0033 => KeyCode::Comma, - 0x000B => KeyCode::Digit0, - 0x0002 => KeyCode::Digit1, - 0x0003 => KeyCode::Digit2, - 0x0004 => KeyCode::Digit3, - 0x0005 => KeyCode::Digit4, - 0x0006 => KeyCode::Digit5, - 0x0007 => KeyCode::Digit6, - 0x0008 => KeyCode::Digit7, - 0x0009 => KeyCode::Digit8, - 0x000A => KeyCode::Digit9, - 0x000D => KeyCode::Equal, - 0x0056 => KeyCode::IntlBackslash, - 0x0073 => KeyCode::IntlRo, - 0x007D => KeyCode::IntlYen, - 0x001E => KeyCode::KeyA, - 0x0030 => KeyCode::KeyB, - 0x002E => KeyCode::KeyC, - 0x0020 => KeyCode::KeyD, - 0x0012 => KeyCode::KeyE, - 0x0021 => KeyCode::KeyF, - 0x0022 => KeyCode::KeyG, - 0x0023 => KeyCode::KeyH, - 0x0017 => KeyCode::KeyI, - 0x0024 => KeyCode::KeyJ, - 0x0025 => KeyCode::KeyK, - 0x0026 => KeyCode::KeyL, - 0x0032 => KeyCode::KeyM, - 0x0031 => KeyCode::KeyN, - 0x0018 => KeyCode::KeyO, - 0x0019 => KeyCode::KeyP, - 0x0010 => KeyCode::KeyQ, - 0x0013 => KeyCode::KeyR, - 0x001F => KeyCode::KeyS, - 0x0014 => KeyCode::KeyT, - 0x0016 => KeyCode::KeyU, - 0x002F => KeyCode::KeyV, - 0x0011 => KeyCode::KeyW, - 0x002D => KeyCode::KeyX, - 0x0015 => KeyCode::KeyY, - 0x002C => KeyCode::KeyZ, - 0x000C => KeyCode::Minus, - 0x0034 => KeyCode::Period, - 0x0028 => KeyCode::Quote, - 0x0027 => KeyCode::Semicolon, - 0x0035 => KeyCode::Slash, - 0x0038 => KeyCode::AltLeft, - 0xE038 => KeyCode::AltRight, - 0x003A => KeyCode::CapsLock, - 0xE05D => KeyCode::ContextMenu, - 0x001D => KeyCode::ControlLeft, - 0xE01D => KeyCode::ControlRight, - 0x001C => KeyCode::Enter, - 0xE05B => KeyCode::SuperLeft, - 0xE05C => KeyCode::SuperRight, - 0x002A => KeyCode::ShiftLeft, - 0x0036 => KeyCode::ShiftRight, - 0x0039 => KeyCode::Space, - 0x000F => KeyCode::Tab, - 0x0079 => KeyCode::Convert, - 0x0072 => KeyCode::Lang1, // for non-Korean layout - 0xE0F2 => KeyCode::Lang1, // for Korean layout - 0x0071 => KeyCode::Lang2, // for non-Korean layout - 0xE0F1 => KeyCode::Lang2, // for Korean layout - 0x0070 => KeyCode::KanaMode, - 0x007B => KeyCode::NonConvert, - 0xE053 => KeyCode::Delete, - 0xE04F => KeyCode::End, - 0xE047 => KeyCode::Home, - 0xE052 => KeyCode::Insert, - 0xE051 => KeyCode::PageDown, - 0xE049 => KeyCode::PageUp, - 0xE050 => KeyCode::ArrowDown, - 0xE04B => KeyCode::ArrowLeft, - 0xE04D => KeyCode::ArrowRight, - 0xE048 => KeyCode::ArrowUp, - 0xE045 => KeyCode::NumLock, - 0x0052 => KeyCode::Numpad0, - 0x004F => KeyCode::Numpad1, - 0x0050 => KeyCode::Numpad2, - 0x0051 => KeyCode::Numpad3, - 0x004B => KeyCode::Numpad4, - 0x004C => KeyCode::Numpad5, - 0x004D => KeyCode::Numpad6, - 0x0047 => KeyCode::Numpad7, - 0x0048 => KeyCode::Numpad8, - 0x0049 => KeyCode::Numpad9, - 0x004E => KeyCode::NumpadAdd, - 0x007E => KeyCode::NumpadComma, - 0x0053 => KeyCode::NumpadDecimal, - 0xE035 => KeyCode::NumpadDivide, - 0xE01C => KeyCode::NumpadEnter, - 0x0059 => KeyCode::NumpadEqual, - 0x0037 => KeyCode::NumpadMultiply, - 0x004A => KeyCode::NumpadSubtract, - 0x0001 => KeyCode::Escape, - 0x003B => KeyCode::F1, - 0x003C => KeyCode::F2, - 0x003D => KeyCode::F3, - 0x003E => KeyCode::F4, - 0x003F => KeyCode::F5, - 0x0040 => KeyCode::F6, - 0x0041 => KeyCode::F7, - 0x0042 => KeyCode::F8, - 0x0043 => KeyCode::F9, - 0x0044 => KeyCode::F10, - 0x0057 => KeyCode::F11, - 0x0058 => KeyCode::F12, - 0x0064 => KeyCode::F13, - 0x0065 => KeyCode::F14, - 0x0066 => KeyCode::F15, - 0x0067 => KeyCode::F16, - 0x0068 => KeyCode::F17, - 0x0069 => KeyCode::F18, - 0x006A => KeyCode::F19, - 0x006B => KeyCode::F20, - 0x006C => KeyCode::F21, - 0x006D => KeyCode::F22, - 0x006E => KeyCode::F23, - 0x0076 => KeyCode::F24, - 0xE037 => KeyCode::PrintScreen, - 0x0054 => KeyCode::PrintScreen, // Alt + PrintScreen - 0x0046 => KeyCode::ScrollLock, - 0x0045 => KeyCode::Pause, - 0xE046 => KeyCode::Pause, // Ctrl + Pause - 0xE06A => KeyCode::BrowserBack, - 0xE066 => KeyCode::BrowserFavorites, - 0xE069 => KeyCode::BrowserForward, - 0xE032 => KeyCode::BrowserHome, - 0xE067 => KeyCode::BrowserRefresh, - 0xE065 => KeyCode::BrowserSearch, - 0xE068 => KeyCode::BrowserStop, - 0xE06B => KeyCode::LaunchApp1, - 0xE021 => KeyCode::LaunchApp2, - 0xE06C => KeyCode::LaunchMail, - 0xE022 => KeyCode::MediaPlayPause, - 0xE06D => KeyCode::MediaSelect, - 0xE024 => KeyCode::MediaStop, - 0xE019 => KeyCode::MediaTrackNext, - 0xE010 => KeyCode::MediaTrackPrevious, - 0xE05E => KeyCode::Power, - 0xE02E => KeyCode::AudioVolumeDown, - 0xE020 => KeyCode::AudioVolumeMute, - 0xE030 => KeyCode::AudioVolumeUp, - _ => return PhysicalKey::Unidentified(NativeKeyCode::Windows(scancode as u16)), - }) + match code { + KeyCode::Backquote => Some(0x0029), + KeyCode::Backslash => Some(0x002B), + KeyCode::Backspace => Some(0x000E), + KeyCode::BracketLeft => Some(0x001A), + KeyCode::BracketRight => Some(0x001B), + KeyCode::Comma => Some(0x0033), + KeyCode::Digit0 => Some(0x000B), + KeyCode::Digit1 => Some(0x0002), + KeyCode::Digit2 => Some(0x0003), + KeyCode::Digit3 => Some(0x0004), + KeyCode::Digit4 => Some(0x0005), + KeyCode::Digit5 => Some(0x0006), + KeyCode::Digit6 => Some(0x0007), + KeyCode::Digit7 => Some(0x0008), + KeyCode::Digit8 => Some(0x0009), + KeyCode::Digit9 => Some(0x000A), + KeyCode::Equal => Some(0x000D), + KeyCode::IntlBackslash => Some(0x0056), + KeyCode::IntlRo => Some(0x0073), + KeyCode::IntlYen => Some(0x007D), + KeyCode::KeyA => Some(0x001E), + KeyCode::KeyB => Some(0x0030), + KeyCode::KeyC => Some(0x002E), + KeyCode::KeyD => Some(0x0020), + KeyCode::KeyE => Some(0x0012), + KeyCode::KeyF => Some(0x0021), + KeyCode::KeyG => Some(0x0022), + KeyCode::KeyH => Some(0x0023), + KeyCode::KeyI => Some(0x0017), + KeyCode::KeyJ => Some(0x0024), + KeyCode::KeyK => Some(0x0025), + KeyCode::KeyL => Some(0x0026), + KeyCode::KeyM => Some(0x0032), + KeyCode::KeyN => Some(0x0031), + KeyCode::KeyO => Some(0x0018), + KeyCode::KeyP => Some(0x0019), + KeyCode::KeyQ => Some(0x0010), + KeyCode::KeyR => Some(0x0013), + KeyCode::KeyS => Some(0x001F), + KeyCode::KeyT => Some(0x0014), + KeyCode::KeyU => Some(0x0016), + KeyCode::KeyV => Some(0x002F), + KeyCode::KeyW => Some(0x0011), + KeyCode::KeyX => Some(0x002D), + KeyCode::KeyY => Some(0x0015), + KeyCode::KeyZ => Some(0x002C), + KeyCode::Minus => Some(0x000C), + KeyCode::Period => Some(0x0034), + KeyCode::Quote => Some(0x0028), + KeyCode::Semicolon => Some(0x0027), + KeyCode::Slash => Some(0x0035), + KeyCode::AltLeft => Some(0x0038), + KeyCode::AltRight => Some(0xE038), + KeyCode::CapsLock => Some(0x003A), + KeyCode::ContextMenu => Some(0xE05D), + KeyCode::ControlLeft => Some(0x001D), + KeyCode::ControlRight => Some(0xE01D), + KeyCode::Enter => Some(0x001C), + KeyCode::SuperLeft => Some(0xE05B), + KeyCode::SuperRight => Some(0xE05C), + KeyCode::ShiftLeft => Some(0x002A), + KeyCode::ShiftRight => Some(0x0036), + KeyCode::Space => Some(0x0039), + KeyCode::Tab => Some(0x000F), + KeyCode::Convert => Some(0x0079), + KeyCode::Lang1 => { + if is_korean { + Some(0xE0F2) + } else { + Some(0x0072) + } + } + KeyCode::Lang2 => { + if is_korean { + Some(0xE0F1) + } else { + Some(0x0071) + } + } + KeyCode::KanaMode => Some(0x0070), + KeyCode::NonConvert => Some(0x007B), + KeyCode::Delete => Some(0xE053), + KeyCode::End => Some(0xE04F), + KeyCode::Home => Some(0xE047), + KeyCode::Insert => Some(0xE052), + KeyCode::PageDown => Some(0xE051), + KeyCode::PageUp => Some(0xE049), + KeyCode::ArrowDown => Some(0xE050), + KeyCode::ArrowLeft => Some(0xE04B), + KeyCode::ArrowRight => Some(0xE04D), + KeyCode::ArrowUp => Some(0xE048), + KeyCode::NumLock => Some(0xE045), + KeyCode::Numpad0 => Some(0x0052), + KeyCode::Numpad1 => Some(0x004F), + KeyCode::Numpad2 => Some(0x0050), + KeyCode::Numpad3 => Some(0x0051), + KeyCode::Numpad4 => Some(0x004B), + KeyCode::Numpad5 => Some(0x004C), + KeyCode::Numpad6 => Some(0x004D), + KeyCode::Numpad7 => Some(0x0047), + KeyCode::Numpad8 => Some(0x0048), + KeyCode::Numpad9 => Some(0x0049), + KeyCode::NumpadAdd => Some(0x004E), + KeyCode::NumpadComma => Some(0x007E), + KeyCode::NumpadDecimal => Some(0x0053), + KeyCode::NumpadDivide => Some(0xE035), + KeyCode::NumpadEnter => Some(0xE01C), + KeyCode::NumpadEqual => Some(0x0059), + KeyCode::NumpadMultiply => Some(0x0037), + KeyCode::NumpadSubtract => Some(0x004A), + KeyCode::Escape => Some(0x0001), + KeyCode::F1 => Some(0x003B), + KeyCode::F2 => Some(0x003C), + KeyCode::F3 => Some(0x003D), + KeyCode::F4 => Some(0x003E), + KeyCode::F5 => Some(0x003F), + KeyCode::F6 => Some(0x0040), + KeyCode::F7 => Some(0x0041), + KeyCode::F8 => Some(0x0042), + KeyCode::F9 => Some(0x0043), + KeyCode::F10 => Some(0x0044), + KeyCode::F11 => Some(0x0057), + KeyCode::F12 => Some(0x0058), + KeyCode::F13 => Some(0x0064), + KeyCode::F14 => Some(0x0065), + KeyCode::F15 => Some(0x0066), + KeyCode::F16 => Some(0x0067), + KeyCode::F17 => Some(0x0068), + KeyCode::F18 => Some(0x0069), + KeyCode::F19 => Some(0x006A), + KeyCode::F20 => Some(0x006B), + KeyCode::F21 => Some(0x006C), + KeyCode::F22 => Some(0x006D), + KeyCode::F23 => Some(0x006E), + KeyCode::F24 => Some(0x0076), + KeyCode::PrintScreen => Some(0xE037), + //KeyCode::PrintScreen => Some(0x0054), // Alt + PrintScreen + KeyCode::ScrollLock => Some(0x0046), + KeyCode::Pause => Some(0x0045), + //KeyCode::Pause => Some(0xE046), // Ctrl + Pause + KeyCode::BrowserBack => Some(0xE06A), + KeyCode::BrowserFavorites => Some(0xE066), + KeyCode::BrowserForward => Some(0xE069), + KeyCode::BrowserHome => Some(0xE032), + KeyCode::BrowserRefresh => Some(0xE067), + KeyCode::BrowserSearch => Some(0xE065), + KeyCode::BrowserStop => Some(0xE068), + KeyCode::LaunchApp1 => Some(0xE06B), + KeyCode::LaunchApp2 => Some(0xE021), + KeyCode::LaunchMail => Some(0xE06C), + KeyCode::MediaPlayPause => Some(0xE022), + KeyCode::MediaSelect => Some(0xE06D), + KeyCode::MediaStop => Some(0xE024), + KeyCode::MediaTrackNext => Some(0xE019), + KeyCode::MediaTrackPrevious => Some(0xE010), + KeyCode::Power => Some(0xE05E), + KeyCode::AudioVolumeDown => Some(0xE02E), + KeyCode::AudioVolumeMute => Some(0xE020), + KeyCode::AudioVolumeUp => Some(0xE030), + _ => None, } } + +pub(crate) fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey { + // See: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // and: https://www.w3.org/TR/uievents-code/ + // and: The widget/NativeKeyToDOMCodeName.h file in the firefox source + + PhysicalKey::Code(match scancode { + 0x0029 => KeyCode::Backquote, + 0x002B => KeyCode::Backslash, + 0x000E => KeyCode::Backspace, + 0x001A => KeyCode::BracketLeft, + 0x001B => KeyCode::BracketRight, + 0x0033 => KeyCode::Comma, + 0x000B => KeyCode::Digit0, + 0x0002 => KeyCode::Digit1, + 0x0003 => KeyCode::Digit2, + 0x0004 => KeyCode::Digit3, + 0x0005 => KeyCode::Digit4, + 0x0006 => KeyCode::Digit5, + 0x0007 => KeyCode::Digit6, + 0x0008 => KeyCode::Digit7, + 0x0009 => KeyCode::Digit8, + 0x000A => KeyCode::Digit9, + 0x000D => KeyCode::Equal, + 0x0056 => KeyCode::IntlBackslash, + 0x0073 => KeyCode::IntlRo, + 0x007D => KeyCode::IntlYen, + 0x001E => KeyCode::KeyA, + 0x0030 => KeyCode::KeyB, + 0x002E => KeyCode::KeyC, + 0x0020 => KeyCode::KeyD, + 0x0012 => KeyCode::KeyE, + 0x0021 => KeyCode::KeyF, + 0x0022 => KeyCode::KeyG, + 0x0023 => KeyCode::KeyH, + 0x0017 => KeyCode::KeyI, + 0x0024 => KeyCode::KeyJ, + 0x0025 => KeyCode::KeyK, + 0x0026 => KeyCode::KeyL, + 0x0032 => KeyCode::KeyM, + 0x0031 => KeyCode::KeyN, + 0x0018 => KeyCode::KeyO, + 0x0019 => KeyCode::KeyP, + 0x0010 => KeyCode::KeyQ, + 0x0013 => KeyCode::KeyR, + 0x001F => KeyCode::KeyS, + 0x0014 => KeyCode::KeyT, + 0x0016 => KeyCode::KeyU, + 0x002F => KeyCode::KeyV, + 0x0011 => KeyCode::KeyW, + 0x002D => KeyCode::KeyX, + 0x0015 => KeyCode::KeyY, + 0x002C => KeyCode::KeyZ, + 0x000C => KeyCode::Minus, + 0x0034 => KeyCode::Period, + 0x0028 => KeyCode::Quote, + 0x0027 => KeyCode::Semicolon, + 0x0035 => KeyCode::Slash, + 0x0038 => KeyCode::AltLeft, + 0xE038 => KeyCode::AltRight, + 0x003A => KeyCode::CapsLock, + 0xE05D => KeyCode::ContextMenu, + 0x001D => KeyCode::ControlLeft, + 0xE01D => KeyCode::ControlRight, + 0x001C => KeyCode::Enter, + 0xE05B => KeyCode::SuperLeft, + 0xE05C => KeyCode::SuperRight, + 0x002A => KeyCode::ShiftLeft, + 0x0036 => KeyCode::ShiftRight, + 0x0039 => KeyCode::Space, + 0x000F => KeyCode::Tab, + 0x0079 => KeyCode::Convert, + 0x0072 => KeyCode::Lang1, // for non-Korean layout + 0xE0F2 => KeyCode::Lang1, // for Korean layout + 0x0071 => KeyCode::Lang2, // for non-Korean layout + 0xE0F1 => KeyCode::Lang2, // for Korean layout + 0x0070 => KeyCode::KanaMode, + 0x007B => KeyCode::NonConvert, + 0xE053 => KeyCode::Delete, + 0xE04F => KeyCode::End, + 0xE047 => KeyCode::Home, + 0xE052 => KeyCode::Insert, + 0xE051 => KeyCode::PageDown, + 0xE049 => KeyCode::PageUp, + 0xE050 => KeyCode::ArrowDown, + 0xE04B => KeyCode::ArrowLeft, + 0xE04D => KeyCode::ArrowRight, + 0xE048 => KeyCode::ArrowUp, + 0xE045 => KeyCode::NumLock, + 0x0052 => KeyCode::Numpad0, + 0x004F => KeyCode::Numpad1, + 0x0050 => KeyCode::Numpad2, + 0x0051 => KeyCode::Numpad3, + 0x004B => KeyCode::Numpad4, + 0x004C => KeyCode::Numpad5, + 0x004D => KeyCode::Numpad6, + 0x0047 => KeyCode::Numpad7, + 0x0048 => KeyCode::Numpad8, + 0x0049 => KeyCode::Numpad9, + 0x004E => KeyCode::NumpadAdd, + 0x007E => KeyCode::NumpadComma, + 0x0053 => KeyCode::NumpadDecimal, + 0xE035 => KeyCode::NumpadDivide, + 0xE01C => KeyCode::NumpadEnter, + 0x0059 => KeyCode::NumpadEqual, + 0x0037 => KeyCode::NumpadMultiply, + 0x004A => KeyCode::NumpadSubtract, + 0x0001 => KeyCode::Escape, + 0x003B => KeyCode::F1, + 0x003C => KeyCode::F2, + 0x003D => KeyCode::F3, + 0x003E => KeyCode::F4, + 0x003F => KeyCode::F5, + 0x0040 => KeyCode::F6, + 0x0041 => KeyCode::F7, + 0x0042 => KeyCode::F8, + 0x0043 => KeyCode::F9, + 0x0044 => KeyCode::F10, + 0x0057 => KeyCode::F11, + 0x0058 => KeyCode::F12, + 0x0064 => KeyCode::F13, + 0x0065 => KeyCode::F14, + 0x0066 => KeyCode::F15, + 0x0067 => KeyCode::F16, + 0x0068 => KeyCode::F17, + 0x0069 => KeyCode::F18, + 0x006A => KeyCode::F19, + 0x006B => KeyCode::F20, + 0x006C => KeyCode::F21, + 0x006D => KeyCode::F22, + 0x006E => KeyCode::F23, + 0x0076 => KeyCode::F24, + 0xE037 => KeyCode::PrintScreen, + 0x0054 => KeyCode::PrintScreen, // Alt + PrintScreen + 0x0046 => KeyCode::ScrollLock, + 0x0045 => KeyCode::Pause, + 0xE046 => KeyCode::Pause, // Ctrl + Pause + 0xE06A => KeyCode::BrowserBack, + 0xE066 => KeyCode::BrowserFavorites, + 0xE069 => KeyCode::BrowserForward, + 0xE032 => KeyCode::BrowserHome, + 0xE067 => KeyCode::BrowserRefresh, + 0xE065 => KeyCode::BrowserSearch, + 0xE068 => KeyCode::BrowserStop, + 0xE06B => KeyCode::LaunchApp1, + 0xE021 => KeyCode::LaunchApp2, + 0xE06C => KeyCode::LaunchMail, + 0xE022 => KeyCode::MediaPlayPause, + 0xE06D => KeyCode::MediaSelect, + 0xE024 => KeyCode::MediaStop, + 0xE019 => KeyCode::MediaTrackNext, + 0xE010 => KeyCode::MediaTrackPrevious, + 0xE05E => KeyCode::Power, + 0xE02E => KeyCode::AudioVolumeDown, + 0xE020 => KeyCode::AudioVolumeMute, + 0xE030 => KeyCode::AudioVolumeUp, + _ => return PhysicalKey::Unidentified(NativeKeyCode::Windows(scancode as u16)), + }) +} diff --git a/src/platform_impl/windows/keyboard_layout.rs b/src/platform_impl/windows/keyboard_layout.rs index 1258fb05..a0fdb956 100644 --- a/src/platform_impl/windows/keyboard_layout.rs +++ b/src/platform_impl/windows/keyboard_layout.rs @@ -53,8 +53,7 @@ use windows_sys::Win32::{ use crate::{ keyboard::{Key, KeyCode, ModifiersState, NamedKey, NativeKey, PhysicalKey}, - platform::scancode::PhysicalKeyExtScancode, - platform_impl::{loword, primarylangid}, + platform_impl::{loword, primarylangid, scancode_to_physicalkey}, }; pub(crate) static LAYOUT_CACHE: Lazy> = @@ -336,7 +335,7 @@ impl LayoutCache { if scancode == 0 { continue; } - let keycode = match PhysicalKey::from_scancode(scancode) { + let keycode = match scancode_to_physicalkey(scancode) { PhysicalKey::Code(code) => code, // TODO: validate that we can skip on unidentified keys (probably never occurs?) _ => continue, @@ -388,7 +387,7 @@ impl LayoutCache { } let native_code = NativeKey::Windows(vk as VIRTUAL_KEY); - let key_code = match PhysicalKey::from_scancode(scancode) { + let key_code = match scancode_to_physicalkey(scancode) { PhysicalKey::Code(code) => code, // TODO: validate that we can skip on unidentified keys (probably never occurs?) _ => continue, diff --git a/src/platform_impl/windows/mod.rs b/src/platform_impl/windows/mod.rs index 6978f496..270a2f86 100644 --- a/src/platform_impl/windows/mod.rs +++ b/src/platform_impl/windows/mod.rs @@ -11,6 +11,7 @@ pub(crate) use self::{ EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, }, icon::{SelectedCursor, WinIcon}, + keyboard::{physicalkey_to_scancode, scancode_to_physicalkey}, monitor::{MonitorHandle, VideoModeHandle}, window::Window, }; @@ -90,7 +91,7 @@ pub type OsError = std::io::Error; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct KeyEventExtra { - pub text_with_all_modifers: Option, + pub text_with_all_modifiers: Option, pub key_without_modifiers: Key, } diff --git a/src/platform_impl/windows/raw_input.rs b/src/platform_impl/windows/raw_input.rs index 897b2a29..a53a9b67 100644 --- a/src/platform_impl/windows/raw_input.rs +++ b/src/platform_impl/windows/raw_input.rs @@ -27,11 +27,11 @@ use windows_sys::Win32::{ }, }; +use super::scancode_to_physicalkey; use crate::{ event::ElementState, event_loop::DeviceEvents, keyboard::{KeyCode, PhysicalKey}, - platform::scancode::PhysicalKeyExtScancode, platform_impl::platform::util, }; @@ -284,7 +284,7 @@ pub fn get_keyboard_physical_key(keyboard: RAWKEYBOARD) -> Option { // https://devblogs.microsoft.com/oldnewthing/20080211-00/?p=23503 PhysicalKey::Code(KeyCode::NumLock) } else { - PhysicalKey::from_scancode(scancode as u32) + scancode_to_physicalkey(scancode as u32) }; if keyboard.VKey == VK_SHIFT { if let PhysicalKey::Code(code) = physical_key {