Compare commits
17 Commits
v0.30.10
...
notgull/sp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d28c867b61 | ||
|
|
cfd35d2708 | ||
|
|
1b9c576f53 | ||
|
|
52532d2579 | ||
|
|
4b28f10470 | ||
|
|
daf1304879 | ||
|
|
c6e57430bb | ||
|
|
284f4c0558 | ||
|
|
859a6f109c | ||
|
|
a232f7bc77 | ||
|
|
48831f7910 | ||
|
|
114e6999d3 | ||
|
|
2f197315d9 | ||
|
|
557464489e | ||
|
|
623b3e5070 | ||
|
|
a97255e0fc | ||
|
|
3a817647d5 |
8
.github/workflows/ci.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
- { name: 'Linux 64bit', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, }
|
- { name: 'Linux 64bit', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, }
|
||||||
- { name: 'X11', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=x11' }
|
- { name: 'X11', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=x11' }
|
||||||
- { name: 'Wayland', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=wayland,wayland-dlopen' }
|
- { name: 'Wayland', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=wayland,wayland-dlopen' }
|
||||||
- { name: 'Android', target: aarch64-linux-android, os: ubuntu-latest, options: '--package=winit --features=android-native-activity', cmd: 'apk --' }
|
- { name: 'Android', target: aarch64-linux-android, os: ubuntu-latest, options: '--features=android-native-activity', cmd: 'apk --' }
|
||||||
- { name: 'Redox OS', target: x86_64-unknown-redox, os: ubuntu-latest, }
|
- { name: 'Redox OS', target: x86_64-unknown-redox, os: ubuntu-latest, }
|
||||||
- { name: 'macOS', target: x86_64-apple-darwin, os: macos-latest, }
|
- { name: 'macOS', target: x86_64-apple-darwin, os: macos-latest, }
|
||||||
- { name: 'iOS x86_64', target: x86_64-apple-ios, os: macos-latest, }
|
- { name: 'iOS x86_64', target: x86_64-apple-ios, os: macos-latest, }
|
||||||
@@ -125,13 +125,13 @@ jobs:
|
|||||||
RUSTDOCFLAGS: '--deny=warnings ${{ matrix.platform.rustflags }}'
|
RUSTDOCFLAGS: '--deny=warnings ${{ matrix.platform.rustflags }}'
|
||||||
|
|
||||||
- name: Build crate
|
- name: Build crate
|
||||||
run: cargo $CMD build $OPTIONS
|
run: cargo $CMD build -p winit $OPTIONS
|
||||||
|
|
||||||
- name: Build tests
|
- name: Build tests
|
||||||
if: >
|
if: >
|
||||||
!contains(matrix.platform.target, 'redox') &&
|
!contains(matrix.platform.target, 'redox') &&
|
||||||
matrix.toolchain != '1.70.0'
|
matrix.toolchain != '1.70.0'
|
||||||
run: cargo $CMD test --no-run $OPTIONS
|
run: cargo $CMD test -p winit --no-run $OPTIONS
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
if: >
|
if: >
|
||||||
@@ -150,7 +150,7 @@ jobs:
|
|||||||
if: >
|
if: >
|
||||||
!contains(matrix.platform.target, 'redox') &&
|
!contains(matrix.platform.target, 'redox') &&
|
||||||
matrix.toolchain != '1.70.0'
|
matrix.toolchain != '1.70.0'
|
||||||
run: cargo $CMD test --no-run $OPTIONS --features serde
|
run: cargo $CMD test --no-run $OPTIONS -p winit --features serde
|
||||||
|
|
||||||
- name: Run tests with serde enabled
|
- name: Run tests with serde enabled
|
||||||
if: >
|
if: >
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ Unreleased` header.
|
|||||||
- On Wayland, fix `Window::set_{min,max}_inner_size` not always applied.
|
- On Wayland, fix `Window::set_{min,max}_inner_size` not always applied.
|
||||||
- On Windows, fix inconsistent resizing behavior with multi-monitor setups when repositioning outside the event loop.
|
- On Windows, fix inconsistent resizing behavior with multi-monitor setups when repositioning outside the event loop.
|
||||||
- On Wayland, fix `WAYLAND_SOCKET` not used when detecting platform.
|
- On Wayland, fix `WAYLAND_SOCKET` not used when detecting platform.
|
||||||
|
- **Breaking:** Move some types to the `winit-core` crate. Most types are
|
||||||
|
re-exported verbatim; however:
|
||||||
|
- `Event`, `WindowEvent` and `KeyEvent` now take a generic that `winit`
|
||||||
|
implements.
|
||||||
|
- `ActivationToken` and `InnerSizeWriter` expose new methods to make them
|
||||||
|
useful.
|
||||||
|
- `InnerSizeWriter::request_inner_size` returns an `InnerSizeIgnored` error
|
||||||
|
instead of an `ExternalError`.
|
||||||
|
|
||||||
# 0.29.10
|
# 0.29.10
|
||||||
|
|
||||||
|
|||||||
271
Cargo.toml
@@ -1,265 +1,16 @@
|
|||||||
[package]
|
|
||||||
name = "winit"
|
|
||||||
version = "0.29.10"
|
|
||||||
authors = ["The winit contributors", "Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
|
||||||
description = "Cross-platform window creation library."
|
|
||||||
edition = "2021"
|
|
||||||
keywords = ["windowing"]
|
|
||||||
license = "Apache-2.0"
|
|
||||||
readme = "README.md"
|
|
||||||
repository = "https://github.com/rust-windowing/winit"
|
|
||||||
documentation = "https://docs.rs/winit"
|
|
||||||
categories = ["gui"]
|
|
||||||
rust-version = "1.70.0"
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
features = [
|
|
||||||
"rwh_04",
|
|
||||||
"rwh_05",
|
|
||||||
"rwh_06",
|
|
||||||
"serde",
|
|
||||||
"mint",
|
|
||||||
# Enabled to get docs to compile
|
|
||||||
"android-native-activity",
|
|
||||||
]
|
|
||||||
default-target = "x86_64-unknown-linux-gnu"
|
|
||||||
# These are all tested in CI
|
|
||||||
targets = [
|
|
||||||
# Windows
|
|
||||||
"i686-pc-windows-msvc",
|
|
||||||
"x86_64-pc-windows-msvc",
|
|
||||||
# macOS
|
|
||||||
"x86_64-apple-darwin",
|
|
||||||
# Unix (X11 & Wayland)
|
|
||||||
"i686-unknown-linux-gnu",
|
|
||||||
"x86_64-unknown-linux-gnu",
|
|
||||||
# iOS
|
|
||||||
"x86_64-apple-ios",
|
|
||||||
# Android
|
|
||||||
"aarch64-linux-android",
|
|
||||||
# Web
|
|
||||||
"wasm32-unknown-unknown",
|
|
||||||
]
|
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["rwh_06", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
|
|
||||||
x11 = ["x11-dl", "bytemuck", "percent-encoding", "xkbcommon-dl/x11", "x11rb"]
|
|
||||||
wayland = ["wayland-client", "wayland-backend", "wayland-protocols", "wayland-protocols-plasma", "sctk", "ahash", "memmap2"]
|
|
||||||
wayland-dlopen = ["wayland-backend/dlopen"]
|
|
||||||
wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/ab_glyph"]
|
|
||||||
wayland-csd-adwaita-crossfont = ["sctk-adwaita", "sctk-adwaita/crossfont"]
|
|
||||||
wayland-csd-adwaita-notitle = ["sctk-adwaita"]
|
|
||||||
android-native-activity = ["android-activity/native-activity"]
|
|
||||||
android-game-activity = ["android-activity/game-activity"]
|
|
||||||
serde = ["dep:serde", "cursor-icon/serde", "smol_str/serde"]
|
|
||||||
rwh_04 = ["dep:rwh_04", "ndk/rwh_04"]
|
|
||||||
rwh_05 = ["dep:rwh_05", "ndk/rwh_05"]
|
|
||||||
rwh_06 = ["dep:rwh_06", "ndk/rwh_06"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cfg_aliases = "0.2.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
bitflags = "2"
|
|
||||||
cursor-icon = "1.1.0"
|
|
||||||
log = "0.4"
|
|
||||||
mint = { version = "0.5.6", optional = true }
|
|
||||||
once_cell = "1.12"
|
|
||||||
rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true }
|
|
||||||
rwh_05 = { package = "raw-window-handle", version = "0.5.2", features = ["std"], optional = true }
|
|
||||||
rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"], optional = true }
|
|
||||||
serde = { version = "1", optional = true, features = ["serde_derive"] }
|
|
||||||
smol_str = "0.2.0"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
image = { version = "0.24.0", default-features = false, features = ["png"] }
|
|
||||||
simple_logger = { version = "4.2.0", default_features = false }
|
|
||||||
winit = { path = ".", features = ["rwh_05"] }
|
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dev-dependencies]
|
|
||||||
softbuffer = { version = "0.3.0", default-features = false, features = ["x11", "x11-dlopen", "wayland", "wayland-dlopen"] }
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
|
||||||
android-activity = "0.5.0"
|
|
||||||
ndk = { version = "0.8.0", default-features = false }
|
|
||||||
ndk-sys = "0.5.0"
|
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
|
|
||||||
core-foundation = "0.9.3"
|
|
||||||
objc2 = "0.5.0"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
|
||||||
core-graphics = "0.23.1"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.icrate]
|
|
||||||
version = "0.1.0"
|
|
||||||
features = [
|
|
||||||
"dispatch",
|
|
||||||
"Foundation",
|
|
||||||
"Foundation_NSArray",
|
|
||||||
"Foundation_NSAttributedString",
|
|
||||||
"Foundation_NSMutableAttributedString",
|
|
||||||
"Foundation_NSData",
|
|
||||||
"Foundation_NSDictionary",
|
|
||||||
"Foundation_NSString",
|
|
||||||
"Foundation_NSProcessInfo",
|
|
||||||
"Foundation_NSThread",
|
|
||||||
"Foundation_NSNumber",
|
|
||||||
"AppKit",
|
|
||||||
"AppKit_NSAppearance",
|
|
||||||
"AppKit_NSApplication",
|
|
||||||
"AppKit_NSBitmapImageRep",
|
|
||||||
"AppKit_NSButton",
|
|
||||||
"AppKit_NSColor",
|
|
||||||
"AppKit_NSControl",
|
|
||||||
"AppKit_NSCursor",
|
|
||||||
"AppKit_NSEvent",
|
|
||||||
"AppKit_NSGraphicsContext",
|
|
||||||
"AppKit_NSImage",
|
|
||||||
"AppKit_NSImageRep",
|
|
||||||
"AppKit_NSMenu",
|
|
||||||
"AppKit_NSMenuItem",
|
|
||||||
"AppKit_NSPasteboard",
|
|
||||||
"AppKit_NSResponder",
|
|
||||||
"AppKit_NSScreen",
|
|
||||||
"AppKit_NSTextInputContext",
|
|
||||||
"AppKit_NSView",
|
|
||||||
"AppKit_NSWindow",
|
|
||||||
"AppKit_NSWindowTabGroup",
|
|
||||||
]
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "ios")'.dependencies.icrate]
|
|
||||||
version = "0.1.0"
|
|
||||||
features = [
|
|
||||||
"dispatch",
|
|
||||||
"Foundation",
|
|
||||||
"Foundation_NSArray",
|
|
||||||
"Foundation_NSString",
|
|
||||||
"Foundation_NSProcessInfo",
|
|
||||||
"Foundation_NSThread",
|
|
||||||
"Foundation_NSSet",
|
|
||||||
]
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
|
||||||
unicode-segmentation = "1.7.1"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
|
|
||||||
version = "0.48"
|
|
||||||
features = [
|
|
||||||
"Win32_Devices_HumanInterfaceDevice",
|
|
||||||
"Win32_Foundation",
|
|
||||||
"Win32_Globalization",
|
|
||||||
"Win32_Graphics_Dwm",
|
|
||||||
"Win32_Graphics_Gdi",
|
|
||||||
"Win32_Media",
|
|
||||||
"Win32_System_Com_StructuredStorage",
|
|
||||||
"Win32_System_Com",
|
|
||||||
"Win32_System_LibraryLoader",
|
|
||||||
"Win32_System_Ole",
|
|
||||||
"Win32_System_SystemInformation",
|
|
||||||
"Win32_System_SystemServices",
|
|
||||||
"Win32_System_Threading",
|
|
||||||
"Win32_System_WindowsProgramming",
|
|
||||||
"Win32_UI_Accessibility",
|
|
||||||
"Win32_UI_Controls",
|
|
||||||
"Win32_UI_HiDpi",
|
|
||||||
"Win32_UI_Input_Ime",
|
|
||||||
"Win32_UI_Input_KeyboardAndMouse",
|
|
||||||
"Win32_UI_Input_Pointer",
|
|
||||||
"Win32_UI_Input_Touch",
|
|
||||||
"Win32_UI_Shell",
|
|
||||||
"Win32_UI_TextServices",
|
|
||||||
"Win32_UI_WindowsAndMessaging",
|
|
||||||
]
|
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_os = "ios", target_os = "macos"))))'.dependencies]
|
|
||||||
ahash = { version = "0.8.3", features = ["no-rng"], optional = true }
|
|
||||||
bytemuck = { version = "1.13.1", default-features = false, optional = true }
|
|
||||||
calloop = "0.12.3"
|
|
||||||
libc = "0.2.64"
|
|
||||||
memmap2 = { version = "0.9.0", optional = true }
|
|
||||||
percent-encoding = { version = "2.0", optional = true }
|
|
||||||
rustix = { version = "0.38.4", default-features = false, features = ["std", "system", "thread", "process"] }
|
|
||||||
sctk = { package = "smithay-client-toolkit", version = "0.18.0", default-features = false, features = ["calloop"], optional = true }
|
|
||||||
sctk-adwaita = { version = "0.8.0", default_features = false, optional = true }
|
|
||||||
wayland-backend = { version = "0.3.0", default_features = false, features = ["client_system"], optional = true }
|
|
||||||
wayland-client = { version = "0.31.1", optional = true }
|
|
||||||
wayland-protocols = { version = "0.31.0", features = [ "staging"], optional = true }
|
|
||||||
wayland-protocols-plasma = { version = "0.2.0", features = [ "client" ], optional = true }
|
|
||||||
x11-dl = { version = "2.18.5", optional = true }
|
|
||||||
x11rb = { version = "0.13.0", default-features = false, features = ["allow-unsafe-code", "dl-libxcb", "randr", "resource_manager", "xinput", "xkb"], optional = true }
|
|
||||||
xkbcommon-dl = "0.4.0"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "redox")'.dependencies]
|
|
||||||
orbclient = { version = "0.3.47", default-features = false }
|
|
||||||
redox_syscall = "0.4.1"
|
|
||||||
|
|
||||||
[target.'cfg(target_family = "wasm")'.dependencies.web_sys]
|
|
||||||
package = "web-sys"
|
|
||||||
version = "0.3.64"
|
|
||||||
features = [
|
|
||||||
'AbortController',
|
|
||||||
'AbortSignal',
|
|
||||||
'Blob',
|
|
||||||
'console',
|
|
||||||
'CssStyleDeclaration',
|
|
||||||
'Document',
|
|
||||||
'DomException',
|
|
||||||
'DomRect',
|
|
||||||
'DomRectReadOnly',
|
|
||||||
'Element',
|
|
||||||
'Event',
|
|
||||||
'EventTarget',
|
|
||||||
'FocusEvent',
|
|
||||||
'HtmlCanvasElement',
|
|
||||||
'HtmlElement',
|
|
||||||
'HtmlImageElement',
|
|
||||||
'ImageBitmap',
|
|
||||||
'ImageBitmapOptions',
|
|
||||||
'ImageBitmapRenderingContext',
|
|
||||||
'ImageData',
|
|
||||||
'IntersectionObserver',
|
|
||||||
'IntersectionObserverEntry',
|
|
||||||
'KeyboardEvent',
|
|
||||||
'MediaQueryList',
|
|
||||||
'MessageChannel',
|
|
||||||
'MessagePort',
|
|
||||||
'Node',
|
|
||||||
'PageTransitionEvent',
|
|
||||||
'PointerEvent',
|
|
||||||
'PremultiplyAlpha',
|
|
||||||
'ResizeObserver',
|
|
||||||
'ResizeObserverBoxOptions',
|
|
||||||
'ResizeObserverEntry',
|
|
||||||
'ResizeObserverOptions',
|
|
||||||
'ResizeObserverSize',
|
|
||||||
'VisibilityState',
|
|
||||||
'Window',
|
|
||||||
'WheelEvent',
|
|
||||||
'Url',
|
|
||||||
]
|
|
||||||
|
|
||||||
[target.'cfg(target_family = "wasm")'.dependencies]
|
|
||||||
js-sys = "0.3.64"
|
|
||||||
pin-project = "1"
|
|
||||||
wasm-bindgen = "0.2"
|
|
||||||
wasm-bindgen-futures = "0.4"
|
|
||||||
web-time = "1"
|
|
||||||
|
|
||||||
[target.'cfg(all(target_family = "wasm", target_feature = "atomics"))'.dependencies]
|
|
||||||
atomic-waker = "1"
|
|
||||||
concurrent-queue = { version = "2", default-features = false }
|
|
||||||
|
|
||||||
[target.'cfg(target_family = "wasm")'.dev-dependencies]
|
|
||||||
console_log = "1"
|
|
||||||
web-sys = { version = "0.3.22", features = ['CanvasRenderingContext2d'] }
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"run-wasm",
|
"run-wasm",
|
||||||
|
"winit",
|
||||||
|
"winit-core"
|
||||||
]
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[[example]]
|
[workspace.dependencies]
|
||||||
doc-scrape-examples = true
|
bitflags = "2"
|
||||||
name = "window"
|
cfg_aliases = "0.2.0"
|
||||||
|
cursor-icon = "1.1.0"
|
||||||
|
serde = { version = "1", features = ["serde_derive"] }
|
||||||
|
smol_str = "0.2.0"
|
||||||
|
web-time = "1"
|
||||||
|
winit-core = { path = "./winit-core", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ skip = [
|
|||||||
{ name = "bitflags" }, # the ecosystem is in the process of migrating.
|
{ name = "bitflags" }, # the ecosystem is in the process of migrating.
|
||||||
{ name = "libloading" }, # x11rb uses a different version until the next update
|
{ name = "libloading" }, # x11rb uses a different version until the next update
|
||||||
]
|
]
|
||||||
skip-tree = []
|
skip-tree = [
|
||||||
|
{ name = "run-wasm", version = "0.1.0" }
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
[licenses]
|
[licenses]
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
name = "run-wasm"
|
name = "run-wasm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cargo-run-wasm = "0.2.0"
|
cargo-run-wasm = "0.2.0"
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeviceId(pub i32);
|
|
||||||
|
|
||||||
impl DeviceId {
|
|
||||||
pub const unsafe fn dummy() -> Self {
|
|
||||||
Self(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,522 +0,0 @@
|
|||||||
use smol_str::SmolStr;
|
|
||||||
|
|
||||||
use crate::keyboard::{Key, KeyCode, NamedKey, NativeKey, NativeKeyCode, PhysicalKey};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
||||||
pub(crate) struct KeyEventExtra;
|
|
||||||
|
|
||||||
impl Key {
|
|
||||||
pub(crate) fn from_key_attribute_value(kav: &str) -> Self {
|
|
||||||
Key::Named(match kav {
|
|
||||||
"Unidentified" => return Key::Unidentified(NativeKey::Web(SmolStr::new(kav))),
|
|
||||||
"Dead" => return Key::Dead(None),
|
|
||||||
"Alt" => NamedKey::Alt,
|
|
||||||
"AltGraph" => NamedKey::AltGraph,
|
|
||||||
"CapsLock" => NamedKey::CapsLock,
|
|
||||||
"Control" => NamedKey::Control,
|
|
||||||
"Fn" => NamedKey::Fn,
|
|
||||||
"FnLock" => NamedKey::FnLock,
|
|
||||||
"NumLock" => NamedKey::NumLock,
|
|
||||||
"ScrollLock" => NamedKey::ScrollLock,
|
|
||||||
"Shift" => NamedKey::Shift,
|
|
||||||
"Symbol" => NamedKey::Symbol,
|
|
||||||
"SymbolLock" => NamedKey::SymbolLock,
|
|
||||||
"Hyper" => NamedKey::Hyper,
|
|
||||||
"Meta" => NamedKey::Super,
|
|
||||||
"Enter" => NamedKey::Enter,
|
|
||||||
"Tab" => NamedKey::Tab,
|
|
||||||
" " => NamedKey::Space,
|
|
||||||
"ArrowDown" => NamedKey::ArrowDown,
|
|
||||||
"ArrowLeft" => NamedKey::ArrowLeft,
|
|
||||||
"ArrowRight" => NamedKey::ArrowRight,
|
|
||||||
"ArrowUp" => NamedKey::ArrowUp,
|
|
||||||
"End" => NamedKey::End,
|
|
||||||
"Home" => NamedKey::Home,
|
|
||||||
"PageDown" => NamedKey::PageDown,
|
|
||||||
"PageUp" => NamedKey::PageUp,
|
|
||||||
"Backspace" => NamedKey::Backspace,
|
|
||||||
"Clear" => NamedKey::Clear,
|
|
||||||
"Copy" => NamedKey::Copy,
|
|
||||||
"CrSel" => NamedKey::CrSel,
|
|
||||||
"Cut" => NamedKey::Cut,
|
|
||||||
"Delete" => NamedKey::Delete,
|
|
||||||
"EraseEof" => NamedKey::EraseEof,
|
|
||||||
"ExSel" => NamedKey::ExSel,
|
|
||||||
"Insert" => NamedKey::Insert,
|
|
||||||
"Paste" => NamedKey::Paste,
|
|
||||||
"Redo" => NamedKey::Redo,
|
|
||||||
"Undo" => NamedKey::Undo,
|
|
||||||
"Accept" => NamedKey::Accept,
|
|
||||||
"Again" => NamedKey::Again,
|
|
||||||
"Attn" => NamedKey::Attn,
|
|
||||||
"Cancel" => NamedKey::Cancel,
|
|
||||||
"ContextMenu" => NamedKey::ContextMenu,
|
|
||||||
"Escape" => NamedKey::Escape,
|
|
||||||
"Execute" => NamedKey::Execute,
|
|
||||||
"Find" => NamedKey::Find,
|
|
||||||
"Help" => NamedKey::Help,
|
|
||||||
"Pause" => NamedKey::Pause,
|
|
||||||
"Play" => NamedKey::Play,
|
|
||||||
"Props" => NamedKey::Props,
|
|
||||||
"Select" => NamedKey::Select,
|
|
||||||
"ZoomIn" => NamedKey::ZoomIn,
|
|
||||||
"ZoomOut" => NamedKey::ZoomOut,
|
|
||||||
"BrightnessDown" => NamedKey::BrightnessDown,
|
|
||||||
"BrightnessUp" => NamedKey::BrightnessUp,
|
|
||||||
"Eject" => NamedKey::Eject,
|
|
||||||
"LogOff" => NamedKey::LogOff,
|
|
||||||
"Power" => NamedKey::Power,
|
|
||||||
"PowerOff" => NamedKey::PowerOff,
|
|
||||||
"PrintScreen" => NamedKey::PrintScreen,
|
|
||||||
"Hibernate" => NamedKey::Hibernate,
|
|
||||||
"Standby" => NamedKey::Standby,
|
|
||||||
"WakeUp" => NamedKey::WakeUp,
|
|
||||||
"AllCandidates" => NamedKey::AllCandidates,
|
|
||||||
"Alphanumeric" => NamedKey::Alphanumeric,
|
|
||||||
"CodeInput" => NamedKey::CodeInput,
|
|
||||||
"Compose" => NamedKey::Compose,
|
|
||||||
"Convert" => NamedKey::Convert,
|
|
||||||
"FinalMode" => NamedKey::FinalMode,
|
|
||||||
"GroupFirst" => NamedKey::GroupFirst,
|
|
||||||
"GroupLast" => NamedKey::GroupLast,
|
|
||||||
"GroupNext" => NamedKey::GroupNext,
|
|
||||||
"GroupPrevious" => NamedKey::GroupPrevious,
|
|
||||||
"ModeChange" => NamedKey::ModeChange,
|
|
||||||
"NextCandidate" => NamedKey::NextCandidate,
|
|
||||||
"NonConvert" => NamedKey::NonConvert,
|
|
||||||
"PreviousCandidate" => NamedKey::PreviousCandidate,
|
|
||||||
"Process" => NamedKey::Process,
|
|
||||||
"SingleCandidate" => NamedKey::SingleCandidate,
|
|
||||||
"HangulMode" => NamedKey::HangulMode,
|
|
||||||
"HanjaMode" => NamedKey::HanjaMode,
|
|
||||||
"JunjaMode" => NamedKey::JunjaMode,
|
|
||||||
"Eisu" => NamedKey::Eisu,
|
|
||||||
"Hankaku" => NamedKey::Hankaku,
|
|
||||||
"Hiragana" => NamedKey::Hiragana,
|
|
||||||
"HiraganaKatakana" => NamedKey::HiraganaKatakana,
|
|
||||||
"KanaMode" => NamedKey::KanaMode,
|
|
||||||
"KanjiMode" => NamedKey::KanjiMode,
|
|
||||||
"Katakana" => NamedKey::Katakana,
|
|
||||||
"Romaji" => NamedKey::Romaji,
|
|
||||||
"Zenkaku" => NamedKey::Zenkaku,
|
|
||||||
"ZenkakuHankaku" => NamedKey::ZenkakuHankaku,
|
|
||||||
"Soft1" => NamedKey::Soft1,
|
|
||||||
"Soft2" => NamedKey::Soft2,
|
|
||||||
"Soft3" => NamedKey::Soft3,
|
|
||||||
"Soft4" => NamedKey::Soft4,
|
|
||||||
"ChannelDown" => NamedKey::ChannelDown,
|
|
||||||
"ChannelUp" => NamedKey::ChannelUp,
|
|
||||||
"Close" => NamedKey::Close,
|
|
||||||
"MailForward" => NamedKey::MailForward,
|
|
||||||
"MailReply" => NamedKey::MailReply,
|
|
||||||
"MailSend" => NamedKey::MailSend,
|
|
||||||
"MediaClose" => NamedKey::MediaClose,
|
|
||||||
"MediaFastForward" => NamedKey::MediaFastForward,
|
|
||||||
"MediaPause" => NamedKey::MediaPause,
|
|
||||||
"MediaPlay" => NamedKey::MediaPlay,
|
|
||||||
"MediaPlayPause" => NamedKey::MediaPlayPause,
|
|
||||||
"MediaRecord" => NamedKey::MediaRecord,
|
|
||||||
"MediaRewind" => NamedKey::MediaRewind,
|
|
||||||
"MediaStop" => NamedKey::MediaStop,
|
|
||||||
"MediaTrackNext" => NamedKey::MediaTrackNext,
|
|
||||||
"MediaTrackPrevious" => NamedKey::MediaTrackPrevious,
|
|
||||||
"New" => NamedKey::New,
|
|
||||||
"Open" => NamedKey::Open,
|
|
||||||
"Print" => NamedKey::Print,
|
|
||||||
"Save" => NamedKey::Save,
|
|
||||||
"SpellCheck" => NamedKey::SpellCheck,
|
|
||||||
"Key11" => NamedKey::Key11,
|
|
||||||
"Key12" => NamedKey::Key12,
|
|
||||||
"AudioBalanceLeft" => NamedKey::AudioBalanceLeft,
|
|
||||||
"AudioBalanceRight" => NamedKey::AudioBalanceRight,
|
|
||||||
"AudioBassBoostDown" => NamedKey::AudioBassBoostDown,
|
|
||||||
"AudioBassBoostToggle" => NamedKey::AudioBassBoostToggle,
|
|
||||||
"AudioBassBoostUp" => NamedKey::AudioBassBoostUp,
|
|
||||||
"AudioFaderFront" => NamedKey::AudioFaderFront,
|
|
||||||
"AudioFaderRear" => NamedKey::AudioFaderRear,
|
|
||||||
"AudioSurroundModeNext" => NamedKey::AudioSurroundModeNext,
|
|
||||||
"AudioTrebleDown" => NamedKey::AudioTrebleDown,
|
|
||||||
"AudioTrebleUp" => NamedKey::AudioTrebleUp,
|
|
||||||
"AudioVolumeDown" => NamedKey::AudioVolumeDown,
|
|
||||||
"AudioVolumeUp" => NamedKey::AudioVolumeUp,
|
|
||||||
"AudioVolumeMute" => NamedKey::AudioVolumeMute,
|
|
||||||
"MicrophoneToggle" => NamedKey::MicrophoneToggle,
|
|
||||||
"MicrophoneVolumeDown" => NamedKey::MicrophoneVolumeDown,
|
|
||||||
"MicrophoneVolumeUp" => NamedKey::MicrophoneVolumeUp,
|
|
||||||
"MicrophoneVolumeMute" => NamedKey::MicrophoneVolumeMute,
|
|
||||||
"SpeechCorrectionList" => NamedKey::SpeechCorrectionList,
|
|
||||||
"SpeechInputToggle" => NamedKey::SpeechInputToggle,
|
|
||||||
"LaunchApplication1" => NamedKey::LaunchApplication1,
|
|
||||||
"LaunchApplication2" => NamedKey::LaunchApplication2,
|
|
||||||
"LaunchCalendar" => NamedKey::LaunchCalendar,
|
|
||||||
"LaunchContacts" => NamedKey::LaunchContacts,
|
|
||||||
"LaunchMail" => NamedKey::LaunchMail,
|
|
||||||
"LaunchMediaPlayer" => NamedKey::LaunchMediaPlayer,
|
|
||||||
"LaunchMusicPlayer" => NamedKey::LaunchMusicPlayer,
|
|
||||||
"LaunchPhone" => NamedKey::LaunchPhone,
|
|
||||||
"LaunchScreenSaver" => NamedKey::LaunchScreenSaver,
|
|
||||||
"LaunchSpreadsheet" => NamedKey::LaunchSpreadsheet,
|
|
||||||
"LaunchWebBrowser" => NamedKey::LaunchWebBrowser,
|
|
||||||
"LaunchWebCam" => NamedKey::LaunchWebCam,
|
|
||||||
"LaunchWordProcessor" => NamedKey::LaunchWordProcessor,
|
|
||||||
"BrowserBack" => NamedKey::BrowserBack,
|
|
||||||
"BrowserFavorites" => NamedKey::BrowserFavorites,
|
|
||||||
"BrowserForward" => NamedKey::BrowserForward,
|
|
||||||
"BrowserHome" => NamedKey::BrowserHome,
|
|
||||||
"BrowserRefresh" => NamedKey::BrowserRefresh,
|
|
||||||
"BrowserSearch" => NamedKey::BrowserSearch,
|
|
||||||
"BrowserStop" => NamedKey::BrowserStop,
|
|
||||||
"AppSwitch" => NamedKey::AppSwitch,
|
|
||||||
"Call" => NamedKey::Call,
|
|
||||||
"Camera" => NamedKey::Camera,
|
|
||||||
"CameraFocus" => NamedKey::CameraFocus,
|
|
||||||
"EndCall" => NamedKey::EndCall,
|
|
||||||
"GoBack" => NamedKey::GoBack,
|
|
||||||
"GoHome" => NamedKey::GoHome,
|
|
||||||
"HeadsetHook" => NamedKey::HeadsetHook,
|
|
||||||
"LastNumberRedial" => NamedKey::LastNumberRedial,
|
|
||||||
"Notification" => NamedKey::Notification,
|
|
||||||
"MannerMode" => NamedKey::MannerMode,
|
|
||||||
"VoiceDial" => NamedKey::VoiceDial,
|
|
||||||
"TV" => NamedKey::TV,
|
|
||||||
"TV3DMode" => NamedKey::TV3DMode,
|
|
||||||
"TVAntennaCable" => NamedKey::TVAntennaCable,
|
|
||||||
"TVAudioDescription" => NamedKey::TVAudioDescription,
|
|
||||||
"TVAudioDescriptionMixDown" => NamedKey::TVAudioDescriptionMixDown,
|
|
||||||
"TVAudioDescriptionMixUp" => NamedKey::TVAudioDescriptionMixUp,
|
|
||||||
"TVContentsMenu" => NamedKey::TVContentsMenu,
|
|
||||||
"TVDataService" => NamedKey::TVDataService,
|
|
||||||
"TVInput" => NamedKey::TVInput,
|
|
||||||
"TVInputComponent1" => NamedKey::TVInputComponent1,
|
|
||||||
"TVInputComponent2" => NamedKey::TVInputComponent2,
|
|
||||||
"TVInputComposite1" => NamedKey::TVInputComposite1,
|
|
||||||
"TVInputComposite2" => NamedKey::TVInputComposite2,
|
|
||||||
"TVInputHDMI1" => NamedKey::TVInputHDMI1,
|
|
||||||
"TVInputHDMI2" => NamedKey::TVInputHDMI2,
|
|
||||||
"TVInputHDMI3" => NamedKey::TVInputHDMI3,
|
|
||||||
"TVInputHDMI4" => NamedKey::TVInputHDMI4,
|
|
||||||
"TVInputVGA1" => NamedKey::TVInputVGA1,
|
|
||||||
"TVMediaContext" => NamedKey::TVMediaContext,
|
|
||||||
"TVNetwork" => NamedKey::TVNetwork,
|
|
||||||
"TVNumberEntry" => NamedKey::TVNumberEntry,
|
|
||||||
"TVPower" => NamedKey::TVPower,
|
|
||||||
"TVRadioService" => NamedKey::TVRadioService,
|
|
||||||
"TVSatellite" => NamedKey::TVSatellite,
|
|
||||||
"TVSatelliteBS" => NamedKey::TVSatelliteBS,
|
|
||||||
"TVSatelliteCS" => NamedKey::TVSatelliteCS,
|
|
||||||
"TVSatelliteToggle" => NamedKey::TVSatelliteToggle,
|
|
||||||
"TVTerrestrialAnalog" => NamedKey::TVTerrestrialAnalog,
|
|
||||||
"TVTerrestrialDigital" => NamedKey::TVTerrestrialDigital,
|
|
||||||
"TVTimer" => NamedKey::TVTimer,
|
|
||||||
"AVRInput" => NamedKey::AVRInput,
|
|
||||||
"AVRPower" => NamedKey::AVRPower,
|
|
||||||
"ColorF0Red" => NamedKey::ColorF0Red,
|
|
||||||
"ColorF1Green" => NamedKey::ColorF1Green,
|
|
||||||
"ColorF2Yellow" => NamedKey::ColorF2Yellow,
|
|
||||||
"ColorF3Blue" => NamedKey::ColorF3Blue,
|
|
||||||
"ColorF4Grey" => NamedKey::ColorF4Grey,
|
|
||||||
"ColorF5Brown" => NamedKey::ColorF5Brown,
|
|
||||||
"ClosedCaptionToggle" => NamedKey::ClosedCaptionToggle,
|
|
||||||
"Dimmer" => NamedKey::Dimmer,
|
|
||||||
"DisplaySwap" => NamedKey::DisplaySwap,
|
|
||||||
"DVR" => NamedKey::DVR,
|
|
||||||
"Exit" => NamedKey::Exit,
|
|
||||||
"FavoriteClear0" => NamedKey::FavoriteClear0,
|
|
||||||
"FavoriteClear1" => NamedKey::FavoriteClear1,
|
|
||||||
"FavoriteClear2" => NamedKey::FavoriteClear2,
|
|
||||||
"FavoriteClear3" => NamedKey::FavoriteClear3,
|
|
||||||
"FavoriteRecall0" => NamedKey::FavoriteRecall0,
|
|
||||||
"FavoriteRecall1" => NamedKey::FavoriteRecall1,
|
|
||||||
"FavoriteRecall2" => NamedKey::FavoriteRecall2,
|
|
||||||
"FavoriteRecall3" => NamedKey::FavoriteRecall3,
|
|
||||||
"FavoriteStore0" => NamedKey::FavoriteStore0,
|
|
||||||
"FavoriteStore1" => NamedKey::FavoriteStore1,
|
|
||||||
"FavoriteStore2" => NamedKey::FavoriteStore2,
|
|
||||||
"FavoriteStore3" => NamedKey::FavoriteStore3,
|
|
||||||
"Guide" => NamedKey::Guide,
|
|
||||||
"GuideNextDay" => NamedKey::GuideNextDay,
|
|
||||||
"GuidePreviousDay" => NamedKey::GuidePreviousDay,
|
|
||||||
"Info" => NamedKey::Info,
|
|
||||||
"InstantReplay" => NamedKey::InstantReplay,
|
|
||||||
"Link" => NamedKey::Link,
|
|
||||||
"ListProgram" => NamedKey::ListProgram,
|
|
||||||
"LiveContent" => NamedKey::LiveContent,
|
|
||||||
"Lock" => NamedKey::Lock,
|
|
||||||
"MediaApps" => NamedKey::MediaApps,
|
|
||||||
"MediaAudioTrack" => NamedKey::MediaAudioTrack,
|
|
||||||
"MediaLast" => NamedKey::MediaLast,
|
|
||||||
"MediaSkipBackward" => NamedKey::MediaSkipBackward,
|
|
||||||
"MediaSkipForward" => NamedKey::MediaSkipForward,
|
|
||||||
"MediaStepBackward" => NamedKey::MediaStepBackward,
|
|
||||||
"MediaStepForward" => NamedKey::MediaStepForward,
|
|
||||||
"MediaTopMenu" => NamedKey::MediaTopMenu,
|
|
||||||
"NavigateIn" => NamedKey::NavigateIn,
|
|
||||||
"NavigateNext" => NamedKey::NavigateNext,
|
|
||||||
"NavigateOut" => NamedKey::NavigateOut,
|
|
||||||
"NavigatePrevious" => NamedKey::NavigatePrevious,
|
|
||||||
"NextFavoriteChannel" => NamedKey::NextFavoriteChannel,
|
|
||||||
"NextUserProfile" => NamedKey::NextUserProfile,
|
|
||||||
"OnDemand" => NamedKey::OnDemand,
|
|
||||||
"Pairing" => NamedKey::Pairing,
|
|
||||||
"PinPDown" => NamedKey::PinPDown,
|
|
||||||
"PinPMove" => NamedKey::PinPMove,
|
|
||||||
"PinPToggle" => NamedKey::PinPToggle,
|
|
||||||
"PinPUp" => NamedKey::PinPUp,
|
|
||||||
"PlaySpeedDown" => NamedKey::PlaySpeedDown,
|
|
||||||
"PlaySpeedReset" => NamedKey::PlaySpeedReset,
|
|
||||||
"PlaySpeedUp" => NamedKey::PlaySpeedUp,
|
|
||||||
"RandomToggle" => NamedKey::RandomToggle,
|
|
||||||
"RcLowBattery" => NamedKey::RcLowBattery,
|
|
||||||
"RecordSpeedNext" => NamedKey::RecordSpeedNext,
|
|
||||||
"RfBypass" => NamedKey::RfBypass,
|
|
||||||
"ScanChannelsToggle" => NamedKey::ScanChannelsToggle,
|
|
||||||
"ScreenModeNext" => NamedKey::ScreenModeNext,
|
|
||||||
"Settings" => NamedKey::Settings,
|
|
||||||
"SplitScreenToggle" => NamedKey::SplitScreenToggle,
|
|
||||||
"STBInput" => NamedKey::STBInput,
|
|
||||||
"STBPower" => NamedKey::STBPower,
|
|
||||||
"Subtitle" => NamedKey::Subtitle,
|
|
||||||
"Teletext" => NamedKey::Teletext,
|
|
||||||
"VideoModeNext" => NamedKey::VideoModeNext,
|
|
||||||
"Wink" => NamedKey::Wink,
|
|
||||||
"ZoomToggle" => NamedKey::ZoomToggle,
|
|
||||||
"F1" => NamedKey::F1,
|
|
||||||
"F2" => NamedKey::F2,
|
|
||||||
"F3" => NamedKey::F3,
|
|
||||||
"F4" => NamedKey::F4,
|
|
||||||
"F5" => NamedKey::F5,
|
|
||||||
"F6" => NamedKey::F6,
|
|
||||||
"F7" => NamedKey::F7,
|
|
||||||
"F8" => NamedKey::F8,
|
|
||||||
"F9" => NamedKey::F9,
|
|
||||||
"F10" => NamedKey::F10,
|
|
||||||
"F11" => NamedKey::F11,
|
|
||||||
"F12" => NamedKey::F12,
|
|
||||||
"F13" => NamedKey::F13,
|
|
||||||
"F14" => NamedKey::F14,
|
|
||||||
"F15" => NamedKey::F15,
|
|
||||||
"F16" => NamedKey::F16,
|
|
||||||
"F17" => NamedKey::F17,
|
|
||||||
"F18" => NamedKey::F18,
|
|
||||||
"F19" => NamedKey::F19,
|
|
||||||
"F20" => NamedKey::F20,
|
|
||||||
"F21" => NamedKey::F21,
|
|
||||||
"F22" => NamedKey::F22,
|
|
||||||
"F23" => NamedKey::F23,
|
|
||||||
"F24" => NamedKey::F24,
|
|
||||||
"F25" => NamedKey::F25,
|
|
||||||
"F26" => NamedKey::F26,
|
|
||||||
"F27" => NamedKey::F27,
|
|
||||||
"F28" => NamedKey::F28,
|
|
||||||
"F29" => NamedKey::F29,
|
|
||||||
"F30" => NamedKey::F30,
|
|
||||||
"F31" => NamedKey::F31,
|
|
||||||
"F32" => NamedKey::F32,
|
|
||||||
"F33" => NamedKey::F33,
|
|
||||||
"F34" => NamedKey::F34,
|
|
||||||
"F35" => NamedKey::F35,
|
|
||||||
string => return Key::Character(SmolStr::new(string)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PhysicalKey {
|
|
||||||
pub fn from_key_code_attribute_value(kcav: &str) -> Self {
|
|
||||||
PhysicalKey::Code(match kcav {
|
|
||||||
"Backquote" => KeyCode::Backquote,
|
|
||||||
"Backslash" => KeyCode::Backslash,
|
|
||||||
"BracketLeft" => KeyCode::BracketLeft,
|
|
||||||
"BracketRight" => KeyCode::BracketRight,
|
|
||||||
"Comma" => KeyCode::Comma,
|
|
||||||
"Digit0" => KeyCode::Digit0,
|
|
||||||
"Digit1" => KeyCode::Digit1,
|
|
||||||
"Digit2" => KeyCode::Digit2,
|
|
||||||
"Digit3" => KeyCode::Digit3,
|
|
||||||
"Digit4" => KeyCode::Digit4,
|
|
||||||
"Digit5" => KeyCode::Digit5,
|
|
||||||
"Digit6" => KeyCode::Digit6,
|
|
||||||
"Digit7" => KeyCode::Digit7,
|
|
||||||
"Digit8" => KeyCode::Digit8,
|
|
||||||
"Digit9" => KeyCode::Digit9,
|
|
||||||
"Equal" => KeyCode::Equal,
|
|
||||||
"IntlBackslash" => KeyCode::IntlBackslash,
|
|
||||||
"IntlRo" => KeyCode::IntlRo,
|
|
||||||
"IntlYen" => KeyCode::IntlYen,
|
|
||||||
"KeyA" => KeyCode::KeyA,
|
|
||||||
"KeyB" => KeyCode::KeyB,
|
|
||||||
"KeyC" => KeyCode::KeyC,
|
|
||||||
"KeyD" => KeyCode::KeyD,
|
|
||||||
"KeyE" => KeyCode::KeyE,
|
|
||||||
"KeyF" => KeyCode::KeyF,
|
|
||||||
"KeyG" => KeyCode::KeyG,
|
|
||||||
"KeyH" => KeyCode::KeyH,
|
|
||||||
"KeyI" => KeyCode::KeyI,
|
|
||||||
"KeyJ" => KeyCode::KeyJ,
|
|
||||||
"KeyK" => KeyCode::KeyK,
|
|
||||||
"KeyL" => KeyCode::KeyL,
|
|
||||||
"KeyM" => KeyCode::KeyM,
|
|
||||||
"KeyN" => KeyCode::KeyN,
|
|
||||||
"KeyO" => KeyCode::KeyO,
|
|
||||||
"KeyP" => KeyCode::KeyP,
|
|
||||||
"KeyQ" => KeyCode::KeyQ,
|
|
||||||
"KeyR" => KeyCode::KeyR,
|
|
||||||
"KeyS" => KeyCode::KeyS,
|
|
||||||
"KeyT" => KeyCode::KeyT,
|
|
||||||
"KeyU" => KeyCode::KeyU,
|
|
||||||
"KeyV" => KeyCode::KeyV,
|
|
||||||
"KeyW" => KeyCode::KeyW,
|
|
||||||
"KeyX" => KeyCode::KeyX,
|
|
||||||
"KeyY" => KeyCode::KeyY,
|
|
||||||
"KeyZ" => KeyCode::KeyZ,
|
|
||||||
"Minus" => KeyCode::Minus,
|
|
||||||
"Period" => KeyCode::Period,
|
|
||||||
"Quote" => KeyCode::Quote,
|
|
||||||
"Semicolon" => KeyCode::Semicolon,
|
|
||||||
"Slash" => KeyCode::Slash,
|
|
||||||
"AltLeft" => KeyCode::AltLeft,
|
|
||||||
"AltRight" => KeyCode::AltRight,
|
|
||||||
"Backspace" => KeyCode::Backspace,
|
|
||||||
"CapsLock" => KeyCode::CapsLock,
|
|
||||||
"ContextMenu" => KeyCode::ContextMenu,
|
|
||||||
"ControlLeft" => KeyCode::ControlLeft,
|
|
||||||
"ControlRight" => KeyCode::ControlRight,
|
|
||||||
"Enter" => KeyCode::Enter,
|
|
||||||
"MetaLeft" => KeyCode::SuperLeft,
|
|
||||||
"MetaRight" => KeyCode::SuperRight,
|
|
||||||
"ShiftLeft" => KeyCode::ShiftLeft,
|
|
||||||
"ShiftRight" => KeyCode::ShiftRight,
|
|
||||||
"Space" => KeyCode::Space,
|
|
||||||
"Tab" => KeyCode::Tab,
|
|
||||||
"Convert" => KeyCode::Convert,
|
|
||||||
"KanaMode" => KeyCode::KanaMode,
|
|
||||||
"Lang1" => KeyCode::Lang1,
|
|
||||||
"Lang2" => KeyCode::Lang2,
|
|
||||||
"Lang3" => KeyCode::Lang3,
|
|
||||||
"Lang4" => KeyCode::Lang4,
|
|
||||||
"Lang5" => KeyCode::Lang5,
|
|
||||||
"NonConvert" => KeyCode::NonConvert,
|
|
||||||
"Delete" => KeyCode::Delete,
|
|
||||||
"End" => KeyCode::End,
|
|
||||||
"Help" => KeyCode::Help,
|
|
||||||
"Home" => KeyCode::Home,
|
|
||||||
"Insert" => KeyCode::Insert,
|
|
||||||
"PageDown" => KeyCode::PageDown,
|
|
||||||
"PageUp" => KeyCode::PageUp,
|
|
||||||
"ArrowDown" => KeyCode::ArrowDown,
|
|
||||||
"ArrowLeft" => KeyCode::ArrowLeft,
|
|
||||||
"ArrowRight" => KeyCode::ArrowRight,
|
|
||||||
"ArrowUp" => KeyCode::ArrowUp,
|
|
||||||
"NumLock" => KeyCode::NumLock,
|
|
||||||
"Numpad0" => KeyCode::Numpad0,
|
|
||||||
"Numpad1" => KeyCode::Numpad1,
|
|
||||||
"Numpad2" => KeyCode::Numpad2,
|
|
||||||
"Numpad3" => KeyCode::Numpad3,
|
|
||||||
"Numpad4" => KeyCode::Numpad4,
|
|
||||||
"Numpad5" => KeyCode::Numpad5,
|
|
||||||
"Numpad6" => KeyCode::Numpad6,
|
|
||||||
"Numpad7" => KeyCode::Numpad7,
|
|
||||||
"Numpad8" => KeyCode::Numpad8,
|
|
||||||
"Numpad9" => KeyCode::Numpad9,
|
|
||||||
"NumpadAdd" => KeyCode::NumpadAdd,
|
|
||||||
"NumpadBackspace" => KeyCode::NumpadBackspace,
|
|
||||||
"NumpadClear" => KeyCode::NumpadClear,
|
|
||||||
"NumpadClearEntry" => KeyCode::NumpadClearEntry,
|
|
||||||
"NumpadComma" => KeyCode::NumpadComma,
|
|
||||||
"NumpadDecimal" => KeyCode::NumpadDecimal,
|
|
||||||
"NumpadDivide" => KeyCode::NumpadDivide,
|
|
||||||
"NumpadEnter" => KeyCode::NumpadEnter,
|
|
||||||
"NumpadEqual" => KeyCode::NumpadEqual,
|
|
||||||
"NumpadHash" => KeyCode::NumpadHash,
|
|
||||||
"NumpadMemoryAdd" => KeyCode::NumpadMemoryAdd,
|
|
||||||
"NumpadMemoryClear" => KeyCode::NumpadMemoryClear,
|
|
||||||
"NumpadMemoryRecall" => KeyCode::NumpadMemoryRecall,
|
|
||||||
"NumpadMemoryStore" => KeyCode::NumpadMemoryStore,
|
|
||||||
"NumpadMemorySubtract" => KeyCode::NumpadMemorySubtract,
|
|
||||||
"NumpadMultiply" => KeyCode::NumpadMultiply,
|
|
||||||
"NumpadParenLeft" => KeyCode::NumpadParenLeft,
|
|
||||||
"NumpadParenRight" => KeyCode::NumpadParenRight,
|
|
||||||
"NumpadStar" => KeyCode::NumpadStar,
|
|
||||||
"NumpadSubtract" => KeyCode::NumpadSubtract,
|
|
||||||
"Escape" => KeyCode::Escape,
|
|
||||||
"Fn" => KeyCode::Fn,
|
|
||||||
"FnLock" => KeyCode::FnLock,
|
|
||||||
"PrintScreen" => KeyCode::PrintScreen,
|
|
||||||
"ScrollLock" => KeyCode::ScrollLock,
|
|
||||||
"Pause" => KeyCode::Pause,
|
|
||||||
"BrowserBack" => KeyCode::BrowserBack,
|
|
||||||
"BrowserFavorites" => KeyCode::BrowserFavorites,
|
|
||||||
"BrowserForward" => KeyCode::BrowserForward,
|
|
||||||
"BrowserHome" => KeyCode::BrowserHome,
|
|
||||||
"BrowserRefresh" => KeyCode::BrowserRefresh,
|
|
||||||
"BrowserSearch" => KeyCode::BrowserSearch,
|
|
||||||
"BrowserStop" => KeyCode::BrowserStop,
|
|
||||||
"Eject" => KeyCode::Eject,
|
|
||||||
"LaunchApp1" => KeyCode::LaunchApp1,
|
|
||||||
"LaunchApp2" => KeyCode::LaunchApp2,
|
|
||||||
"LaunchMail" => KeyCode::LaunchMail,
|
|
||||||
"MediaPlayPause" => KeyCode::MediaPlayPause,
|
|
||||||
"MediaSelect" => KeyCode::MediaSelect,
|
|
||||||
"MediaStop" => KeyCode::MediaStop,
|
|
||||||
"MediaTrackNext" => KeyCode::MediaTrackNext,
|
|
||||||
"MediaTrackPrevious" => KeyCode::MediaTrackPrevious,
|
|
||||||
"Power" => KeyCode::Power,
|
|
||||||
"Sleep" => KeyCode::Sleep,
|
|
||||||
"AudioVolumeDown" => KeyCode::AudioVolumeDown,
|
|
||||||
"AudioVolumeMute" => KeyCode::AudioVolumeMute,
|
|
||||||
"AudioVolumeUp" => KeyCode::AudioVolumeUp,
|
|
||||||
"WakeUp" => KeyCode::WakeUp,
|
|
||||||
"Hyper" => KeyCode::Hyper,
|
|
||||||
"Turbo" => KeyCode::Turbo,
|
|
||||||
"Abort" => KeyCode::Abort,
|
|
||||||
"Resume" => KeyCode::Resume,
|
|
||||||
"Suspend" => KeyCode::Suspend,
|
|
||||||
"Again" => KeyCode::Again,
|
|
||||||
"Copy" => KeyCode::Copy,
|
|
||||||
"Cut" => KeyCode::Cut,
|
|
||||||
"Find" => KeyCode::Find,
|
|
||||||
"Open" => KeyCode::Open,
|
|
||||||
"Paste" => KeyCode::Paste,
|
|
||||||
"Props" => KeyCode::Props,
|
|
||||||
"Select" => KeyCode::Select,
|
|
||||||
"Undo" => KeyCode::Undo,
|
|
||||||
"Hiragana" => KeyCode::Hiragana,
|
|
||||||
"Katakana" => KeyCode::Katakana,
|
|
||||||
"F1" => KeyCode::F1,
|
|
||||||
"F2" => KeyCode::F2,
|
|
||||||
"F3" => KeyCode::F3,
|
|
||||||
"F4" => KeyCode::F4,
|
|
||||||
"F5" => KeyCode::F5,
|
|
||||||
"F6" => KeyCode::F6,
|
|
||||||
"F7" => KeyCode::F7,
|
|
||||||
"F8" => KeyCode::F8,
|
|
||||||
"F9" => KeyCode::F9,
|
|
||||||
"F10" => KeyCode::F10,
|
|
||||||
"F11" => KeyCode::F11,
|
|
||||||
"F12" => KeyCode::F12,
|
|
||||||
"F13" => KeyCode::F13,
|
|
||||||
"F14" => KeyCode::F14,
|
|
||||||
"F15" => KeyCode::F15,
|
|
||||||
"F16" => KeyCode::F16,
|
|
||||||
"F17" => KeyCode::F17,
|
|
||||||
"F18" => KeyCode::F18,
|
|
||||||
"F19" => KeyCode::F19,
|
|
||||||
"F20" => KeyCode::F20,
|
|
||||||
"F21" => KeyCode::F21,
|
|
||||||
"F22" => KeyCode::F22,
|
|
||||||
"F23" => KeyCode::F23,
|
|
||||||
"F24" => KeyCode::F24,
|
|
||||||
"F25" => KeyCode::F25,
|
|
||||||
"F26" => KeyCode::F26,
|
|
||||||
"F27" => KeyCode::F27,
|
|
||||||
"F28" => KeyCode::F28,
|
|
||||||
"F29" => KeyCode::F29,
|
|
||||||
"F30" => KeyCode::F30,
|
|
||||||
"F31" => KeyCode::F31,
|
|
||||||
"F32" => KeyCode::F32,
|
|
||||||
"F33" => KeyCode::F33,
|
|
||||||
"F34" => KeyCode::F34,
|
|
||||||
"F35" => KeyCode::F35,
|
|
||||||
_ => return PhysicalKey::Unidentified(NativeKeyCode::Unidentified),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
32
winit-core/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[package]
|
||||||
|
name = "winit-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["The winit contributors"]
|
||||||
|
description = "Base types for windowing libraries"
|
||||||
|
edition = "2021"
|
||||||
|
keywords = ["windowing"]
|
||||||
|
license = "Apache-2.0"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/rust-windowing/winit"
|
||||||
|
documentation = "https://docs.rs/winit"
|
||||||
|
categories = ["gui"]
|
||||||
|
rust-version = "1.70.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = ["alloc"]
|
||||||
|
alloc = []
|
||||||
|
serde = ["dep:serde", "cursor-icon/serde", "smol_str/serde"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags.workspace = true
|
||||||
|
cursor-icon.workspace = true
|
||||||
|
mint = { version = "0.5.6", optional = true }
|
||||||
|
serde = { workspace = true, optional = true }
|
||||||
|
smol_str.workspace = true
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||||
|
web-time.workspace = true
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cfg_aliases.workspace = true
|
||||||
3
winit-core/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# winit-core - Base types for a windowing system
|
||||||
|
|
||||||
|
TODO
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
//! [points]: https://en.wikipedia.org/wiki/Point_(typography)
|
//! [points]: https://en.wikipedia.org/wiki/Point_(typography)
|
||||||
//! [picas]: https://en.wikipedia.org/wiki/Pica_(typography)
|
//! [picas]: https://en.wikipedia.org/wiki/Pica_(typography)
|
||||||
//! [`ScaleFactorChanged`]: crate::event::WindowEvent::ScaleFactorChanged
|
//! [`ScaleFactorChanged`]: crate::event::WindowEvent::ScaleFactorChanged
|
||||||
//! [`window.scale_factor()`]: crate::window::Window::scale_factor
|
//! [`window.scale_factor()`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.scale_factor
|
||||||
//! [windows_1]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
|
//! [windows_1]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
|
||||||
//! [apple_1]: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html
|
//! [apple_1]: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html
|
||||||
//! [apple_2]: https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/image-size-and-resolution/
|
//! [apple_2]: https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/image-size-and-resolution/
|
||||||
54
winit-core/src/error.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
//! Common error types.
|
||||||
|
|
||||||
|
use std::{error, fmt};
|
||||||
|
|
||||||
|
/// The error type for when the requested operation is not supported by the backend.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct NotSupportedError {
|
||||||
|
_marker: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for NotSupportedError {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NotSupportedError {
|
||||||
|
/// Create a new [`NotSupportedError`].
|
||||||
|
#[inline]
|
||||||
|
pub fn new() -> NotSupportedError {
|
||||||
|
NotSupportedError { _marker: () }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for NotSupportedError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
f.debug_struct("NotSupportedError").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for NotSupportedError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
f.pad("the requested operation is not supported by Winit")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for NotSupportedError {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#![allow(clippy::redundant_clone)]
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// Eat attributes for testing
|
||||||
|
#[test]
|
||||||
|
fn ensure_fmt_does_not_panic() {
|
||||||
|
let _ = format!(
|
||||||
|
"{:?}, {}",
|
||||||
|
NotSupportedError::new(),
|
||||||
|
NotSupportedError::new().clone()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,64 +1,64 @@
|
|||||||
//! The [`Event`] enum and assorted supporting types.
|
//! Incoming notifications from the GUI system.
|
||||||
//!
|
|
||||||
//! These are sent to the closure given to [`EventLoop::run(...)`], where they get
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
//! processed and used to modify the program state. For more details, see the root-level documentation.
|
use crate::event_loop::AsyncRequestSerial;
|
||||||
//!
|
use crate::keyboard::{self, ModifiersKeyState, ModifiersKeys, ModifiersState};
|
||||||
//! Some of these events represent different "parts" of a traditional event-handling loop. You could
|
use crate::window::{ActivationToken, Theme, WindowId};
|
||||||
//! approximate the basic ordering loop of [`EventLoop::run(...)`] like this:
|
|
||||||
//!
|
use std::fmt;
|
||||||
//! ```rust,ignore
|
|
||||||
//! let mut start_cause = StartCause::Init;
|
|
||||||
//!
|
|
||||||
//! while !elwt.exiting() {
|
|
||||||
//! event_handler(NewEvents(start_cause), elwt);
|
|
||||||
//!
|
|
||||||
//! for e in (window events, user events, device events) {
|
|
||||||
//! event_handler(e, elwt);
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! for w in (redraw windows) {
|
|
||||||
//! event_handler(RedrawRequested(w), elwt);
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! event_handler(AboutToWait, elwt);
|
|
||||||
//! start_cause = wait_if_necessary();
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! event_handler(LoopExiting, elwt);
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! This leaves out timing details like [`ControlFlow::WaitUntil`] but hopefully
|
|
||||||
//! describes what happens in what order.
|
|
||||||
//!
|
|
||||||
//! [`EventLoop::run(...)`]: crate::event_loop::EventLoop::run
|
|
||||||
//! [`ControlFlow::WaitUntil`]: crate::event_loop::ControlFlow::WaitUntil
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Mutex, Weak};
|
use std::sync::{Mutex, Weak};
|
||||||
|
|
||||||
#[cfg(not(web_platform))]
|
#[cfg(not(web_platform))]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use smol_str::SmolStr;
|
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
use web_time::Instant;
|
use web_time::Instant;
|
||||||
|
|
||||||
use crate::error::ExternalError;
|
#[cfg(feature = "serde")]
|
||||||
#[cfg(doc)]
|
pub use serde::{Deserialize, Serialize};
|
||||||
use crate::window::Window;
|
|
||||||
use crate::{
|
use smol_str::SmolStr;
|
||||||
dpi::{PhysicalPosition, PhysicalSize},
|
|
||||||
event_loop::AsyncRequestSerial,
|
/// Identifier of an input device.
|
||||||
keyboard::{self, ModifiersKeyState, ModifiersKeys, ModifiersState},
|
///
|
||||||
platform_impl,
|
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
||||||
window::{ActivationToken, Theme, WindowId},
|
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
|
||||||
};
|
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct DeviceId(u64);
|
||||||
|
|
||||||
|
impl DeviceId {
|
||||||
|
/// Returns a dummy id, useful for unit testing.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The only guarantee made about the return value of this function is that
|
||||||
|
/// it will always be equal to itself and to future values returned by this function.
|
||||||
|
/// No other guarantees are made. This may be equal to a real `DeviceId`.
|
||||||
|
///
|
||||||
|
/// **Passing this into a winit function will result in undefined behavior.**
|
||||||
|
pub const unsafe fn dummy() -> Self {
|
||||||
|
DeviceId(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for DeviceId {
|
||||||
|
fn from(value: u64) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DeviceId> for u64 {
|
||||||
|
fn from(value: DeviceId) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a generic event.
|
/// Describes a generic event.
|
||||||
///
|
///
|
||||||
/// See the module-level docs for more information on the event loop manages each event.
|
/// See the module-level docs for more information on the event loop manages each event.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Event<T: 'static> {
|
pub enum Event<T: 'static, KeyExtra> {
|
||||||
/// Emitted when new events arrive from the OS to be processed.
|
/// Emitted when new events arrive from the OS to be processed.
|
||||||
///
|
///
|
||||||
/// This event type is useful as a place to put code that should be done before you start
|
/// This event type is useful as a place to put code that should be done before you start
|
||||||
@@ -70,7 +70,7 @@ pub enum Event<T: 'static> {
|
|||||||
/// Emitted when the OS sends an event to a winit window.
|
/// Emitted when the OS sends an event to a winit window.
|
||||||
WindowEvent {
|
WindowEvent {
|
||||||
window_id: WindowId,
|
window_id: WindowId,
|
||||||
event: WindowEvent,
|
event: WindowEvent<KeyExtra>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Emitted when the OS sends an event to a device.
|
/// Emitted when the OS sends an event to a device.
|
||||||
@@ -79,7 +79,7 @@ pub enum Event<T: 'static> {
|
|||||||
event: DeviceEvent,
|
event: DeviceEvent,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Emitted when an event is sent from [`EventLoopProxy::send_event`](crate::event_loop::EventLoopProxy::send_event)
|
/// Emitted when an event is sent from [`EventLoopProxy::send_event`](https://docs.rs/winit/latest/winit/event_loop/struct.EventLoopProxy.html#method.send_event)
|
||||||
UserEvent(T),
|
UserEvent(T),
|
||||||
|
|
||||||
/// Emitted when the application has been suspended.
|
/// Emitted when the application has been suspended.
|
||||||
@@ -255,9 +255,9 @@ pub enum Event<T: 'static> {
|
|||||||
MemoryWarning,
|
MemoryWarning,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Event<T> {
|
impl<T, Extra> Event<T, Extra> {
|
||||||
#[allow(clippy::result_large_err)]
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn map_nonuser_event<U>(self) -> Result<Event<U>, Event<T>> {
|
pub fn map_nonuser_event<U>(self) -> Result<Event<U, Extra>, Event<T, Extra>> {
|
||||||
use self::Event::*;
|
use self::Event::*;
|
||||||
match self {
|
match self {
|
||||||
UserEvent(_) => Err(self),
|
UserEvent(_) => Err(self),
|
||||||
@@ -304,8 +304,10 @@ pub enum StartCause {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Describes an event from a [`Window`].
|
/// Describes an event from a [`Window`].
|
||||||
|
///
|
||||||
|
/// [`Window`]: https://docs.rs/winit/latest/winit/window/struct.Window.html
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum WindowEvent {
|
pub enum WindowEvent<KeyExtra> {
|
||||||
/// The activation token was delivered back and now could be used.
|
/// The activation token was delivered back and now could be used.
|
||||||
///
|
///
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -367,7 +369,7 @@ pub enum WindowEvent {
|
|||||||
/// events which are not marked as `is_synthetic`.
|
/// events which are not marked as `is_synthetic`.
|
||||||
KeyboardInput {
|
KeyboardInput {
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
event: KeyEvent,
|
event: KeyEvent<KeyExtra>,
|
||||||
|
|
||||||
/// If `true`, the event was generated synthetically by winit
|
/// If `true`, the event was generated synthetically by winit
|
||||||
/// in one of the following circumstances:
|
/// in one of the following circumstances:
|
||||||
@@ -391,6 +393,8 @@ pub enum WindowEvent {
|
|||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS / Android / Web / Orbital:** Unsupported.
|
/// - **iOS / Android / Web / Orbital:** Unsupported.
|
||||||
|
///
|
||||||
|
/// [`Window::set_ime_allowed`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_ime_allowed
|
||||||
Ime(Ime),
|
Ime(Ime),
|
||||||
|
|
||||||
/// The cursor has moved on the window.
|
/// The cursor has moved on the window.
|
||||||
@@ -596,33 +600,11 @@ pub enum WindowEvent {
|
|||||||
///
|
///
|
||||||
/// Winit will aggregate duplicate redraw requests into a single event, to
|
/// Winit will aggregate duplicate redraw requests into a single event, to
|
||||||
/// help avoid duplicating rendering work.
|
/// help avoid duplicating rendering work.
|
||||||
|
///
|
||||||
|
/// [`Window::request_redraw`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.request_redraw
|
||||||
RedrawRequested,
|
RedrawRequested,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Identifier of an input device.
|
|
||||||
///
|
|
||||||
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
|
||||||
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
|
|
||||||
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeviceId(pub(crate) platform_impl::DeviceId);
|
|
||||||
|
|
||||||
impl DeviceId {
|
|
||||||
/// Returns a dummy id, useful for unit testing.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The only guarantee made about the return value of this function is that
|
|
||||||
/// it will always be equal to itself and to future values returned by this function.
|
|
||||||
/// No other guarantees are made. This may be equal to a real `DeviceId`.
|
|
||||||
///
|
|
||||||
/// **Passing this into a winit function will result in undefined behavior.**
|
|
||||||
pub const unsafe fn dummy() -> Self {
|
|
||||||
#[allow(unused_unsafe)]
|
|
||||||
DeviceId(unsafe { platform_impl::DeviceId::dummy() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents raw hardware events that are not associated with any particular window.
|
/// Represents raw hardware events that are not associated with any particular window.
|
||||||
///
|
///
|
||||||
/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
|
/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
|
||||||
@@ -683,7 +665,7 @@ pub struct RawKeyEvent {
|
|||||||
|
|
||||||
/// Describes a keyboard input targeting a window.
|
/// Describes a keyboard input targeting a window.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct KeyEvent {
|
pub struct KeyEvent<Extra> {
|
||||||
/// Represents the position of a key independent of the currently active layout.
|
/// Represents the position of a key independent of the currently active layout.
|
||||||
///
|
///
|
||||||
/// It also uniquely identifies the physical key (i.e. it's mostly synonymous with a scancode).
|
/// It also uniquely identifies the physical key (i.e. it's mostly synonymous with a scancode).
|
||||||
@@ -733,7 +715,7 @@ pub struct KeyEvent {
|
|||||||
/// - **Web:** Dead keys might be reported as the real key instead
|
/// - **Web:** Dead keys might be reported as the real key instead
|
||||||
/// of `Dead` depending on the browser/OS.
|
/// of `Dead` depending on the browser/OS.
|
||||||
///
|
///
|
||||||
/// [`key_without_modifiers`]: crate::platform::modifier_supplement::KeyEventExtModifierSupplement::key_without_modifiers
|
/// [`key_without_modifiers`]: https://docs.rs/winit/latest/winit/platform/modifier_supplement/trait.KeyEventExtModifierSupplement.html#tymethod.key_without_modifiers
|
||||||
pub logical_key: keyboard::Key,
|
pub logical_key: keyboard::Key,
|
||||||
|
|
||||||
/// Contains the text produced by this keypress.
|
/// Contains the text produced by this keypress.
|
||||||
@@ -790,7 +772,7 @@ pub struct KeyEvent {
|
|||||||
/// modifiers applied.
|
/// modifiers applied.
|
||||||
///
|
///
|
||||||
/// On Android, iOS, Redox and Web, this type is a no-op.
|
/// On Android, iOS, Redox and Web, this type is a no-op.
|
||||||
pub(crate) platform_specific: platform_impl::KeyEventExtra,
|
pub extra: Extra,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes keyboard modifiers event.
|
/// Describes keyboard modifiers event.
|
||||||
@@ -805,6 +787,15 @@ pub struct Modifiers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Modifiers {
|
impl Modifiers {
|
||||||
|
/// Only `winit` should instantiate this!
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn new(state: ModifiersState, pressed_mods: ModifiersKeys) -> Self {
|
||||||
|
Self {
|
||||||
|
state,
|
||||||
|
pressed_mods,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The state of the modifiers.
|
/// The state of the modifiers.
|
||||||
pub fn state(&self) -> ModifiersState {
|
pub fn state(&self) -> ModifiersState {
|
||||||
self.state
|
self.state
|
||||||
@@ -904,6 +895,8 @@ impl From<ModifiersState> for Modifiers {
|
|||||||
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
||||||
/// Ime::Commit("啊不")
|
/// Ime::Commit("啊不")
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Window::set_ime_cursor_area`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_ime_cursor_area
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum Ime {
|
pub enum Ime {
|
||||||
@@ -912,6 +905,8 @@ pub enum Ime {
|
|||||||
/// After getting this event you could receive [`Preedit`](Self::Preedit) and
|
/// After getting this event you could receive [`Preedit`](Self::Preedit) and
|
||||||
/// [`Commit`](Self::Commit) events. You should also start performing IME related requests
|
/// [`Commit`](Self::Commit) events. You should also start performing IME related requests
|
||||||
/// like [`Window::set_ime_cursor_area`].
|
/// like [`Window::set_ime_cursor_area`].
|
||||||
|
///
|
||||||
|
/// [`Window::set_ime_cursor_area`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_ime_cursor_area
|
||||||
Enabled,
|
Enabled,
|
||||||
|
|
||||||
/// Notifies when a new composing text should be set at the cursor position.
|
/// Notifies when a new composing text should be set at the cursor position.
|
||||||
@@ -934,6 +929,8 @@ pub enum Ime {
|
|||||||
/// [`Commit`](Self::Commit) events until the next [`Enabled`](Self::Enabled) event. You should
|
/// [`Commit`](Self::Commit) events until the next [`Enabled`](Self::Enabled) event. You should
|
||||||
/// also stop issuing IME related requests like [`Window::set_ime_cursor_area`] and clear pending
|
/// also stop issuing IME related requests like [`Window::set_ime_cursor_area`] and clear pending
|
||||||
/// preedit text.
|
/// preedit text.
|
||||||
|
///
|
||||||
|
/// [`Window::set_ime_cursor_area`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_ime_cursor_area
|
||||||
Disabled,
|
Disabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,7 +1119,7 @@ pub struct InnerSizeWriter {
|
|||||||
|
|
||||||
impl InnerSizeWriter {
|
impl InnerSizeWriter {
|
||||||
#[cfg(not(orbital_platform))]
|
#[cfg(not(orbital_platform))]
|
||||||
pub(crate) fn new(new_inner_size: Weak<Mutex<PhysicalSize<u32>>>) -> Self {
|
pub fn new(new_inner_size: Weak<Mutex<PhysicalSize<u32>>>) -> Self {
|
||||||
Self { new_inner_size }
|
Self { new_inner_size }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1130,14 +1127,19 @@ impl InnerSizeWriter {
|
|||||||
pub fn request_inner_size(
|
pub fn request_inner_size(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_inner_size: PhysicalSize<u32>,
|
new_inner_size: PhysicalSize<u32>,
|
||||||
) -> Result<(), ExternalError> {
|
) -> Result<(), InnerSizeIgnored> {
|
||||||
if let Some(inner) = self.new_inner_size.upgrade() {
|
if let Some(inner) = self.new_inner_size.upgrade() {
|
||||||
*inner.lock().unwrap() = new_inner_size;
|
*inner.lock().unwrap() = new_inner_size;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ExternalError::Ignored)
|
Err(InnerSizeIgnored { _private: () })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the underlying size.
|
||||||
|
pub fn get(&self) -> PhysicalSize<u32> {
|
||||||
|
*self.new_inner_size.upgrade().unwrap().lock().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for InnerSizeWriter {
|
impl PartialEq for InnerSizeWriter {
|
||||||
@@ -1146,6 +1148,25 @@ impl PartialEq for InnerSizeWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Could not write the inner size.
|
||||||
|
pub struct InnerSizeIgnored {
|
||||||
|
_private: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for InnerSizeIgnored {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("InnerSizeIgnored").finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InnerSizeIgnored {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str("tried to write inner size after")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for InnerSizeIgnored {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::event;
|
use crate::event;
|
||||||
@@ -1271,7 +1292,7 @@ mod tests {
|
|||||||
#[allow(clippy::redundant_clone)]
|
#[allow(clippy::redundant_clone)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_event_clone() {
|
fn test_event_clone() {
|
||||||
foreach_event!(|event: event::Event<()>| {
|
foreach_event!(|event: event::Event<(), ()>| {
|
||||||
let event2 = event.clone();
|
let event2 = event.clone();
|
||||||
assert_eq!(event, event2);
|
assert_eq!(event, event2);
|
||||||
})
|
})
|
||||||
@@ -1279,7 +1300,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_map_nonuser_event() {
|
fn test_map_nonuser_event() {
|
||||||
foreach_event!(|event: event::Event<()>| {
|
foreach_event!(|event: event::Event<(), ()>| {
|
||||||
let is_user = matches!(event, event::Event::UserEvent(()));
|
let is_user = matches!(event, event::Event::UserEvent(()));
|
||||||
let event2 = event.map_nonuser_event::<()>();
|
let event2 = event.map_nonuser_event::<()>();
|
||||||
if is_user {
|
if is_user {
|
||||||
@@ -1313,7 +1334,7 @@ mod tests {
|
|||||||
#[allow(clippy::clone_on_copy)]
|
#[allow(clippy::clone_on_copy)]
|
||||||
#[test]
|
#[test]
|
||||||
fn ensure_attrs_do_not_panic() {
|
fn ensure_attrs_do_not_panic() {
|
||||||
foreach_event!(|event: event::Event<()>| {
|
foreach_event!(|event: event::Event<(), ()>| {
|
||||||
let _ = format!("{:?}", event);
|
let _ = format!("{:?}", event);
|
||||||
});
|
});
|
||||||
let _ = event::StartCause::Init.clone();
|
let _ = event::StartCause::Init.clone();
|
||||||
80
winit-core/src/event_loop.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//! Types needed to define the event loop.
|
||||||
|
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
|
#[cfg(not(web_platform))]
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
#[cfg(web_platform)]
|
||||||
|
use web_time::{Duration, Instant};
|
||||||
|
|
||||||
|
/// A unique identifier of the winit's async request.
|
||||||
|
///
|
||||||
|
/// This could be used to identify the async request once it's done
|
||||||
|
/// and a specific action must be taken.
|
||||||
|
///
|
||||||
|
/// One of the handling scenarious could be to maintain a working list
|
||||||
|
/// containing [`AsyncRequestSerial`] and some closure associated with it.
|
||||||
|
/// Then once event is arriving the working list is being traversed and a job
|
||||||
|
/// executed and removed from the list.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct AsyncRequestSerial {
|
||||||
|
serial: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRequestSerial {
|
||||||
|
/// Get the next serial in the sequence.
|
||||||
|
pub fn get() -> Self {
|
||||||
|
static CURRENT_SERIAL: AtomicU64 = AtomicU64::new(0);
|
||||||
|
// NOTE: we rely on wrap around here, while the user may just request
|
||||||
|
// in the loop u64::MAX times that's issue is considered on them.
|
||||||
|
let serial = CURRENT_SERIAL.fetch_add(1, Ordering::Relaxed);
|
||||||
|
Self { serial }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set through [`EventLoopWindowTarget::set_control_flow()`].
|
||||||
|
///
|
||||||
|
/// Indicates the desired behavior of the event loop after [`Event::AboutToWait`] is emitted.
|
||||||
|
///
|
||||||
|
/// Defaults to [`Wait`].
|
||||||
|
///
|
||||||
|
/// [`Wait`]: Self::Wait
|
||||||
|
///
|
||||||
|
/// [`EventLoopWindowTarget::set_control_flow()`]: https://docs.rs/winit/latest/winit/event_loop/struct.EventLoopWindowTarget.html#method.set_control_flow
|
||||||
|
/// [`Event::AboutToWait`]: crate::event::Event::AboutToWait
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
pub enum ControlFlow {
|
||||||
|
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
|
||||||
|
/// whether or not new events are available to process.
|
||||||
|
Poll,
|
||||||
|
|
||||||
|
/// When the current loop iteration finishes, suspend the thread until another event arrives.
|
||||||
|
#[default]
|
||||||
|
Wait,
|
||||||
|
|
||||||
|
/// When the current loop iteration finishes, suspend the thread until either another event
|
||||||
|
/// arrives or the given time is reached.
|
||||||
|
///
|
||||||
|
/// Useful for implementing efficient timers. Applications which want to render at the display's
|
||||||
|
/// native refresh rate should instead use [`Poll`] and the VSync functionality of a graphics API
|
||||||
|
/// to reduce odds of missed frames.
|
||||||
|
///
|
||||||
|
/// [`Poll`]: Self::Poll
|
||||||
|
WaitUntil(Instant),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ControlFlow {
|
||||||
|
/// Creates a [`ControlFlow`] that waits until a timeout has expired.
|
||||||
|
///
|
||||||
|
/// In most cases, this is set to [`WaitUntil`]. However, if the timeout overflows, it is
|
||||||
|
/// instead set to [`Wait`].
|
||||||
|
///
|
||||||
|
/// [`WaitUntil`]: Self::WaitUntil
|
||||||
|
/// [`Wait`]: Self::Wait
|
||||||
|
pub fn wait_duration(timeout: Duration) -> Self {
|
||||||
|
match Instant::now().checked_add(timeout) {
|
||||||
|
Some(instant) => Self::WaitUntil(instant),
|
||||||
|
None => Self::Wait,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1454,6 +1454,29 @@ pub enum NamedKey {
|
|||||||
F35,
|
F35,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: the exact modifier key is not used to represent modifiers state in the
|
||||||
|
// first place due to a fact that modifiers state could be changed without any
|
||||||
|
// key being pressed and on some platforms like Wayland/X11 which key resulted
|
||||||
|
// in modifiers change is hidden, also, not that it really matters.
|
||||||
|
//
|
||||||
|
// The reason this API is even exposed is mostly to provide a way for users
|
||||||
|
// to treat modifiers differently based on their position, which is required
|
||||||
|
// on macOS due to their AltGr/Option situation.
|
||||||
|
bitflags! {
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ModifiersKeys: u8 {
|
||||||
|
const LSHIFT = 0b0000_0001;
|
||||||
|
const RSHIFT = 0b0000_0010;
|
||||||
|
const LCONTROL = 0b0000_0100;
|
||||||
|
const RCONTROL = 0b0000_1000;
|
||||||
|
const LALT = 0b0001_0000;
|
||||||
|
const RALT = 0b0010_0000;
|
||||||
|
const LSUPER = 0b0100_0000;
|
||||||
|
const RSUPER = 0b1000_0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Key represents the meaning of a keypress.
|
/// Key represents the meaning of a keypress.
|
||||||
///
|
///
|
||||||
/// This is a superset of the UI Events Specification's [`KeyboardEvent.key`] with
|
/// This is a superset of the UI Events Specification's [`KeyboardEvent.key`] with
|
||||||
@@ -1565,7 +1588,7 @@ impl NamedKey {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use winit::keyboard::NamedKey;
|
/// use winit_core::keyboard::NamedKey;
|
||||||
///
|
///
|
||||||
/// assert_eq!(NamedKey::Enter.to_text(), Some("\r"));
|
/// assert_eq!(NamedKey::Enter.to_text(), Some("\r"));
|
||||||
/// assert_eq!(NamedKey::F20.to_text(), None);
|
/// assert_eq!(NamedKey::F20.to_text(), None);
|
||||||
@@ -1588,7 +1611,7 @@ impl Key {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use winit::keyboard::{NamedKey, Key};
|
/// use winit_core::keyboard::{NamedKey, Key};
|
||||||
///
|
///
|
||||||
/// assert_eq!(Key::Character("a".into()).to_text(), Some("a"));
|
/// assert_eq!(Key::Character("a".into()).to_text(), Some("a"));
|
||||||
/// assert_eq!(Key::Named(NamedKey::Enter).to_text(), Some("\r"));
|
/// assert_eq!(Key::Named(NamedKey::Enter).to_text(), Some("\r"));
|
||||||
@@ -1727,28 +1750,6 @@ pub enum ModifiersKeyState {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: the exact modifier key is not used to represent modifiers state in the
|
|
||||||
// first place due to a fact that modifiers state could be changed without any
|
|
||||||
// key being pressed and on some platforms like Wayland/X11 which key resulted
|
|
||||||
// in modifiers change is hidden, also, not that it really matters.
|
|
||||||
//
|
|
||||||
// The reason this API is even exposed is mostly to provide a way for users
|
|
||||||
// to treat modifiers differently based on their position, which is required
|
|
||||||
// on macOS due to their AltGr/Option situation.
|
|
||||||
bitflags! {
|
|
||||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct ModifiersKeys: u8 {
|
|
||||||
const LSHIFT = 0b0000_0001;
|
|
||||||
const RSHIFT = 0b0000_0010;
|
|
||||||
const LCONTROL = 0b0000_0100;
|
|
||||||
const RCONTROL = 0b0000_1000;
|
|
||||||
const LALT = 0b0001_0000;
|
|
||||||
const RALT = 0b0010_0000;
|
|
||||||
const LSUPER = 0b0100_0000;
|
|
||||||
const RSUPER = 0b1000_0000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
mod modifiers_serde {
|
mod modifiers_serde {
|
||||||
use super::ModifiersState;
|
use super::ModifiersState;
|
||||||
18
winit-core/src/lib.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//! Base types for a windowing library.
|
||||||
|
//!
|
||||||
|
//! This crate contains types, traits and basic functions from [`winit`] that are platform
|
||||||
|
//! independent. It is intended to allow for other crates to build abstractions around [`winit`]
|
||||||
|
//! without needing to pull in all of [`winit`]'s dependencies, as well as to provide an
|
||||||
|
//! interface for alternative backends for [`winit`] to be constructed.
|
||||||
|
//!
|
||||||
|
//! [`winit`]: https://docs.rs/winit
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "std"), not(feature = "alloc")))]
|
||||||
|
compile_error! { "no-std and no-alloc usage are not yet supported" }
|
||||||
|
|
||||||
|
pub mod dpi;
|
||||||
|
pub mod error;
|
||||||
|
pub mod event;
|
||||||
|
pub mod event_loop;
|
||||||
|
pub mod keyboard;
|
||||||
|
pub mod window;
|
||||||
229
winit-core/src/window.rs
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
//! Types used in window construction.
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
pub use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Identifier of a window. Unique for each window.
|
||||||
|
///
|
||||||
|
/// Can be obtained with [`window.id()`](https://docs.rs/winit/latest/winit/window/struct.Window.html#method.id).
|
||||||
|
///
|
||||||
|
/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
|
||||||
|
/// can then compare to the ids of your windows.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct WindowId(u64);
|
||||||
|
|
||||||
|
impl WindowId {
|
||||||
|
/// Returns a dummy id, useful for unit testing.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The only guarantee made about the return value of this function is that
|
||||||
|
/// it will always be equal to itself and to future values returned by this function.
|
||||||
|
/// No other guarantees are made. This may be equal to a real [`WindowId`].
|
||||||
|
///
|
||||||
|
/// **Passing this into a winit function will result in undefined behavior.**
|
||||||
|
pub const unsafe fn dummy() -> Self {
|
||||||
|
WindowId(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WindowId> for u64 {
|
||||||
|
fn from(window_id: WindowId) -> Self {
|
||||||
|
window_id.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for WindowId {
|
||||||
|
fn from(raw_id: u64) -> Self {
|
||||||
|
Self(raw_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The behavior of cursor grabbing.
|
||||||
|
///
|
||||||
|
/// Use this enum with [`Window::set_cursor_grab`] to grab the cursor.
|
||||||
|
///
|
||||||
|
/// [`Window::set_cursor_grab`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_cursor_grab
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum CursorGrabMode {
|
||||||
|
/// No grabbing of the cursor is performed.
|
||||||
|
None,
|
||||||
|
|
||||||
|
/// The cursor is confined to the window area.
|
||||||
|
///
|
||||||
|
/// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
|
||||||
|
/// want to do so.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Not implemented. Always returns [`ExternalError::NotSupported`] for now.
|
||||||
|
/// - **iOS / Android / Web / Orbital:** Always returns an [`ExternalError::NotSupported`].
|
||||||
|
///
|
||||||
|
/// [`ExternalError::NotSupported`]: https://docs.rs/winit/latest/winit/error/enum.ExternalError.html#variant.NotSupported
|
||||||
|
Confined,
|
||||||
|
|
||||||
|
/// The cursor is locked inside the window area to the certain position.
|
||||||
|
///
|
||||||
|
/// There's no guarantee that the cursor will be hidden. You should hide it by yourself if you
|
||||||
|
/// want to do so.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **X11 / Windows:** Not implemented. Always returns [`ExternalError::NotSupported`] for now.
|
||||||
|
/// - **iOS / Android / Orbital:** Always returns an [`ExternalError::NotSupported`].
|
||||||
|
///
|
||||||
|
/// [`ExternalError::NotSupported`]: https://docs.rs/winit/latest/winit/error/enum.ExternalError.html#variant.NotSupported
|
||||||
|
Locked,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines the orientation that a window resize will be performed.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ResizeDirection {
|
||||||
|
East,
|
||||||
|
North,
|
||||||
|
NorthEast,
|
||||||
|
NorthWest,
|
||||||
|
South,
|
||||||
|
SouthEast,
|
||||||
|
SouthWest,
|
||||||
|
West,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ResizeDirection> for CursorIcon {
|
||||||
|
fn from(direction: ResizeDirection) -> Self {
|
||||||
|
use ResizeDirection::*;
|
||||||
|
match direction {
|
||||||
|
East => CursorIcon::EResize,
|
||||||
|
North => CursorIcon::NResize,
|
||||||
|
NorthEast => CursorIcon::NeResize,
|
||||||
|
NorthWest => CursorIcon::NwResize,
|
||||||
|
South => CursorIcon::SResize,
|
||||||
|
SouthEast => CursorIcon::SeResize,
|
||||||
|
SouthWest => CursorIcon::SwResize,
|
||||||
|
West => CursorIcon::WResize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The theme variant to use.
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum Theme {
|
||||||
|
/// Use the light variant.
|
||||||
|
Light,
|
||||||
|
|
||||||
|
/// Use the dark variant.
|
||||||
|
Dark,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between [`Critical`] and [`Informational`].
|
||||||
|
///
|
||||||
|
/// [`Critical`]: Self::Critical
|
||||||
|
/// [`Informational`]: Self::Informational
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||||
|
pub enum UserAttentionType {
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Bounces the dock icon until the application is in focus.
|
||||||
|
/// - **Windows:** Flashes both the window and the taskbar button until the application is in focus.
|
||||||
|
Critical,
|
||||||
|
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Bounces the dock icon once.
|
||||||
|
/// - **Windows:** Flashes the taskbar button until the application is in focus.
|
||||||
|
#[default]
|
||||||
|
Informational,
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct WindowButtons: u32 {
|
||||||
|
const CLOSE = 1 << 0;
|
||||||
|
const MINIMIZE = 1 << 1;
|
||||||
|
const MAXIMIZE = 1 << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A window level groups windows with respect to their z-position.
|
||||||
|
///
|
||||||
|
/// The relative ordering between windows in different window levels is fixed.
|
||||||
|
/// The z-order of a window within the same window level may change dynamically on user interaction.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Wayland:** Unsupported.
|
||||||
|
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub enum WindowLevel {
|
||||||
|
/// The window will always be below normal windows.
|
||||||
|
///
|
||||||
|
/// This is useful for a widget-based app.
|
||||||
|
AlwaysOnBottom,
|
||||||
|
|
||||||
|
/// The default.
|
||||||
|
#[default]
|
||||||
|
Normal,
|
||||||
|
|
||||||
|
/// The window will always be on top of normal windows.
|
||||||
|
AlwaysOnTop,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic IME purposes for use in [`Window::set_ime_purpose`].
|
||||||
|
///
|
||||||
|
/// The purpose may improve UX by optimizing the IME for the specific use case,
|
||||||
|
/// if winit can express the purpose to the platform and the platform reacts accordingly.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS / Android / Web / Windows / X11 / macOS / Orbital:** Unsupported.
|
||||||
|
///
|
||||||
|
/// [`Window::set_ime_purpose`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.set_ime_purpose
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum ImePurpose {
|
||||||
|
/// No special hints for the IME (default).
|
||||||
|
Normal,
|
||||||
|
/// The IME is used for password input.
|
||||||
|
Password,
|
||||||
|
/// The IME is used to input into a terminal.
|
||||||
|
///
|
||||||
|
/// For example, that could alter OSK on Wayland to show extra buttons.
|
||||||
|
Terminal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ImePurpose {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An stringly-typed token used to activate the [`Window`].
|
||||||
|
///
|
||||||
|
/// [`Window`]: https://docs.rs/winit/latest/winit/window/struct.Window.html
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub struct ActivationToken {
|
||||||
|
pub(crate) token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivationToken {
|
||||||
|
/// Create a new [`ActivationToken`].
|
||||||
|
pub fn new(token: String) -> Self {
|
||||||
|
Self { token }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the underlying token.
|
||||||
|
pub fn token(&self) -> &str {
|
||||||
|
&self.token
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert into the underlying token.
|
||||||
|
pub fn into_token(self) -> String {
|
||||||
|
self.token
|
||||||
|
}
|
||||||
|
}
|
||||||
261
winit/Cargo.toml
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
[package]
|
||||||
|
name = "winit"
|
||||||
|
version = "0.29.10"
|
||||||
|
authors = ["The winit contributors", "Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||||
|
description = "Cross-platform window creation library."
|
||||||
|
edition = "2021"
|
||||||
|
keywords = ["windowing"]
|
||||||
|
license = "Apache-2.0"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/rust-windowing/winit"
|
||||||
|
documentation = "https://docs.rs/winit"
|
||||||
|
categories = ["gui"]
|
||||||
|
rust-version = "1.70.0"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
features = [
|
||||||
|
"rwh_04",
|
||||||
|
"rwh_05",
|
||||||
|
"rwh_06",
|
||||||
|
"serde",
|
||||||
|
"mint",
|
||||||
|
# Enabled to get docs to compile
|
||||||
|
"android-native-activity",
|
||||||
|
]
|
||||||
|
default-target = "x86_64-unknown-linux-gnu"
|
||||||
|
# These are all tested in CI
|
||||||
|
targets = [
|
||||||
|
# Windows
|
||||||
|
"i686-pc-windows-msvc",
|
||||||
|
"x86_64-pc-windows-msvc",
|
||||||
|
# macOS
|
||||||
|
"x86_64-apple-darwin",
|
||||||
|
# Unix (X11 & Wayland)
|
||||||
|
"i686-unknown-linux-gnu",
|
||||||
|
"x86_64-unknown-linux-gnu",
|
||||||
|
# iOS
|
||||||
|
"x86_64-apple-ios",
|
||||||
|
# Android
|
||||||
|
"aarch64-linux-android",
|
||||||
|
# Web
|
||||||
|
"wasm32-unknown-unknown",
|
||||||
|
]
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["rwh_06", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
|
||||||
|
x11 = ["x11-dl", "bytemuck", "percent-encoding", "xkbcommon-dl/x11", "x11rb"]
|
||||||
|
wayland = ["wayland-client", "wayland-backend", "wayland-protocols", "wayland-protocols-plasma", "sctk", "ahash", "memmap2"]
|
||||||
|
wayland-dlopen = ["wayland-backend/dlopen"]
|
||||||
|
wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/ab_glyph"]
|
||||||
|
wayland-csd-adwaita-crossfont = ["sctk-adwaita", "sctk-adwaita/crossfont"]
|
||||||
|
wayland-csd-adwaita-notitle = ["sctk-adwaita"]
|
||||||
|
android-native-activity = ["android-activity/native-activity"]
|
||||||
|
android-game-activity = ["android-activity/game-activity"]
|
||||||
|
mint = ["winit-core/mint"]
|
||||||
|
serde = ["dep:serde", "winit-core/serde", "cursor-icon/serde", "smol_str/serde"]
|
||||||
|
rwh_04 = ["dep:rwh_04", "ndk/rwh_04"]
|
||||||
|
rwh_05 = ["dep:rwh_05", "ndk/rwh_05"]
|
||||||
|
rwh_06 = ["dep:rwh_06", "ndk/rwh_06"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cfg_aliases.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags.workspace = true
|
||||||
|
cursor-icon.workspace = true
|
||||||
|
log = "0.4"
|
||||||
|
once_cell = "1.12"
|
||||||
|
rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true }
|
||||||
|
rwh_05 = { package = "raw-window-handle", version = "0.5.2", features = ["std"], optional = true }
|
||||||
|
rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"], optional = true }
|
||||||
|
serde = { workspace = true, optional = true }
|
||||||
|
smol_str.workspace = true
|
||||||
|
winit-core.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
image = { version = "0.24.0", default-features = false, features = ["png"] }
|
||||||
|
simple_logger = { version = "4.2.0", default_features = false }
|
||||||
|
winit = { path = ".", features = ["rwh_05"] }
|
||||||
|
|
||||||
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dev-dependencies]
|
||||||
|
softbuffer = { version = "0.3.0", default-features = false, features = ["x11", "x11-dlopen", "wayland", "wayland-dlopen"] }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
|
android-activity = "0.5.0"
|
||||||
|
ndk = { version = "0.8.0", default-features = false }
|
||||||
|
ndk-sys = "0.5.0"
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
|
||||||
|
core-foundation = "0.9.3"
|
||||||
|
objc2 = "0.5.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
core-graphics = "0.23.1"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies.icrate]
|
||||||
|
version = "0.1.0"
|
||||||
|
features = [
|
||||||
|
"dispatch",
|
||||||
|
"Foundation",
|
||||||
|
"Foundation_NSArray",
|
||||||
|
"Foundation_NSAttributedString",
|
||||||
|
"Foundation_NSMutableAttributedString",
|
||||||
|
"Foundation_NSData",
|
||||||
|
"Foundation_NSDictionary",
|
||||||
|
"Foundation_NSString",
|
||||||
|
"Foundation_NSProcessInfo",
|
||||||
|
"Foundation_NSThread",
|
||||||
|
"Foundation_NSNumber",
|
||||||
|
"AppKit",
|
||||||
|
"AppKit_NSAppearance",
|
||||||
|
"AppKit_NSApplication",
|
||||||
|
"AppKit_NSBitmapImageRep",
|
||||||
|
"AppKit_NSButton",
|
||||||
|
"AppKit_NSColor",
|
||||||
|
"AppKit_NSControl",
|
||||||
|
"AppKit_NSCursor",
|
||||||
|
"AppKit_NSEvent",
|
||||||
|
"AppKit_NSGraphicsContext",
|
||||||
|
"AppKit_NSImage",
|
||||||
|
"AppKit_NSImageRep",
|
||||||
|
"AppKit_NSMenu",
|
||||||
|
"AppKit_NSMenuItem",
|
||||||
|
"AppKit_NSPasteboard",
|
||||||
|
"AppKit_NSResponder",
|
||||||
|
"AppKit_NSScreen",
|
||||||
|
"AppKit_NSTextInputContext",
|
||||||
|
"AppKit_NSView",
|
||||||
|
"AppKit_NSWindow",
|
||||||
|
"AppKit_NSWindowTabGroup",
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "ios")'.dependencies.icrate]
|
||||||
|
version = "0.1.0"
|
||||||
|
features = [
|
||||||
|
"dispatch",
|
||||||
|
"Foundation",
|
||||||
|
"Foundation_NSArray",
|
||||||
|
"Foundation_NSString",
|
||||||
|
"Foundation_NSProcessInfo",
|
||||||
|
"Foundation_NSThread",
|
||||||
|
"Foundation_NSSet",
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
unicode-segmentation = "1.7.1"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
|
||||||
|
version = "0.48"
|
||||||
|
features = [
|
||||||
|
"Win32_Devices_HumanInterfaceDevice",
|
||||||
|
"Win32_Foundation",
|
||||||
|
"Win32_Globalization",
|
||||||
|
"Win32_Graphics_Dwm",
|
||||||
|
"Win32_Graphics_Gdi",
|
||||||
|
"Win32_Media",
|
||||||
|
"Win32_System_Com_StructuredStorage",
|
||||||
|
"Win32_System_Com",
|
||||||
|
"Win32_System_LibraryLoader",
|
||||||
|
"Win32_System_Ole",
|
||||||
|
"Win32_System_SystemInformation",
|
||||||
|
"Win32_System_SystemServices",
|
||||||
|
"Win32_System_Threading",
|
||||||
|
"Win32_System_WindowsProgramming",
|
||||||
|
"Win32_UI_Accessibility",
|
||||||
|
"Win32_UI_Controls",
|
||||||
|
"Win32_UI_HiDpi",
|
||||||
|
"Win32_UI_Input_Ime",
|
||||||
|
"Win32_UI_Input_KeyboardAndMouse",
|
||||||
|
"Win32_UI_Input_Pointer",
|
||||||
|
"Win32_UI_Input_Touch",
|
||||||
|
"Win32_UI_Shell",
|
||||||
|
"Win32_UI_TextServices",
|
||||||
|
"Win32_UI_WindowsAndMessaging",
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_os = "ios", target_os = "macos"))))'.dependencies]
|
||||||
|
ahash = { version = "0.8.3", features = ["no-rng"], optional = true }
|
||||||
|
bytemuck = { version = "1.13.1", default-features = false, optional = true }
|
||||||
|
calloop = "0.12.3"
|
||||||
|
libc = "0.2.64"
|
||||||
|
memmap2 = { version = "0.9.0", optional = true }
|
||||||
|
percent-encoding = { version = "2.0", optional = true }
|
||||||
|
rustix = { version = "0.38.4", default-features = false, features = ["std", "system", "thread", "process"] }
|
||||||
|
sctk = { package = "smithay-client-toolkit", version = "0.18.0", default-features = false, features = ["calloop"], optional = true }
|
||||||
|
sctk-adwaita = { version = "0.8.0", default_features = false, optional = true }
|
||||||
|
wayland-backend = { version = "0.3.0", default_features = false, features = ["client_system"], optional = true }
|
||||||
|
wayland-client = { version = "0.31.1", optional = true }
|
||||||
|
wayland-protocols = { version = "0.31.0", features = [ "staging"], optional = true }
|
||||||
|
wayland-protocols-plasma = { version = "0.2.0", features = [ "client" ], optional = true }
|
||||||
|
x11-dl = { version = "2.18.5", optional = true }
|
||||||
|
x11rb = { version = "0.13.0", default-features = false, features = ["allow-unsafe-code", "dl-libxcb", "randr", "resource_manager", "xinput", "xkb"], optional = true }
|
||||||
|
xkbcommon-dl = "0.4.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "redox")'.dependencies]
|
||||||
|
orbclient = { version = "0.3.47", default-features = false }
|
||||||
|
redox_syscall = "0.4.1"
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "wasm")'.dependencies.web_sys]
|
||||||
|
package = "web-sys"
|
||||||
|
version = "0.3.64"
|
||||||
|
features = [
|
||||||
|
'AbortController',
|
||||||
|
'AbortSignal',
|
||||||
|
'Blob',
|
||||||
|
'console',
|
||||||
|
'CssStyleDeclaration',
|
||||||
|
'Document',
|
||||||
|
'DomException',
|
||||||
|
'DomRect',
|
||||||
|
'DomRectReadOnly',
|
||||||
|
'Element',
|
||||||
|
'Event',
|
||||||
|
'EventTarget',
|
||||||
|
'FocusEvent',
|
||||||
|
'HtmlCanvasElement',
|
||||||
|
'HtmlElement',
|
||||||
|
'HtmlImageElement',
|
||||||
|
'ImageBitmap',
|
||||||
|
'ImageBitmapOptions',
|
||||||
|
'ImageBitmapRenderingContext',
|
||||||
|
'ImageData',
|
||||||
|
'IntersectionObserver',
|
||||||
|
'IntersectionObserverEntry',
|
||||||
|
'KeyboardEvent',
|
||||||
|
'MediaQueryList',
|
||||||
|
'MessageChannel',
|
||||||
|
'MessagePort',
|
||||||
|
'Node',
|
||||||
|
'PageTransitionEvent',
|
||||||
|
'PointerEvent',
|
||||||
|
'PremultiplyAlpha',
|
||||||
|
'ResizeObserver',
|
||||||
|
'ResizeObserverBoxOptions',
|
||||||
|
'ResizeObserverEntry',
|
||||||
|
'ResizeObserverOptions',
|
||||||
|
'ResizeObserverSize',
|
||||||
|
'VisibilityState',
|
||||||
|
'Window',
|
||||||
|
'WheelEvent',
|
||||||
|
'Url',
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||||
|
js-sys = "0.3.64"
|
||||||
|
pin-project = "1"
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-futures = "0.4"
|
||||||
|
web-time.workspace = true
|
||||||
|
|
||||||
|
[target.'cfg(all(target_family = "wasm", target_feature = "atomics"))'.dependencies]
|
||||||
|
atomic-waker = "1"
|
||||||
|
concurrent-queue = { version = "2", default-features = false }
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "wasm")'.dev-dependencies]
|
||||||
|
console_log = "1"
|
||||||
|
web-sys = { version = "0.3.22", features = ['CanvasRenderingContext2d'] }
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
doc-scrape-examples = true
|
||||||
|
name = "window"
|
||||||
1
winit/README.md
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../README.md
|
||||||
24
winit/build.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use cfg_aliases::cfg_aliases;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// The script doesn't depend on our code
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
|
||||||
|
// Setup cfg aliases
|
||||||
|
cfg_aliases! {
|
||||||
|
// Systems.
|
||||||
|
android_platform: { target_os = "android" },
|
||||||
|
web_platform: { all(target_family = "wasm", target_os = "unknown") },
|
||||||
|
macos_platform: { target_os = "macos" },
|
||||||
|
ios_platform: { target_os = "ios" },
|
||||||
|
windows_platform: { target_os = "windows" },
|
||||||
|
apple: { any(target_os = "ios", target_os = "macos") },
|
||||||
|
free_unix: { all(unix, not(apple), not(android_platform), not(target_os = "emscripten")) },
|
||||||
|
redox: { target_os = "redox" },
|
||||||
|
|
||||||
|
// Native displays.
|
||||||
|
x11_platform: { all(feature = "x11", free_unix, not(redox)) },
|
||||||
|
wayland_platform: { all(feature = "wayland", free_unix, not(redox)) },
|
||||||
|
orbital_platform: { redox },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 229 B |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -1,6 +1,8 @@
|
|||||||
|
use crate::platform_impl;
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
use crate::platform_impl;
|
#[doc(inline)]
|
||||||
|
pub use winit_core::error::NotSupportedError;
|
||||||
|
|
||||||
// TODO: Rename
|
// TODO: Rename
|
||||||
/// An error that may be generated when requesting Winit state
|
/// An error that may be generated when requesting Winit state
|
||||||
@@ -14,10 +16,10 @@ pub enum ExternalError {
|
|||||||
Os(OsError),
|
Os(OsError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The error type for when the requested operation is not supported by the backend.
|
impl From<winit_core::event::InnerSizeIgnored> for ExternalError {
|
||||||
#[derive(Clone)]
|
fn from(_: winit_core::event::InnerSizeIgnored) -> Self {
|
||||||
pub struct NotSupportedError {
|
Self::Ignored
|
||||||
_marker: (),
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The error type for when the OS cannot perform the requested operation.
|
/// The error type for when the OS cannot perform the requested operation.
|
||||||
@@ -47,14 +49,6 @@ impl From<OsError> for EventLoopError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NotSupportedError {
|
|
||||||
#[inline]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn new() -> NotSupportedError {
|
|
||||||
NotSupportedError { _marker: () }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OsError {
|
impl OsError {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError {
|
pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError {
|
||||||
@@ -88,18 +82,6 @@ impl fmt::Display for ExternalError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for NotSupportedError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
f.debug_struct("NotSupportedError").finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for NotSupportedError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
||||||
f.pad("the requested operation is not supported by Winit")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for EventLoopError {
|
impl fmt::Display for EventLoopError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
@@ -113,7 +95,6 @@ impl fmt::Display for EventLoopError {
|
|||||||
|
|
||||||
impl error::Error for OsError {}
|
impl error::Error for OsError {}
|
||||||
impl error::Error for ExternalError {}
|
impl error::Error for ExternalError {}
|
||||||
impl error::Error for NotSupportedError {}
|
|
||||||
impl error::Error for EventLoopError {}
|
impl error::Error for EventLoopError {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -125,11 +106,6 @@ mod tests {
|
|||||||
// Eat attributes for testing
|
// Eat attributes for testing
|
||||||
#[test]
|
#[test]
|
||||||
fn ensure_fmt_does_not_panic() {
|
fn ensure_fmt_does_not_panic() {
|
||||||
let _ = format!(
|
|
||||||
"{:?}, {}",
|
|
||||||
NotSupportedError::new(),
|
|
||||||
NotSupportedError::new().clone()
|
|
||||||
);
|
|
||||||
let _ = format!(
|
let _ = format!(
|
||||||
"{:?}, {}",
|
"{:?}, {}",
|
||||||
ExternalError::NotSupported(NotSupportedError::new()),
|
ExternalError::NotSupported(NotSupportedError::new()),
|
||||||
53
winit/src/event.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//! The [`Event`] enum and assorted supporting types.
|
||||||
|
//!
|
||||||
|
//! These are sent to the closure given to [`EventLoop::run(...)`], where they get
|
||||||
|
//! processed and used to modify the program state. For more details, see the root-level documentation.
|
||||||
|
//!
|
||||||
|
//! Some of these events represent different "parts" of a traditional event-handling loop. You could
|
||||||
|
//! approximate the basic ordering loop of [`EventLoop::run(...)`] like this:
|
||||||
|
//!
|
||||||
|
//! ```rust,ignore
|
||||||
|
//! let mut start_cause = StartCause::Init;
|
||||||
|
//!
|
||||||
|
//! while !elwt.exiting() {
|
||||||
|
//! event_handler(NewEvents(start_cause), elwt);
|
||||||
|
//!
|
||||||
|
//! for e in (window events, user events, device events) {
|
||||||
|
//! event_handler(e, elwt);
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! for w in (redraw windows) {
|
||||||
|
//! event_handler(RedrawRequested(w), elwt);
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! event_handler(AboutToWait, elwt);
|
||||||
|
//! start_cause = wait_if_necessary();
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! event_handler(LoopExiting, elwt);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! This leaves out timing details like [`ControlFlow::WaitUntil`] but hopefully
|
||||||
|
//! describes what happens in what order.
|
||||||
|
//!
|
||||||
|
//! [`EventLoop::run(...)`]: crate::event_loop::EventLoop::run
|
||||||
|
//! [`ControlFlow::WaitUntil`]: crate::event_loop::ControlFlow::WaitUntil
|
||||||
|
|
||||||
|
use crate::platform_impl;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use winit_core::event::{
|
||||||
|
DeviceEvent, DeviceId, ElementState, Force, Ime, InnerSizeIgnored, InnerSizeWriter, Modifiers,
|
||||||
|
MouseButton, MouseScrollDelta, RawKeyEvent, StartCause, Touch, TouchPhase,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type Event<T> = winit_core::event::Event<T, KeyExtra>;
|
||||||
|
pub type WindowEvent = winit_core::event::WindowEvent<KeyExtra>;
|
||||||
|
pub type KeyEvent = winit_core::event::KeyEvent<KeyExtra>;
|
||||||
|
|
||||||
|
/// Extra keyboard information.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct KeyExtra {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) extra: platform_impl::KeyEventExtra,
|
||||||
|
}
|
||||||
@@ -11,17 +11,15 @@ use std::marker::PhantomData;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
#[cfg(not(web_platform))]
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
#[cfg(web_platform)]
|
|
||||||
use web_time::{Duration, Instant};
|
|
||||||
|
|
||||||
use crate::error::EventLoopError;
|
use crate::error::EventLoopError;
|
||||||
use crate::{event::Event, monitor::MonitorHandle, platform_impl};
|
use crate::{event::Event, monitor::MonitorHandle, platform_impl};
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use winit_core::event_loop::{AsyncRequestSerial, ControlFlow};
|
||||||
|
|
||||||
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
||||||
/// the events loop.
|
/// the events loop.
|
||||||
///
|
///
|
||||||
@@ -141,50 +139,6 @@ impl fmt::Debug for EventLoopWindowTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set through [`EventLoopWindowTarget::set_control_flow()`].
|
|
||||||
///
|
|
||||||
/// Indicates the desired behavior of the event loop after [`Event::AboutToWait`] is emitted.
|
|
||||||
///
|
|
||||||
/// Defaults to [`Wait`].
|
|
||||||
///
|
|
||||||
/// [`Wait`]: Self::Wait
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
|
||||||
pub enum ControlFlow {
|
|
||||||
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
|
|
||||||
/// whether or not new events are available to process.
|
|
||||||
Poll,
|
|
||||||
|
|
||||||
/// When the current loop iteration finishes, suspend the thread until another event arrives.
|
|
||||||
#[default]
|
|
||||||
Wait,
|
|
||||||
|
|
||||||
/// When the current loop iteration finishes, suspend the thread until either another event
|
|
||||||
/// arrives or the given time is reached.
|
|
||||||
///
|
|
||||||
/// Useful for implementing efficient timers. Applications which want to render at the display's
|
|
||||||
/// native refresh rate should instead use [`Poll`] and the VSync functionality of a graphics API
|
|
||||||
/// to reduce odds of missed frames.
|
|
||||||
///
|
|
||||||
/// [`Poll`]: Self::Poll
|
|
||||||
WaitUntil(Instant),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ControlFlow {
|
|
||||||
/// Creates a [`ControlFlow`] that waits until a timeout has expired.
|
|
||||||
///
|
|
||||||
/// In most cases, this is set to [`WaitUntil`]. However, if the timeout overflows, it is
|
|
||||||
/// instead set to [`Wait`].
|
|
||||||
///
|
|
||||||
/// [`WaitUntil`]: Self::WaitUntil
|
|
||||||
/// [`Wait`]: Self::Wait
|
|
||||||
pub fn wait_duration(timeout: Duration) -> Self {
|
|
||||||
match Instant::now().checked_add(timeout) {
|
|
||||||
Some(instant) => Self::WaitUntil(instant),
|
|
||||||
None => Self::Wait,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventLoop<()> {
|
impl EventLoop<()> {
|
||||||
/// Create the event loop.
|
/// Create the event loop.
|
||||||
///
|
///
|
||||||
@@ -506,29 +460,3 @@ pub enum DeviceEvents {
|
|||||||
/// Never capture device events.
|
/// Never capture device events.
|
||||||
Never,
|
Never,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A unique identifier of the winit's async request.
|
|
||||||
///
|
|
||||||
/// This could be used to identify the async request once it's done
|
|
||||||
/// and a specific action must be taken.
|
|
||||||
///
|
|
||||||
/// One of the handling scenarious could be to maintain a working list
|
|
||||||
/// containing [`AsyncRequestSerial`] and some closure associated with it.
|
|
||||||
/// Then once event is arriving the working list is being traversed and a job
|
|
||||||
/// executed and removed from the list.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub struct AsyncRequestSerial {
|
|
||||||
serial: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsyncRequestSerial {
|
|
||||||
// TODO(kchibisov) remove `cfg` when the clipboard will be added.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn get() -> Self {
|
|
||||||
static CURRENT_SERIAL: AtomicU64 = AtomicU64::new(0);
|
|
||||||
// NOTE: we rely on wrap around here, while the user may just request
|
|
||||||
// in the loop u64::MAX times that's issue is considered on them.
|
|
||||||
let serial = CURRENT_SERIAL.fetch_add(1, Ordering::Relaxed);
|
|
||||||
Self { serial }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -164,14 +164,15 @@
|
|||||||
#[cfg(feature = "rwh_06")]
|
#[cfg(feature = "rwh_06")]
|
||||||
pub use rwh_06 as raw_window_handle;
|
pub use rwh_06 as raw_window_handle;
|
||||||
|
|
||||||
pub mod dpi;
|
#[doc(inline)]
|
||||||
|
pub use winit_core::{dpi, keyboard};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod event_loop;
|
pub mod event_loop;
|
||||||
mod icon;
|
mod icon;
|
||||||
pub mod keyboard;
|
|
||||||
pub mod monitor;
|
pub mod monitor;
|
||||||
mod platform_impl;
|
mod platform_impl;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
@@ -25,7 +25,8 @@ pub trait KeyEventExtModifierSupplement {
|
|||||||
impl KeyEventExtModifierSupplement for KeyEvent {
|
impl KeyEventExtModifierSupplement for KeyEvent {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn text_with_all_modifiers(&self) -> Option<&str> {
|
fn text_with_all_modifiers(&self) -> Option<&str> {
|
||||||
self.platform_specific
|
self.extra
|
||||||
|
.extra
|
||||||
.text_with_all_modifiers
|
.text_with_all_modifiers
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|s| s.as_str())
|
.map(|s| s.as_str())
|
||||||
@@ -33,6 +34,6 @@ impl KeyEventExtModifierSupplement for KeyEvent {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn key_without_modifiers(&self) -> Key {
|
fn key_without_modifiers(&self) -> Key {
|
||||||
self.platform_specific.key_without_modifiers.clone()
|
self.extra.extra.key_without_modifiers.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ impl EventLoopExtStartupNotify for EventLoopWindowTarget {
|
|||||||
crate::platform_impl::EventLoopWindowTarget::X(_) => env::var(X11_VAR),
|
crate::platform_impl::EventLoopWindowTarget::X(_) => env::var(X11_VAR),
|
||||||
}
|
}
|
||||||
.ok()
|
.ok()
|
||||||
.map(ActivationToken::_new)
|
.map(ActivationToken::new)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +94,6 @@ pub fn reset_activation_token_env() {
|
|||||||
///
|
///
|
||||||
/// This could be used before running daemon processes.
|
/// This could be used before running daemon processes.
|
||||||
pub fn set_activation_token_env(token: ActivationToken) {
|
pub fn set_activation_token_env(token: ActivationToken) {
|
||||||
env::set_var(X11_VAR, &token._token);
|
env::set_var(X11_VAR, token.token());
|
||||||
env::set_var(WAYLAND_VAR, token._token);
|
env::set_var(WAYLAND_VAR, token.token());
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ pub trait DeviceIdExtWindows {
|
|||||||
impl DeviceIdExtWindows for DeviceId {
|
impl DeviceIdExtWindows for DeviceId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn persistent_identifier(&self) -> Option<String> {
|
fn persistent_identifier(&self) -> Option<String> {
|
||||||
self.0.persistent_identifier()
|
crate::platform_impl::persistent_identifier(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,8 @@ use crate::{
|
|||||||
event_loop::{self, ControlFlow, DeviceEvents, EventLoopWindowTarget as RootELW},
|
event_loop::{self, ControlFlow, DeviceEvents, EventLoopWindowTarget as RootELW},
|
||||||
platform::pump_events::PumpStatus,
|
platform::pump_events::PumpStatus,
|
||||||
window::{
|
window::{
|
||||||
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowId,
|
||||||
|
WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
||||||
@@ -35,6 +36,7 @@ use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
|||||||
mod keycodes;
|
mod keycodes;
|
||||||
|
|
||||||
static HAS_FOCUS: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
|
static HAS_FOCUS: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
|
||||||
|
const WINDOW_ID: u64 = 0;
|
||||||
|
|
||||||
/// Returns the minimum `Option<Duration>`, taking into account that `None`
|
/// Returns the minimum `Option<Duration>`, taking into account that `None`
|
||||||
/// equates to an infinite timeout, not a zero timeout (so can't just use
|
/// equates to an infinite timeout, not a zero timeout (so can't just use
|
||||||
@@ -234,7 +236,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
*HAS_FOCUS.write().unwrap() = true;
|
*HAS_FOCUS.write().unwrap() = true;
|
||||||
callback(
|
callback(
|
||||||
event::Event::WindowEvent {
|
event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::Focused(true),
|
event: event::WindowEvent::Focused(true),
|
||||||
},
|
},
|
||||||
self.window_target(),
|
self.window_target(),
|
||||||
@@ -244,7 +246,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
*HAS_FOCUS.write().unwrap() = false;
|
*HAS_FOCUS.write().unwrap() = false;
|
||||||
callback(
|
callback(
|
||||||
event::Event::WindowEvent {
|
event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::Focused(false),
|
event: event::WindowEvent::Focused(false),
|
||||||
},
|
},
|
||||||
self.window_target(),
|
self.window_target(),
|
||||||
@@ -259,7 +261,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
MonitorHandle::new(self.android_app.clone()).size(),
|
MonitorHandle::new(self.android_app.clone()).size(),
|
||||||
));
|
));
|
||||||
let event = event::Event::WindowEvent {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::ScaleFactorChanged {
|
event: event::WindowEvent::ScaleFactorChanged {
|
||||||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
||||||
&new_inner_size,
|
&new_inner_size,
|
||||||
@@ -347,7 +349,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
PhysicalSize::new(0, 0)
|
PhysicalSize::new(0, 0)
|
||||||
};
|
};
|
||||||
let event = event::Event::WindowEvent {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::Resized(size),
|
event: event::WindowEvent::Resized(size),
|
||||||
};
|
};
|
||||||
callback(event, self.window_target());
|
callback(event, self.window_target());
|
||||||
@@ -357,7 +359,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
if pending_redraw {
|
if pending_redraw {
|
||||||
pending_redraw = false;
|
pending_redraw = false;
|
||||||
let event = event::Event::WindowEvent {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::RedrawRequested,
|
event: event::WindowEvent::RedrawRequested,
|
||||||
};
|
};
|
||||||
callback(event, self.window_target());
|
callback(event, self.window_target());
|
||||||
@@ -382,8 +384,8 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
let mut input_status = InputStatus::Handled;
|
let mut input_status = InputStatus::Handled;
|
||||||
match event {
|
match event {
|
||||||
InputEvent::MotionEvent(motion_event) => {
|
InputEvent::MotionEvent(motion_event) => {
|
||||||
let window_id = window::WindowId(WindowId);
|
let window_id = WindowId::from(WINDOW_ID);
|
||||||
let device_id = event::DeviceId(DeviceId(motion_event.device_id()));
|
let device_id = event::DeviceId::from(motion_event.device_id() as u64);
|
||||||
|
|
||||||
let phase = match motion_event.action() {
|
let phase = match motion_event.action() {
|
||||||
MotionAction::Down | MotionAction::PointerDown => {
|
MotionAction::Down | MotionAction::PointerDown => {
|
||||||
@@ -453,9 +455,9 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let event = event::Event::WindowEvent {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: WindowId::from(WINDOW_ID),
|
||||||
event: event::WindowEvent::KeyboardInput {
|
event: event::WindowEvent::KeyboardInput {
|
||||||
device_id: event::DeviceId(DeviceId(key.device_id())),
|
device_id: event::DeviceId::from(key.device_id() as u64),
|
||||||
event: event::KeyEvent {
|
event: event::KeyEvent {
|
||||||
state,
|
state,
|
||||||
physical_key: keycodes::to_physical_key(keycode),
|
physical_key: keycodes::to_physical_key(keycode),
|
||||||
@@ -463,7 +465,9 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
location: keycodes::to_location(keycode),
|
location: keycodes::to_location(keycode),
|
||||||
repeat: key.repeat_count() > 0,
|
repeat: key.repeat_count() > 0,
|
||||||
text: None,
|
text: None,
|
||||||
platform_specific: KeyEventExtra {},
|
extra: event::KeyExtra {
|
||||||
|
extra: KeyEventExtra {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
is_synthetic: false,
|
is_synthetic: false,
|
||||||
},
|
},
|
||||||
@@ -742,36 +746,6 @@ impl OwnedDisplayHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
|
||||||
pub(crate) struct WindowId;
|
|
||||||
|
|
||||||
impl WindowId {
|
|
||||||
pub const fn dummy() -> Self {
|
|
||||||
WindowId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<WindowId> for u64 {
|
|
||||||
fn from(_: WindowId) -> Self {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u64> for WindowId {
|
|
||||||
fn from(_: u64) -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
|
||||||
pub struct DeviceId(i32);
|
|
||||||
|
|
||||||
impl DeviceId {
|
|
||||||
pub const fn dummy() -> Self {
|
|
||||||
DeviceId(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes;
|
pub struct PlatformSpecificWindowBuilderAttributes;
|
||||||
|
|
||||||
@@ -802,7 +776,7 @@ impl Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> WindowId {
|
pub fn id(&self) -> WindowId {
|
||||||
WindowId
|
WindowId::from(WINDOW_ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||||
@@ -30,7 +30,6 @@ use crate::{
|
|||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event::{Event, InnerSizeWriter, StartCause, WindowEvent},
|
event::{Event, InnerSizeWriter, StartCause, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget},
|
||||||
window::WindowId as RootWindowId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! bug {
|
macro_rules! bug {
|
||||||
@@ -93,16 +92,14 @@ enum UserCallbackTransitionResult<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event<HandlePendingUserEvents> {
|
fn is_redraw(event: &Event<HandlePendingUserEvents>) -> bool {
|
||||||
fn is_redraw(&self) -> bool {
|
matches!(
|
||||||
matches!(
|
event,
|
||||||
self,
|
Event::WindowEvent {
|
||||||
Event::WindowEvent {
|
event: WindowEvent::RedrawRequested,
|
||||||
event: WindowEvent::RedrawRequested,
|
..
|
||||||
..
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the state machine for the app lifecycle
|
// this is the state machine for the app lifecycle
|
||||||
@@ -622,9 +619,9 @@ pub(crate) fn handle_nonuser_events<I: IntoIterator<Item = EventWrapper>>(
|
|||||||
for wrapper in events {
|
for wrapper in events {
|
||||||
match wrapper {
|
match wrapper {
|
||||||
EventWrapper::StaticEvent(event) => {
|
EventWrapper::StaticEvent(event) => {
|
||||||
if !processing_redraws && event.is_redraw() {
|
if !processing_redraws && is_redraw(&event) {
|
||||||
log::info!("processing `RedrawRequested` during the main event loop");
|
log::info!("processing `RedrawRequested` during the main event loop");
|
||||||
} else if processing_redraws && !event.is_redraw() {
|
} else if processing_redraws && !is_redraw(&event) {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"processing non `RedrawRequested` event after the main event loop: {:#?}",
|
"processing non `RedrawRequested` event after the main event loop: {:#?}",
|
||||||
event
|
event
|
||||||
@@ -676,9 +673,9 @@ pub(crate) fn handle_nonuser_events<I: IntoIterator<Item = EventWrapper>>(
|
|||||||
for wrapper in queued_events {
|
for wrapper in queued_events {
|
||||||
match wrapper {
|
match wrapper {
|
||||||
EventWrapper::StaticEvent(event) => {
|
EventWrapper::StaticEvent(event) => {
|
||||||
if !processing_redraws && event.is_redraw() {
|
if !processing_redraws && is_redraw(&event) {
|
||||||
log::info!("processing `RedrawRequested` during the main event loop");
|
log::info!("processing `RedrawRequested` during the main event loop");
|
||||||
} else if processing_redraws && !event.is_redraw() {
|
} else if processing_redraws && !is_redraw(&event) {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"processing non-`RedrawRequested` event after the main event loop: {:#?}",
|
"processing non-`RedrawRequested` event after the main event loop: {:#?}",
|
||||||
event
|
event
|
||||||
@@ -768,7 +765,7 @@ pub fn handle_main_events_cleared(mtm: MainThreadMarker) {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|window| {
|
.map(|window| {
|
||||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: RootWindowId(window.id()),
|
window_id: window.id(),
|
||||||
event: WindowEvent::RedrawRequested,
|
event: WindowEvent::RedrawRequested,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -799,7 +796,7 @@ fn handle_hidpi_proxy(handler: &mut EventLoopHandler, event: ScaleFactorChanged)
|
|||||||
} = event;
|
} = event;
|
||||||
let new_inner_size = Arc::new(Mutex::new(suggested_size));
|
let new_inner_size = Arc::new(Mutex::new(suggested_size));
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: RootWindowId(window.id()),
|
window_id: window.id(),
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
@@ -68,7 +68,7 @@ mod window;
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::event::DeviceId as RootDeviceId;
|
use crate::event::DeviceId;
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
event_loop::{
|
event_loop::{
|
||||||
@@ -76,27 +76,14 @@ pub(crate) use self::{
|
|||||||
PlatformSpecificEventLoopAttributes,
|
PlatformSpecificEventLoopAttributes,
|
||||||
},
|
},
|
||||||
monitor::{MonitorHandle, VideoModeHandle},
|
monitor::{MonitorHandle, VideoModeHandle},
|
||||||
window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId},
|
window::{PlatformSpecificWindowBuilderAttributes, Window},
|
||||||
};
|
};
|
||||||
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursor;
|
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursor;
|
||||||
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursorBuilder;
|
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursorBuilder;
|
||||||
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
||||||
pub(crate) use crate::platform_impl::Fullscreen;
|
pub(crate) use crate::platform_impl::Fullscreen;
|
||||||
|
|
||||||
/// There is no way to detect which device that performed a certain event in
|
pub(crate) const DEVICE_ID: DeviceId = unsafe { DeviceId::dummy() };
|
||||||
/// UIKit (i.e. you can't differentiate between different external keyboards,
|
|
||||||
/// or wether it was the main touchscreen, assistive technologies, or some
|
|
||||||
/// other pointer device that caused a touch event).
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeviceId;
|
|
||||||
|
|
||||||
impl DeviceId {
|
|
||||||
pub const unsafe fn dummy() -> Self {
|
|
||||||
DeviceId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct KeyEventExtra {}
|
pub struct KeyEventExtra {}
|
||||||