Compare commits
6 Commits
notgull/sp
...
request-ig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac0f918500 | ||
|
|
4112fccc12 | ||
|
|
bd6ce32860 | ||
|
|
8936fe1acd | ||
|
|
fedb86ea5a | ||
|
|
20687fef1c |
8
.github/workflows/ci.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
- { name: 'Linux 64bit', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, }
|
- { name: 'Linux 64bit', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, }
|
||||||
- { name: 'X11', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=x11' }
|
- { name: 'X11', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=x11' }
|
||||||
- { name: 'Wayland', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=wayland,wayland-dlopen' }
|
- { name: 'Wayland', target: x86_64-unknown-linux-gnu, os: ubuntu-latest, options: '--no-default-features --features=wayland,wayland-dlopen' }
|
||||||
- { name: 'Android', target: aarch64-linux-android, os: ubuntu-latest, options: '--features=android-native-activity', cmd: 'apk --' }
|
- { name: 'Android', target: aarch64-linux-android, os: ubuntu-latest, options: '--package=winit --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 -p winit $OPTIONS
|
run: cargo $CMD build $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 -p winit --no-run $OPTIONS
|
run: cargo $CMD test --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 -p winit --features serde
|
run: cargo $CMD test --no-run $OPTIONS --features serde
|
||||||
|
|
||||||
- name: Run tests with serde enabled
|
- name: Run tests with serde enabled
|
||||||
if: >
|
if: >
|
||||||
|
|||||||
13
CHANGELOG.md
@@ -11,6 +11,8 @@ Unreleased` header.
|
|||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- **Breaking:** Use `RequestIgnored` as the error type in `InnerSizeWriter::request_inner_size`.
|
||||||
|
- Fix compatibility with 32-bit platforms without 64-bit atomics.
|
||||||
- On X11, fix swapped instance and general class names.
|
- On X11, fix swapped instance and general class names.
|
||||||
- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`.
|
- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`.
|
||||||
- On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example.
|
- On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example.
|
||||||
@@ -49,14 +51,9 @@ 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
|
- On Orbital, fix `logical_key` and `text` not reported in `KeyEvent`.
|
||||||
re-exported verbatim; however:
|
- On Orbital, implement `KeyEventExtModifierSupplement`.
|
||||||
- `Event`, `WindowEvent` and `KeyEvent` now take a generic that `winit`
|
- On Orbital, map keys to `NamedKey` when possible.
|
||||||
implements.
|
|
||||||
- `ActivationToken` and `InnerSizeWriter` expose new methods to make them
|
|
||||||
useful.
|
|
||||||
- `InnerSizeWriter::request_inner_size` returns an `InnerSizeIgnored` error
|
|
||||||
instead of an `ExternalError`.
|
|
||||||
|
|
||||||
# 0.29.10
|
# 0.29.10
|
||||||
|
|
||||||
|
|||||||
271
Cargo.toml
@@ -1,16 +1,265 @@
|
|||||||
|
[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.7", 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"
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
[[example]]
|
||||||
bitflags = "2"
|
doc-scrape-examples = true
|
||||||
cfg_aliases = "0.2.0"
|
name = "window"
|
||||||
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"] }
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ For features _outside_ the scope of winit, see [Are we GUI Yet?](https://arewegu
|
|||||||
|
|
||||||
Join us in our [](https://matrix.to/#/#rust-windowing:matrix.org) room. If you don't get an answer there, try [](https://web.libera.chat/#winit).
|
Join us in our [](https://matrix.to/#/#rust-windowing:matrix.org) room. If you don't get an answer there, try [](https://web.libera.chat/#winit).
|
||||||
|
|
||||||
The maintainers have a meeting every friday at UTC 14. The meeting notes can be found [here](https://hackmd.io/@winit-meetings).
|
The maintainers have a meeting every friday at UTC 15. The meeting notes can be found [here](https://hackmd.io/@winit-meetings).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,7 @@ 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]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 229 B |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -2,7 +2,8 @@
|
|||||||
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"
|
||||||
|
|||||||
@@ -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()`]: https://docs.rs/winit/latest/winit/window/struct.Window.html#method.scale_factor
|
//! [`window.scale_factor()`]: crate::window::Window::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/
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
use crate::platform_impl;
|
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
#[doc(inline)]
|
use crate::platform_impl;
|
||||||
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
|
||||||
@@ -16,10 +14,10 @@ pub enum ExternalError {
|
|||||||
Os(OsError),
|
Os(OsError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<winit_core::event::InnerSizeIgnored> for ExternalError {
|
/// The error type for when the requested operation is not supported by the backend.
|
||||||
fn from(_: winit_core::event::InnerSizeIgnored) -> Self {
|
#[derive(Clone)]
|
||||||
Self::Ignored
|
pub struct NotSupportedError {
|
||||||
}
|
_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.
|
||||||
@@ -49,6 +47,14 @@ 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 {
|
||||||
@@ -82,6 +88,18 @@ 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 {
|
||||||
@@ -95,6 +113,7 @@ 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)]
|
||||||
@@ -106,6 +125,11 @@ 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()),
|
||||||
@@ -1,64 +1,65 @@
|
|||||||
//! Incoming notifications from the GUI system.
|
//! The [`Event`] enum and assorted supporting types.
|
||||||
|
//!
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
//! These are sent to the closure given to [`EventLoop::run(...)`], where they get
|
||||||
use crate::event_loop::AsyncRequestSerial;
|
//! processed and used to modify the program state. For more details, see the root-level documentation.
|
||||||
use crate::keyboard::{self, ModifiersKeyState, ModifiersKeys, ModifiersState};
|
//!
|
||||||
use crate::window::{ActivationToken, Theme, WindowId};
|
//! 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 std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
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;
|
||||||
|
|
||||||
#[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, KeyExtra> {
|
pub enum Event<T: 'static> {
|
||||||
/// 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 +71,7 @@ pub enum Event<T: 'static, KeyExtra> {
|
|||||||
/// 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<KeyExtra>,
|
event: WindowEvent,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Emitted when the OS sends an event to a device.
|
/// Emitted when the OS sends an event to a device.
|
||||||
@@ -79,7 +80,7 @@ pub enum Event<T: 'static, KeyExtra> {
|
|||||||
event: DeviceEvent,
|
event: DeviceEvent,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Emitted when an event is sent from [`EventLoopProxy::send_event`](https://docs.rs/winit/latest/winit/event_loop/struct.EventLoopProxy.html#method.send_event)
|
/// Emitted when an event is sent from [`EventLoopProxy::send_event`](crate::event_loop::EventLoopProxy::send_event)
|
||||||
UserEvent(T),
|
UserEvent(T),
|
||||||
|
|
||||||
/// Emitted when the application has been suspended.
|
/// Emitted when the application has been suspended.
|
||||||
@@ -255,9 +256,9 @@ pub enum Event<T: 'static, KeyExtra> {
|
|||||||
MemoryWarning,
|
MemoryWarning,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Extra> Event<T, Extra> {
|
impl<T> Event<T> {
|
||||||
#[allow(clippy::result_large_err)]
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn map_nonuser_event<U>(self) -> Result<Event<U, Extra>, Event<T, Extra>> {
|
pub fn map_nonuser_event<U>(self) -> Result<Event<U>, Event<T>> {
|
||||||
use self::Event::*;
|
use self::Event::*;
|
||||||
match self {
|
match self {
|
||||||
UserEvent(_) => Err(self),
|
UserEvent(_) => Err(self),
|
||||||
@@ -304,10 +305,8 @@ 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<KeyExtra> {
|
pub enum WindowEvent {
|
||||||
/// 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(
|
||||||
@@ -369,7 +368,7 @@ pub enum WindowEvent<KeyExtra> {
|
|||||||
/// 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<KeyExtra>,
|
event: KeyEvent,
|
||||||
|
|
||||||
/// 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:
|
||||||
@@ -393,8 +392,6 @@ pub enum WindowEvent<KeyExtra> {
|
|||||||
/// ## 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.
|
||||||
@@ -600,11 +597,33 @@ pub enum WindowEvent<KeyExtra> {
|
|||||||
///
|
///
|
||||||
/// 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
|
||||||
@@ -665,7 +684,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<Extra> {
|
pub struct KeyEvent {
|
||||||
/// 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).
|
||||||
@@ -715,7 +734,7 @@ pub struct KeyEvent<Extra> {
|
|||||||
/// - **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`]: https://docs.rs/winit/latest/winit/platform/modifier_supplement/trait.KeyEventExtModifierSupplement.html#tymethod.key_without_modifiers
|
/// [`key_without_modifiers`]: crate::platform::modifier_supplement::KeyEventExtModifierSupplement::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.
|
||||||
@@ -772,7 +791,7 @@ pub struct KeyEvent<Extra> {
|
|||||||
/// 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 extra: Extra,
|
pub(crate) platform_specific: platform_impl::KeyEventExtra,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes keyboard modifiers event.
|
/// Describes keyboard modifiers event.
|
||||||
@@ -787,15 +806,6 @@ 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
|
||||||
@@ -895,8 +905,6 @@ 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 {
|
||||||
@@ -905,8 +913,6 @@ 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.
|
||||||
@@ -929,8 +935,6 @@ 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1119,27 +1123,29 @@ pub struct InnerSizeWriter {
|
|||||||
|
|
||||||
impl InnerSizeWriter {
|
impl InnerSizeWriter {
|
||||||
#[cfg(not(orbital_platform))]
|
#[cfg(not(orbital_platform))]
|
||||||
pub fn new(new_inner_size: Weak<Mutex<PhysicalSize<u32>>>) -> Self {
|
pub(crate) fn new(new_inner_size: Weak<Mutex<PhysicalSize<u32>>>) -> Self {
|
||||||
Self { new_inner_size }
|
Self { new_inner_size }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to request inner size which will be set synchroniously on the window.
|
/// Try to request a new inner size which will be set synchronously on the
|
||||||
|
/// window.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// This method returns an error when the request was ignored because it
|
||||||
|
/// was done asynchronously, outside the event loop callback.
|
||||||
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<(), InnerSizeIgnored> {
|
) -> Result<(), RequestIgnored> {
|
||||||
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(InnerSizeIgnored { _private: () })
|
Err(RequestIgnored { _priv: () })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
||||||
@@ -1148,24 +1154,21 @@ impl PartialEq for InnerSizeWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Could not write the inner size.
|
/// The request to change the inner size synchronously was ignored.
|
||||||
pub struct InnerSizeIgnored {
|
///
|
||||||
_private: (),
|
/// See [`InnerSizeWriter::request_inner_size`] for details.
|
||||||
|
#[derive(Debug, Clone)] // Explicitly not other traits, in case we want to extend it in the future
|
||||||
|
pub struct RequestIgnored {
|
||||||
|
_priv: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for InnerSizeIgnored {
|
impl fmt::Display for RequestIgnored {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
f.debug_struct("InnerSizeIgnored").finish_non_exhaustive()
|
f.write_str("the request to change the inner size was ignored")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for InnerSizeIgnored {
|
impl Error for RequestIgnored {}
|
||||||
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 {
|
||||||
@@ -1292,7 +1295,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);
|
||||||
})
|
})
|
||||||
@@ -1300,7 +1303,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 {
|
||||||
@@ -1334,7 +1337,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();
|
||||||
@@ -11,15 +11,17 @@ 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, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, 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.
|
||||||
///
|
///
|
||||||
@@ -139,6 +141,50 @@ 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.
|
||||||
///
|
///
|
||||||
@@ -460,3 +506,29 @@ 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: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRequestSerial {
|
||||||
|
// TODO(kchibisov): Remove `cfg` when the clipboard will be added.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn get() -> Self {
|
||||||
|
static CURRENT_SERIAL: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
// NOTE: We rely on wrap around here, while the user may just request
|
||||||
|
// in the loop usize::MAX times that's issue is considered on them.
|
||||||
|
let serial = CURRENT_SERIAL.fetch_add(1, Ordering::Relaxed);
|
||||||
|
Self { serial }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1454,29 +1454,6 @@ 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
|
||||||
@@ -1588,7 +1565,7 @@ impl NamedKey {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use winit_core::keyboard::NamedKey;
|
/// use winit::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);
|
||||||
@@ -1611,7 +1588,7 @@ impl Key {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use winit_core::keyboard::{NamedKey, Key};
|
/// use winit::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"));
|
||||||
@@ -1750,6 +1727,28 @@ 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;
|
||||||
@@ -164,15 +164,14 @@
|
|||||||
#[cfg(feature = "rwh_06")]
|
#[cfg(feature = "rwh_06")]
|
||||||
pub use rwh_06 as raw_window_handle;
|
pub use rwh_06 as raw_window_handle;
|
||||||
|
|
||||||
#[doc(inline)]
|
pub mod dpi;
|
||||||
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;
|
||||||
@@ -46,6 +46,7 @@ pub mod pump_events;
|
|||||||
macos_platform,
|
macos_platform,
|
||||||
x11_platform,
|
x11_platform,
|
||||||
wayland_platform,
|
wayland_platform,
|
||||||
|
orbital_platform,
|
||||||
docsrs
|
docsrs
|
||||||
))]
|
))]
|
||||||
pub mod modifier_supplement;
|
pub mod modifier_supplement;
|
||||||
@@ -25,8 +25,7 @@ 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.extra
|
self.platform_specific
|
||||||
.extra
|
|
||||||
.text_with_all_modifiers
|
.text_with_all_modifiers
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|s| s.as_str())
|
.map(|s| s.as_str())
|
||||||
@@ -34,6 +33,6 @@ impl KeyEventExtModifierSupplement for KeyEvent {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn key_without_modifiers(&self) -> Key {
|
fn key_without_modifiers(&self) -> Key {
|
||||||
self.extra.extra.key_without_modifiers.clone()
|
self.platform_specific.key_without_modifiers.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ impl EventLoopExtStartupNotify for EventLoopWindowTarget {
|
|||||||
crate::platform_impl::EventLoopWindowTarget::X(_) => env::var(X11_VAR),
|
crate::platform_impl::EventLoopWindowTarget::X(_) => env::var(X11_VAR),
|
||||||
}
|
}
|
||||||
.ok()
|
.ok()
|
||||||
.map(ActivationToken::new)
|
.map(ActivationToken::_new)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +94,6 @@ pub fn reset_activation_token_env() {
|
|||||||
///
|
///
|
||||||
/// This could be used before running daemon processes.
|
/// This could be used before running daemon processes.
|
||||||
pub fn set_activation_token_env(token: ActivationToken) {
|
pub fn set_activation_token_env(token: ActivationToken) {
|
||||||
env::set_var(X11_VAR, token.token());
|
env::set_var(X11_VAR, &token._token);
|
||||||
env::set_var(WAYLAND_VAR, token.token());
|
env::set_var(WAYLAND_VAR, token._token);
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ pub trait DeviceIdExtWindows {
|
|||||||
impl DeviceIdExtWindows for DeviceId {
|
impl DeviceIdExtWindows for DeviceId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn persistent_identifier(&self) -> Option<String> {
|
fn persistent_identifier(&self) -> Option<String> {
|
||||||
crate::platform_impl::persistent_identifier(*self)
|
self.0.persistent_identifier()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +27,7 @@ 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, WindowId,
|
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
||||||
WindowLevel,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
||||||
@@ -36,7 +35,6 @@ 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
|
||||||
@@ -236,7 +234,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: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::Focused(true),
|
event: event::WindowEvent::Focused(true),
|
||||||
},
|
},
|
||||||
self.window_target(),
|
self.window_target(),
|
||||||
@@ -246,7 +244,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: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::Focused(false),
|
event: event::WindowEvent::Focused(false),
|
||||||
},
|
},
|
||||||
self.window_target(),
|
self.window_target(),
|
||||||
@@ -261,7 +259,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: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
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,
|
||||||
@@ -349,7 +347,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: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::Resized(size),
|
event: event::WindowEvent::Resized(size),
|
||||||
};
|
};
|
||||||
callback(event, self.window_target());
|
callback(event, self.window_target());
|
||||||
@@ -359,7 +357,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: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::RedrawRequested,
|
event: event::WindowEvent::RedrawRequested,
|
||||||
};
|
};
|
||||||
callback(event, self.window_target());
|
callback(event, self.window_target());
|
||||||
@@ -384,8 +382,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 = WindowId::from(WINDOW_ID);
|
let window_id = window::WindowId(WindowId);
|
||||||
let device_id = event::DeviceId::from(motion_event.device_id() as u64);
|
let device_id = event::DeviceId(DeviceId(motion_event.device_id()));
|
||||||
|
|
||||||
let phase = match motion_event.action() {
|
let phase = match motion_event.action() {
|
||||||
MotionAction::Down | MotionAction::PointerDown => {
|
MotionAction::Down | MotionAction::PointerDown => {
|
||||||
@@ -455,9 +453,9 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let event = event::Event::WindowEvent {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: WindowId::from(WINDOW_ID),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::KeyboardInput {
|
event: event::WindowEvent::KeyboardInput {
|
||||||
device_id: event::DeviceId::from(key.device_id() as u64),
|
device_id: event::DeviceId(DeviceId(key.device_id())),
|
||||||
event: event::KeyEvent {
|
event: event::KeyEvent {
|
||||||
state,
|
state,
|
||||||
physical_key: keycodes::to_physical_key(keycode),
|
physical_key: keycodes::to_physical_key(keycode),
|
||||||
@@ -465,9 +463,7 @@ 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,
|
||||||
extra: event::KeyExtra {
|
platform_specific: KeyEventExtra {},
|
||||||
extra: KeyEventExtra {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
is_synthetic: false,
|
is_synthetic: false,
|
||||||
},
|
},
|
||||||
@@ -746,6 +742,36 @@ 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;
|
||||||
|
|
||||||
@@ -776,7 +802,7 @@ impl Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> WindowId {
|
pub fn id(&self) -> WindowId {
|
||||||
WindowId::from(WINDOW_ID)
|
WindowId
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||||
@@ -30,6 +30,7 @@ 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 {
|
||||||
@@ -92,14 +93,16 @@ enum UserCallbackTransitionResult<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_redraw(event: &Event<HandlePendingUserEvents>) -> bool {
|
impl Event<HandlePendingUserEvents> {
|
||||||
|
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
|
||||||
@@ -619,9 +622,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 && is_redraw(&event) {
|
if !processing_redraws && event.is_redraw() {
|
||||||
log::info!("processing `RedrawRequested` during the main event loop");
|
log::info!("processing `RedrawRequested` during the main event loop");
|
||||||
} else if processing_redraws && !is_redraw(&event) {
|
} else if processing_redraws && !event.is_redraw() {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"processing non `RedrawRequested` event after the main event loop: {:#?}",
|
"processing non `RedrawRequested` event after the main event loop: {:#?}",
|
||||||
event
|
event
|
||||||
@@ -673,9 +676,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 && is_redraw(&event) {
|
if !processing_redraws && event.is_redraw() {
|
||||||
log::info!("processing `RedrawRequested` during the main event loop");
|
log::info!("processing `RedrawRequested` during the main event loop");
|
||||||
} else if processing_redraws && !is_redraw(&event) {
|
} else if processing_redraws && !event.is_redraw() {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"processing non-`RedrawRequested` event after the main event loop: {:#?}",
|
"processing non-`RedrawRequested` event after the main event loop: {:#?}",
|
||||||
event
|
event
|
||||||
@@ -765,7 +768,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: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::RedrawRequested,
|
event: WindowEvent::RedrawRequested,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -796,7 +799,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: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
@@ -68,7 +68,7 @@ mod window;
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::event::DeviceId;
|
use crate::event::DeviceId as RootDeviceId;
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
event_loop::{
|
event_loop::{
|
||||||
@@ -76,14 +76,27 @@ pub(crate) use self::{
|
|||||||
PlatformSpecificEventLoopAttributes,
|
PlatformSpecificEventLoopAttributes,
|
||||||
},
|
},
|
||||||
monitor::{MonitorHandle, VideoModeHandle},
|
monitor::{MonitorHandle, VideoModeHandle},
|
||||||
window::{PlatformSpecificWindowBuilderAttributes, Window},
|
window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId},
|
||||||
};
|
};
|
||||||
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;
|
||||||
|
|
||||||
pub(crate) const DEVICE_ID: DeviceId = unsafe { DeviceId::dummy() };
|
/// There is no way to detect which device that performed a certain event in
|
||||||
|
/// 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 {}
|
||||||
@@ -15,6 +15,7 @@ use super::uikit::{
|
|||||||
UIStatusBarStyle, UITapGestureRecognizer, UITouch, UITouchPhase, UITouchType,
|
UIStatusBarStyle, UITapGestureRecognizer, UITouch, UITouchPhase, UITouchType,
|
||||||
UITraitCollection, UIView, UIViewController, UIWindow,
|
UITraitCollection, UIView, UIViewController, UIWindow,
|
||||||
};
|
};
|
||||||
|
use super::window::WindowId;
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::PhysicalPosition,
|
dpi::PhysicalPosition,
|
||||||
event::{Event, Force, Touch, TouchPhase, WindowEvent},
|
event::{Event, Force, Touch, TouchPhase, WindowEvent},
|
||||||
@@ -23,7 +24,7 @@ use crate::{
|
|||||||
ffi::{UIRectEdge, UIUserInterfaceIdiom},
|
ffi::{UIRectEdge, UIUserInterfaceIdiom},
|
||||||
Fullscreen, DEVICE_ID,
|
Fullscreen, DEVICE_ID,
|
||||||
},
|
},
|
||||||
window::{WindowAttributes, WindowId},
|
window::{WindowAttributes, WindowId as RootWindowId},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct WinitViewState {
|
pub struct WinitViewState {
|
||||||
@@ -54,7 +55,7 @@ declare_class!(
|
|||||||
app_state::handle_nonuser_event(
|
app_state::handle_nonuser_event(
|
||||||
mtm,
|
mtm,
|
||||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::RedrawRequested,
|
event: WindowEvent::RedrawRequested,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -89,7 +90,7 @@ declare_class!(
|
|||||||
app_state::handle_nonuser_event(
|
app_state::handle_nonuser_event(
|
||||||
mtm,
|
mtm,
|
||||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::Resized(size),
|
event: WindowEvent::Resized(size),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -128,7 +129,7 @@ declare_class!(
|
|||||||
width: screen_frame.size.width as f64,
|
width: screen_frame.size.width as f64,
|
||||||
height: screen_frame.size.height as f64,
|
height: screen_frame.size.height as f64,
|
||||||
};
|
};
|
||||||
let window_id = window.id();
|
let window_id = RootWindowId(window.id());
|
||||||
app_state::handle_nonuser_events(
|
app_state::handle_nonuser_events(
|
||||||
mtm,
|
mtm,
|
||||||
std::iter::once(EventWrapper::ScaleFactorChanged(
|
std::iter::once(EventWrapper::ScaleFactorChanged(
|
||||||
@@ -182,7 +183,7 @@ declare_class!(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::PinchGesture {
|
event: WindowEvent::PinchGesture {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
delta: recognizer.velocity() as _,
|
delta: recognizer.velocity() as _,
|
||||||
@@ -200,7 +201,7 @@ declare_class!(
|
|||||||
|
|
||||||
if recognizer.state() == UIGestureRecognizerState::Ended {
|
if recognizer.state() == UIGestureRecognizerState::Ended {
|
||||||
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::DoubleTapGesture {
|
event: WindowEvent::DoubleTapGesture {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
},
|
},
|
||||||
@@ -228,7 +229,7 @@ declare_class!(
|
|||||||
// Flip the velocity to match macOS.
|
// Flip the velocity to match macOS.
|
||||||
let delta = -recognizer.velocity() as _;
|
let delta = -recognizer.velocity() as _;
|
||||||
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
let gesture_event = EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::RotationGesture {
|
event: WindowEvent::RotationGesture {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
delta,
|
delta,
|
||||||
@@ -379,7 +380,7 @@ impl WinitView {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::Touch(Touch {
|
event: WindowEvent::Touch(Touch {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
id: touch_id,
|
id: touch_id,
|
||||||
@@ -582,7 +583,7 @@ declare_class!(
|
|||||||
app_state::handle_nonuser_event(
|
app_state::handle_nonuser_event(
|
||||||
mtm,
|
mtm,
|
||||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: self.id(),
|
window_id: RootWindowId(self.id()),
|
||||||
event: WindowEvent::Focused(true),
|
event: WindowEvent::Focused(true),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -595,7 +596,7 @@ declare_class!(
|
|||||||
app_state::handle_nonuser_event(
|
app_state::handle_nonuser_event(
|
||||||
mtm,
|
mtm,
|
||||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: self.id(),
|
window_id: RootWindowId(self.id()),
|
||||||
event: WindowEvent::Focused(false),
|
event: WindowEvent::Focused(false),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -690,7 +691,7 @@ declare_class!(
|
|||||||
&*ptr
|
&*ptr
|
||||||
};
|
};
|
||||||
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::Destroyed,
|
event: WindowEvent::Destroyed,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -720,7 +721,7 @@ impl WinitApplicationDelegate {
|
|||||||
&*ptr
|
&*ptr
|
||||||
};
|
};
|
||||||
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||||
window_id: window.id(),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::Occluded(occluded),
|
event: WindowEvent::Occluded(occluded),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ use std::collections::VecDeque;
|
|||||||
use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker};
|
use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker};
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Id;
|
||||||
|
use objc2::runtime::AnyObject;
|
||||||
use objc2::{class, msg_send};
|
use objc2::{class, msg_send};
|
||||||
|
|
||||||
use super::app_state::EventWrapper;
|
use super::app_state::EventWrapper;
|
||||||
@@ -22,7 +23,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
window::{
|
window::{
|
||||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
||||||
WindowButtons, WindowId, WindowLevel,
|
WindowButtons, WindowId as RootWindowId, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -464,7 +465,7 @@ impl Window {
|
|||||||
width: screen_frame.size.width as f64,
|
width: screen_frame.size.width as f64,
|
||||||
height: screen_frame.size.height as f64,
|
height: screen_frame.size.height as f64,
|
||||||
};
|
};
|
||||||
let window_id = window.id();
|
let window_id = RootWindowId(window.id());
|
||||||
app_state::handle_nonuser_events(
|
app_state::handle_nonuser_events(
|
||||||
mtm,
|
mtm,
|
||||||
std::iter::once(EventWrapper::ScaleFactorChanged(
|
std::iter::once(EventWrapper::ScaleFactorChanged(
|
||||||
@@ -638,6 +639,44 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct WindowId {
|
||||||
|
window: *mut WinitUIWindow,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowId {
|
||||||
|
pub const unsafe fn dummy() -> Self {
|
||||||
|
WindowId {
|
||||||
|
window: std::ptr::null_mut(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WindowId> for u64 {
|
||||||
|
fn from(window_id: WindowId) -> Self {
|
||||||
|
window_id.window as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for WindowId {
|
||||||
|
fn from(raw_id: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
window: raw_id as _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for WindowId {}
|
||||||
|
unsafe impl Sync for WindowId {}
|
||||||
|
|
||||||
|
impl From<&AnyObject> for WindowId {
|
||||||
|
fn from(window: &AnyObject) -> WindowId {
|
||||||
|
WindowId {
|
||||||
|
window: window as *const _ as _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub scale_factor: Option<f64>,
|
pub scale_factor: Option<f64>,
|
||||||
@@ -409,9 +409,7 @@ impl KbdState {
|
|||||||
location,
|
location,
|
||||||
state,
|
state,
|
||||||
repeat,
|
repeat,
|
||||||
extra: crate::event::KeyExtra {
|
platform_specific,
|
||||||
extra: platform_specific,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||