Desktop: Switch to the latest unreleased version of Winit (#3177)

* Use unstable winit

* Improve

* Remove unnecessary heap indirection
This commit is contained in:
Timon 2025-09-17 05:16:11 -07:00 committed by Dennis Kobert
parent 4662cbbbc1
commit 3fe7c477e9
No known key found for this signature in database
GPG Key ID: 5A4358CB9530F933
14 changed files with 567 additions and 527 deletions

638
Cargo.lock generated
View File

@ -308,7 +308,7 @@ dependencies = [
"futures-lite",
"parking",
"polling",
"rustix 1.0.8",
"rustix",
"slab",
"windows-sys 0.60.2",
]
@ -350,7 +350,7 @@ dependencies = [
"cfg-if",
"event-listener",
"futures-lite",
"rustix 1.0.8",
"rustix",
]
[[package]]
@ -376,7 +376,7 @@ dependencies = [
"cfg-if",
"futures-core",
"futures-io",
"rustix 1.0.8",
"rustix",
"signal-hook-registry",
"slab",
"windows-sys 0.60.2",
@ -521,22 +521,13 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block2"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [
"objc2 0.5.2",
]
[[package]]
name = "block2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2"
dependencies = [
"objc2 0.6.2",
"objc2",
]
[[package]]
@ -552,6 +543,15 @@ dependencies = [
"piper",
]
[[package]]
name = "borsh"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce"
dependencies = [
"cfg_aliases",
]
[[package]]
name = "built"
version = "0.7.7"
@ -613,26 +613,25 @@ dependencies = [
[[package]]
name = "calloop"
version = "0.13.0"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec"
checksum = "cb9f6e1368bd4621d2c86baa7e37de77a938adf5221e5dd3d6133340101b309e"
dependencies = [
"bitflags 2.9.3",
"log",
"polling",
"rustix 0.38.44",
"rustix",
"slab",
"thiserror 1.0.69",
"tracing",
]
[[package]]
name = "calloop-wayland-source"
version = "0.3.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa"
dependencies = [
"calloop",
"rustix 0.38.44",
"rustix",
"wayland-backend",
"wayland-client",
]
@ -998,19 +997,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core-graphics"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-graphics-types",
"foreign-types 0.5.0",
"libc",
]
[[package]]
name = "core-graphics-types"
version = "0.1.3"
@ -1119,7 +1105,7 @@ dependencies = [
"document-features",
"mio",
"parking_lot",
"rustix 1.0.8",
"rustix",
"signal-hook",
"signal-hook-mio",
"winapi",
@ -1262,12 +1248,6 @@ dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "dispatch"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "dispatch2"
version = "0.3.0"
@ -1275,9 +1255,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [
"bitflags 2.9.3",
"block2 0.6.1",
"block2",
"libc",
"objc2 0.6.2",
"objc2",
]
[[package]]
@ -1337,8 +1317,7 @@ dependencies = [
[[package]]
name = "dpi"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"serde",
]
@ -1671,10 +1650,10 @@ dependencies = [
"hashbrown",
"icu_locid",
"memmap2",
"objc2 0.6.2",
"objc2",
"objc2-core-foundation",
"objc2-core-text",
"objc2-foundation 0.3.1",
"objc2-foundation",
"peniko",
"read-fonts 0.29.3",
"roxmltree",
@ -1872,7 +1851,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
dependencies = [
"rustix 1.0.8",
"rustix",
"windows-targets 0.52.6",
]
@ -2275,7 +2254,7 @@ dependencies = [
"graphite-desktop-wrapper",
"libc",
"objc2-io-surface",
"objc2-metal 0.3.1",
"objc2-metal",
"open",
"rand 0.9.2",
"rfd",
@ -3059,6 +3038,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "keyboard-types"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53cea01d04c8251f945a9f16c5364da6cdb8bce69a61382663302c62f4186d13"
dependencies = [
"bitflags 2.9.3",
"serde",
]
[[package]]
name = "khronos-egl"
version = "6.0.0"
@ -3166,15 +3155,9 @@ checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
dependencies = [
"bitflags 2.9.3",
"libc",
"redox_syscall 0.5.17",
"redox_syscall",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.9.4"
@ -3642,22 +3625,6 @@ dependencies = [
"malloc_buf",
]
[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]]
name = "objc2"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
"objc2-encode",
]
[[package]]
name = "objc2"
version = "0.6.2"
@ -3667,22 +3634,6 @@ dependencies = [
"objc2-encode",
]
[[package]]
name = "objc2-app-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"libc",
"objc2 0.5.2",
"objc2-core-data",
"objc2-core-image",
"objc2-foundation 0.2.2",
"objc2-quartz-core",
]
[[package]]
name = "objc2-app-kit"
version = "0.3.1"
@ -3690,45 +3641,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
dependencies = [
"bitflags 2.9.3",
"block2 0.6.1",
"objc2 0.6.2",
"objc2-foundation 0.3.1",
]
[[package]]
name = "objc2-cloud-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-core-location",
"objc2-foundation 0.2.2",
]
[[package]]
name = "objc2-contacts"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
[[package]]
name = "objc2-core-data"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"block2",
"objc2",
"objc2-core-foundation",
"objc2-foundation",
]
[[package]]
@ -3738,32 +3654,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
dependencies = [
"bitflags 2.9.3",
"block2",
"dispatch2",
"objc2 0.6.2",
"objc2",
]
[[package]]
name = "objc2-core-image"
version = "0.2.2"
name = "objc2-core-graphics"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-metal 0.2.2",
]
[[package]]
name = "objc2-core-location"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-contacts",
"objc2-foundation 0.2.2",
"bitflags 2.9.3",
"libc",
"objc2-core-foundation",
]
[[package]]
@ -3776,25 +3680,23 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "objc2-core-video"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1989c3e76c7e978cab0ba9e6f4961cd00ed14ca21121444cc26877403bfb6303"
dependencies = [
"bitflags 2.9.3",
"objc2-core-foundation",
"objc2-core-graphics",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
name = "objc2-foundation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"dispatch",
"libc",
"objc2 0.5.2",
]
[[package]]
name = "objc2-foundation"
version = "0.3.1"
@ -3802,7 +3704,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
dependencies = [
"bitflags 2.9.3",
"objc2 0.6.2",
"block2",
"objc2",
"objc2-core-foundation",
]
@ -3814,33 +3717,9 @@ checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
dependencies = [
"bitflags 2.9.3",
"libc",
"objc2 0.6.2",
"objc2",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
]
[[package]]
name = "objc2-link-presentation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-app-kit 0.2.2",
"objc2-foundation 0.2.2",
]
[[package]]
name = "objc2-metal"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-foundation",
]
[[package]]
@ -3850,79 +3729,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874"
dependencies = [
"bitflags 2.9.3",
"block2 0.6.1",
"block2",
"dispatch2",
"objc2 0.6.2",
"objc2",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
]
[[package]]
name = "objc2-quartz-core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-metal 0.2.2",
]
[[package]]
name = "objc2-symbols"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
dependencies = [
"objc2 0.5.2",
"objc2-foundation 0.2.2",
"objc2-foundation",
]
[[package]]
name = "objc2-ui-kit"
version = "0.2.2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-cloud-kit",
"objc2-core-data",
"objc2-core-image",
"objc2-core-location",
"objc2-foundation 0.2.2",
"objc2-link-presentation",
"objc2-quartz-core",
"objc2-symbols",
"objc2-uniform-type-identifiers",
"objc2-user-notifications",
]
[[package]]
name = "objc2-uniform-type-identifiers"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-foundation 0.2.2",
]
[[package]]
name = "objc2-user-notifications"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
dependencies = [
"bitflags 2.9.3",
"block2 0.5.1",
"objc2 0.5.2",
"objc2-core-location",
"objc2-foundation 0.2.2",
"objc2",
"objc2-core-foundation",
"objc2-foundation",
]
[[package]]
@ -4083,7 +3906,7 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.5.17",
"redox_syscall",
"smallvec",
"windows-targets 0.52.6",
]
@ -4320,7 +4143,7 @@ dependencies = [
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix 1.0.8",
"rustix",
"windows-sys 0.60.2",
]
@ -4730,15 +4553,6 @@ dependencies = [
"font-types",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.5.17"
@ -4873,14 +4687,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
dependencies = [
"ashpd",
"block2 0.6.1",
"block2",
"dispatch2",
"js-sys",
"log",
"objc2 0.6.2",
"objc2-app-kit 0.3.1",
"objc2",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
"objc2-foundation",
"pollster",
"raw-window-handle",
"urlencoding",
@ -4993,19 +4807,6 @@ dependencies = [
"spirv",
]
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.9.3",
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
]
[[package]]
name = "rustix"
version = "1.0.8"
@ -5015,7 +4816,7 @@ dependencies = [
"bitflags 2.9.3",
"errno",
"libc",
"linux-raw-sys 0.9.4",
"linux-raw-sys",
"windows-sys 0.60.2",
]
@ -5144,9 +4945,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sctk-adwaita"
version = "0.10.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec"
checksum = "1dd3accc0f3f4bbaf2c9e1957a030dc582028130c67660d44c0a0345a22ca69b"
dependencies = [
"ab_glyph",
"log",
@ -5421,9 +5222,9 @@ dependencies = [
[[package]]
name = "smithay-client-toolkit"
version = "0.19.2"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016"
checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0"
dependencies = [
"bitflags 2.9.3",
"calloop",
@ -5432,13 +5233,15 @@ dependencies = [
"libc",
"log",
"memmap2",
"rustix 0.38.44",
"thiserror 1.0.69",
"rustix",
"thiserror 2.0.16",
"wayland-backend",
"wayland-client",
"wayland-csd-frame",
"wayland-cursor",
"wayland-protocols",
"wayland-protocols-experimental",
"wayland-protocols-misc",
"wayland-protocols-wlr",
"wayland-scanner",
"xkeysym",
@ -5446,10 +5249,11 @@ dependencies = [
[[package]]
name = "smol_str"
version = "0.2.2"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d"
dependencies = [
"borsh",
"serde",
]
@ -5776,7 +5580,7 @@ dependencies = [
"fastrand",
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.8",
"rustix",
"windows-sys 0.60.2",
]
@ -6104,6 +5908,7 @@ version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@ -6610,7 +6415,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
dependencies = [
"cc",
"downcast-rs",
"rustix 1.0.8",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
@ -6623,7 +6428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
dependencies = [
"bitflags 2.9.3",
"rustix 1.0.8",
"rustix",
"wayland-backend",
"wayland-scanner",
]
@ -6645,7 +6450,7 @@ version = "0.31.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29"
dependencies = [
"rustix 1.0.8",
"rustix",
"wayland-client",
"xcursor",
]
@ -6662,6 +6467,32 @@ dependencies = [
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-experimental"
version = "20250721.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1"
dependencies = [
"bitflags 2.9.3",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-misc"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfe33d551eb8bffd03ff067a8b44bb963919157841a99957151299a6307d19c"
dependencies = [
"bitflags 2.9.3",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-plasma"
version = "0.3.9"
@ -7303,51 +7134,215 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winit"
version = "0.30.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"ahash",
"android-activity",
"atomic-waker",
"bitflags 2.9.3",
"block2 0.5.1",
"bytemuck",
"calloop",
"cfg_aliases",
"concurrent-queue",
"core-foundation",
"core-graphics",
"cursor-icon",
"dpi",
"js-sys",
"libc",
"raw-window-handle",
"rustix",
"serde",
"smol_str",
"tracing",
"winit-android",
"winit-appkit",
"winit-common",
"winit-core",
"winit-orbital",
"winit-uikit",
"winit-wayland",
"winit-web",
"winit-win32",
"winit-x11",
]
[[package]]
name = "winit-android"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"android-activity",
"bitflags 2.9.3",
"dpi",
"ndk",
"raw-window-handle",
"smol_str",
"tracing",
"winit-core",
]
[[package]]
name = "winit-appkit"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"block2",
"dispatch2",
"dpi",
"objc2",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-core-graphics",
"objc2-core-video",
"objc2-foundation",
"raw-window-handle",
"smol_str",
"tracing",
"winit-common",
"winit-core",
]
[[package]]
name = "winit-common"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"memmap2",
"objc2",
"objc2-core-foundation",
"smol_str",
"tracing",
"winit-core",
"x11-dl",
"xkbcommon-dl",
]
[[package]]
name = "winit-core"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"cursor-icon",
"dpi",
"keyboard-types",
"raw-window-handle",
"serde",
"smol_str",
"web-time",
]
[[package]]
name = "winit-orbital"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"dpi",
"orbclient",
"raw-window-handle",
"redox_syscall",
"smol_str",
"tracing",
"winit-core",
]
[[package]]
name = "winit-uikit"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"block2",
"dispatch2",
"dpi",
"objc2",
"objc2-core-foundation",
"objc2-foundation",
"objc2-ui-kit",
"raw-window-handle",
"serde",
"smol_str",
"tracing",
"winit-common",
"winit-core",
]
[[package]]
name = "winit-wayland"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"ahash",
"bitflags 2.9.3",
"calloop",
"cursor-icon",
"dpi",
"libc",
"memmap2",
"ndk",
"objc2 0.5.2",
"objc2-app-kit 0.2.2",
"objc2-foundation 0.2.2",
"objc2-ui-kit",
"orbclient",
"percent-encoding",
"pin-project",
"raw-window-handle",
"redox_syscall 0.4.1",
"rustix 0.38.44",
"rustix",
"sctk-adwaita",
"serde",
"smithay-client-toolkit",
"smol_str",
"tracing",
"unicode-segmentation",
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-protocols-plasma",
"winit-common",
"winit-core",
]
[[package]]
name = "winit-web"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"atomic-waker",
"bitflags 2.9.3",
"concurrent-queue",
"cursor-icon",
"dpi",
"js-sys",
"pin-project",
"raw-window-handle",
"smol_str",
"tracing",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"web-time",
"windows-sys 0.52.0",
"winit-core",
]
[[package]]
name = "winit-win32"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"cursor-icon",
"dpi",
"raw-window-handle",
"smol_str",
"tracing",
"unicode-segmentation",
"windows-sys 0.59.0",
"winit-core",
]
[[package]]
name = "winit-x11"
version = "0.30.12"
source = "git+https://github.com/rust-windowing/winit.git?rev=66283a79bddd034c45fb0e72c84fa5cd4e5f82fb#66283a79bddd034c45fb0e72c84fa5cd4e5f82fb"
dependencies = [
"bitflags 2.9.3",
"bytemuck",
"calloop",
"cursor-icon",
"dpi",
"libc",
"percent-encoding",
"raw-window-handle",
"rustix",
"smol_str",
"tracing",
"winit-common",
"winit-core",
"x11-dl",
"x11rb",
"xkbcommon-dl",
@ -7402,8 +7397,9 @@ dependencies = [
"libc",
"libloading",
"once_cell",
"rustix 1.0.8",
"rustix",
"x11rb-protocol",
"xcursor",
]
[[package]]
@ -7419,7 +7415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909"
dependencies = [
"libc",
"rustix 1.0.8",
"rustix",
]
[[package]]

View File

@ -132,7 +132,7 @@ web-sys = { version = "=0.3.77", features = [
"HtmlImageElement",
"ImageBitmapRenderingContext",
] }
winit = { version = "0.30", features = ["wayland", "rwh_06"] }
winit = { git = "https://github.com/rust-windowing/winit.git", rev = "66283a79bddd034c45fb0e72c84fa5cd4e5f82fb" }
url = "2.5"
tokio = { version = "1.29", features = ["fs", "macros", "io-std", "rt"] }
vello = { git = "https://github.com/linebender/vello.git", rev = "87cc5bee6d3a34d15017dbbb58634ddc7f33ff9b" } # TODO switch back to stable when a release is made

View File

@ -26,7 +26,7 @@ graphite-desktop-wrapper = { path = "wrapper" }
graphite-desktop-embedded-resources = { path = "embedded-resources", optional = true }
wgpu = { workspace = true }
winit = { workspace = true, features = ["serde"] }
winit = { workspace = true, features = [ "serde" ] }
thiserror = { workspace = true }
futures = { workspace = true }
cef = { workspace = true }
@ -34,7 +34,7 @@ cef-dll-sys = { workspace = true }
tracing-subscriber = { workspace = true }
tracing = { workspace = true }
dirs = { workspace = true }
ron = { workspace = true}
ron = { workspace = true }
bytemuck = { workspace = true }
glam = { workspace = true }
vello = { workspace = true }

View File

@ -1,39 +1,37 @@
use crate::CustomEvent;
use crate::cef::WindowSize;
use crate::consts::{APP_NAME, CEF_MESSAGE_LOOP_MAX_ITERATIONS};
use crate::persist::PersistentData;
use crate::render::GraphicsState;
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
use rfd::AsyncFileDialog;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::sync::mpsc::SyncSender;
use std::thread;
use std::time::Duration;
use std::time::Instant;
use winit::application::ApplicationHandler;
use winit::dpi::PhysicalSize;
use winit::event::WindowEvent;
use winit::event_loop::ActiveEventLoop;
use winit::event_loop::ControlFlow;
use winit::event_loop::EventLoopProxy;
use winit::window::Window;
use winit::window::WindowId;
use crate::cef;
use crate::consts::CEF_MESSAGE_LOOP_MAX_ITERATIONS;
use crate::event::{AppEvent, AppEventScheduler};
use crate::native_window;
use crate::persist::PersistentData;
use crate::render::GraphicsState;
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
pub(crate) struct WinitApp {
pub(crate) struct App {
cef_context: Box<dyn cef::CefContext>,
window: Option<Arc<Window>>,
window: Option<Arc<dyn Window>>,
native_window: native_window::NativeWindowHandle,
cef_schedule: Option<Instant>,
window_size_sender: Sender<WindowSize>,
cef_window_size_sender: Sender<cef::WindowSize>,
graphics_state: Option<GraphicsState>,
wgpu_context: WgpuContext,
event_loop_proxy: EventLoopProxy<CustomEvent>,
app_event_receiver: Receiver<AppEvent>,
app_event_scheduler: AppEventScheduler,
desktop_wrapper: DesktopWrapper,
last_ui_update: Instant,
avg_frame_time: f32,
@ -43,14 +41,20 @@ pub(crate) struct WinitApp {
persistent_data: PersistentData,
}
impl WinitApp {
pub(crate) fn new(cef_context: Box<dyn cef::CefContext>, window_size_sender: Sender<WindowSize>, wgpu_context: WgpuContext, event_loop_proxy: EventLoopProxy<CustomEvent>) -> Self {
let rendering_loop_proxy = event_loop_proxy.clone();
impl App {
pub(crate) fn new(
cef_context: Box<dyn cef::CefContext>,
window_size_sender: Sender<cef::WindowSize>,
wgpu_context: WgpuContext,
app_event_receiver: Receiver<AppEvent>,
app_event_scheduler: AppEventScheduler,
) -> Self {
let rendering_app_event_scheduler = app_event_scheduler.clone();
let (start_render_sender, start_render_receiver) = std::sync::mpsc::sync_channel(1);
std::thread::spawn(move || {
loop {
let result = futures::executor::block_on(DesktopWrapper::execute_node_graph());
let _ = rendering_loop_proxy.send_event(CustomEvent::NodeGraphExecutionResult(result));
rendering_app_event_scheduler.schedule(AppEvent::NodeGraphExecutionResult(result));
let _ = start_render_receiver.recv();
}
});
@ -63,9 +67,10 @@ impl WinitApp {
window: None,
cef_schedule: Some(Instant::now()),
graphics_state: None,
window_size_sender,
cef_window_size_sender: window_size_sender,
wgpu_context,
event_loop_proxy,
app_event_receiver,
app_event_scheduler,
desktop_wrapper: DesktopWrapper::new(),
last_ui_update: Instant::now(),
avg_frame_time: 0.,
@ -87,7 +92,7 @@ impl WinitApp {
self.send_or_queue_web_message(bytes);
}
DesktopFrontendMessage::OpenFileDialog { title, filters, context } => {
let event_loop_proxy = self.event_loop_proxy.clone();
let app_event_scheduler = self.app_event_scheduler.clone();
let _ = thread::spawn(move || {
let mut dialog = AsyncFileDialog::new().set_title(title);
for filter in filters {
@ -100,7 +105,7 @@ impl WinitApp {
&& let Ok(content) = std::fs::read(&path)
{
let message = DesktopWrapperMessage::OpenFileDialogResult { path, content, context };
let _ = event_loop_proxy.send_event(CustomEvent::DesktopWrapperMessage(message));
app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
}
});
}
@ -111,7 +116,7 @@ impl WinitApp {
filters,
context,
} => {
let event_loop_proxy = self.event_loop_proxy.clone();
let app_event_scheduler = self.app_event_scheduler.clone();
let _ = thread::spawn(move || {
let mut dialog = AsyncFileDialog::new().set_title(title).set_file_name(default_filename);
if let Some(folder) = default_folder {
@ -125,7 +130,7 @@ impl WinitApp {
if let Some(path) = futures::executor::block_on(show_dialog) {
let message = DesktopWrapperMessage::SaveFileDialogResult { path, context };
let _ = event_loop_proxy.send_event(CustomEvent::DesktopWrapperMessage(message));
app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
}
});
}
@ -145,7 +150,7 @@ impl WinitApp {
if let Some(graphics_state) = &mut self.graphics_state
&& let Some(window) = &self.window
{
let window_size = window.inner_size();
let window_size = window.surface_size();
let viewport_offset_x = x / window_size.width as f32;
let viewport_offset_y = y / window_size.height as f32;
@ -173,7 +178,7 @@ impl WinitApp {
}
}
DesktopFrontendMessage::CloseWindow => {
let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow);
self.app_event_scheduler.schedule(AppEvent::CloseWindow);
}
DesktopFrontendMessage::PersistenceWriteDocument { id, document } => {
self.persistent_data.write_document(id, document);
@ -252,43 +257,67 @@ impl WinitApp {
self.web_communication_startup_buffer.push(message);
}
}
}
impl ApplicationHandler<CustomEvent> for WinitApp {
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
// Set a timeout in case we miss any cef schedule requests
let timeout = Instant::now() + Duration::from_millis(10);
let wait_until = timeout.min(self.cef_schedule.unwrap_or(timeout));
if let Some(schedule) = self.cef_schedule
&& schedule < Instant::now()
{
self.cef_schedule = None;
// Poll cef message loop multiple times to avoid message loop starvation
for _ in 0..CEF_MESSAGE_LOOP_MAX_ITERATIONS {
self.cef_context.work();
fn user_event(&mut self, event_loop: &dyn ActiveEventLoop, event: AppEvent) {
match event {
AppEvent::WebCommunicationInitialized => {
self.web_communication_initialized = true;
for message in self.web_communication_startup_buffer.drain(..) {
self.cef_context.send_web_message(message);
}
}
AppEvent::DesktopWrapperMessage(message) => self.dispatch_desktop_wrapper_message(message),
AppEvent::NodeGraphExecutionResult(result) => match result {
NodeGraphExecutionResult::HasRun(texture) => {
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::PollNodeGraphEvaluation);
if let Some(texture) = texture
&& let Some(graphics_state) = self.graphics_state.as_mut()
&& let Some(window) = self.window.as_ref()
{
graphics_state.bind_viewport_texture(texture);
window.request_redraw();
}
}
NodeGraphExecutionResult::NotRun => {}
},
AppEvent::UiUpdate(texture) => {
if let Some(graphics_state) = self.graphics_state.as_mut() {
graphics_state.resize(texture.width(), texture.height());
graphics_state.bind_ui_texture(texture);
let elapsed = self.last_ui_update.elapsed().as_secs_f32();
self.last_ui_update = Instant::now();
if elapsed < 0.5 {
self.avg_frame_time = (self.avg_frame_time * 3. + elapsed) / 4.;
}
}
if let Some(window) = &self.window {
window.request_redraw();
}
}
AppEvent::ScheduleBrowserWork(instant) => {
if instant <= Instant::now() {
self.cef_context.work();
} else {
self.cef_schedule = Some(instant);
}
}
AppEvent::CloseWindow => {
// TODO: Implement graceful shutdown
tracing::info!("Exiting main event loop");
event_loop.exit();
}
}
if let Some(window) = &self.window.as_ref() {
window.request_redraw();
}
event_loop.set_control_flow(ControlFlow::WaitUntil(wait_until));
}
}
impl ApplicationHandler for App {
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
let window_attributes = self.native_window.build(event_loop);
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let mut window = Window::default_attributes()
.with_title(APP_NAME)
.with_min_inner_size(winit::dpi::LogicalSize::new(400, 300))
.with_inner_size(winit::dpi::LogicalSize::new(1200, 800))
.with_resizable(true);
let window: Arc<dyn Window> = Arc::from(event_loop.create_window(window_attributes).unwrap());
window = self.native_window.build(window, event_loop);
self.native_window.setup(window.as_ref());
let window = event_loop.create_window(window).unwrap();
self.native_window.setup(&window);
let window = Arc::new(window);
let graphics_state = GraphicsState::new(window.clone(), self.wgpu_context.clone());
self.window = Some(window);
@ -307,67 +336,21 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::UpdatePlatform(platform));
}
fn user_event(&mut self, event_loop: &ActiveEventLoop, event: CustomEvent) {
match event {
CustomEvent::WebCommunicationInitialized => {
self.web_communication_initialized = true;
for message in self.web_communication_startup_buffer.drain(..) {
self.cef_context.send_web_message(message);
}
}
CustomEvent::DesktopWrapperMessage(message) => self.dispatch_desktop_wrapper_message(message),
CustomEvent::NodeGraphExecutionResult(result) => match result {
NodeGraphExecutionResult::HasRun(texture) => {
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::PollNodeGraphEvaluation);
if let Some(texture) = texture
&& let Some(graphics_state) = self.graphics_state.as_mut()
&& let Some(window) = self.window.as_ref()
{
graphics_state.bind_viewport_texture(texture);
window.request_redraw();
}
}
NodeGraphExecutionResult::NotRun => {}
},
CustomEvent::UiUpdate(texture) => {
if let Some(graphics_state) = self.graphics_state.as_mut() {
graphics_state.resize(texture.width(), texture.height());
graphics_state.bind_ui_texture(texture);
let elapsed = self.last_ui_update.elapsed().as_secs_f32();
self.last_ui_update = Instant::now();
if elapsed < 0.5 {
self.avg_frame_time = (self.avg_frame_time * 3. + elapsed) / 4.;
}
}
if let Some(window) = &self.window {
window.request_redraw();
}
}
CustomEvent::ScheduleBrowserWork(instant) => {
if instant <= Instant::now() {
self.cef_context.work();
} else {
self.cef_schedule = Some(instant);
}
}
CustomEvent::CloseWindow => {
// TODO: Implement graceful shutdown
tracing::info!("Exiting main event loop");
event_loop.exit();
}
fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) {
while let Ok(event) = self.app_event_receiver.try_recv() {
self.user_event(event_loop, event);
}
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {
fn window_event(&mut self, event_loop: &dyn ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {
self.cef_context.handle_window_event(&event);
match event {
WindowEvent::CloseRequested => {
let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow);
self.app_event_scheduler.schedule(AppEvent::CloseWindow);
}
WindowEvent::Resized(PhysicalSize { width, height }) => {
let _ = self.window_size_sender.send(WindowSize::new(width as usize, height as usize));
WindowEvent::SurfaceResized(size) => {
let _ = self.cef_window_size_sender.send(size.into());
self.cef_context.notify_of_resize();
}
WindowEvent::RedrawRequested => {
@ -387,18 +370,19 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
let _ = self.start_render_sender.try_send(());
}
}
// Currently not supported on wayland see https://github.com/rust-windowing/winit/issues/1881
WindowEvent::DroppedFile(path) => {
match std::fs::read(&path) {
Ok(content) => {
let message = DesktopWrapperMessage::OpenFile { path, content };
let _ = self.event_loop_proxy.send_event(CustomEvent::DesktopWrapperMessage(message));
}
Err(e) => {
tracing::error!("Failed to read dropped file {}: {}", path.display(), e);
return;
}
};
WindowEvent::DragDropped { paths, .. } => {
for path in paths {
match std::fs::read(&path) {
Ok(content) => {
let message = DesktopWrapperMessage::OpenFile { path, content };
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
}
Err(e) => {
tracing::error!("Failed to read dropped file {}: {}", path.display(), e);
return;
}
};
}
}
_ => {}
}
@ -406,4 +390,24 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
// Notify cef of possible input events
self.cef_context.work();
}
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
// Set a timeout in case we miss any cef schedule requests
let timeout = Instant::now() + Duration::from_millis(10);
let wait_until = timeout.min(self.cef_schedule.unwrap_or(timeout));
if let Some(schedule) = self.cef_schedule
&& schedule < Instant::now()
{
self.cef_schedule = None;
// Poll cef message loop multiple times to avoid message loop starvation
for _ in 0..CEF_MESSAGE_LOOP_MAX_ITERATIONS {
self.cef_context.work();
}
}
if let Some(window) = &self.window.as_ref() {
window.request_redraw();
}
event_loop.set_control_flow(ControlFlow::WaitUntil(wait_until));
}
}

View File

@ -10,10 +10,9 @@
//! - **Windows**: D3D11 shared textures via either Vulkan or D3D12 interop (`accelerated_paint_d3d11` feature)
//! - **macOS**: IOSurface via Metal/Vulkan interop (`accelerated_paint_iosurface` feature)
//!
//!
//! The system gracefully falls back to CPU textures when hardware acceleration is unavailable.
use crate::CustomEvent;
use crate::event::{AppEvent, AppEventScheduler};
use crate::render::FrameBufferRef;
use graphite_desktop_wrapper::{WgpuContext, deserialize_editor_message};
use std::fs::File;
@ -38,7 +37,6 @@ mod texture_import;
use texture_import::SharedTextureHandle;
pub(crate) use context::{CefContext, CefContextBuilder, InitError};
use winit::event_loop::EventLoopProxy;
pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
fn window_size(&self) -> WindowSize;
@ -58,12 +56,16 @@ pub(crate) struct WindowSize {
pub(crate) width: usize,
pub(crate) height: usize,
}
impl WindowSize {
pub(crate) fn new(width: usize, height: usize) -> Self {
Self { width, height }
}
}
impl From<winit::dpi::PhysicalSize<u32>> for WindowSize {
fn from(size: winit::dpi::PhysicalSize<u32>) -> Self {
Self::new(size.width as usize, size.height as usize)
}
}
#[derive(Clone)]
pub(crate) struct Resource {
@ -88,29 +90,17 @@ impl Read for ResourceReader {
#[derive(Clone)]
pub(crate) struct CefHandler {
window_size_receiver: Arc<Mutex<WindowSizeReceiver>>,
event_loop_proxy: EventLoopProxy<CustomEvent>,
wgpu_context: WgpuContext,
app_event_scheduler: AppEventScheduler,
window_size_receiver: Arc<Mutex<WindowSizeReceiver>>,
}
struct WindowSizeReceiver {
receiver: Receiver<WindowSize>,
window_size: WindowSize,
}
impl WindowSizeReceiver {
fn new(window_size_receiver: Receiver<WindowSize>) -> Self {
Self {
window_size: WindowSize { width: 1, height: 1 },
receiver: window_size_receiver,
}
}
}
impl CefHandler {
pub(crate) fn new(window_size_receiver: Receiver<WindowSize>, event_loop_proxy: EventLoopProxy<CustomEvent>, wgpu_context: WgpuContext) -> Self {
pub(crate) fn new(wgpu_context: WgpuContext, app_event_scheduler: AppEventScheduler, window_size_receiver: Receiver<WindowSize>) -> Self {
Self {
window_size_receiver: Arc::new(Mutex::new(WindowSizeReceiver::new(window_size_receiver))),
event_loop_proxy,
wgpu_context,
app_event_scheduler,
window_size_receiver: Arc::new(Mutex::new(WindowSizeReceiver::new(window_size_receiver))),
}
}
}
@ -164,14 +154,14 @@ impl CefEventHandler for CefHandler {
},
);
let _ = self.event_loop_proxy.send_event(CustomEvent::UiUpdate(texture));
self.app_event_scheduler.schedule(AppEvent::UiUpdate(texture));
}
#[cfg(feature = "accelerated_paint")]
fn draw_gpu(&self, shared_texture: SharedTextureHandle) {
match shared_texture.import_texture(&self.wgpu_context.device) {
Ok(texture) => {
let _ = self.event_loop_proxy.send_event(CustomEvent::UiUpdate(texture));
self.app_event_scheduler.schedule(AppEvent::UiUpdate(texture));
}
Err(e) => {
tracing::error!("Failed to import shared texture: {}", e);
@ -235,11 +225,11 @@ impl CefEventHandler for CefHandler {
}
fn schedule_cef_message_loop_work(&self, scheduled_time: std::time::Instant) {
let _ = self.event_loop_proxy.send_event(CustomEvent::ScheduleBrowserWork(scheduled_time));
self.app_event_scheduler.schedule(AppEvent::ScheduleBrowserWork(scheduled_time));
}
fn initialized_web_communication(&self) {
let _ = self.event_loop_proxy.send_event(CustomEvent::WebCommunicationInitialized);
self.app_event_scheduler.schedule(AppEvent::WebCommunicationInitialized);
}
fn receive_web_message(&self, message: &[u8]) {
@ -247,6 +237,19 @@ impl CefEventHandler for CefHandler {
tracing::error!("Failed to deserialize web message");
return;
};
let _ = self.event_loop_proxy.send_event(CustomEvent::DesktopWrapperMessage(desktop_wrapper_message));
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(desktop_wrapper_message));
}
}
struct WindowSizeReceiver {
window_size: WindowSize,
receiver: Receiver<WindowSize>,
}
impl WindowSizeReceiver {
fn new(window_size_receiver: Receiver<WindowSize>) -> Self {
Self {
window_size: WindowSize { width: 1, height: 1 },
receiver: window_size_receiver,
}
}
}

View File

@ -2,7 +2,7 @@ use cef::sys::{cef_event_flags_t, cef_key_event_type_t, cef_mouse_button_type_t}
use cef::{Browser, ImplBrowser, ImplBrowserHost, KeyEvent, KeyEventType, MouseEvent};
use std::time::Instant;
use winit::dpi::PhysicalPosition;
use winit::event::{ElementState, MouseButton, MouseScrollDelta, WindowEvent};
use winit::event::{ButtonSource, ElementState, MouseButton, MouseScrollDelta, WindowEvent};
mod keymap;
use keymap::{ToNativeKeycode, ToVKBits};
@ -11,7 +11,7 @@ use super::consts::{MULTICLICK_ALLOWED_TRAVEL, MULTICLICK_TIMEOUT, SCROLL_LINE_H
pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputState, event: &WindowEvent) {
match event {
WindowEvent::CursorMoved { position, .. } => {
WindowEvent::PointerMoved { position, .. } => {
input_state.cursor_move(position);
let Some(host) = browser.host() else {
@ -19,13 +19,20 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
};
host.send_mouse_move_event(Some(&input_state.into()), 0);
}
WindowEvent::MouseInput { state, button, .. } => {
let cef_click_count = input_state.mouse_input(button, state).into();
WindowEvent::PointerButton { state, button, .. } => {
let mouse_button = match button {
ButtonSource::Mouse(mouse_button) => mouse_button,
_ => {
return; // TODO: Handle touch input
}
};
let cef_click_count = input_state.mouse_input(mouse_button, state).into();
let cef_mouse_up = match state {
ElementState::Pressed => 0,
ElementState::Released => 1,
};
let cef_button = match button {
let cef_button = match mouse_button {
MouseButton::Left => cef::MouseButtonType::from(cef_mouse_button_type_t::MBT_LEFT),
MouseButton::Right => cef::MouseButtonType::from(cef_mouse_button_type_t::MBT_RIGHT),
MouseButton::Middle => cef::MouseButtonType::from(cef_mouse_button_type_t::MBT_MIDDLE),
@ -59,7 +66,6 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
winit::keyboard::Key::Named(named_key) => (
Some(named_key),
match named_key {
winit::keyboard::NamedKey::Space => Some(' '),
winit::keyboard::NamedKey::Enter => Some('\u{000d}'),
_ => None,
},
@ -312,7 +318,7 @@ impl CefModifiers {
if input_state.modifiers.alt_key() {
inner |= cef_event_flags_t::EVENTFLAG_ALT_DOWN as u32;
}
if input_state.modifiers.super_key() {
if input_state.modifiers.meta_key() {
inner |= cef_event_flags_t::EVENTFLAG_COMMAND_DOWN as u32;
}

View File

@ -47,10 +47,8 @@ impl ToVKBits for winit::keyboard::NamedKey {
(0x91, ScrollLock),
(0x10, Shift),
(0x5B, Meta),
(0x5C, Super),
(0x0D, Enter),
(0x09, Tab),
(0x20, Space),
(0x28, ArrowDown),
(0x25, ArrowLeft),
(0x27, ArrowRight),
@ -253,6 +251,7 @@ impl ToVKBits for char {
(0xDE, '"'),
(0xBF, '/'),
(0xBF, '?'),
(0x20, ' '),
)
}
}

34
desktop/src/event.rs Normal file
View File

@ -0,0 +1,34 @@
use graphite_desktop_wrapper::NodeGraphExecutionResult;
use graphite_desktop_wrapper::messages::DesktopWrapperMessage;
pub(crate) enum AppEvent {
UiUpdate(wgpu::Texture),
ScheduleBrowserWork(std::time::Instant),
WebCommunicationInitialized,
DesktopWrapperMessage(DesktopWrapperMessage),
NodeGraphExecutionResult(NodeGraphExecutionResult),
CloseWindow,
}
#[derive(Clone)]
pub(crate) struct AppEventScheduler {
pub(crate) proxy: winit::event_loop::EventLoopProxy,
pub(crate) sender: std::sync::mpsc::Sender<AppEvent>,
}
impl AppEventScheduler {
pub(crate) fn schedule(&self, event: AppEvent) {
let _ = self.sender.send(event);
self.proxy.wake_up();
}
}
pub(crate) trait CreateAppEventSchedulerEventLoopExt {
fn create_app_event_scheduler(&self, sender: std::sync::mpsc::Sender<AppEvent>) -> AppEventScheduler;
}
impl CreateAppEventSchedulerEventLoopExt for winit::event_loop::EventLoop {
fn create_app_event_scheduler(&self, sender: std::sync::mpsc::Sender<AppEvent>) -> AppEventScheduler {
AppEventScheduler { proxy: self.create_proxy(), sender }
}
}

View File

@ -1,35 +1,22 @@
use std::process::exit;
use std::time::Instant;
use cef::CefHandler;
use tracing_subscriber::EnvFilter;
use winit::event_loop::EventLoop;
use graphite_desktop_wrapper::WgpuContext;
pub(crate) mod consts;
mod app;
mod cef;
mod dirs;
mod event;
mod native_window;
mod persist;
mod render;
mod app;
use app::WinitApp;
mod dirs;
mod persist;
use graphite_desktop_wrapper::messages::DesktopWrapperMessage;
use graphite_desktop_wrapper::{NodeGraphExecutionResult, WgpuContext};
pub(crate) enum CustomEvent {
UiUpdate(wgpu::Texture),
ScheduleBrowserWork(Instant),
WebCommunicationInitialized,
DesktopWrapperMessage(DesktopWrapperMessage),
NodeGraphExecutionResult(NodeGraphExecutionResult),
CloseWindow,
}
use app::App;
use cef::CefHandler;
use event::CreateAppEventSchedulerEventLoopExt;
fn main() {
tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init();
@ -46,13 +33,18 @@ fn main() {
let wgpu_context = futures::executor::block_on(WgpuContext::new()).unwrap();
let event_loop = EventLoop::<CustomEvent>::with_user_event().build().unwrap();
let event_loop = EventLoop::new().unwrap();
let (app_event_sender, app_event_receiver) = std::sync::mpsc::channel();
let app_event_scheduler = event_loop.create_app_event_scheduler(app_event_sender);
let (window_size_sender, window_size_receiver) = std::sync::mpsc::channel();
let cef_handler = cef::CefHandler::new(window_size_receiver, event_loop.create_proxy(), wgpu_context.clone());
let cef_handler = cef::CefHandler::new(wgpu_context.clone(), app_event_scheduler.clone(), window_size_receiver);
let cef_context = match cef_context_builder.initialize(cef_handler) {
Ok(c) => c,
Ok(c) => {
tracing::info!("CEF initialized successfully");
c
}
Err(cef::InitError::AlreadyRunning) => {
tracing::error!("Another instance is already running, Exiting.");
exit(0);
@ -71,9 +63,7 @@ fn main() {
}
};
tracing::info!("CEF initialized successfully");
let mut app = App::new(Box::new(cef_context), window_size_sender, wgpu_context, app_event_receiver, app_event_scheduler);
let mut winit_app = WinitApp::new(Box::new(cef_context), window_size_sender, wgpu_context, event_loop.create_proxy());
event_loop.run_app(&mut winit_app).unwrap();
event_loop.run_app(&mut app).unwrap();
}

View File

@ -1,6 +1,8 @@
use winit::event_loop::ActiveEventLoop;
use winit::window::{Window, WindowAttributes};
use crate::consts::APP_NAME;
#[cfg(target_os = "windows")]
mod windows;
@ -17,25 +19,31 @@ impl Default for NativeWindowHandle {
}
impl NativeWindowHandle {
#[allow(unused_variables)]
pub(super) fn build(&mut self, window: WindowAttributes, event_loop: &ActiveEventLoop) -> WindowAttributes {
pub(super) fn build(&mut self, event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
let mut window = WindowAttributes::default()
.with_title(APP_NAME)
.with_min_surface_size(winit::dpi::LogicalSize::new(400, 300))
.with_surface_size(winit::dpi::LogicalSize::new(1200, 800))
.with_resizable(true);
#[cfg(target_os = "linux")]
{
use crate::consts::{APP_ID, APP_NAME};
use winit::platform::wayland::ActiveEventLoopExtWayland;
if event_loop.is_wayland() {
winit::platform::wayland::WindowAttributesExtWayland::with_name(window, APP_ID, "")
use winit::platform::wayland::WindowAttributesWayland;
use winit::platform::x11::WindowAttributesX11;
window = if event_loop.is_wayland() {
let wayland_window = WindowAttributesWayland::default().with_name(APP_ID, "");
window.with_platform_attributes(Box::new(wayland_window))
} else {
winit::platform::x11::WindowAttributesExtX11::with_name(window, APP_ID, APP_NAME)
let x11_window = WindowAttributesX11::default().with_name(APP_ID, APP_NAME);
window.with_platform_attributes(Box::new(x11_window))
}
}
#[cfg(not(target_os = "linux"))]
{
window
}
window
}
#[allow(unused_variables)]
pub(crate) fn setup(&mut self, window: &Window) {
pub(crate) fn setup(&mut self, window: &dyn Window) {
#[cfg(target_os = "windows")]
{
*self = NativeWindowHandle::Windows(windows::WindowsNativeWindowHandle::new(window));

View File

@ -23,7 +23,7 @@ pub(super) struct WindowsNativeWindowHandle {
inner: WindowsNativeWindowHandleInner,
}
impl WindowsNativeWindowHandle {
pub(super) fn new(window: &Window) -> Self {
pub(super) fn new(window: &dyn Window) -> Self {
let inner = WindowsNativeWindowHandleInner::new(window);
WindowsNativeWindowHandle { inner }
}
@ -41,7 +41,7 @@ struct WindowsNativeWindowHandleInner {
prev_window_message_handler: isize,
}
impl WindowsNativeWindowHandleInner {
fn new(window: &Window) -> WindowsNativeWindowHandleInner {
fn new(window: &dyn Window) -> WindowsNativeWindowHandleInner {
// Extract Win32 HWND from winit.
let hwnd = match window.window_handle().expect("No window handle").as_raw() {
RawWindowHandle::Win32(h) => HWND(h.hwnd.get() as *mut std::ffi::c_void),

View File

@ -24,8 +24,8 @@ pub(crate) struct GraphicsState {
}
impl GraphicsState {
pub(crate) fn new(window: Arc<Window>, context: WgpuContext) -> Self {
let size = window.inner_size();
pub(crate) fn new(window: Arc<dyn Window>, context: WgpuContext) -> Self {
let size = window.surface_size();
let surface = context.instance.create_surface(window).unwrap();
@ -232,7 +232,7 @@ impl GraphicsState {
self.bind_overlays_texture(texture);
}
pub(crate) fn render(&mut self, window: &Window) -> Result<(), wgpu::SurfaceError> {
pub(crate) fn render(&mut self, window: &dyn Window) -> Result<(), wgpu::SurfaceError> {
if let Some(scene) = self.overlays_scene.take() {
self.render_overlays(scene);
}

View File

@ -26,7 +26,7 @@ struct WindowWrapper {
#[cfg(target_family = "wasm")]
window: SurfaceHandle<HtmlCanvasElement>,
#[cfg(not(target_family = "wasm"))]
window: SurfaceHandle<Arc<winit::window::Window>>,
window: SurfaceHandle<Arc<dyn winit::window::Window>>,
}
#[cfg(target_family = "wasm")]
@ -187,7 +187,7 @@ impl ApplicationIo for WasmApplicationIo {
#[cfg(target_family = "wasm")]
type Surface = HtmlCanvasElement;
#[cfg(not(target_family = "wasm"))]
type Surface = Arc<winit::window::Window>;
type Surface = Arc<dyn winit::window::Window>;
#[cfg(feature = "wgpu")]
type Executor = WgpuExecutor;
#[cfg(not(feature = "wgpu"))]

View File

@ -53,7 +53,7 @@ pub struct TargetTexture {
#[cfg(target_family = "wasm")]
pub type Window = web_sys::HtmlCanvasElement;
#[cfg(not(target_family = "wasm"))]
pub type Window = Arc<winit::window::Window>;
pub type Window = Arc<dyn winit::window::Window>;
unsafe impl StaticType for Surface {
type Static = Surface;