Compare commits

...

17 Commits

Author SHA1 Message Date
John Nunley
d28c867b61 chore: Rebase on latest master
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:41 -08:00
John Nunley
cfd35d2708 ci: Missed a spot
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:11 -08:00
John Nunley
1b9c576f53 ci: Use -p option in CI
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:10 -08:00
John Nunley
52532d2579 chore: Fix failing CI
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:10 -08:00
John Nunley
4b28f10470 chore: fmt and doc fixes
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:10 -08:00
John Nunley
daf1304879 chore: Housekeeping
- Update CHANGELOG
- Add documentation to items I forgot to document
- Trait implementations

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:02:08 -08:00
John Nunley
c6e57430bb chore: Move over ControlFlow
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:01:49 -08:00
John Nunley
284f4c0558 feat: Move Event to winit-core
This requires a lot of restructuring on the backend side, as we need to
accommodate for backends not being able to construct these types
implicitly. In addition, we also need to expose some new APIs on these
types to make them usable.

Several breaking changes occurred in this commit.

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:01:49 -08:00
John Nunley
859a6f109c feat: Move DeviceId to winit-core
This requires a similar restructuring as with WindowId.

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:01:49 -08:00
John Nunley
a232f7bc77 feat: Move WindowId to winit-core
This commit moves WindowId to winit-core and replaces its inner type
with a platform-agnostic `u64`. This required some changes to many of
the backend in order to accommodate this new system.

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 19:01:46 -08:00
John Nunley
48831f7910 feat: Re-export cursor types in winit-core/window
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:06 -08:00
John Nunley
114e6999d3 chore: Move parts of window.rs to winit-core
As winit no longer owns some of the types this requires some adjustments
in the Wayland backend.

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:06 -08:00
John Nunley
2f197315d9 chore: Move most of keyboard.rs to winit-core
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:06 -08:00
John Nunley
557464489e chore: Move dpi.rs to winit-core wholesale
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:06 -08:00
John Nunley
623b3e5070 chore: Move part of error.rs to winit-core
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:06 -08:00
John Nunley
a97255e0fc chore: Bring up winit-core crate
Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:59:05 -08:00
John Nunley
3a817647d5 chore: Move winit files to winit subfolder
This will allow us to split off crates from the main winit crate.

Signed-off-by: John Nunley <dev@notgull.net>
2024-02-06 18:58:48 -08:00
229 changed files with 1833 additions and 1935 deletions

View File

@@ -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: >

View File

@@ -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

View File

@@ -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"] }

View File

@@ -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]

View File

@@ -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"

View File

@@ -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)
}
}

View File

@@ -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
View 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
View File

@@ -0,0 +1,3 @@
# winit-core - Base types for a windowing system
TODO

View File

@@ -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
View 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()
);
}
}

View File

@@ -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();

View 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,
}
}
}

View File

@@ -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
View 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
View 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
View 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
View File

@@ -0,0 +1 @@
../README.md

24
winit/build.rs Normal file
View 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 },
}
}

View File

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 159 B

View File

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 129 B

View File

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 229 B

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -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
View 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,
}

View File

@@ -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 }
}
}

View File

@@ -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;

View File

@@ -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()
} }
} }

View File

@@ -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());
} }

View File

@@ -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)
} }
} }

View File

@@ -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> {

View File

@@ -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)),

View File

@@ -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 {}

Some files were not shown because too many files have changed in this diff Show More