From 00c282da47e5e3c11b88cc81e06010afaf5030d2 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Thu, 18 Jul 2024 19:58:20 +0100 Subject: [PATCH 01/23] Initial conversion to winit 0.30 --- Cargo.lock | 763 ++++++++++++------ Cargo.toml | 8 +- crates/eframe/Cargo.toml | 13 +- crates/eframe/src/epi.rs | 2 +- crates/eframe/src/native/epi_integration.rs | 41 +- crates/eframe/src/native/glow_integration.rs | 49 +- crates/eframe/src/native/run.rs | 427 ++++------ crates/eframe/src/native/wgpu_integration.rs | 32 +- crates/eframe/src/native/winit_integration.rs | 14 +- crates/egui-winit/Cargo.toml | 2 +- crates/egui-winit/src/lib.rs | 68 +- crates/egui-winit/src/window_settings.rs | 16 +- crates/egui/Cargo.toml | 2 +- crates/egui/src/context.rs | 16 +- crates/egui/src/response.rs | 12 +- crates/egui/tests/accesskit.rs | 2 +- crates/egui_glow/Cargo.toml | 10 +- crates/egui_glow/examples/pure_glow.rs | 223 +++-- crates/egui_glow/src/winit.rs | 4 +- examples/serial_windows/src/main.rs | 11 - 20 files changed, 970 insertions(+), 745 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cc7f53f362..927e0dcfe47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,76 +20,94 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8410747ed85a17c4a1e9ed3f5a74d3e7bdcc876cf9a18ff40ae21d645997b2" +checksum = "0ac5b518d65f20dc920b3a7bb92bb2b90cdb301416f27c2a55a128cd99f75c0c" dependencies = [ "enumn", "serde", ] +[[package]] +name = "accesskit_atspi_common" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d50c9c8c4e3ad243b8a567ddf3595c6eb064304b76baf246bb069700e03a2e" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror", + "zvariant", +] + [[package]] name = "accesskit_consumer" -version = "0.16.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" +checksum = "17fa06310c6256253ef3474cb4694346222b4bca85a53aec7f796a73d18e7082" dependencies = [ "accesskit", + "immutable-chunkmap", ] [[package]] name = "accesskit_macos" -version = "0.10.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" +checksum = "46a3c2a5bb8b5e403502faff2bbb85de5c14bb822a0ba7e9561cb5229b42a176" dependencies = [ "accesskit", "accesskit_consumer", - "objc2 0.3.0-beta.3.patch-leaks.3", + "objc2", + "objc2-app-kit", + "objc2-foundation", "once_cell", ] [[package]] name = "accesskit_unix" -version = "0.6.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8c9b4467d77cacfbc93cee9aa8e7822f6d527c774efdca5f8b3a5280c34847" +checksum = "f8b8bfe5d626a7a0ae929df970857b3738198c66dfbf27a8d60d199e29bf2836" dependencies = [ "accesskit", - "accesskit_consumer", - "async-channel", - "async-once-cell", + "accesskit_atspi_common", + "async-channel 2.3.1", + "async-executor", + "async-task", "atspi", "futures-lite", - "once_cell", + "futures-util", "serde", "zbus", ] [[package]] name = "accesskit_windows" -version = "0.15.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" +checksum = "f2ab7baf1a8adacddc2c5a4f14d1f936f73a0f0e1c6d4592514992c4d4c57743" dependencies = [ "accesskit", "accesskit_consumer", - "once_cell", "paste", "static_assertions", - "windows 0.48.0", + "windows 0.54.0", ] [[package]] name = "accesskit_winit" -version = "0.16.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284218aca17d9e150164428a0ebc7b955f70e3a9a78b4c20894513aabf98a67" +checksum = "9e8201853811d37a43c4753753d89d86802913be12496e5d77c1a418f7f2eaac" dependencies = [ "accesskit", "accesskit_macos", "accesskit_unix", "accesskit_windows", + "raw-window-handle 0.6.0", "winit", ] @@ -139,9 +157,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-activity" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052ad56e336bcc615a214bffbeca6c181ee9550acec193f0327e0b103b033a4d" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", "bitflags 2.5.0", @@ -153,7 +171,7 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "thiserror", ] @@ -205,7 +223,7 @@ checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" dependencies = [ "clipboard-win", "log", - "objc2 0.5.1", + "objc2", "objc2-app-kit", "objc2-foundation", "parking_lot", @@ -260,6 +278,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-executor" version = "1.5.3" @@ -315,12 +345,6 @@ dependencies = [ "event-listener 2.5.3", ] -[[package]] -name = "async-once-cell" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb" - [[package]] name = "async-process" version = "1.8.0" @@ -532,51 +556,13 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-sys" -version = "0.1.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" -dependencies = [ - "objc-sys 0.2.0-beta.2", -] - -[[package]] -name = "block-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" -dependencies = [ - "objc-sys 0.3.3", -] - -[[package]] -name = "block2" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" -dependencies = [ - "block-sys 0.1.0-beta.1", - "objc2-encode 2.0.0-pre.2", -] - -[[package]] -name = "block2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" -dependencies = [ - "block-sys 0.2.0", - "objc2 0.4.1", -] - [[package]] name = "block2" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ff7d91d3c1d568065b06c899777d1e48dcf76103a672a0adbc238a7f247f1e" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2 0.5.1", + "objc2", ] [[package]] @@ -585,7 +571,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94c4ef1f913d78636d78d538eec1f18de81e481f44b1be0a81060090530846e1" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-lock", "async-task", "fastrand 2.0.1", @@ -657,13 +643,39 @@ dependencies = [ "thiserror", ] +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.5.0", + "log", + "polling 3.3.0", + "rustix 0.38.21", + "slab", + "thiserror", +] + [[package]] name = "calloop-wayland-source" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ - "calloop", + "calloop 0.12.3", + "rustix 0.38.21", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", "rustix 0.38.21", "wayland-backend", "wayland-client", @@ -713,6 +725,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "cgl" version = "0.3.2" @@ -868,9 +886,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -1154,6 +1172,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + [[package]] name = "ecolor" version = "0.28.1" @@ -1184,14 +1208,13 @@ dependencies = [ "image", "js-sys", "log", - "objc2 0.5.1", + "objc2", "objc2-app-kit", "objc2-foundation", "parking_lot", "percent-encoding", "pollster", "puffin", - "raw-window-handle 0.5.2", "raw-window-handle 0.6.0", "ron", "serde", @@ -1199,7 +1222,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "web-time", + "web-time 0.2.0", "wgpu", "winapi", "winit", @@ -1235,7 +1258,7 @@ dependencies = [ "puffin", "thiserror", "type-map", - "web-time", + "web-time 0.2.0", "wgpu", "winit", ] @@ -1254,7 +1277,7 @@ dependencies = [ "raw-window-handle 0.6.0", "serde", "smithay-clipboard", - "web-time", + "web-time 0.2.0", "webbrowser", "winit", ] @@ -1332,7 +1355,6 @@ dependencies = [ "log", "memoffset 0.9.0", "puffin", - "raw-window-handle 0.5.2", "wasm-bindgen", "web-sys", "winit", @@ -1503,6 +1525,27 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fancy-regex" version = "0.11.0" @@ -1631,6 +1674,17 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -1651,6 +1705,7 @@ checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -1784,55 +1839,56 @@ dependencies = [ [[package]] name = "glutin" -version = "0.31.2" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005459a22af86adc706522d78d360101118e2638ec21df3852fcc626e0dbb212" +checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" dependencies = [ "bitflags 2.5.0", - "cfg_aliases", + "cfg_aliases 0.2.1", "cgl", "core-foundation", "dispatch", "glutin_egl_sys", "glutin_glx_sys", - "glutin_wgl_sys", - "icrate", + "glutin_wgl_sys 0.6.0", "libloading 0.8.0", - "objc2 0.4.1", + "objc2", + "objc2-app-kit", + "objc2-foundation", "once_cell", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "wayland-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x11-dl", ] [[package]] name = "glutin-winit" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.2.1", "glutin", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "winit", ] [[package]] name = "glutin_egl_sys" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" dependencies = [ "gl_generator", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "glutin_glx_sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" dependencies = [ "gl_generator", "x11-dl", @@ -1847,6 +1903,15 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + [[package]] name = "gobject-sys" version = "0.18.0" @@ -2035,7 +2100,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.51.1", ] [[package]] @@ -2047,17 +2112,6 @@ dependencies = [ "cc", ] -[[package]] -name = "icrate" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" -dependencies = [ - "block2 0.3.0", - "dispatch", - "objc2 0.4.1", -] - [[package]] name = "idna" version = "0.4.0" @@ -2100,6 +2154,15 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" +[[package]] +name = "immutable-chunkmap" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4419f022e55cc63d5bbd6b44b71e1d226b9c9480a47824c706e9d54e5c40c5eb" +dependencies = [ + "arrayvec", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -2256,6 +2319,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "line-wrap" version = "0.2.0" @@ -2434,16 +2508,15 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.5.0", "jni-sys", "log", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", - "raw-window-handle 0.5.2", "raw-window-handle 0.6.0", "thiserror", ] @@ -2463,6 +2536,15 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + [[package]] name = "nix" version = "0.26.4" @@ -2543,99 +2625,205 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.2.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" - -[[package]] -name = "objc-sys" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da284c198fb9b7b0603f8635185e85fbd5b64ee154b1ed406d489077de2d6d60" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" [[package]] name = "objc2" -version = "0.3.0-beta.3.patch-leaks.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ - "block2 0.2.0-alpha.6", - "objc-sys 0.2.0-beta.2", - "objc2-encode 2.0.0-pre.2", + "objc-sys", + "objc2-encode", ] [[package]] -name = "objc2" -version = "0.4.1" +name = "objc2-app-kit" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "objc-sys 0.3.3", - "objc2-encode 3.0.0", + "bitflags 2.5.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", ] [[package]] -name = "objc2" -version = "0.5.1" +name = "objc2-cloud-kit" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b25e1034d0e636cd84707ccdaa9f81243d399196b8a773946dcffec0401659" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "objc-sys 0.3.3", - "objc2-encode 4.0.1", + "bitflags 2.5.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", ] [[package]] -name = "objc2-app-kit" -version = "0.2.0" +name = "objc2-contacts" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb79768a710a9a1798848179edb186d1af7e8a8679f369e4b8d201dd2a034047" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2 0.5.0", - "objc2 0.5.1", - "objc2-core-data", + "block2", + "objc2", "objc2-foundation", ] [[package]] name = "objc2-core-data" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e092bc42eaf30a08844e6a076938c60751225ec81431ab89f5d1ccd9f958d6c" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "block2 0.5.0", - "objc2 0.5.1", + "bitflags 2.5.0", + "block2", + "objc2", "objc2-foundation", ] [[package]] -name = "objc2-encode" -version = "2.0.0-pre.2" +name = "objc2-core-image" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "objc-sys 0.2.0-beta.2", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", ] [[package]] -name = "objc2-encode" -version = "3.0.0" +name = "objc2-core-location" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] [[package]] name = "objc2-encode" -version = "4.0.1" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88658da63e4cc2c8adb1262902cd6af51094df0488b760d6fd27194269c0950a" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" [[package]] name = "objc2-foundation" -version = "0.2.0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.5.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfaefe14254871ea16c7d88968c0ff14ba554712a20d76421eec52f0a7fb8904" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2 0.5.0", - "objc2 0.5.1", + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.5.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.5.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.5.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "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", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.5.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", ] [[package]] @@ -2676,11 +2864,11 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.46" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "redox_syscall 0.3.5", + "libredox", ] [[package]] @@ -2761,6 +2949,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -2955,18 +3163,18 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", ] [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] @@ -3066,6 +3274,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[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_users" version = "0.4.3" @@ -3300,14 +3517,14 @@ dependencies = [ [[package]] name = "sctk-adwaita" -version = "0.8.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", "memmap2", - "smithay-client-toolkit", + "smithay-client-toolkit 0.19.2", "tiny-skia", ] @@ -3442,8 +3659,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" dependencies = [ "bitflags 2.5.0", - "calloop", - "calloop-wayland-source", + "calloop 0.12.3", + "calloop-wayland-source 0.2.0", "cursor-icon", "libc", "log", @@ -3454,8 +3671,33 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", + "wayland-protocols 0.31.0", + "wayland-protocols-wlr 0.2.0", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.5.0", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.21", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols 0.32.3", + "wayland-protocols-wlr 0.3.3", "wayland-scanner", "xkeysym", ] @@ -3467,7 +3709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" dependencies = [ "libc", - "smithay-client-toolkit", + "smithay-client-toolkit 0.18.0", "wayland-backend", ] @@ -3783,11 +4025,10 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3795,9 +4036,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", @@ -3806,9 +4047,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -4085,13 +4326,13 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wayland-backend" -version = "0.3.2" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19152ddd73f45f024ed4534d9ca2594e0ef252c1847695255dae47f34df9fbe4" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", - "nix", + "rustix 0.38.21", "scoped-tls", "smallvec", "wayland-sys", @@ -4099,12 +4340,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.1" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca7d52347346f5473bf2f56705f360e8440873052e575e55890c4fa57843ed3" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ "bitflags 2.5.0", - "nix", + "rustix 0.38.21", "wayland-backend", "wayland-scanner", ] @@ -4143,16 +4384,28 @@ dependencies = [ "wayland-scanner", ] +[[package]] +name = "wayland-protocols" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" +dependencies = [ + "bitflags 2.5.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" dependencies = [ "bitflags 2.5.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.32.3", "wayland-scanner", ] @@ -4165,26 +4418,39 @@ dependencies = [ "bitflags 2.5.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.31.0", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" +dependencies = [ + "bitflags 2.5.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.3", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.31.0" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8e28403665c9f9513202b7e1ed71ec56fde5c107816843fb14057910b2c09c" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", - "quick-xml 0.30.0", + "quick-xml 0.34.0", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -4213,6 +4479,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webbrowser" version = "1.0.0" @@ -4250,7 +4526,7 @@ checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c" dependencies = [ "arrayvec", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.1.1", "document-features", "js-sys", "log", @@ -4277,7 +4553,7 @@ dependencies = [ "arrayvec", "bit-vec", "bitflags 2.5.0", - "cfg_aliases", + "cfg_aliases 0.1.1", "codespan-reporting", "document-features", "indexmap", @@ -4306,10 +4582,10 @@ dependencies = [ "ash", "bitflags 2.5.0", "block", - "cfg_aliases", + "cfg_aliases 0.1.1", "core-graphics-types", "glow", - "glutin_wgl_sys", + "glutin_wgl_sys 0.5.0", "gpu-alloc", "gpu-allocator", "gpu-descriptor", @@ -4321,7 +4597,7 @@ dependencies = [ "log", "metal", "naga", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", "parking_lot", @@ -4387,23 +4663,24 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.48.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-implement", - "windows-interface", + "windows-core 0.51.1", "windows-targets 0.48.5", ] [[package]] name = "windows" -version = "0.51.1" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ - "windows-core", - "windows-targets 0.48.5", + "windows-core 0.54.0", + "windows-implement", + "windows-interface", + "windows-targets 0.52.5", ] [[package]] @@ -4415,26 +4692,45 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.5", +] + [[package]] name = "windows-implement" -version = "0.48.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" +checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "windows-interface" -version = "0.48.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" +checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.5", ] [[package]] @@ -4644,48 +4940,51 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winit" -version = "0.29.10" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" +checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.5.0", + "block2", "bytemuck", - "calloop", - "cfg_aliases", + "calloop 0.13.0", + "cfg_aliases 0.2.1", + "concurrent-queue", "core-foundation", "core-graphics", "cursor-icon", - "icrate", + "dpi", "js-sys", "libc", - "log", "memmap2", "ndk", - "ndk-sys", - "objc2 0.4.1", - "once_cell", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", "orbclient", "percent-encoding", - "raw-window-handle 0.5.2", + "pin-project", "raw-window-handle 0.6.0", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix 0.38.21", "sctk-adwaita", - "smithay-client-toolkit", + "smithay-client-toolkit 0.19.2", "smol_str", + "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.32.3", "wayland-protocols-plasma", "web-sys", - "web-time", - "windows-sys 0.48.0", + "web-time 1.1.0", + "windows-sys 0.52.0", "x11-dl", "x11rb", "xkbcommon-dl", @@ -4753,9 +5052,9 @@ dependencies = [ [[package]] name = "xkbcommon-dl" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6924668544c48c0133152e7eec86d644a056ca3d09275eb8d5cdb9855f9d8699" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ "bitflags 2.5.0", "dlib", diff --git a/Cargo.toml b/Cargo.toml index a8575f468be..53cf8177a43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,8 +73,8 @@ bytemuck = "1.7.2" criterion = { version = "0.5.1", default-features = false } document-features = " 0.2.8" glow = "0.13" -glutin = "0.31" -glutin-winit = "0.4" +glutin = "0.32.0" +glutin-winit = "0.5.0" image = { version = "0.25", default-features = false } log = { version = "0.4", features = ["std"] } nohash-hasher = "0.2" @@ -89,11 +89,11 @@ web-time = "0.2" # Timekeeping for native and web wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = "0.3.58" -wgpu = { version = "0.20.0", default-features = false, features = [ +wgpu = { version = "0.20.1", default-features = false, features = [ # Make the renderer `Sync` even on wasm32, because it makes the code simpler: "fragile-send-sync-non-atomic-wasm", ] } -winit = { version = "0.29.4", default-features = false } +winit = { version = "0.30.4", default-features = false } [workspace.lints.rust] diff --git a/crates/eframe/Cargo.toml b/crates/eframe/Cargo.toml index d9bbe6b9715..c0246567524 100644 --- a/crates/eframe/Cargo.toml +++ b/crates/eframe/Cargo.toml @@ -59,14 +59,7 @@ android-native-activity = ["egui-winit/android-native-activity"] default_fonts = ["egui/default_fonts"] ## Use [`glow`](https://github.com/grovesNL/glow) for painting, via [`egui_glow`](https://github.com/emilk/egui/tree/master/crates/egui_glow). -glow = [ - "dep:egui_glow", - "dep:glow", - "dep:glutin-winit", - "dep:glutin", - "dep:rwh_05", - "winit/rwh_05", -] +glow = ["dep:egui_glow", "dep:glow", "dep:glutin-winit", "dep:glutin"] ## Enable saving app state to disk. persistence = [ @@ -141,10 +134,6 @@ web-time.workspace = true egui_glow = { workspace = true, optional = true, default-features = false } glow = { workspace = true, optional = true } -# glutin stuck on old version of raw-window-handle: -rwh_05 = { package = "raw-window-handle", version = "0.5.2", optional = true, features = [ - "std", -] } ron = { workspace = true, optional = true, features = ["integer128"] } serde = { workspace = true, optional = true } diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index c8c9069a0bf..ac6d0f45a24 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -23,7 +23,7 @@ use static_assertions::assert_not_impl_any; #[cfg(not(target_arch = "wasm32"))] #[cfg(any(feature = "glow", feature = "wgpu"))] -pub use winit::{event_loop::EventLoopBuilder, window::WindowBuilder}; +pub use winit::{event_loop::EventLoopBuilder, window::WindowAttributes}; /// Hook into the building of an event loop before it is run /// diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index c033eeef6ab..e070c3e2870 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -3,7 +3,7 @@ use web_time::Instant; use std::path::PathBuf; -use winit::event_loop::EventLoopWindowTarget; +use winit::event_loop::ActiveEventLoop; use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _}; @@ -12,9 +12,9 @@ use egui_winit::{EventResponse, WindowSettings}; use crate::{epi, Theme}; -pub fn viewport_builder( +pub fn viewport_builder( egui_zoom_factor: f32, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, native_options: &mut epi::NativeOptions, window_settings: Option, ) -> ViewportBuilder { @@ -95,10 +95,7 @@ pub fn apply_window_settings( } } -fn largest_monitor_point_size( - egui_zoom_factor: f32, - event_loop: &EventLoopWindowTarget, -) -> egui::Vec2 { +fn largest_monitor_point_size(egui_zoom_factor: f32, event_loop: &ActiveEventLoop) -> egui::Vec2 { crate::profile_function!(); let mut max_size = egui::Vec2::ZERO; @@ -167,6 +164,24 @@ pub struct EpiIntegration { app_icon_setter: super::app_icon::AppTitleIconSetter, } +#[cfg(feature = "accesskit")] +struct AccessKitInitHandler { + egui_ctx: egui::Context, +} + +#[cfg(feature = "accesskit")] +impl egui::accesskit::ActivationHandler for AccessKitInitHandler { + fn request_initial_tree(&mut self) -> Option { + // This function is called when an accessibility client + // (e.g. screen reader) makes its first request. If we got here, + // we know that an accessibility tree is actually wanted. + self.egui_ctx.enable_accesskit(); + // Enqueue a repaint so we'll receive a full tree update soon. + self.egui_ctx.request_repaint(); + Some(self.egui_ctx.accesskit_placeholder_tree_update()) + } +} + impl EpiIntegration { #[allow(clippy::too_many_arguments)] pub fn new( @@ -230,7 +245,7 @@ impl EpiIntegration { } #[cfg(feature = "accesskit")] - pub fn init_accesskit + Send>( + pub fn init_accesskit + Send>( &self, egui_winit: &mut egui_winit::State, window: &winit::window::Window, @@ -239,15 +254,7 @@ impl EpiIntegration { crate::profile_function!(); let egui_ctx = self.egui_ctx.clone(); - egui_winit.init_accesskit(window, event_loop_proxy, move || { - // This function is called when an accessibility client - // (e.g. screen reader) makes its first request. If we got here, - // we know that an accessibility tree is actually wanted. - egui_ctx.enable_accesskit(); - // Enqueue a repaint so we'll receive a full tree update soon. - egui_ctx.request_repaint(); - egui_ctx.accesskit_placeholder_tree_update() - }); + egui_winit.init_accesskit(window, event_loop_proxy, AccessKitInitHandler { egui_ctx }); } /// If `true`, it is time to close the native window. diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index fd19f633fde..60ba3cb5d29 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -21,8 +21,9 @@ use glutin::{ prelude::{GlDisplay, PossiblyCurrentGlContext}, surface::GlSurface, }; +use raw_window_handle::HasWindowHandle; use winit::{ - event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}, window::{Window, WindowId}, }; @@ -145,7 +146,7 @@ impl GlowWinitApp { #[allow(unsafe_code)] fn create_glutin_windowed_context( egui_ctx: &egui::Context, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, storage: Option<&dyn Storage>, native_options: &mut NativeOptions, ) -> Result<(GlutinWindowContext, egui_glow::Painter)> { @@ -194,10 +195,7 @@ impl GlowWinitApp { Ok((glutin_window_context, painter)) } - fn init_run_state( - &mut self, - event_loop: &EventLoopWindowTarget, - ) -> Result<&mut GlowWinitRunning> { + fn init_run_state(&mut self, event_loop: &ActiveEventLoop) -> Result<&mut GlowWinitRunning> { crate::profile_function!(); let storage = if let Some(file) = &self.native_options.persistence_path { @@ -330,7 +328,7 @@ impl GlowWinitApp { let painter = Rc::downgrade(&painter); let beginning = integration.beginning; - let event_loop: *const EventLoopWindowTarget = event_loop; + let event_loop: *const ActiveEventLoop = event_loop; egui::Context::set_immediate_viewport_renderer(move |egui_ctx, immediate_viewport| { if let (Some(glutin), Some(painter)) = (glutin.upgrade(), painter.upgrade()) { @@ -401,7 +399,7 @@ impl WinitApp for GlowWinitApp { fn run_ui_and_paint( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, window_id: WindowId, ) -> EventResult { if let Some(running) = &mut self.running { @@ -413,7 +411,7 @@ impl WinitApp for GlowWinitApp { fn on_event( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, event: &winit::event::Event, ) -> Result { crate::profile_function!(winit_integration::short_event_description(event)); @@ -481,7 +479,10 @@ impl WinitApp for GlowWinitApp { #[cfg(feature = "accesskit")] winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest( - accesskit_winit::ActionRequestEvent { request, window_id }, + accesskit_winit::Event { + window_id, + window_event: accesskit_winit::WindowEvent::ActionRequested(request), + }, )) => { if let Some(running) = &self.running { let mut glutin = running.glutin.borrow_mut(); @@ -508,7 +509,7 @@ impl WinitApp for GlowWinitApp { impl GlowWinitRunning { fn run_ui_and_paint( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, window_id: WindowId, ) -> EventResult { crate::profile_function!(); @@ -908,7 +909,7 @@ impl GlutinWindowContext { egui_ctx: &egui::Context, viewport_builder: ViewportBuilder, native_options: &NativeOptions, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, ) -> Result { crate::profile_function!(); @@ -957,7 +958,7 @@ impl GlutinWindowContext { let display_builder = glutin_winit::DisplayBuilder::new() // we might want to expose this option to users in the future. maybe using an env var or using native_options. .with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150 - .with_window_builder(Some(egui_winit::create_winit_window_builder( + .with_window_attributes(Some(egui_winit::create_winit_window_atrributes( egui_ctx, event_loop, viewport_builder.clone(), @@ -993,8 +994,9 @@ impl GlutinWindowContext { gl_display.supported_features() ); let glutin_raw_window_handle = window.as_ref().map(|w| { - use rwh_05::HasRawWindowHandle as _; // glutin stuck on old version of raw-window-handle - w.raw_window_handle() + w.window_handle() + .expect("Failed to get window handle") + .as_raw() }); log::debug!("creating gl context using raw window handle: {glutin_raw_window_handle:?}"); @@ -1080,7 +1082,7 @@ impl GlutinWindowContext { /// Create a surface, window, and winit integration for all viewports lacking any of that. /// /// Errors will be logged. - fn initialize_all_windows(&mut self, event_loop: &EventLoopWindowTarget) { + fn initialize_all_windows(&mut self, event_loop: &ActiveEventLoop) { crate::profile_function!(); let viewports: Vec = self.viewports.keys().copied().collect(); @@ -1097,7 +1099,7 @@ impl GlutinWindowContext { pub(crate) fn initialize_window( &mut self, viewport_id: ViewportId, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, ) -> Result { crate::profile_function!(); @@ -1110,7 +1112,7 @@ impl GlutinWindowContext { window } else { log::debug!("Creating a window for viewport {viewport_id:?}"); - let window_builder = egui_winit::create_winit_window_builder( + let window_builder = egui_winit::create_winit_window_atrributes( &self.egui_ctx, event_loop, viewport.builder.clone(), @@ -1150,9 +1152,12 @@ impl GlutinWindowContext { let width_px = NonZeroU32::new(width_px).unwrap_or(NonZeroU32::MIN); let height_px = NonZeroU32::new(height_px).unwrap_or(NonZeroU32::MIN); let surface_attributes = { - use rwh_05::HasRawWindowHandle as _; // glutin stuck on old version of raw-window-handle glutin::surface::SurfaceAttributesBuilder::::new() - .build(window.raw_window_handle(), width_px, height_px) + .build( + window.window_handle().expect("TODO TDO").as_raw(), + width_px, + height_px, + ) }; log::trace!("creating surface with attributes: {surface_attributes:?}"); @@ -1267,7 +1272,7 @@ impl GlutinWindowContext { fn handle_viewport_output( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, egui_ctx: &egui::Context, viewport_output: &ViewportIdMap, ) { @@ -1389,7 +1394,7 @@ fn initialize_or_update_viewport( /// This is called (via a callback) by user code to render immediate viewports, /// i.e. viewport that are directly nested inside a parent viewport. fn render_immediate_viewport( - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, egui_ctx: &egui::Context, glutin: &RefCell, painter: &RefCell, diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 6ba5486b678..222984a2c87 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -1,6 +1,11 @@ use std::{cell::RefCell, time::Instant}; -use winit::event_loop::{EventLoop, EventLoopBuilder}; +use winit::{ + application::ApplicationHandler, + event::Event, + event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, + window::WindowId, +}; use ahash::HashMap; @@ -13,24 +18,14 @@ use crate::{ use super::winit_integration::{UserEvent, WinitApp}; // ---------------------------------------------------------------------------- - -fn create_event_loop_builder( - native_options: &mut epi::NativeOptions, -) -> EventLoopBuilder { +fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result> { crate::profile_function!(); - let mut event_loop_builder = winit::event_loop::EventLoopBuilder::with_user_event(); + let mut builder = winit::event_loop::EventLoop::with_user_event(); if let Some(hook) = std::mem::take(&mut native_options.event_loop_builder) { - hook(&mut event_loop_builder); + hook(&mut builder); } - event_loop_builder -} - -fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result> { - crate::profile_function!(); - let mut builder = create_event_loop_builder(native_options); - crate::profile_scope!("EventLoopBuilder::build"); Ok(builder.build()?) } @@ -59,306 +54,183 @@ fn with_event_loop( }) } -#[cfg(not(target_os = "ios"))] -fn run_and_return(event_loop: &mut EventLoop, mut winit_app: impl WinitApp) -> Result { - use winit::{event_loop::ControlFlow, platform::run_on_demand::EventLoopExtRunOnDemand}; - - log::trace!("Entering the winit event loop (run_on_demand)…"); - - // When to repaint what window - let mut windows_next_repaint_times = HashMap::default(); - - let mut returned_result = Ok(()); - - event_loop.run_on_demand(|event, event_loop_window_target| { - crate::profile_scope!("winit_event", short_event_description(&event)); - - log::trace!("winit event: {event:?}"); +struct App { + windows_next_repaint_times: HashMap, + winit_app: T, + return_result: Result<(), crate::Error>, +} - if matches!(event, winit::event::Event::AboutToWait) { - return; // early-out: don't trigger another wait +impl App { + fn new(winit_app: T) -> Self { + Self { + windows_next_repaint_times: HashMap::default(), + winit_app, + return_result: Ok(()), } + } - let event_result = match &event { - winit::event::Event::LoopExiting => { - // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), - // so we need to save state now: - log::debug!("Received Event::LoopExiting - saving app state…"); - winit_app.save_and_destroy(); - return; - } - - winit::event::Event::WindowEvent { - event: winit::event::WindowEvent::RedrawRequested, - window_id, - } => { - windows_next_repaint_times.remove(window_id); - winit_app.run_ui_and_paint(event_loop_window_target, *window_id) + fn handle_event(&mut self, event_loop: &ActiveEventLoop, event: &Event) { + let event_result = match self.winit_app.on_event(event_loop, event) { + Ok(event_result) => { + log::trace!("event_result: {event_result:?}"); + event_result } - - winit::event::Event::UserEvent(UserEvent::RequestRepaint { - when, - frame_nr, - viewport_id, - }) => { - let current_frame_nr = winit_app.frame_nr(*viewport_id); - if current_frame_nr == *frame_nr || current_frame_nr == *frame_nr + 1 { - log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); - if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) { - EventResult::RepaintAt(window_id, *when) - } else { - EventResult::Wait - } - } else { - log::trace!("Got outdated UserEvent::RequestRepaint"); - EventResult::Wait // old request - we've already repainted - } - } - - winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { - .. - }) => { - log::trace!("Woke up to check next_repaint_time"); - EventResult::Wait + Err(err) => { + log::error!("Exiting because of error: {err} during event {event:?}"); + self.return_result = Err(err); + EventResult::Exit } - - event => match winit_app.on_event(event_loop_window_target, event) { - Ok(event_result) => { - log::trace!("event_result: {event_result:?}"); - event_result - } - Err(err) => { - log::error!("Exiting because of error: {err} during event {event:?}"); - returned_result = Err(err); - EventResult::Exit - } - }, }; + self.handle_event_result(event_loop, event_result, event); + } + fn handle_event_result( + &mut self, + event_loop: &ActiveEventLoop, + event_result: EventResult, + event: &Event, + ) { match event_result { EventResult::Wait => { - event_loop_window_target.set_control_flow(ControlFlow::Wait); + event_loop.set_control_flow(ControlFlow::Wait); } EventResult::RepaintNow(window_id) => { log::trace!( "RepaintNow of {window_id:?} caused by {}", - short_event_description(&event) + short_event_description(event) ); if cfg!(target_os = "windows") { // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 - windows_next_repaint_times.remove(&window_id); - - winit_app.run_ui_and_paint(event_loop_window_target, window_id); + self.windows_next_repaint_times.remove(&window_id); + self.winit_app.run_ui_and_paint(event_loop, window_id); } else { // Fix for https://github.com/emilk/egui/issues/2425 - windows_next_repaint_times.insert(window_id, Instant::now()); + self.windows_next_repaint_times + .insert(window_id, Instant::now()); } } EventResult::RepaintNext(window_id) => { log::trace!( "RepaintNext of {window_id:?} caused by {}", - short_event_description(&event) - ); - windows_next_repaint_times.insert(window_id, Instant::now()); - } - EventResult::RepaintAt(window_id, repaint_time) => { - windows_next_repaint_times.insert( - window_id, - windows_next_repaint_times - .get(&window_id) - .map_or(repaint_time, |last| (*last).min(repaint_time)), + short_event_description(event) ); + self.windows_next_repaint_times + .insert(window_id, Instant::now()); } EventResult::Exit => { log::debug!("Asking to exit event loop…"); - winit_app.save_and_destroy(); - event_loop_window_target.exit(); - return; + self.winit_app.save_and_destroy(); + event_loop.exit(); } } + } +} - let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); +impl ApplicationHandler for App { + fn suspended(&mut self, event_loop: &ActiveEventLoop) { + self.handle_event(event_loop, &Event::Suspended); + } - windows_next_repaint_times.retain(|window_id, repaint_time| { - if Instant::now() < *repaint_time { - return true; // not yet ready - }; + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + self.handle_event(event_loop, &Event::Resumed); + } - next_repaint_time = None; - event_loop_window_target.set_control_flow(ControlFlow::Poll); + fn exiting(&mut self, _: &ActiveEventLoop) { + // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), + // so we need to save state now: + log::debug!("Received Event::LoopExiting - saving app state…"); + self.winit_app.save_and_destroy(); + } - if let Some(window) = winit_app.window(*window_id) { - log::trace!("request_redraw for {window_id:?}"); - let is_minimized = window.is_minimized().unwrap_or(false); - if is_minimized { - false + fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) { + #[allow(irrefutable_let_patterns)] + // when accesskit is not enabled, there are no other events to handle here. + if let UserEvent::RequestRepaint { + when, + frame_nr, + viewport_id, + } = event + { + let current_frame_nr = self.winit_app.frame_nr(viewport_id); + if current_frame_nr == frame_nr || current_frame_nr == frame_nr + 1 { + log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); + if let Some(window_id) = self.winit_app.window_id_from_viewport_id(viewport_id) { + self.windows_next_repaint_times.insert( + window_id, + self.windows_next_repaint_times + .get(&window_id) + .map_or(when, |last| (*last).min(when)), + ); } else { - window.request_redraw(); - true + event_loop.set_control_flow(ControlFlow::Wait); } } else { - log::trace!("No window found for {window_id:?}"); - false + log::trace!("Got outdated UserEvent::RequestRepaint"); + event_loop.set_control_flow(ControlFlow::Wait); } - }); - - if let Some(next_repaint_time) = next_repaint_time { - event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); - }; - })?; - - log::debug!("eframe window closed"); - - drop(winit_app); - - // On Windows this clears out events so that we can later create another window. - // See https://github.com/emilk/egui/pull/1889 for details. - // - // Note that this approach may cause issues on macOS (emilk/egui#2768); therefore, - // we only apply this approach on Windows to minimize the affect. - #[cfg(target_os = "windows")] - { - event_loop - .run_on_demand(|_, event_loop_window_target| { - event_loop_window_target.exit(); - }) - .ok(); + } else { + self.handle_event(event_loop, &Event::UserEvent(event)); + } } - returned_result -} - -fn run_and_exit( - event_loop: EventLoop, - mut winit_app: impl WinitApp + 'static, -) -> Result { - use winit::event_loop::ControlFlow; - log::trace!("Entering the winit event loop (run)…"); - - // When to repaint what window - let mut windows_next_repaint_times = HashMap::default(); - - event_loop.run(move |event, event_loop_window_target| { - crate::profile_scope!("winit_event", short_event_description(&event)); - - log::trace!("winit event: {event:?}"); - - if matches!(event, winit::event::Event::AboutToWait) { - return; // early-out: don't trigger another wait + fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: winit::event::StartCause) { + if matches!(cause, winit::event::StartCause::ResumeTimeReached { .. }) { + log::trace!("Woke up to check next_repaint_time"); } + // TODO: Is this needed? + event_loop.set_control_flow(ControlFlow::Wait); + } - let event_result = match &event { - winit::event::Event::LoopExiting => { - log::debug!("Received Event::LoopExiting"); - EventResult::Exit - } - - winit::event::Event::WindowEvent { - event: winit::event::WindowEvent::RedrawRequested, - window_id, - } => { - windows_next_repaint_times.remove(window_id); - winit_app.run_ui_and_paint(event_loop_window_target, *window_id) - } - - winit::event::Event::UserEvent(UserEvent::RequestRepaint { - when, - frame_nr, - viewport_id, - }) => { - let current_frame_nr = winit_app.frame_nr(*viewport_id); - if current_frame_nr == *frame_nr || current_frame_nr == *frame_nr + 1 { - if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) { - EventResult::RepaintAt(window_id, *when) - } else { - EventResult::Wait - } - } else { - log::trace!("Got outdated UserEvent::RequestRepaint"); - EventResult::Wait // old request - we've already repainted - } - } - - winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { - .. - }) => { - log::trace!("Woke up to check next_repaint_time"); - EventResult::Wait - } - - event => match winit_app.on_event(event_loop_window_target, event) { - Ok(event_result) => { - log::trace!("event_result: {event_result:?}"); - event_result - } - Err(err) => { - panic!("eframe encountered a fatal error: {err} during event {event:?}"); - } - }, - }; - - match event_result { - EventResult::Wait => { - event_loop_window_target.set_control_flow(ControlFlow::Wait); - } - EventResult::RepaintNow(window_id) => { - log::trace!("RepaintNow caused by {}", short_event_description(&event)); - if cfg!(target_os = "windows") { - // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 - windows_next_repaint_times.remove(&window_id); - - winit_app.run_ui_and_paint(event_loop_window_target, window_id); - } else { - // Fix for https://github.com/emilk/egui/issues/2425 - windows_next_repaint_times.insert(window_id, Instant::now()); - } - } - EventResult::RepaintNext(window_id) => { - log::trace!("RepaintNext caused by {}", short_event_description(&event)); - windows_next_repaint_times.insert(window_id, Instant::now()); - } - EventResult::RepaintAt(window_id, repaint_time) => { - windows_next_repaint_times.insert( + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + window_id: WindowId, + event: winit::event::WindowEvent, + ) { + if matches!(event, winit::event::WindowEvent::RedrawRequested) { + self.windows_next_repaint_times.remove(&window_id); + let event_result = self.winit_app.run_ui_and_paint(event_loop, window_id); + + self.handle_event_result( + event_loop, + event_result, + &Event::WindowEvent { window_id, event }, + ); + } else { + self.handle_event( + event_loop, + &Event::WindowEvent { window_id, - windows_next_repaint_times - .get(&window_id) - .map_or(repaint_time, |last| (*last).min(repaint_time)), - ); - } - EventResult::Exit => { - log::debug!("Quitting - saving app state…"); - winit_app.save_and_destroy(); - - log::debug!("Exiting with return code 0"); - #[allow(clippy::exit)] - std::process::exit(0); - } + event: event.clone(), + }, + ); } - let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); + let mut next_repaint_time = self.windows_next_repaint_times.values().min().copied(); - windows_next_repaint_times.retain(|window_id, repaint_time| { - if Instant::now() < *repaint_time { - return true; // not yet ready - } + self.windows_next_repaint_times + .retain(|window_id, repaint_time| { + if Instant::now() < *repaint_time { + return true; // not yet ready + }; - next_repaint_time = None; - event_loop_window_target.set_control_flow(ControlFlow::Poll); + next_repaint_time = None; + event_loop.set_control_flow(ControlFlow::Poll); - if let Some(window) = winit_app.window(*window_id) { - log::trace!("request_redraw for {window_id:?}"); - let is_minimized = window.is_minimized().unwrap_or(false); - if is_minimized { - false + if let Some(window) = self.winit_app.window(*window_id) { + log::trace!("request_redraw for {window_id:?}"); + let is_minimized = window.is_minimized().unwrap_or(false); + if is_minimized { + false + } else { + window.request_redraw(); + true + } } else { - window.request_redraw(); - true + log::trace!("No window found for {window_id:?}"); + false } - } else { - log::trace!("No window found for {window_id:?}"); - false - } - }); + }); if let Some(next_repaint_time) = next_repaint_time { // WaitUntil seems to not work on iOS @@ -371,12 +243,31 @@ fn run_and_exit( .map(|window| window.request_redraw()) }); - event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); + event_loop.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); }; - })?; + } +} - log::debug!("winit event loop unexpectedly returned"); +#[cfg(not(target_os = "ios"))] +fn run_and_return(event_loop: &mut EventLoop, winit_app: impl WinitApp) -> Result { + use winit::platform::run_on_demand::EventLoopExtRunOnDemand; + + log::trace!("Entering the winit event loop (run_on_demand)…"); + + let mut app = App::new(winit_app); + event_loop.run_app_on_demand(&mut app)?; + log::debug!("eframe window closed"); + app.return_result +} + +fn run_and_exit(event_loop: EventLoop, winit_app: impl WinitApp + 'static) -> Result { + log::trace!("Entering the winit event loop (run)…"); + // When to repaint what window + let mut app = App::new(winit_app); + event_loop.run_app(&mut app)?; + + log::debug!("winit event loop unexpectedly returned"); Ok(()) } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index fc3f6e9e134..44d9c0341ef 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -11,7 +11,7 @@ use egui_winit::ActionRequested; use parking_lot::Mutex; use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _}; use winit::{ - event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy}, window::{Window, WindowId}, }; @@ -22,10 +22,11 @@ use egui::{ }; #[cfg(feature = "accesskit")] use egui_winit::accesskit_winit; +use winit_integration::UserEvent; use crate::{ native::{epi_integration::EpiIntegration, winit_integration::EventResult}, - App, AppCreator, CreationContext, NativeOptions, Result, Storage, UserEvent, + App, AppCreator, CreationContext, NativeOptions, Result, Storage, }; use super::{winit_integration::WinitApp, *}; @@ -119,7 +120,7 @@ impl WgpuWinitApp { } /// Create a window for all viewports lacking one. - fn initialized_all_windows(&mut self, event_loop: &EventLoopWindowTarget) { + fn initialized_all_windows(&mut self, event_loop: &ActiveEventLoop) { let Some(running) = &mut self.running else { return; }; @@ -142,11 +143,7 @@ impl WgpuWinitApp { } #[cfg(target_os = "android")] - fn recreate_window( - &self, - event_loop: &EventLoopWindowTarget, - running: &WgpuWinitRunning, - ) { + fn recreate_window(&self, event_loop: &ActiveEventLoop, running: &WgpuWinitRunning) { let SharedState { egui_ctx, viewports, @@ -178,7 +175,7 @@ impl WgpuWinitApp { fn init_run_state( &mut self, egui_ctx: egui::Context, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, storage: Option>, window: Window, builder: ViewportBuilder, @@ -311,7 +308,7 @@ impl WgpuWinitApp { let shared = Rc::downgrade(&shared); let beginning = integration.beginning; - let event_loop: *const EventLoopWindowTarget = event_loop; + let event_loop: *const ActiveEventLoop = event_loop; egui::Context::set_immediate_viewport_renderer(move |_egui_ctx, immediate_viewport| { if let Some(shared) = shared.upgrade() { @@ -377,7 +374,7 @@ impl WinitApp for WgpuWinitApp { fn run_ui_and_paint( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, window_id: WindowId, ) -> EventResult { self.initialized_all_windows(event_loop); @@ -391,7 +388,7 @@ impl WinitApp for WgpuWinitApp { fn on_event( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, event: &winit::event::Event, ) -> Result { crate::profile_function!(winit_integration::short_event_description(event)); @@ -479,7 +476,10 @@ impl WinitApp for WgpuWinitApp { #[cfg(feature = "accesskit")] winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest( - accesskit_winit::ActionRequestEvent { request, window_id }, + accesskit_winit::Event { + window_id, + window_event: accesskit_winit::WindowEvent::ActionRequested(request), + }, )) => { if let Some(running) = &mut self.running { let mut shared_lock = running.shared.borrow_mut(); @@ -865,7 +865,7 @@ impl Viewport { /// Create winit window, if needed. fn initialize_window( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, egui_ctx: &egui::Context, windows_id: &mut HashMap, painter: &mut egui_wgpu::winit::Painter, @@ -910,7 +910,7 @@ impl Viewport { fn create_window( egui_ctx: &egui::Context, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, storage: Option<&dyn Storage>, native_options: &mut NativeOptions, ) -> Result<(Window, ViewportBuilder), winit::error::OsError> { @@ -931,7 +931,7 @@ fn create_window( } fn render_immediate_viewport( - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, beginning: Instant, shared: &RefCell, immediate_viewport: ImmediateViewport<'_>, diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index fbbd7910732..bf6c1a1f9fb 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -1,7 +1,7 @@ use std::{sync::Arc, time::Instant}; use winit::{ - event_loop::EventLoopWindowTarget, + event_loop::ActiveEventLoop, window::{Window, WindowId}, }; @@ -48,12 +48,12 @@ pub enum UserEvent { /// A request related to [`accesskit`](https://accesskit.dev/). #[cfg(feature = "accesskit")] - AccessKitActionRequest(accesskit_winit::ActionRequestEvent), + AccessKitActionRequest(accesskit_winit::Event), } #[cfg(feature = "accesskit")] -impl From for UserEvent { - fn from(inner: accesskit_winit::ActionRequestEvent) -> Self { +impl From for UserEvent { + fn from(inner: accesskit_winit::Event) -> Self { Self::AccessKitActionRequest(inner) } } @@ -70,13 +70,13 @@ pub trait WinitApp { fn run_ui_and_paint( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, window_id: WindowId, ) -> EventResult; fn on_event( &mut self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, event: &winit::event::Event, ) -> crate::Result; } @@ -98,8 +98,6 @@ pub enum EventResult { /// cause any delay like `RepaintNow`. RepaintNext(WindowId), - RepaintAt(WindowId, Instant), - Exit, } diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 0cf9bf9403a..7c073c14832 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -69,7 +69,7 @@ winit = { workspace = true, default-features = false, features = ["rwh_06"] } #! ### Optional dependencies # feature accesskit -accesskit_winit = { version = "0.16.0", optional = true } +accesskit_winit = { version = "0.21.1", optional = true } ## Enable this when generating docs. document-features = { workspace = true, optional = true } diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 4854cd2fd68..3f98f89b5d3 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -31,7 +31,7 @@ pub(crate) use profiling_scopes::*; use winit::{ dpi::{PhysicalPosition, PhysicalSize}, event::ElementState, - event_loop::EventLoopWindowTarget, + event_loop::ActiveEventLoop, window::{CursorGrabMode, Window, WindowButtons, WindowLevel}, }; @@ -158,16 +158,17 @@ impl State { } #[cfg(feature = "accesskit")] - pub fn init_accesskit + Send>( + pub fn init_accesskit + Send>( &mut self, window: &Window, event_loop_proxy: winit::event_loop::EventLoopProxy, - initial_tree_update_factory: impl 'static + FnOnce() -> accesskit::TreeUpdate + Send, + activation_handler: impl egui::accesskit::ActivationHandler + Send + 'static, ) { crate::profile_function!(); - self.accesskit = Some(accesskit_winit::Adapter::new( + + self.accesskit = Some(accesskit_winit::Adapter::with_mixed_handlers( window, - initial_tree_update_factory, + activation_handler, event_loop_proxy, )); } @@ -263,7 +264,7 @@ impl State { crate::profile_function!(short_window_event_description(event)); #[cfg(feature = "accesskit")] - if let Some(accesskit) = &self.accesskit { + if let Some(accesskit) = self.accesskit.as_mut() { accesskit.process_event(window, event); } @@ -474,13 +475,14 @@ impl State { // Things we completely ignore: WindowEvent::ActivationTokenDone { .. } | WindowEvent::AxisMotion { .. } - | WindowEvent::SmartMagnify { .. } - | WindowEvent::TouchpadRotate { .. } => EventResponse { + | WindowEvent::DoubleTapGesture { .. } + | WindowEvent::RotationGesture { .. } + | WindowEvent::PanGesture { .. } => EventResponse { repaint: false, consumed: false, }, - WindowEvent::TouchpadMagnify { delta, .. } => { + WindowEvent::PinchGesture { delta, .. } => { // Positive delta values indicate magnification (zooming in). // Negative delta values indicate shrinking (zooming out). let zoom_factor = (*delta as f32).exp(); @@ -859,7 +861,7 @@ impl State { } #[cfg(feature = "accesskit")] - if let Some(accesskit) = self.accesskit.as_ref() { + if let Some(accesskit) = self.accesskit.as_mut() { if let Some(update) = accesskit_update { crate::profile_scope!("accesskit"); accesskit.update_if_active(|| update); @@ -880,7 +882,7 @@ impl State { if let Some(winit_cursor_icon) = translate_cursor(cursor_icon) { window.set_cursor_visible(true); - window.set_cursor_icon(winit_cursor_icon); + window.set_cursor(winit_cursor_icon); } else { window.set_cursor_visible(false); } @@ -1510,28 +1512,25 @@ fn process_viewport_command( /// /// # Errors /// Possible causes of error include denied permission, incompatible system, and lack of memory. -pub fn create_window( +pub fn create_window( egui_ctx: &egui::Context, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, viewport_builder: &ViewportBuilder, ) -> Result { crate::profile_function!(); - let window_builder = - create_winit_window_builder(egui_ctx, event_loop, viewport_builder.clone()); - let window = { - crate::profile_scope!("WindowBuilder::build"); - window_builder.build(event_loop)? - }; + let window_attributes = + create_winit_window_atrributes(egui_ctx, event_loop, viewport_builder.clone()); + let window = event_loop.create_window(window_attributes)?; apply_viewport_builder_to_window(egui_ctx, &window, viewport_builder); Ok(window) } -pub fn create_winit_window_builder( +pub fn create_winit_window_atrributes( egui_ctx: &egui::Context, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, viewport_builder: ViewportBuilder, -) -> winit::window::WindowBuilder { +) -> winit::window::WindowAttributes { crate::profile_function!(); // We set sizes and positions in egui:s own ui points, which depends on the egui @@ -1590,7 +1589,7 @@ pub fn create_winit_window_builder( clamp_size_to_monitor_size: _, // Handled in `viewport_builder` in `epi_integration.rs` } = viewport_builder; - let mut window_builder = winit::window::WindowBuilder::new() + let mut window_attributes = winit::window::WindowAttributes::default() .with_title(title.unwrap_or_else(|| "egui window".to_owned())) .with_transparent(transparent.unwrap_or(false)) .with_decorations(decorations.unwrap_or(true)) @@ -1621,28 +1620,28 @@ pub fn create_winit_window_builder( .with_active(active.unwrap_or(true)); if let Some(size) = inner_size { - window_builder = window_builder.with_inner_size(PhysicalSize::new( + window_attributes = window_attributes.with_inner_size(PhysicalSize::new( pixels_per_point * size.x, pixels_per_point * size.y, )); } if let Some(size) = min_inner_size { - window_builder = window_builder.with_min_inner_size(PhysicalSize::new( + window_attributes = window_attributes.with_min_inner_size(PhysicalSize::new( pixels_per_point * size.x, pixels_per_point * size.y, )); } if let Some(size) = max_inner_size { - window_builder = window_builder.with_max_inner_size(PhysicalSize::new( + window_attributes = window_attributes.with_max_inner_size(PhysicalSize::new( pixels_per_point * size.x, pixels_per_point * size.y, )); } if let Some(pos) = position { - window_builder = window_builder.with_position(PhysicalPosition::new( + window_attributes = window_attributes.with_position(PhysicalPosition::new( pixels_per_point * pos.x, pixels_per_point * pos.y, )); @@ -1650,7 +1649,7 @@ pub fn create_winit_window_builder( if let Some(icon) = icon { let winit_icon = to_winit_icon(&icon); - window_builder = window_builder.with_window_icon(winit_icon); + window_attributes = window_attributes.with_window_icon(winit_icon); } #[cfg(all(feature = "wayland", target_os = "linux"))] @@ -1696,15 +1695,15 @@ pub fn create_winit_window_builder( #[cfg(target_os = "macos")] { - use winit::platform::macos::WindowBuilderExtMacOS as _; - window_builder = window_builder + use winit::platform::macos::WindowAttributesExtMacOS as _; + window_attributes = window_attributes .with_title_hidden(!_title_shown.unwrap_or(true)) .with_titlebar_buttons_hidden(!_titlebar_buttons_shown.unwrap_or(true)) .with_titlebar_transparent(!_titlebar_shown.unwrap_or(true)) .with_fullsize_content_view(_fullsize_content_view.unwrap_or(false)); } - window_builder + window_attributes } fn to_winit_icon(icon: &egui::IconData) -> Option { @@ -1828,16 +1827,17 @@ pub fn short_window_event_description(event: &winit::event::WindowEvent) -> &'st WindowEvent::CursorLeft { .. } => "WindowEvent::CursorLeft", WindowEvent::MouseWheel { .. } => "WindowEvent::MouseWheel", WindowEvent::MouseInput { .. } => "WindowEvent::MouseInput", - WindowEvent::TouchpadMagnify { .. } => "WindowEvent::TouchpadMagnify", + WindowEvent::PinchGesture { .. } => "WindowEvent::PinchGesture", WindowEvent::RedrawRequested { .. } => "WindowEvent::RedrawRequested", - WindowEvent::SmartMagnify { .. } => "WindowEvent::SmartMagnify", - WindowEvent::TouchpadRotate { .. } => "WindowEvent::TouchpadRotate", + WindowEvent::DoubleTapGesture { .. } => "WindowEvent::DoubleTapGesture", + WindowEvent::RotationGesture { .. } => "WindowEvent::RotationGesture", WindowEvent::TouchpadPressure { .. } => "WindowEvent::TouchpadPressure", WindowEvent::AxisMotion { .. } => "WindowEvent::AxisMotion", WindowEvent::Touch { .. } => "WindowEvent::Touch", WindowEvent::ScaleFactorChanged { .. } => "WindowEvent::ScaleFactorChanged", WindowEvent::ThemeChanged { .. } => "WindowEvent::ThemeChanged", WindowEvent::Occluded { .. } => "WindowEvent::Occluded", + WindowEvent::PanGesture { .. } => "WindowEvent::PanGesture", } } diff --git a/crates/egui-winit/src/window_settings.rs b/crates/egui-winit/src/window_settings.rs index ec633d3df0a..627d88158c0 100644 --- a/crates/egui-winit/src/window_settings.rs +++ b/crates/egui-winit/src/window_settings.rs @@ -50,10 +50,10 @@ impl WindowSettings { self.inner_size_points } - pub fn initialize_viewport_builder( + pub fn initialize_viewport_builder( &self, egui_zoom_factor: f32, - event_loop: &winit::event_loop::EventLoopWindowTarget, + event_loop: &winit::event_loop::ActiveEventLoop, mut viewport_builder: ViewportBuilder, ) -> ViewportBuilder { crate::profile_function!(); @@ -110,10 +110,10 @@ impl WindowSettings { } } - pub fn clamp_position_to_monitors( + pub fn clamp_position_to_monitors( &mut self, egui_zoom_factor: f32, - event_loop: &winit::event_loop::EventLoopWindowTarget, + event_loop: &winit::event_loop::ActiveEventLoop, ) { // If the app last ran on two monitors and only one is now connected, then // the given position is invalid. @@ -137,9 +137,9 @@ impl WindowSettings { } } -fn find_active_monitor( +fn find_active_monitor( egui_zoom_factor: f32, - event_loop: &winit::event_loop::EventLoopWindowTarget, + event_loop: &winit::event_loop::ActiveEventLoop, window_size_pts: egui::Vec2, position_px: &egui::Pos2, ) -> Option { @@ -172,9 +172,9 @@ fn find_active_monitor( Some(active_monitor) } -fn clamp_pos_to_monitors( +fn clamp_pos_to_monitors( egui_zoom_factor: f32, - event_loop: &winit::event_loop::EventLoopWindowTarget, + event_loop: &winit::event_loop::ActiveEventLoop, window_size_pts: egui::Vec2, position_px: &mut egui::Pos2, ) { diff --git a/crates/egui/Cargo.toml b/crates/egui/Cargo.toml index 2e8e1ddd557..470e2b0e70c 100644 --- a/crates/egui/Cargo.toml +++ b/crates/egui/Cargo.toml @@ -86,7 +86,7 @@ ahash.workspace = true nohash-hasher.workspace = true #! ### Optional dependencies -accesskit = { version = "0.12", optional = true } +accesskit = { version = "0.15", optional = true } backtrace = { workspace = true, optional = true } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 5ddadf78321..9cc55627c77 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -396,8 +396,6 @@ struct ContextImpl { #[cfg(feature = "accesskit")] is_accesskit_enabled: bool, - #[cfg(feature = "accesskit")] - accesskit_node_classes: accesskit::NodeClassSet, loaders: Arc, } @@ -2016,12 +2014,7 @@ impl ContextImpl { state .node_builders .into_iter() - .map(|(id, builder)| { - ( - id.accesskit_id(), - builder.build(&mut self.accesskit_node_classes), - ) - }) + .map(|(id, builder)| (id.accesskit_id(), builder.build())) .collect() }; let focus_id = self @@ -2932,11 +2925,8 @@ impl Context { use accesskit::{NodeBuilder, Role, Tree, TreeUpdate}; let root_id = crate::accesskit_root_id().accesskit_id(); - self.write(|ctx| TreeUpdate { - nodes: vec![( - root_id, - NodeBuilder::new(Role::Window).build(&mut ctx.accesskit_node_classes), - )], + self.write(|_| TreeUpdate { + nodes: vec![(root_id, NodeBuilder::new(Role::Window).build())], tree: Some(Tree::new(root_id)), focus: root_id, }) diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index 143175ba2ee..0b976c63cdc 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -964,7 +964,7 @@ impl Response { info: crate::WidgetInfo, ) { use crate::WidgetType; - use accesskit::{Checked, Role}; + use accesskit::{Role, Toggled}; self.fill_accesskit_node_common(builder); builder.set_role(match info.typ { @@ -976,7 +976,7 @@ impl Response { } WidgetType::Checkbox => Role::CheckBox, WidgetType::RadioButton => Role::RadioButton, - WidgetType::SelectableLabel => Role::ToggleButton, + WidgetType::SelectableLabel => Role::Button, WidgetType::ComboBox => Role::ComboBox, WidgetType::Slider => Role::Slider, WidgetType::DragValue => Role::SpinButton, @@ -997,14 +997,14 @@ impl Response { builder.set_numeric_value(value); } if let Some(selected) = info.selected { - builder.set_checked(if selected { - Checked::True + builder.set_toggled(if selected { + Toggled::True } else { - Checked::False + Toggled::False }); } else if matches!(info.typ, WidgetType::Checkbox) { // Indeterminate state - builder.set_checked(Checked::Mixed); + builder.set_toggled(Toggled::Mixed); } } diff --git a/crates/egui/tests/accesskit.rs b/crates/egui/tests/accesskit.rs index e3d1c7b56ab..e5dc3d97a93 100644 --- a/crates/egui/tests/accesskit.rs +++ b/crates/egui/tests/accesskit.rs @@ -94,7 +94,7 @@ fn toggle_button_node() { let (_, toggle) = output .nodes .iter() - .find(|(_, node)| node.role() == Role::ToggleButton) + .find(|(_, node)| node.role() == Role::Button) .expect("Toggle button should exist in the accesskit output"); assert_eq!(toggle.name(), Some(button_text)); diff --git a/crates/egui_glow/Cargo.toml b/crates/egui_glow/Cargo.toml index 28de667e8c1..567c348a166 100644 --- a/crates/egui_glow/Cargo.toml +++ b/crates/egui_glow/Cargo.toml @@ -82,15 +82,7 @@ wasm-bindgen.workspace = true [dev-dependencies] glutin.workspace = true # examples/pure_glow glutin-winit.workspace = true -# glutin stuck on old version of raw-window-handle: -rwh_05 = { package = "raw-window-handle", version = "0.5.2", features = [ - "std", -] } [[example]] name = "pure_glow" -required-features = [ - "winit", - "egui/default_fonts", - "winit/rwh_05", # glutin stuck on old version of raw-window-handle -] +required-features = ["winit", "egui/default_fonts", "winit/rwh_06"] diff --git a/crates/egui_glow/examples/pure_glow.rs b/crates/egui_glow/examples/pure_glow.rs index 0066b2ea815..95658157ab2 100644 --- a/crates/egui_glow/examples/pure_glow.rs +++ b/crates/egui_glow/examples/pure_glow.rs @@ -8,8 +8,10 @@ #![allow(unsafe_code)] use std::num::NonZeroU32; +use std::sync::Arc; use egui_winit::winit; +use winit::raw_window_handle::HasWindowHandle; /// The majority of `GlutinWindowContext` is taken from `eframe` struct GlutinWindowContext { @@ -23,13 +25,12 @@ impl GlutinWindowContext { // refactor this function to use `glutin-winit` crate eventually. // preferably add android support at the same time. #[allow(unsafe_code)] - unsafe fn new(event_loop: &winit::event_loop::EventLoopWindowTarget) -> Self { + unsafe fn new(event_loop: &winit::event_loop::ActiveEventLoop) -> Self { use glutin::context::NotCurrentGlContext; use glutin::display::GetGlDisplay; use glutin::display::GlDisplay; use glutin::prelude::GlSurface; - use rwh_05::HasRawWindowHandle; - let winit_window_builder = winit::window::WindowBuilder::new() + let winit_window_builder = winit::window::WindowAttributes::default() .with_resizable(true) .with_inner_size(winit::dpi::LogicalSize { width: 800.0, @@ -48,7 +49,7 @@ impl GlutinWindowContext { let (mut window, gl_config) = glutin_winit::DisplayBuilder::new() // let glutin-winit helper crate handle the complex parts of opengl context creation .with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150 - .with_window_builder(Some(winit_window_builder.clone())) + .with_window_attributes(Some(winit_window_builder.clone())) .build( event_loop, config_template_builder, @@ -62,7 +63,11 @@ impl GlutinWindowContext { let gl_display = gl_config.display(); log::debug!("found gl_config: {:?}", &gl_config); - let raw_window_handle = window.as_ref().map(|w| w.raw_window_handle()); + let raw_window_handle = window.as_ref().map(|w| { + w.window_handle() + .expect("failed to get window handle") + .as_raw() + }); log::debug!("raw window handle: {:?}", raw_window_handle); let context_attributes = glutin::context::ContextAttributesBuilder::new().build(raw_window_handle); @@ -95,7 +100,14 @@ impl GlutinWindowContext { let height = NonZeroU32::new(height).unwrap_or(NonZeroU32::MIN); let surface_attributes = glutin::surface::SurfaceAttributesBuilder::::new() - .build(window.raw_window_handle(), width, height); + .build( + window + .window_handle() + .expect("failed to get window handle") + .as_raw(), + width, + height, + ); log::debug!( "creating surface with attributes: {:?}", &surface_attributes @@ -152,51 +164,81 @@ pub enum UserEvent { Redraw(std::time::Duration), } -fn main() { - let mut clear_color = [0.1, 0.1, 0.1]; +struct GlowApp { + proxy: winit::event_loop::EventLoopProxy, + gl_window: Option, + gl: Option>, + egui_glow: Option, + repaint_delay: std::time::Duration, + clear_color: [f32; 3], +} - let event_loop = winit::event_loop::EventLoopBuilder::::with_user_event() - .build() - .unwrap(); - let (gl_window, gl) = create_display(&event_loop); - let gl = std::sync::Arc::new(gl); - - let mut egui_glow = egui_glow::EguiGlow::new(&event_loop, gl.clone(), None, None, true); - - let event_loop_proxy = egui::mutex::Mutex::new(event_loop.create_proxy()); - egui_glow - .egui_ctx - .set_request_repaint_callback(move |info| { - event_loop_proxy - .lock() - .send_event(UserEvent::Redraw(info.delay)) - .expect("Cannot send event"); - }); +impl GlowApp { + fn new(proxy: winit::event_loop::EventLoopProxy) -> Self { + Self { + proxy, + gl_window: None, + gl: None, + egui_glow: None, + repaint_delay: std::time::Duration::MAX, + clear_color: [0.1, 0.1, 0.1], + } + } +} - let mut repaint_delay = std::time::Duration::MAX; +impl winit::application::ApplicationHandler for GlowApp { + fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + let (gl_window, gl) = create_display(event_loop); + let gl = std::sync::Arc::new(gl); + gl_window.window().set_visible(true); + + let egui_glow = egui_glow::EguiGlow::new(event_loop, gl.clone(), None, None, true); + + let event_loop_proxy = egui::mutex::Mutex::new(self.proxy.clone()); + egui_glow + .egui_ctx + .set_request_repaint_callback(move |info| { + event_loop_proxy + .lock() + .send_event(UserEvent::Redraw(info.delay)) + .expect("Cannot send event"); + }); + self.gl_window = Some(gl_window); + self.gl = Some(gl); + self.egui_glow = Some(egui_glow); + } - let _ = event_loop.run(move |event, event_loop_window_target| { + fn window_event( + &mut self, + event_loop: &winit::event_loop::ActiveEventLoop, + _window_id: winit::window::WindowId, + event: winit::event::WindowEvent, + ) { let mut redraw = || { let mut quit = false; - egui_glow.run(gl_window.window(), |egui_ctx| { - egui::SidePanel::left("my_side_panel").show(egui_ctx, |ui| { - ui.heading("Hello World!"); - if ui.button("Quit").clicked() { - quit = true; - } - ui.color_edit_button_rgb(&mut clear_color); - }); - }); + self.egui_glow.as_mut().unwrap().run( + self.gl_window.as_mut().unwrap().window(), + |egui_ctx| { + egui::SidePanel::left("my_side_panel").show(egui_ctx, |ui| { + ui.heading("Hello World!"); + if ui.button("Quit").clicked() { + quit = true; + } + + ui.color_edit_button_rgb(self.clear_color.as_mut().try_into().unwrap()); + }); + }, + ); if quit { - event_loop_window_target.exit(); + event_loop.exit(); } else { - event_loop_window_target.set_control_flow(if repaint_delay.is_zero() { - gl_window.window().request_redraw(); + event_loop.set_control_flow(if self.repaint_delay.is_zero() { + self.gl_window.as_mut().unwrap().window().request_redraw(); winit::event_loop::ControlFlow::Poll } else if let Some(repaint_after_instant) = - std::time::Instant::now().checked_add(repaint_delay) + std::time::Instant::now().checked_add(self.repaint_delay) { winit::event_loop::ControlFlow::WaitUntil(repaint_after_instant) } else { @@ -207,64 +249,87 @@ fn main() { { unsafe { use glow::HasContext as _; - gl.clear_color(clear_color[0], clear_color[1], clear_color[2], 1.0); - gl.clear(glow::COLOR_BUFFER_BIT); + self.gl.as_mut().unwrap().clear_color( + self.clear_color[0], + self.clear_color[1], + self.clear_color[2], + 1.0, + ); + self.gl.as_mut().unwrap().clear(glow::COLOR_BUFFER_BIT); } // draw things behind egui here - egui_glow.paint(gl_window.window()); + self.egui_glow + .as_mut() + .unwrap() + .paint(self.gl_window.as_mut().unwrap().window()); // draw things on top of egui here - gl_window.swap_buffers().unwrap(); - gl_window.window().set_visible(true); + self.gl_window.as_mut().unwrap().swap_buffers().unwrap(); + self.gl_window.as_mut().unwrap().window().set_visible(true); } }; - match event { - winit::event::Event::WindowEvent { event, .. } => { - use winit::event::WindowEvent; - if matches!(event, WindowEvent::CloseRequested | WindowEvent::Destroyed) { - event_loop_window_target.exit(); - return; - } - - if matches!(event, WindowEvent::RedrawRequested) { - redraw(); - return; - } + use winit::event::WindowEvent; + if matches!(event, WindowEvent::CloseRequested | WindowEvent::Destroyed) { + event_loop.exit(); + return; + } - if let winit::event::WindowEvent::Resized(physical_size) = &event { - gl_window.resize(*physical_size); - } + if matches!(event, WindowEvent::RedrawRequested) { + redraw(); + return; + } - let event_response = egui_glow.on_window_event(gl_window.window(), &event); + if let winit::event::WindowEvent::Resized(physical_size) = &event { + self.gl_window.as_mut().unwrap().resize(*physical_size); + } - if event_response.repaint { - gl_window.window().request_redraw(); - } - } + let event_response = self + .egui_glow + .as_mut() + .unwrap() + .on_window_event(self.gl_window.as_mut().unwrap().window(), &event); - winit::event::Event::UserEvent(UserEvent::Redraw(delay)) => { - repaint_delay = delay; - } - winit::event::Event::LoopExiting => { - egui_glow.destroy(); - } - winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { - .. - }) => { - gl_window.window().request_redraw(); - } + if event_response.repaint { + self.gl_window.as_mut().unwrap().window().request_redraw(); + } + } + fn user_event(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop, event: UserEvent) { + match event { + UserEvent::Redraw(delay) => self.repaint_delay = delay, + } + } - _ => (), + fn new_events( + &mut self, + _event_loop: &winit::event_loop::ActiveEventLoop, + cause: winit::event::StartCause, + ) { + if let winit::event::StartCause::ResumeTimeReached { .. } = &cause { + self.gl_window.as_mut().unwrap().window().request_redraw(); } - }); + } + + fn exiting(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) { + self.egui_glow.as_mut().unwrap().destroy(); + } +} + +fn main() { + let event_loop = winit::event_loop::EventLoop::::with_user_event() + .build() + .unwrap(); + let proxy = event_loop.create_proxy(); + + let mut app = GlowApp::new(proxy); + event_loop.run_app(&mut app).expect("failed to run app"); } fn create_display( - event_loop: &winit::event_loop::EventLoopWindowTarget, + event_loop: &winit::event_loop::ActiveEventLoop, ) -> (GlutinWindowContext, glow::Context) { let glutin_window_context = unsafe { GlutinWindowContext::new(event_loop) }; let gl = unsafe { diff --git a/crates/egui_glow/src/winit.rs b/crates/egui_glow/src/winit.rs index c3bcfe386b5..0f1d96d08a4 100644 --- a/crates/egui_glow/src/winit.rs +++ b/crates/egui_glow/src/winit.rs @@ -22,8 +22,8 @@ pub struct EguiGlow { impl EguiGlow { /// For automatic shader version detection set `shader_version` to `None`. - pub fn new( - event_loop: &winit::event_loop::EventLoopWindowTarget, + pub fn new( + event_loop: &winit::event_loop::ActiveEventLoop, gl: std::sync::Arc, shader_version: Option, native_pixels_per_point: Option, diff --git a/examples/serial_windows/src/main.rs b/examples/serial_windows/src/main.rs index 133155bd131..f82881e84fe 100644 --- a/examples/serial_windows/src/main.rs +++ b/examples/serial_windows/src/main.rs @@ -6,13 +6,6 @@ use eframe::egui; fn main() -> eframe::Result { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). - if cfg!(target_os = "macos") { - eprintln!( - "This example does not work on Mac! See https://github.com/emilk/egui/issues/1918" - ); - return Ok(()); - } - let options = eframe::NativeOptions { run_and_return: true, viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]), @@ -59,10 +52,6 @@ impl eframe::App for MyApp { }; ui.label(label_text); - if ctx.os() == egui::os::OperatingSystem::Mac { - ui.label("This example doesn't work on Mac!"); - } - if ui.button("Close").clicked() { eprintln!("Pressed Close button"); ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close); From 5294cae0e0104c79340696e27af209013e04c98e Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Thu, 18 Jul 2024 20:52:33 +0100 Subject: [PATCH 02/23] Pin to 0.30.0 as 0.30.1+ has a bug that crashes on mac :/ --- Cargo.lock | 217 +++++------------------------------------------------ Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 927e0dcfe47..7f8cc295d9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -643,39 +643,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "calloop" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" -dependencies = [ - "bitflags 2.5.0", - "log", - "polling 3.3.0", - "rustix 0.38.21", - "slab", - "thiserror", -] - [[package]] name = "calloop-wayland-source" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ - "calloop 0.12.3", - "rustix 0.38.21", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" -dependencies = [ - "calloop 0.13.0", + "calloop", "rustix 0.38.21", "wayland-backend", "wayland-client", @@ -2655,30 +2629,6 @@ dependencies = [ "objc2-quartz-core", ] -[[package]] -name = "objc2-cloud-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" -dependencies = [ - "bitflags 2.5.0", - "block2", - "objc2", - "objc2-core-location", - "objc2-foundation", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2", - "objc2", - "objc2-foundation", -] - [[package]] name = "objc2-core-data" version = "0.2.2" @@ -2703,18 +2653,6 @@ dependencies = [ "objc2-metal", ] -[[package]] -name = "objc2-core-location" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" -dependencies = [ - "block2", - "objc2", - "objc2-contacts", - "objc2-foundation", -] - [[package]] name = "objc2-encode" version = "4.0.3" @@ -2734,18 +2672,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "objc2-link-presentation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" -dependencies = [ - "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", -] - [[package]] name = "objc2-metal" version = "0.2.2" @@ -2771,61 +2697,6 @@ dependencies = [ "objc2-metal", ] -[[package]] -name = "objc2-symbols" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" -dependencies = [ - "bitflags 2.5.0", - "block2", - "objc2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation", - "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", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" -dependencies = [ - "bitflags 2.5.0", - "block2", - "objc2", - "objc2-core-location", - "objc2-foundation", -] - [[package]] name = "objc_id" version = "0.1.1" @@ -3517,14 +3388,14 @@ dependencies = [ [[package]] name = "sctk-adwaita" -version = "0.10.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +checksum = "7555fcb4f753d095d734fdefebb0ad8c98478a21db500492d87c55913d3b0086" dependencies = [ "ab_glyph", "log", "memmap2", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "tiny-skia", ] @@ -3659,33 +3530,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" dependencies = [ "bitflags 2.5.0", - "calloop 0.12.3", - "calloop-wayland-source 0.2.0", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.21", - "thiserror", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.31.0", - "wayland-protocols-wlr 0.2.0", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-client-toolkit" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" -dependencies = [ - "bitflags 2.5.0", - "calloop 0.13.0", - "calloop-wayland-source 0.3.0", + "calloop", + "calloop-wayland-source", "cursor-icon", "libc", "log", @@ -3696,8 +3542,8 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.3", - "wayland-protocols-wlr 0.3.3", + "wayland-protocols", + "wayland-protocols-wlr", "wayland-scanner", "xkeysym", ] @@ -3709,7 +3555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" dependencies = [ "libc", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit", "wayland-backend", ] @@ -4384,28 +4230,16 @@ dependencies = [ "wayland-scanner", ] -[[package]] -name = "wayland-protocols" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" -dependencies = [ - "bitflags 2.5.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - [[package]] name = "wayland-protocols-plasma" -version = "0.3.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ "bitflags 2.5.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-scanner", ] @@ -4418,20 +4252,7 @@ dependencies = [ "bitflags 2.5.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.0", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" -dependencies = [ - "bitflags 2.5.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-scanner", ] @@ -4940,17 +4761,16 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winit" -version = "0.30.4" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" +checksum = "ea9e6d5d66cbf702e0dd820302144f51b69a95acdc495dd98ca280ff206562b1" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.5.0", - "block2", "bytemuck", - "calloop 0.13.0", + "calloop", "cfg_aliases 0.2.1", "concurrent-queue", "core-foundation", @@ -4964,7 +4784,6 @@ dependencies = [ "objc2", "objc2-app-kit", "objc2-foundation", - "objc2-ui-kit", "orbclient", "percent-encoding", "pin-project", @@ -4972,7 +4791,7 @@ dependencies = [ "redox_syscall 0.4.1", "rustix 0.38.21", "sctk-adwaita", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "smol_str", "tracing", "unicode-segmentation", @@ -4980,7 +4799,7 @@ dependencies = [ "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-protocols-plasma", "web-sys", "web-time 1.1.0", diff --git a/Cargo.toml b/Cargo.toml index 53cf8177a43..7d8e1649e0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,7 +93,7 @@ wgpu = { version = "0.20.1", default-features = false, features = [ # Make the renderer `Sync` even on wasm32, because it makes the code simpler: "fragile-send-sync-non-atomic-wasm", ] } -winit = { version = "0.30.4", default-features = false } +winit = { version = "=0.30.0", default-features = false } [workspace.lints.rust] From 3f42b7271eecda9b6a4ed538258d9fd8f771ef0d Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Thu, 18 Jul 2024 20:53:03 +0100 Subject: [PATCH 03/23] Builder -> attributes --- crates/eframe/src/native/glow_integration.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 60ba3cb5d29..c5b80919212 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -1112,17 +1112,18 @@ impl GlutinWindowContext { window } else { log::debug!("Creating a window for viewport {viewport_id:?}"); - let window_builder = egui_winit::create_winit_window_atrributes( + let window_attributes = egui_winit::create_winit_window_atrributes( &self.egui_ctx, event_loop, viewport.builder.clone(), ); - if window_builder.transparent() && self.gl_config.supports_transparency() == Some(false) + if window_attributes.transparent() + && self.gl_config.supports_transparency() == Some(false) { log::error!("Cannot create transparent window: the GL config does not support it"); } let window = - glutin_winit::finalize_window(event_loop, window_builder, &self.gl_config)?; + glutin_winit::finalize_window(event_loop, window_attributes, &self.gl_config)?; egui_winit::apply_viewport_builder_to_window( &self.egui_ctx, &window, From 2e6c0d34fe8f2d6cec6e9f09187bb18e5399ef3a Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Thu, 18 Jul 2024 23:22:40 +0100 Subject: [PATCH 04/23] Add link to problematic winit PR --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7d8e1649e0a..26d1c33687b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,8 +93,9 @@ wgpu = { version = "0.20.1", default-features = false, features = [ # Make the renderer `Sync` even on wasm32, because it makes the code simpler: "fragile-send-sync-non-atomic-wasm", ] } -winit = { version = "=0.30.0", default-features = false } +# Version 0.30.1 and up unfortunately crash on macOS, due to https://github.com/rust-windowing/winit/pull/3684 +winit = { version = "=0.30.0", default-features = false } [workspace.lints.rust] unsafe_code = "deny" From 4f0e7d5d0c2fbc46e7dbbf841359d51dcc7c84b8 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Thu, 18 Jul 2024 23:47:22 +0100 Subject: [PATCH 05/23] Update WinitApp integration to be more like ApplicationHandler --- crates/eframe/src/native/glow_integration.rs | 202 ++++++------ crates/eframe/src/native/run.rs | 287 ++++++++++-------- crates/eframe/src/native/wgpu_integration.rs | 241 +++++++-------- crates/eframe/src/native/winit_integration.rs | 34 ++- crates/egui-winit/src/lib.rs | 37 +-- 5 files changed, 393 insertions(+), 408 deletions(-) diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index c5b80919212..c5218b19ac5 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -401,108 +401,103 @@ impl WinitApp for GlowWinitApp { &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, - ) -> EventResult { + ) -> Result { if let Some(running) = &mut self.running { running.run_ui_and_paint(event_loop, window_id) } else { - EventResult::Wait + Ok(EventResult::Wait) } } - fn on_event( - &mut self, - event_loop: &ActiveEventLoop, - event: &winit::event::Event, - ) -> Result { - crate::profile_function!(winit_integration::short_event_description(event)); - - Ok(match event { - winit::event::Event::Resumed => { - log::debug!("Event::Resumed"); - - let running = if let Some(running) = &mut self.running { - // Not the first resume event. Create all outstanding windows. - running - .glutin - .borrow_mut() - .initialize_all_windows(event_loop); - running - } else { - // First resume event. Created our root window etc. - self.init_run_state(event_loop)? - }; - let window_id = running.glutin.borrow().window_from_viewport[&ViewportId::ROOT]; - EventResult::RepaintNow(window_id) - } + fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result { + log::debug!("Event::Resumed"); - winit::event::Event::Suspended => { - if let Some(running) = &mut self.running { - running.glutin.borrow_mut().on_suspend()?; - } - EventResult::Wait - } + let running = if let Some(running) = &mut self.running { + // Not the first resume event. Create all outstanding windows. + running + .glutin + .borrow_mut() + .initialize_all_windows(event_loop); + running + } else { + // First resume event. Created our root window etc. + self.init_run_state(event_loop)? + }; + let window_id = running.glutin.borrow().window_from_viewport[&ViewportId::ROOT]; + Ok(EventResult::RepaintNow(window_id)) + } - winit::event::Event::WindowEvent { event, window_id } => { - if let Some(running) = &mut self.running { - running.on_window_event(*window_id, event) - } else { - EventResult::Wait - } - } + fn suspended(&mut self, _: &ActiveEventLoop) -> crate::Result { + if let Some(running) = &mut self.running { + running.glutin.borrow_mut().on_suspend()?; + } + Ok(EventResult::Wait) + } - winit::event::Event::DeviceEvent { - device_id: _, - event: winit::event::DeviceEvent::MouseMotion { delta }, - } => { - if let Some(running) = &mut self.running { - let mut glutin = running.glutin.borrow_mut(); - if let Some(viewport) = glutin - .focused_viewport - .and_then(|viewport| glutin.viewports.get_mut(&viewport)) - { - if let Some(egui_winit) = viewport.egui_winit.as_mut() { - egui_winit.on_mouse_motion(*delta); - } + fn device_event( + &mut self, + _: &ActiveEventLoop, + _: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) -> crate::Result { + if let winit::event::DeviceEvent::MouseMotion { delta } = event { + if let Some(running) = &mut self.running { + let mut glutin = running.glutin.borrow_mut(); + if let Some(viewport) = glutin + .focused_viewport + .and_then(|viewport| glutin.viewports.get_mut(&viewport)) + { + if let Some(egui_winit) = viewport.egui_winit.as_mut() { + egui_winit.on_mouse_motion(delta); + } - if let Some(window) = viewport.window.as_ref() { - EventResult::RepaintNext(window.id()) - } else { - EventResult::Wait - } - } else { - EventResult::Wait + if let Some(window) = viewport.window.as_ref() { + return Ok(EventResult::RepaintNext(window.id())); } - } else { - EventResult::Wait } } + } - #[cfg(feature = "accesskit")] - winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest( - accesskit_winit::Event { - window_id, - window_event: accesskit_winit::WindowEvent::ActionRequested(request), - }, - )) => { - if let Some(running) = &self.running { - let mut glutin = running.glutin.borrow_mut(); - if let Some(viewport_id) = glutin.viewport_from_window.get(window_id).copied() { - if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) { - if let Some(egui_winit) = &mut viewport.egui_winit { - crate::profile_scope!("on_accesskit_action_request"); - egui_winit.on_accesskit_action_request(request.clone()); - } + Ok(EventResult::Wait) + } + + fn window_event( + &mut self, + _: &ActiveEventLoop, + window_id: WindowId, + event: winit::event::WindowEvent, + ) -> Result { + if let Some(running) = &mut self.running { + Ok(running.on_window_event(window_id, &event)) + } else { + Ok(EventResult::Wait) + } + } + + #[cfg(feature = "accesskit")] + fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result { + if let accesskit_winit::Event { + window_id, + window_event: accesskit_winit::WindowEvent::ActionRequested(request), + } = event + { + if let Some(running) = &self.running { + let mut glutin = running.glutin.borrow_mut(); + if let Some(viewport_id) = glutin.viewport_from_window.get(&window_id).copied() { + if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) { + if let Some(egui_winit) = &mut viewport.egui_winit { + crate::profile_scope!("on_accesskit_action_request"); + egui_winit.on_accesskit_action_request(request.clone()); } } - // As a form of user input, accessibility actions should - // lead to a repaint. - EventResult::RepaintNext(*window_id) - } else { - EventResult::Wait } + // As a form of user input, accessibility actions should + // lead to a repaint. + return Ok(EventResult::RepaintNext(window_id)); } - _ => EventResult::Wait, - }) + } + + Ok(EventResult::Wait) } } @@ -511,7 +506,7 @@ impl GlowWinitRunning { &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, - ) -> EventResult { + ) -> Result { crate::profile_function!(); let Some(viewport_id) = self @@ -521,7 +516,7 @@ impl GlowWinitRunning { .get(&window_id) .copied() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; #[cfg(feature = "puffin")] @@ -539,10 +534,10 @@ impl GlowWinitRunning { // That means that the viewport cannot be rendered by itself and needs his parent to be rendered. if let Some(parent_viewport) = glutin.viewports.get(&viewport.ids.parent) { if let Some(window) = parent_viewport.window.as_ref() { - return EventResult::RepaintNext(window.id()); + return Ok(EventResult::RepaintNext(window.id())); } } - return EventResult::Wait; + return Ok(EventResult::Wait); } } @@ -550,15 +545,15 @@ impl GlowWinitRunning { let mut glutin = self.glutin.borrow_mut(); let egui_ctx = glutin.egui_ctx.clone(); let Some(viewport) = glutin.viewports.get_mut(&viewport_id) else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let Some(window) = viewport.window.as_ref() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window, false); let Some(egui_winit) = viewport.egui_winit.as_mut() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let mut raw_input = egui_winit.take_egui_input(window); let viewport_ui_cb = viewport.viewport_ui_cb.clone(); @@ -594,10 +589,10 @@ impl GlowWinitRunning { } = &mut *glutin; let viewport = &viewports[&viewport_id]; let Some(window) = viewport.window.as_ref() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let Some(gl_surface) = viewport.gl_surface.as_ref() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let screen_size_in_pixels: [u32; 2] = window.inner_size().into(); @@ -652,7 +647,7 @@ impl GlowWinitRunning { } = &mut *glutin; let Some(viewport) = viewports.get_mut(&viewport_id) else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; viewport.info.events.clear(); // they should have been processed @@ -724,13 +719,12 @@ impl GlowWinitRunning { // vsync - don't count as frame-time: frame_timer.pause(); crate::profile_scope!("swap_buffers"); - if let Err(err) = gl_surface.swap_buffers( - current_gl_context - .as_ref() - .expect("failed to get current context to swap buffers"), - ) { - log::error!("swap_buffers failed: {err}"); - } + let context = current_gl_context.as_ref().ok_or(std::convert::Into::< + egui_glow::PainterError, + >::into( + "failed to get current context to swap buffers".to_owned(), + ))?; + gl_surface.swap_buffers(context)?; frame_timer.resume(); } @@ -756,9 +750,9 @@ impl GlowWinitRunning { } if integration.should_close() { - EventResult::Exit + Ok(EventResult::Exit) } else { - EventResult::Wait + Ok(EventResult::Wait) } } @@ -767,8 +761,6 @@ impl GlowWinitRunning { window_id: WindowId, event: &winit::event::WindowEvent, ) -> EventResult { - crate::profile_function!(egui_winit::short_window_event_description(event)); - let mut glutin = self.glutin.borrow_mut(); let viewport_id = glutin.viewport_from_window.get(&window_id).copied(); diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 222984a2c87..b6969c4f1e6 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -2,20 +2,14 @@ use std::{cell::RefCell, time::Instant}; use winit::{ application::ApplicationHandler, - event::Event, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, window::WindowId, }; use ahash::HashMap; -use crate::{ - epi, - native::winit_integration::{short_event_description, EventResult}, - Result, -}; - use super::winit_integration::{UserEvent, WinitApp}; +use crate::{epi, native::winit_integration::EventResult, Result}; // ---------------------------------------------------------------------------- fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result> { @@ -54,156 +48,87 @@ fn with_event_loop( }) } -struct App { +/// Wraps a [`WinitApp`] to implement [`ApplicationHandler`]. This handles redrawing, exit states, and +/// some events, but otherwise forwards events to the [`WinitApp`]. +struct WinitAppWrapper { windows_next_repaint_times: HashMap, winit_app: T, return_result: Result<(), crate::Error>, + run_and_return: bool, } -impl App { - fn new(winit_app: T) -> Self { +impl WinitAppWrapper { + fn new(winit_app: T, run_and_return: bool) -> Self { Self { windows_next_repaint_times: HashMap::default(), winit_app, return_result: Ok(()), + run_and_return, } } - fn handle_event(&mut self, event_loop: &ActiveEventLoop, event: &Event) { - let event_result = match self.winit_app.on_event(event_loop, event) { - Ok(event_result) => { - log::trace!("event_result: {event_result:?}"); - event_result - } - Err(err) => { - log::error!("Exiting because of error: {err} during event {event:?}"); - self.return_result = Err(err); - EventResult::Exit - } - }; - self.handle_event_result(event_loop, event_result, event); - } - fn handle_event_result( &mut self, event_loop: &ActiveEventLoop, - event_result: EventResult, - event: &Event, + event_result: Result, ) { + let mut exit = false; + match event_result { - EventResult::Wait => { - event_loop.set_control_flow(ControlFlow::Wait); - } - EventResult::RepaintNow(window_id) => { - log::trace!( - "RepaintNow of {window_id:?} caused by {}", - short_event_description(event) - ); - if cfg!(target_os = "windows") { - // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 - self.windows_next_repaint_times.remove(&window_id); - self.winit_app.run_ui_and_paint(event_loop, window_id); - } else { - // Fix for https://github.com/emilk/egui/issues/2425 - self.windows_next_repaint_times - .insert(window_id, Instant::now()); + Ok(event_result) => { + log::trace!("event_result: {event_result:?}"); + match event_result { + EventResult::Wait => { + event_loop.set_control_flow(ControlFlow::Wait); + } + EventResult::RepaintNow(window_id) => { + log::trace!("RepaintNow of {window_id:?}",); + if cfg!(target_os = "windows") { + // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 + self.windows_next_repaint_times.remove(&window_id); + + let _ = self.winit_app.run_ui_and_paint(event_loop, window_id); + } else { + // Fix for https://github.com/emilk/egui/issues/2425 + self.windows_next_repaint_times + .insert(window_id, Instant::now()); + } + } + EventResult::RepaintNext(window_id) => { + log::trace!("RepaintNext of {window_id:?}",); + self.windows_next_repaint_times + .insert(window_id, Instant::now()); + } + EventResult::RepaintAt(window_id, repaint_time) => { + self.windows_next_repaint_times.insert( + window_id, + self.windows_next_repaint_times + .get(&window_id) + .map_or(repaint_time, |last| (*last).min(repaint_time)), + ); + } + EventResult::Exit => exit = true, } } - EventResult::RepaintNext(window_id) => { - log::trace!( - "RepaintNext of {window_id:?} caused by {}", - short_event_description(event) - ); - self.windows_next_repaint_times - .insert(window_id, Instant::now()); + Err(err) => { + log::error!("Exiting because of error: {err}"); + exit = true; + self.return_result = Err(err); } - EventResult::Exit => { + }; + + if exit { + if self.run_and_return { log::debug!("Asking to exit event loop…"); - self.winit_app.save_and_destroy(); event_loop.exit(); - } - } - } -} - -impl ApplicationHandler for App { - fn suspended(&mut self, event_loop: &ActiveEventLoop) { - self.handle_event(event_loop, &Event::Suspended); - } - - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - self.handle_event(event_loop, &Event::Resumed); - } - - fn exiting(&mut self, _: &ActiveEventLoop) { - // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), - // so we need to save state now: - log::debug!("Received Event::LoopExiting - saving app state…"); - self.winit_app.save_and_destroy(); - } - - fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) { - #[allow(irrefutable_let_patterns)] - // when accesskit is not enabled, there are no other events to handle here. - if let UserEvent::RequestRepaint { - when, - frame_nr, - viewport_id, - } = event - { - let current_frame_nr = self.winit_app.frame_nr(viewport_id); - if current_frame_nr == frame_nr || current_frame_nr == frame_nr + 1 { - log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); - if let Some(window_id) = self.winit_app.window_id_from_viewport_id(viewport_id) { - self.windows_next_repaint_times.insert( - window_id, - self.windows_next_repaint_times - .get(&window_id) - .map_or(when, |last| (*last).min(when)), - ); - } else { - event_loop.set_control_flow(ControlFlow::Wait); - } } else { - log::trace!("Got outdated UserEvent::RequestRepaint"); - event_loop.set_control_flow(ControlFlow::Wait); - } - } else { - self.handle_event(event_loop, &Event::UserEvent(event)); - } - } - - fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: winit::event::StartCause) { - if matches!(cause, winit::event::StartCause::ResumeTimeReached { .. }) { - log::trace!("Woke up to check next_repaint_time"); - } - // TODO: Is this needed? - event_loop.set_control_flow(ControlFlow::Wait); - } + log::debug!("Quitting - saving app state…"); + self.winit_app.save_and_destroy(); - fn window_event( - &mut self, - event_loop: &ActiveEventLoop, - window_id: WindowId, - event: winit::event::WindowEvent, - ) { - if matches!(event, winit::event::WindowEvent::RedrawRequested) { - self.windows_next_repaint_times.remove(&window_id); - let event_result = self.winit_app.run_ui_and_paint(event_loop, window_id); - - self.handle_event_result( - event_loop, - event_result, - &Event::WindowEvent { window_id, event }, - ); - } else { - self.handle_event( - event_loop, - &Event::WindowEvent { - window_id, - event: event.clone(), - }, - ); + log::debug!("Exiting with return code 0"); + #[allow(clippy::exit)] + std::process::exit(0); + } } let mut next_repaint_time = self.windows_next_repaint_times.values().min().copied(); @@ -248,13 +173,105 @@ impl ApplicationHandler for App { } } +impl ApplicationHandler for WinitAppWrapper { + fn suspended(&mut self, event_loop: &ActiveEventLoop) { + crate::profile_function!("Event::Suspended"); + let event_result = self.winit_app.suspended(event_loop); + self.handle_event_result(event_loop, event_result); + } + + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + crate::profile_function!("Event::Resumed"); + let event_result = self.winit_app.resumed(event_loop); + self.handle_event_result(event_loop, event_result); + } + + fn exiting(&mut self, _: &ActiveEventLoop) { + // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), + // so we need to save state now: + log::debug!("Received Event::LoopExiting - saving app state…"); + self.winit_app.save_and_destroy(); + } + + fn device_event( + &mut self, + event_loop: &ActiveEventLoop, + device_id: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) { + crate::profile_function!(egui_winit::short_device_event_description(&event)); + let event_result = self.winit_app.device_event(event_loop, device_id, event); + self.handle_event_result(event_loop, event_result); + } + + fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) { + crate::profile_function!(match &event { + UserEvent::RequestRepaint { .. } => "UserEvent::RequestRepaint", + #[cfg(feature = "accesskit")] + UserEvent::AccessKitActionRequest(_) => "UserEvent::AccessKitActionRequest", + }); + + let event_result = match event { + UserEvent::RequestRepaint { + when, + frame_nr, + viewport_id, + } => { + let current_frame_nr = self.winit_app.frame_nr(viewport_id); + if current_frame_nr == frame_nr || current_frame_nr == frame_nr + 1 { + log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); + if let Some(window_id) = self.winit_app.window_id_from_viewport_id(viewport_id) + { + Ok(EventResult::RepaintAt(window_id, when)) + } else { + Ok(EventResult::Wait) + } + } else { + log::trace!("Got outdated UserEvent::RequestRepaint"); + Ok(EventResult::Wait) // old request - we've already repainted + } + } + #[cfg(feature = "accesskit")] + UserEvent::AccessKitActionRequest(request) => { + self.winit_app.on_accesskit_event(request) + } + }; + self.handle_event_result(event_loop, event_result); + } + + fn new_events(&mut self, _: &ActiveEventLoop, cause: winit::event::StartCause) { + if let winit::event::StartCause::ResumeTimeReached { .. } = cause { + log::trace!("Woke up to check next_repaint_time"); + } + } + + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + window_id: WindowId, + event: winit::event::WindowEvent, + ) { + crate::profile_function!(egui_winit::short_window_event_description(&event)); + + let event_result = match event { + winit::event::WindowEvent::RedrawRequested => { + self.windows_next_repaint_times.remove(&window_id); + self.winit_app.run_ui_and_paint(event_loop, window_id) + } + _ => self.winit_app.window_event(event_loop, window_id, event), + }; + + self.handle_event_result(event_loop, event_result); + } +} + #[cfg(not(target_os = "ios"))] fn run_and_return(event_loop: &mut EventLoop, winit_app: impl WinitApp) -> Result { use winit::platform::run_on_demand::EventLoopExtRunOnDemand; log::trace!("Entering the winit event loop (run_on_demand)…"); - let mut app = App::new(winit_app); + let mut app = WinitAppWrapper::new(winit_app, true); event_loop.run_app_on_demand(&mut app)?; log::debug!("eframe window closed"); app.return_result @@ -264,7 +281,7 @@ fn run_and_exit(event_loop: EventLoop, winit_app: impl WinitApp + 'st log::trace!("Entering the winit event loop (run)…"); // When to repaint what window - let mut app = App::new(winit_app); + let mut app = WinitAppWrapper::new(winit_app, false); event_loop.run_app(&mut app)?; log::debug!("winit event loop unexpectedly returned"); diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index 44d9c0341ef..f4db8fb71fe 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -376,135 +376,130 @@ impl WinitApp for WgpuWinitApp { &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, - ) -> EventResult { + ) -> Result { self.initialized_all_windows(event_loop); if let Some(running) = &mut self.running { running.run_ui_and_paint(window_id) } else { - EventResult::Wait + Ok(EventResult::Wait) } } - fn on_event( - &mut self, - event_loop: &ActiveEventLoop, - event: &winit::event::Event, - ) -> Result { - crate::profile_function!(winit_integration::short_event_description(event)); + fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result { + log::debug!("Event::Resumed"); - self.initialized_all_windows(event_loop); + let running = if let Some(running) = &self.running { + #[cfg(target_os = "android")] + self.recreate_window(event_loop, running); + running + } else { + let storage = if let Some(file) = &self.native_options.persistence_path { + epi_integration::create_storage_with_file(file) + } else { + epi_integration::create_storage( + self.native_options + .viewport + .app_id + .as_ref() + .unwrap_or(&self.app_name), + ) + }; + let egui_ctx = winit_integration::create_egui_context(storage.as_deref()); + let (window, builder) = create_window( + &egui_ctx, + event_loop, + storage.as_deref(), + &mut self.native_options, + )?; + self.init_run_state(egui_ctx, event_loop, storage, window, builder)? + }; - Ok(match event { - winit::event::Event::Resumed => { - log::debug!("Event::Resumed"); + let viewport = &running.shared.borrow().viewports[&ViewportId::ROOT]; + if let Some(window) = &viewport.window { + Ok(EventResult::RepaintNow(window.id())) + } else { + Ok(EventResult::Wait) + } + } - let running = if let Some(running) = &self.running { - #[cfg(target_os = "android")] - self.recreate_window(event_loop, running); - running - } else { - let storage = if let Some(file) = &self.native_options.persistence_path { - epi_integration::create_storage_with_file(file) - } else { - epi_integration::create_storage( - self.native_options - .viewport - .app_id - .as_ref() - .unwrap_or(&self.app_name), - ) - }; - let egui_ctx = winit_integration::create_egui_context(storage.as_deref()); - let (window, builder) = create_window( - &egui_ctx, - event_loop, - storage.as_deref(), - &mut self.native_options, - )?; - self.init_run_state(egui_ctx, event_loop, storage, window, builder)? - }; + fn suspended(&mut self, _: &ActiveEventLoop) -> crate::Result { + #[cfg(target_os = "android")] + self.drop_window()?; + Ok(EventResult::Wait) + } - let viewport = &running.shared.borrow().viewports[&ViewportId::ROOT]; - if let Some(window) = &viewport.window { - EventResult::RepaintNow(window.id()) - } else { - EventResult::Wait + fn device_event( + &mut self, + _: &ActiveEventLoop, + _: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) -> crate::Result { + if let winit::event::DeviceEvent::MouseMotion { delta } = event { + if let Some(running) = &mut self.running { + let mut shared = running.shared.borrow_mut(); + if let Some(viewport) = shared + .focused_viewport + .and_then(|viewport| shared.viewports.get_mut(&viewport)) + { + if let Some(egui_winit) = viewport.egui_winit.as_mut() { + egui_winit.on_mouse_motion(delta); + } + + if let Some(window) = viewport.window.as_ref() { + return Ok(EventResult::RepaintNext(window.id())); + } } } + } - winit::event::Event::Suspended => { - #[cfg(target_os = "android")] - self.drop_window()?; - EventResult::Wait - } + Ok(EventResult::Wait) + } - winit::event::Event::WindowEvent { event, window_id } => { - if let Some(running) = &mut self.running { - running.on_window_event(*window_id, event) - } else { - EventResult::Wait - } - } + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + window_id: WindowId, + event: winit::event::WindowEvent, + ) -> crate::Result { + self.initialized_all_windows(event_loop); - winit::event::Event::DeviceEvent { - device_id: _, - event: winit::event::DeviceEvent::MouseMotion { delta }, - } => { - if let Some(running) = &mut self.running { - let mut shared = running.shared.borrow_mut(); - if let Some(viewport) = shared - .focused_viewport - .and_then(|viewport| shared.viewports.get_mut(&viewport)) - { - if let Some(egui_winit) = viewport.egui_winit.as_mut() { - egui_winit.on_mouse_motion(*delta); - } + if let Some(running) = &mut self.running { + Ok(running.on_window_event(window_id, &event)) + } else { + Ok(EventResult::Wait) + } + } - if let Some(window) = viewport.window.as_ref() { - EventResult::RepaintNext(window.id()) - } else { - EventResult::Wait - } - } else { - EventResult::Wait + #[cfg(feature = "accesskit")] + fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result { + if let accesskit_winit::Event { + window_id, + window_event: accesskit_winit::WindowEvent::ActionRequested(request), + } = event + { + if let Some(running) = &mut self.running { + let mut shared_lock = running.shared.borrow_mut(); + let SharedState { + viewport_from_window, + viewports, + .. + } = &mut *shared_lock; + if let Some(viewport) = viewport_from_window + .get(&window_id) + .and_then(|id| viewports.get_mut(id)) + { + if let Some(egui_winit) = &mut viewport.egui_winit { + egui_winit.on_accesskit_action_request(request.clone()); } - } else { - EventResult::Wait } + // As a form of user input, accessibility actions should + // lead to a repaint. + return Ok(EventResult::RepaintNext(window_id)); } + } - #[cfg(feature = "accesskit")] - winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest( - accesskit_winit::Event { - window_id, - window_event: accesskit_winit::WindowEvent::ActionRequested(request), - }, - )) => { - if let Some(running) = &mut self.running { - let mut shared_lock = running.shared.borrow_mut(); - let SharedState { - viewport_from_window, - viewports, - .. - } = &mut *shared_lock; - if let Some(viewport) = viewport_from_window - .get(window_id) - .and_then(|id| viewports.get_mut(id)) - { - if let Some(egui_winit) = &mut viewport.egui_winit { - egui_winit.on_accesskit_action_request(request.clone()); - } - } - // As a form of user input, accessibility actions should - // lead to a repaint. - EventResult::RepaintNext(*window_id) - } else { - EventResult::Wait - } - } - _ => EventResult::Wait, - }) + Ok(EventResult::Wait) } } @@ -527,7 +522,7 @@ impl WgpuWinitRunning { } /// This is called both for the root viewport, and all deferred viewports - fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult { + fn run_ui_and_paint(&mut self, window_id: WindowId) -> Result { crate::profile_function!(); let Some(viewport_id) = self @@ -537,7 +532,7 @@ impl WgpuWinitRunning { .get(&window_id) .copied() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; #[cfg(feature = "puffin")] @@ -562,7 +557,7 @@ impl WgpuWinitRunning { if viewport_id != ViewportId::ROOT { let Some(viewport) = viewports.get(&viewport_id) else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; if viewport.viewport_ui_cb.is_none() { @@ -570,15 +565,15 @@ impl WgpuWinitRunning { // That means that the viewport cannot be rendered by itself and needs his parent to be rendered. if let Some(viewport) = viewports.get(&viewport.ids.parent) { if let Some(window) = viewport.window.as_ref() { - return EventResult::RepaintNext(window.id()); + return Ok(EventResult::RepaintNext(window.id())); } } - return EventResult::Wait; + return Ok(EventResult::Wait); } } let Some(viewport) = viewports.get_mut(&viewport_id) else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let Viewport { @@ -592,21 +587,17 @@ impl WgpuWinitRunning { let viewport_ui_cb = viewport_ui_cb.clone(); let Some(window) = window else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; egui_winit::update_viewport_info(info, &integration.egui_ctx, window, false); { crate::profile_scope!("set_window"); - if let Err(err) = - pollster::block_on(painter.set_window(viewport_id, Some(window.clone()))) - { - log::warn!("Failed to set window: {err}"); - } + pollster::block_on(painter.set_window(viewport_id, Some(window.clone())))?; } let Some(egui_winit) = egui_winit.as_mut() else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; let mut raw_input = egui_winit.take_egui_input(window); @@ -650,7 +641,7 @@ impl WgpuWinitRunning { remove_viewports_not_in(viewports, painter, viewport_from_window, &viewport_output); let Some(viewport) = viewports.get_mut(&viewport_id) else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; viewport.info.events.clear(); // they should have been processed @@ -661,7 +652,7 @@ impl WgpuWinitRunning { .. } = viewport else { - return EventResult::Wait; + return Ok(EventResult::Wait); }; egui_winit.handle_platform_output(window, platform_output); @@ -751,9 +742,9 @@ impl WgpuWinitRunning { } if integration.should_close() { - EventResult::Exit + Ok(EventResult::Exit) } else { - EventResult::Wait + Ok(EventResult::Wait) } } @@ -762,8 +753,6 @@ impl WgpuWinitRunning { window_id: WindowId, event: &winit::event::WindowEvent, ) -> EventResult { - crate::profile_function!(egui_winit::short_window_event_description(event)); - let Self { integration, shared, diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index bf6c1a1f9fb..ff1f0cfe5dc 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -72,13 +72,26 @@ pub trait WinitApp { &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, - ) -> EventResult; + ) -> crate::Result; + + fn suspended(&mut self, event_loop: &ActiveEventLoop) -> crate::Result; + fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result; + fn device_event( + &mut self, + event_loop: &ActiveEventLoop, + device_id: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) -> crate::Result; - fn on_event( + fn window_event( &mut self, event_loop: &ActiveEventLoop, - event: &winit::event::Event, + window_id: WindowId, + event: winit::event::WindowEvent, ) -> crate::Result; + + #[cfg(feature = "accesskit")] + fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result; } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -98,6 +111,8 @@ pub enum EventResult { /// cause any delay like `RepaintNow`. RepaintNext(WindowId), + RepaintAt(WindowId, Instant), + Exit, } @@ -110,16 +125,3 @@ pub fn system_theme(window: &Window, options: &crate::NativeOptions) -> Option) -> &'static str { - match event { - winit::event::Event::UserEvent(user_event) => match user_event { - UserEvent::RequestRepaint { .. } => "UserEvent::RequestRepaint", - #[cfg(feature = "accesskit")] - UserEvent::AccessKitActionRequest(_) => "UserEvent::AccessKitActionRequest", - }, - _ => egui_winit::short_generic_event_description(event), - } -} diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 3f98f89b5d3..c22e31f537f 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -1773,38 +1773,23 @@ pub fn apply_viewport_builder_to_window( // --------------------------------------------------------------------------- -/// Short and fast description of an event. +/// Short and fast description of a device event. /// Useful for logging and profiling. -pub fn short_generic_event_description(event: &winit::event::Event) -> &'static str { - use winit::event::{DeviceEvent, Event, StartCause}; +pub fn short_device_event_description(event: &winit::event::DeviceEvent) -> &'static str { + use winit::event::DeviceEvent; match event { - Event::AboutToWait => "Event::AboutToWait", - Event::LoopExiting => "Event::LoopExiting", - Event::Suspended => "Event::Suspended", - Event::Resumed => "Event::Resumed", - Event::MemoryWarning => "Event::MemoryWarning", - Event::UserEvent(_) => "UserEvent", - Event::DeviceEvent { event, .. } => match event { - DeviceEvent::Added { .. } => "DeviceEvent::Added", - DeviceEvent::Removed { .. } => "DeviceEvent::Removed", - DeviceEvent::MouseMotion { .. } => "DeviceEvent::MouseMotion", - DeviceEvent::MouseWheel { .. } => "DeviceEvent::MouseWheel", - DeviceEvent::Motion { .. } => "DeviceEvent::Motion", - DeviceEvent::Button { .. } => "DeviceEvent::Button", - DeviceEvent::Key { .. } => "DeviceEvent::Key", - }, - Event::NewEvents(start_cause) => match start_cause { - StartCause::ResumeTimeReached { .. } => "NewEvents::ResumeTimeReached", - StartCause::WaitCancelled { .. } => "NewEvents::WaitCancelled", - StartCause::Poll => "NewEvents::Poll", - StartCause::Init => "NewEvents::Init", - }, - Event::WindowEvent { event, .. } => short_window_event_description(event), + DeviceEvent::Added { .. } => "DeviceEvent::Added", + DeviceEvent::Removed { .. } => "DeviceEvent::Removed", + DeviceEvent::MouseMotion { .. } => "DeviceEvent::MouseMotion", + DeviceEvent::MouseWheel { .. } => "DeviceEvent::MouseWheel", + DeviceEvent::Motion { .. } => "DeviceEvent::Motion", + DeviceEvent::Button { .. } => "DeviceEvent::Button", + DeviceEvent::Key { .. } => "DeviceEvent::Key", } } -/// Short and fast description of an event. +/// Short and fast description of a window event. /// Useful for logging and profiling. pub fn short_window_event_description(event: &winit::event::WindowEvent) -> &'static str { use winit::event::WindowEvent; From 46238635494f7a100fe5c8e93559f4d716eab5d8 Mon Sep 17 00:00:00 2001 From: ArthurBrussee Date: Thu, 18 Jul 2024 23:57:47 +0100 Subject: [PATCH 06/23] Fix for windows & linux --- crates/egui-winit/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index c22e31f537f..d1d65ad4fd7 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -1654,16 +1654,16 @@ pub fn create_winit_window_atrributes( #[cfg(all(feature = "wayland", target_os = "linux"))] if let Some(app_id) = _app_id { - use winit::platform::wayland::WindowBuilderExtWayland as _; - window_builder = window_builder.with_name(app_id, ""); + use winit::platform::wayland::WindowAttributesExtWayland as _; + window_attributes = window_attributes.with_name(app_id, ""); } #[cfg(all(feature = "x11", target_os = "linux"))] { if let Some(window_type) = _window_type { - use winit::platform::x11::WindowBuilderExtX11 as _; + use winit::platform::x11::WindowAttributesExtX11 as _; use winit::platform::x11::XWindowType; - window_builder = window_builder.with_x11_window_type(vec![match window_type { + window_attributes = window_attributes.with_x11_window_type(vec![match window_type { egui::X11WindowType::Normal => XWindowType::Normal, egui::X11WindowType::Utility => XWindowType::Utility, egui::X11WindowType::Dock => XWindowType::Dock, @@ -1684,12 +1684,12 @@ pub fn create_winit_window_atrributes( #[cfg(target_os = "windows")] { - use winit::platform::windows::WindowBuilderExtWindows as _; + use winit::platform::windows::WindowAttributesExtWindows as _; if let Some(enable) = _drag_and_drop { - window_builder = window_builder.with_drag_and_drop(enable); + window_attributes = window_attributes.with_drag_and_drop(enable); } if let Some(show) = _taskbar { - window_builder = window_builder.with_skip_taskbar(!show); + window_attributes = window_attributes.with_skip_taskbar(!show); } } From eafed08842fce64e08bbf1a9391096a6d6b18211 Mon Sep 17 00:00:00 2001 From: ArthurBrussee Date: Fri, 19 Jul 2024 00:37:51 +0100 Subject: [PATCH 07/23] Use more modern accesskit lazy init As per the example branch from Matt! Co-authored-by: mwcampbell --- crates/eframe/src/native/epi_integration.rs | 31 -------------- crates/eframe/src/native/glow_integration.rs | 28 +++++-------- crates/eframe/src/native/wgpu_integration.rs | 41 ++++++++----------- crates/eframe/src/native/winit_integration.rs | 33 +++++++++++++++ crates/egui-winit/src/lib.rs | 4 +- crates/egui/src/context.rs | 17 ++------ 6 files changed, 66 insertions(+), 88 deletions(-) diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index e070c3e2870..5d02e2386e9 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -164,24 +164,6 @@ pub struct EpiIntegration { app_icon_setter: super::app_icon::AppTitleIconSetter, } -#[cfg(feature = "accesskit")] -struct AccessKitInitHandler { - egui_ctx: egui::Context, -} - -#[cfg(feature = "accesskit")] -impl egui::accesskit::ActivationHandler for AccessKitInitHandler { - fn request_initial_tree(&mut self) -> Option { - // This function is called when an accessibility client - // (e.g. screen reader) makes its first request. If we got here, - // we know that an accessibility tree is actually wanted. - self.egui_ctx.enable_accesskit(); - // Enqueue a repaint so we'll receive a full tree update soon. - self.egui_ctx.request_repaint(); - Some(self.egui_ctx.accesskit_placeholder_tree_update()) - } -} - impl EpiIntegration { #[allow(clippy::too_many_arguments)] pub fn new( @@ -244,19 +226,6 @@ impl EpiIntegration { } } - #[cfg(feature = "accesskit")] - pub fn init_accesskit + Send>( - &self, - egui_winit: &mut egui_winit::State, - window: &winit::window::Window, - event_loop_proxy: winit::event_loop::EventLoopProxy, - ) { - crate::profile_function!(); - - let egui_ctx = self.egui_ctx.clone(); - egui_winit.init_accesskit(window, event_loop_proxy, AccessKitInitHandler { egui_ctx }); - } - /// If `true`, it is time to close the native window. pub fn should_close(&self) -> bool { self.close diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index c5218b19ac5..25589b93b94 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -277,7 +277,7 @@ impl GlowWinitApp { .. } = viewport { - integration.init_accesskit(egui_winit, window, event_loop_proxy); + egui_winit.init_accesskit(window, event_loop_proxy); } } @@ -476,24 +476,18 @@ impl WinitApp for GlowWinitApp { #[cfg(feature = "accesskit")] fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result { - if let accesskit_winit::Event { - window_id, - window_event: accesskit_winit::WindowEvent::ActionRequested(request), - } = event - { - if let Some(running) = &self.running { - let mut glutin = running.glutin.borrow_mut(); - if let Some(viewport_id) = glutin.viewport_from_window.get(&window_id).copied() { - if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) { - if let Some(egui_winit) = &mut viewport.egui_winit { - crate::profile_scope!("on_accesskit_action_request"); - egui_winit.on_accesskit_action_request(request.clone()); - } + if let Some(running) = &self.running { + let mut glutin = running.glutin.borrow_mut(); + if let Some(viewport_id) = glutin.viewport_from_window.get(&event.window_id).copied() { + if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) { + if let Some(egui_winit) = &mut viewport.egui_winit { + return Ok(winit_integration::on_accesskit_window_event( + egui_winit, + event.window_id, + &event.window_event, + )); } } - // As a form of user input, accessibility actions should - // lead to a repaint. - return Ok(EventResult::RepaintNext(window_id)); } } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index f4db8fb71fe..9c3d6be6a90 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -249,7 +249,7 @@ impl WgpuWinitApp { #[cfg(feature = "accesskit")] { let event_loop_proxy = self.repaint_proxy.lock().clone(); - integration.init_accesskit(&mut egui_winit, &window, event_loop_proxy); + egui_winit.init_accesskit(&window, event_loop_proxy); } let theme = system_theme.unwrap_or(self.native_options.default_theme); egui_ctx.set_visuals(theme.egui_visuals()); @@ -473,29 +473,24 @@ impl WinitApp for WgpuWinitApp { #[cfg(feature = "accesskit")] fn on_accesskit_event(&mut self, event: accesskit_winit::Event) -> crate::Result { - if let accesskit_winit::Event { - window_id, - window_event: accesskit_winit::WindowEvent::ActionRequested(request), - } = event - { - if let Some(running) = &mut self.running { - let mut shared_lock = running.shared.borrow_mut(); - let SharedState { - viewport_from_window, - viewports, - .. - } = &mut *shared_lock; - if let Some(viewport) = viewport_from_window - .get(&window_id) - .and_then(|id| viewports.get_mut(id)) - { - if let Some(egui_winit) = &mut viewport.egui_winit { - egui_winit.on_accesskit_action_request(request.clone()); - } + if let Some(running) = &mut self.running { + let mut shared_lock = running.shared.borrow_mut(); + let SharedState { + viewport_from_window, + viewports, + .. + } = &mut *shared_lock; + if let Some(viewport) = viewport_from_window + .get(&event.window_id) + .and_then(|id| viewports.get_mut(id)) + { + if let Some(egui_winit) = &mut viewport.egui_winit { + return Ok(winit_integration::on_accesskit_window_event( + egui_winit, + event.window_id, + &event.window_event, + )); } - // As a form of user input, accessibility actions should - // lead to a repaint. - return Ok(EventResult::RepaintNext(window_id)); } } diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index ff1f0cfe5dc..abd0e717c9e 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -125,3 +125,36 @@ pub fn system_theme(window: &Window, options: &crate::NativeOptions) -> Option EventResult { + match event { + accesskit_winit::WindowEvent::InitialTreeRequested => { + egui_winit.egui_ctx().enable_accesskit(); + // Because we can't provide the initial tree synchronously + // (because that would require the activation handler to access + // the same mutable state as the winit event handler), some + // AccessKit platform adapters will use a placeholder tree + // until we send the first tree update. To minimize the possible + // bad effects of that workaround, repaint and send the tree + // immediately. + EventResult::RepaintNow(window_id) + } + accesskit_winit::WindowEvent::ActionRequested(request) => { + egui_winit.on_accesskit_action_request(request.clone()); + // As a form of user input, accessibility actions should cause + // a repaint, but not until the next regular frame. + EventResult::RepaintNext(window_id) + } + accesskit_winit::WindowEvent::AccessibilityDeactivated => { + egui_winit.egui_ctx().disable_accesskit(); + // Disabling AccessKit support should have no visible effect, + // so there's no need to repaint. + EventResult::Wait + } + } +} diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index d1d65ad4fd7..ec5469e3d3c 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -162,13 +162,11 @@ impl State { &mut self, window: &Window, event_loop_proxy: winit::event_loop::EventLoopProxy, - activation_handler: impl egui::accesskit::ActivationHandler + Send + 'static, ) { crate::profile_function!(); - self.accesskit = Some(accesskit_winit::Adapter::with_mixed_handlers( + self.accesskit = Some(accesskit_winit::Adapter::with_event_loop_proxy( window, - activation_handler, event_loop_proxy, )); } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 9cc55627c77..0ff473ad2f3 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -2915,21 +2915,10 @@ impl Context { self.write(|ctx| ctx.is_accesskit_enabled = true); } - /// Return a tree update that the egui integration should provide to the - /// AccessKit adapter if it cannot immediately run the egui application - /// to get a full tree update after running [`Context::enable_accesskit`]. + /// Disable generation of AccessKit tree updates in all future frames. #[cfg(feature = "accesskit")] - pub fn accesskit_placeholder_tree_update(&self) -> accesskit::TreeUpdate { - crate::profile_function!(); - - use accesskit::{NodeBuilder, Role, Tree, TreeUpdate}; - - let root_id = crate::accesskit_root_id().accesskit_id(); - self.write(|_| TreeUpdate { - nodes: vec![(root_id, NodeBuilder::new(Role::Window).build())], - tree: Some(Tree::new(root_id)), - focus: root_id, - }) + pub fn disable_accesskit(&self) { + self.write(|ctx| ctx.is_accesskit_enabled = false); } } From e6741d23f26875637f98cd91c6e22b7051c2255e Mon Sep 17 00:00:00 2001 From: ArthurBrussee Date: Fri, 19 Jul 2024 00:46:44 +0100 Subject: [PATCH 08/23] Fixup comments Also forgot to mark j-axa co-author ealier Co-authored-by: j-axa --- crates/eframe/src/native/run.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index b6969c4f1e6..9cb90f97336 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -187,7 +187,7 @@ impl ApplicationHandler for WinitAppWrapper { } fn exiting(&mut self, _: &ActiveEventLoop) { - // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), + // On Mac, Cmd-Q we get here and then `run_app_on_demand` doesn't return (despite its name), // so we need to save state now: log::debug!("Received Event::LoopExiting - saving app state…"); self.winit_app.save_and_destroy(); @@ -269,7 +269,7 @@ impl ApplicationHandler for WinitAppWrapper { fn run_and_return(event_loop: &mut EventLoop, winit_app: impl WinitApp) -> Result { use winit::platform::run_on_demand::EventLoopExtRunOnDemand; - log::trace!("Entering the winit event loop (run_on_demand)…"); + log::trace!("Entering the winit event loop (run_app_on_demand)…"); let mut app = WinitAppWrapper::new(winit_app, true); event_loop.run_app_on_demand(&mut app)?; @@ -278,7 +278,7 @@ fn run_and_return(event_loop: &mut EventLoop, winit_app: impl WinitAp } fn run_and_exit(event_loop: EventLoop, winit_app: impl WinitApp + 'static) -> Result { - log::trace!("Entering the winit event loop (run)…"); + log::trace!("Entering the winit event loop (run_app)…"); // When to repaint what window let mut app = WinitAppWrapper::new(winit_app, false); From f37e52b6eb2b24187bbe865347d40fe134383e16 Mon Sep 17 00:00:00 2001 From: DataTriny Date: Fri, 19 Jul 2024 12:28:58 +0200 Subject: [PATCH 09/23] Update to latest accesskit and accesskit_winit --- Cargo.lock | 28 +++++++++---------- crates/egui-winit/Cargo.toml | 2 +- crates/egui/Cargo.toml | 2 +- crates/egui/src/response.rs | 2 +- .../text_selection/label_text_selection.rs | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f8cc295d9b..f3947064601 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac5b518d65f20dc920b3a7bb92bb2b90cdb301416f27c2a55a128cd99f75c0c" +checksum = "e4700bdc115b306d6c43381c344dc307f03b7f0460c304e4892c309930322bd7" dependencies = [ "enumn", "serde", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "accesskit_atspi_common" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d50c9c8c4e3ad243b8a567ddf3595c6eb064304b76baf246bb069700e03a2e" +checksum = "a1de72dc7093910a1284cef784b6b143bab0a34d67f6178e4fc3aaaf29a09f8b" dependencies = [ "accesskit", "accesskit_consumer", @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "accesskit_consumer" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17fa06310c6256253ef3474cb4694346222b4bca85a53aec7f796a73d18e7082" +checksum = "fe3a07a32ab5837ad83db3230ac490c8504c2cd5b90ac8c00db6535f6ed65d0b" dependencies = [ "accesskit", "immutable-chunkmap", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "accesskit_macos" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a3c2a5bb8b5e403502faff2bbb85de5c14bb822a0ba7e9561cb5229b42a176" +checksum = "a189d159c153ae0fce5f9eefdcfec4a27885f453ce5ef0ccf078f72a73c39d34" dependencies = [ "accesskit", "accesskit_consumer", @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b8bfe5d626a7a0ae929df970857b3738198c66dfbf27a8d60d199e29bf2836" +checksum = "b76c448cfd96d16131a9ad3ab786d06951eb341cdac1db908978ab010245a19d" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab7baf1a8adacddc2c5a4f14d1f936f73a0f0e1c6d4592514992c4d4c57743" +checksum = "682d8c4fb425606f97408e7577793f32e96310b646fa77662eb4216293eddc7f" dependencies = [ "accesskit", "accesskit_consumer", @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "accesskit_winit" -version = "0.21.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8201853811d37a43c4753753d89d86802913be12496e5d77c1a418f7f2eaac" +checksum = "9afbd6d598b7c035639ad2b664aa0edc94c93dc1fc3ebb4b40d8a95fcd43ffac" dependencies = [ "accesskit", "accesskit_macos", diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 7c073c14832..d75ab31491c 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -69,7 +69,7 @@ winit = { workspace = true, default-features = false, features = ["rwh_06"] } #! ### Optional dependencies # feature accesskit -accesskit_winit = { version = "0.21.1", optional = true } +accesskit_winit = { version = "0.22", optional = true } ## Enable this when generating docs. document-features = { workspace = true, optional = true } diff --git a/crates/egui/Cargo.toml b/crates/egui/Cargo.toml index 470e2b0e70c..a920df2bf46 100644 --- a/crates/egui/Cargo.toml +++ b/crates/egui/Cargo.toml @@ -86,7 +86,7 @@ ahash.workspace = true nohash-hasher.workspace = true #! ### Optional dependencies -accesskit = { version = "0.15", optional = true } +accesskit = { version = "0.16", optional = true } backtrace = { workspace = true, optional = true } diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index 0b976c63cdc..cb2ef5467f1 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -968,7 +968,7 @@ impl Response { self.fill_accesskit_node_common(builder); builder.set_role(match info.typ { - WidgetType::Label => Role::StaticText, + WidgetType::Label => Role::Label, WidgetType::Link => Role::Link, WidgetType::TextEdit => Role::TextInput, WidgetType::Button | WidgetType::ImageButton | WidgetType::CollapsingHeader => { diff --git a/crates/egui/src/text_selection/label_text_selection.rs b/crates/egui/src/text_selection/label_text_selection.rs index 7988820d6af..f0660de0459 100644 --- a/crates/egui/src/text_selection/label_text_selection.rs +++ b/crates/egui/src/text_selection/label_text_selection.rs @@ -38,7 +38,7 @@ fn paint_selection( ui.ctx(), _response.id, cursor_range, - accesskit::Role::StaticText, + accesskit::Role::Label, galley_pos, galley, ); From cd894eb51d4fde9c5bd07c1f990c564a6c369b9c Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 19 Jul 2024 12:40:56 +0100 Subject: [PATCH 10/23] Fixes for linux Tested on WSL wayland. Required an annoying workaround for nix/fs :/ --- Cargo.lock | 1 + crates/egui-winit/Cargo.toml | 6 +++++- crates/egui-winit/src/lib.rs | 30 +++++++++++++++--------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3947064601..46e8e9070a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1247,6 +1247,7 @@ dependencies = [ "document-features", "egui", "log", + "nix", "puffin", "raw-window-handle 0.6.0", "serde", diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index d75ab31491c..406a961b879 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -52,7 +52,7 @@ puffin = ["dep:puffin", "egui/puffin"] serde = ["egui/serde", "dep:serde"] ## Enables Wayland support. -wayland = ["winit/wayland", "bytemuck"] +wayland = ["winit/wayland", "bytemuck", "nix/fs"] ## Enables compiling for x11. x11 = ["winit/x11", "bytemuck"] @@ -62,6 +62,10 @@ egui = { workspace = true, default-features = false, features = ["log"] } ahash.workspace = true log.workspace = true + +# wayland-cursor shoud enable the fs feature as it otherwise doesn't compile. +# Instead do this manually for now. +nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true web-time.workspace = true winit = { workspace = true, default-features = false, features = ["rwh_06"] } diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index ec5469e3d3c..3963cc9629b 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -1660,22 +1660,22 @@ pub fn create_winit_window_atrributes( { if let Some(window_type) = _window_type { use winit::platform::x11::WindowAttributesExtX11 as _; - use winit::platform::x11::XWindowType; + use winit::platform::x11::WindowType; window_attributes = window_attributes.with_x11_window_type(vec![match window_type { - egui::X11WindowType::Normal => XWindowType::Normal, - egui::X11WindowType::Utility => XWindowType::Utility, - egui::X11WindowType::Dock => XWindowType::Dock, - egui::X11WindowType::Desktop => XWindowType::Desktop, - egui::X11WindowType::Toolbar => XWindowType::Toolbar, - egui::X11WindowType::Menu => XWindowType::Menu, - egui::X11WindowType::Splash => XWindowType::Splash, - egui::X11WindowType::Dialog => XWindowType::Dialog, - egui::X11WindowType::DropdownMenu => XWindowType::DropdownMenu, - egui::X11WindowType::PopupMenu => XWindowType::PopupMenu, - egui::X11WindowType::Tooltip => XWindowType::Tooltip, - egui::X11WindowType::Notification => XWindowType::Notification, - egui::X11WindowType::Combo => XWindowType::Combo, - egui::X11WindowType::Dnd => XWindowType::Dnd, + egui::X11WindowType::Normal => WindowType::Normal, + egui::X11WindowType::Utility => WindowType::Utility, + egui::X11WindowType::Dock => WindowType::Dock, + egui::X11WindowType::Desktop => WindowType::Desktop, + egui::X11WindowType::Toolbar => WindowType::Toolbar, + egui::X11WindowType::Menu => WindowType::Menu, + egui::X11WindowType::Splash => WindowType::Splash, + egui::X11WindowType::Dialog => WindowType::Dialog, + egui::X11WindowType::DropdownMenu => WindowType::DropdownMenu, + egui::X11WindowType::PopupMenu => WindowType::PopupMenu, + egui::X11WindowType::Tooltip => WindowType::Tooltip, + egui::X11WindowType::Notification => WindowType::Notification, + egui::X11WindowType::Combo => WindowType::Combo, + egui::X11WindowType::Dnd => WindowType::Dnd, }]); } } From 5e0f4791c835d824e44fababe4a0940999f7f684 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 19 Jul 2024 17:56:39 +0100 Subject: [PATCH 11/23] CI fixes --- Cargo.lock | 19 ++++--------------- Cargo.toml | 4 ++-- crates/eframe/src/native/glow_integration.rs | 9 ++++++--- crates/eframe/src/native/winit_integration.rs | 2 ++ crates/egui-winit/Cargo.toml | 2 +- crates/egui-winit/src/lib.rs | 4 ++-- crates/egui/src/context.rs | 8 -------- crates/egui_glow/examples/pure_glow.rs | 1 + deny.toml | 8 ++++---- 9 files changed, 22 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f956c211e52..1bd3efb32ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1211,7 +1211,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "web-time 0.2.0", + "web-time", "wgpu", "winapi", "winit", @@ -1247,7 +1247,7 @@ dependencies = [ "puffin", "thiserror", "type-map", - "web-time 0.2.0", + "web-time", "wgpu", "winit", ] @@ -1267,7 +1267,7 @@ dependencies = [ "raw-window-handle 0.6.0", "serde", "smithay-clipboard", - "web-time 0.2.0", + "web-time", "webbrowser", "winit", ] @@ -4286,17 +4286,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web-time" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19353897b48e2c4d849a2d73cb0aeb16dc2be4e00c565abfc11eb65a806e47de" -dependencies = [ - "js-sys", - "once_cell", - "wasm-bindgen", -] - [[package]] name = "web-time" version = "1.1.0" @@ -4796,7 +4785,7 @@ dependencies = [ "wayland-protocols", "wayland-protocols-plasma", "web-sys", - "web-time 1.1.0", + "web-time", "windows-sys 0.52.0", "x11-dl", "x11rb", diff --git a/Cargo.toml b/Cargo.toml index e3fcfb714f4..f2ede437365 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,7 +85,7 @@ ron = "0.8" raw-window-handle = "0.6.0" serde = { version = "1", features = ["derive"] } thiserror = "1.0.37" -web-time = "0.2" # Timekeeping for native and web +web-time = "1.1.0" # Timekeeping for native and web wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = "0.3.58" @@ -94,7 +94,7 @@ wgpu = { version = "22.0.0", default-features = false, features = [ "fragile-send-sync-non-atomic-wasm", ] } -# Version 0.30.1 and up unfortunately crash on macOS, due to https://github.com/rust-windowing/winit/pull/3684 +# Version 0.30.1 and up unfortunately crash on macOS, see https://github.com/rust-windowing/winit/issues/3800 winit = { version = "=0.30.0", default-features = false } [workspace.lints.rust] diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 25589b93b94..1d4c50a4c54 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -944,7 +944,7 @@ impl GlutinWindowContext { let display_builder = glutin_winit::DisplayBuilder::new() // we might want to expose this option to users in the future. maybe using an env var or using native_options. .with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150 - .with_window_attributes(Some(egui_winit::create_winit_window_atrributes( + .with_window_attributes(Some(egui_winit::create_winit_window_attributes( egui_ctx, event_loop, viewport_builder.clone(), @@ -1098,7 +1098,7 @@ impl GlutinWindowContext { window } else { log::debug!("Creating a window for viewport {viewport_id:?}"); - let window_attributes = egui_winit::create_winit_window_atrributes( + let window_attributes = egui_winit::create_winit_window_attributes( &self.egui_ctx, event_loop, viewport.builder.clone(), @@ -1141,7 +1141,10 @@ impl GlutinWindowContext { let surface_attributes = { glutin::surface::SurfaceAttributesBuilder::::new() .build( - window.window_handle().expect("TODO TDO").as_raw(), + window + .window_handle() + .expect("Failed to get display handle") + .as_raw(), width_px, height_px, ) diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index abd0e717c9e..1489b0bf40d 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -75,7 +75,9 @@ pub trait WinitApp { ) -> crate::Result; fn suspended(&mut self, event_loop: &ActiveEventLoop) -> crate::Result; + fn resumed(&mut self, event_loop: &ActiveEventLoop) -> crate::Result; + fn device_event( &mut self, event_loop: &ActiveEventLoop, diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 406a961b879..8f418547a77 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -63,7 +63,7 @@ egui = { workspace = true, default-features = false, features = ["log"] } ahash.workspace = true log.workspace = true -# wayland-cursor shoud enable the fs feature as it otherwise doesn't compile. +# wayland-cursor should enable the fs feature as it otherwise doesn't compile. # Instead do this manually for now. nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 3963cc9629b..e2565794ae3 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -1518,13 +1518,13 @@ pub fn create_window( crate::profile_function!(); let window_attributes = - create_winit_window_atrributes(egui_ctx, event_loop, viewport_builder.clone()); + create_winit_window_attributes(egui_ctx, event_loop, viewport_builder.clone()); let window = event_loop.create_window(window_attributes)?; apply_viewport_builder_to_window(egui_ctx, &window, viewport_builder); Ok(window) } -pub fn create_winit_window_atrributes( +pub fn create_winit_window_attributes( egui_ctx: &egui::Context, event_loop: &ActiveEventLoop, viewport_builder: ViewportBuilder, diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 0ff473ad2f3..cbb137df77f 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -2902,14 +2902,6 @@ impl Context { } /// Enable generation of AccessKit tree updates in all future frames. - /// - /// If it's practical for the egui integration to immediately run the egui - /// application when it is either initializing the AccessKit adapter or - /// being called by the AccessKit adapter to provide the initial tree update, - /// then it should do so, to provide a complete AccessKit tree to the adapter - /// immediately. Otherwise, it should enqueue a repaint and use the - /// placeholder tree update from [`Context::accesskit_placeholder_tree_update`] - /// in the meantime. #[cfg(feature = "accesskit")] pub fn enable_accesskit(&self) { self.write(|ctx| ctx.is_accesskit_enabled = true); diff --git a/crates/egui_glow/examples/pure_glow.rs b/crates/egui_glow/examples/pure_glow.rs index 95658157ab2..4145e1d6310 100644 --- a/crates/egui_glow/examples/pure_glow.rs +++ b/crates/egui_glow/examples/pure_glow.rs @@ -297,6 +297,7 @@ impl winit::application::ApplicationHandler for GlowApp { self.gl_window.as_mut().unwrap().window().request_redraw(); } } + fn user_event(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop, event: UserEvent) { match event { UserEvent::Redraw(delay) => self.repaint_delay = delay, diff --git a/deny.toml b/deny.toml index 9c8704bcd2d..93973f8e7f4 100644 --- a/deny.toml +++ b/deny.toml @@ -46,19 +46,19 @@ deny = [ ] skip = [ + { name = "async-channel" }, # accesskit pulls in two versions of this 😭 { name = "bit-set" }, # wgpu's naga depends on 0.6, syntect's (used by egui_extras) fancy-regex depends on 0.5 { name = "bit-vec" }, # dependency of bit-set in turn, different between 0.6 and 0.5 { name = "bitflags" }, # old 1.0 version via glutin, png, spirv, … - { name = "block2" }, # old version via glutin->icrate + { name = "cfg_aliases" }, # old version via wgpu + { name = "ndk-sys" }, # old version via wgpu, winit uses newer version { name = "event-listener" }, # TODO(emilk): rustls pulls in two versions of this 😭 - { name = "glutin_wgl_sys" }, # 0.6.0 used by wgpu-hal, 0.5.0 used by glutin which can't be updated until we update to winit 0.30 { name = "memoffset" }, # tiny dependency { name = "quick-xml" }, # old version via wayland-scanner { name = "redox_syscall" }, # old version via winit { name = "time" }, # old version pulled in by unmaintianed crate 'chrono' + { name = "windows-core" }, # old version via accesskit_windows { name = "windows" }, # old version via accesskit_windows - { name = "x11rb-protocol" }, # old version via arboard - { name = "x11rb" }, # old version via arboard ] skip-tree = [ { name = "criterion" }, # dev-dependency From 67c456bb3f40332511a3e74d6fbf5e17d88d1886 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 19 Jul 2024 19:43:53 +0100 Subject: [PATCH 12/23] Add a comment about wayland-cursor. --- crates/egui-winit/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 8f418547a77..63339e164d9 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -64,7 +64,9 @@ ahash.workspace = true log.workspace = true # wayland-cursor should enable the fs feature as it otherwise doesn't compile. -# Instead do this manually for now. +# This is fixed upstream post https://github.com/Smithay/wayland-rs/commit/edd0f60d0baf09604553525c2636df5d6ba05d44 or v0.31.1 +# so should be removed when winit upgrades past that version. +# Enable this feature manually for now. nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true web-time.workspace = true From 6d582f57f5d1522277fc27eae786b7f7cbc0567f Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 26 Jul 2024 01:45:31 +0100 Subject: [PATCH 13/23] Fix crash when using winit 0.30.4 --- Cargo.lock | 165 ++++++++++++++---- Cargo.toml | 2 +- .../eframe/src/native/event_loop_context.rs | 54 ++++++ crates/eframe/src/native/glow_integration.rs | 19 +- crates/eframe/src/native/mod.rs | 1 + crates/eframe/src/native/run.rs | 103 ++++++----- crates/eframe/src/native/wgpu_integration.rs | 14 +- crates/egui-wgpu/Cargo.toml | 4 +- crates/egui-winit/Cargo.toml | 4 +- crates/egui/src/context.rs | 68 ++++---- crates/egui_glow/Cargo.toml | 6 +- 11 files changed, 306 insertions(+), 134 deletions(-) create mode 100644 crates/eframe/src/native/event_loop_context.rs diff --git a/Cargo.lock b/Cargo.lock index 1bd3efb32ba..5f4a7723ecc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,7 +107,7 @@ dependencies = [ "accesskit_macos", "accesskit_unix", "accesskit_windows", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "winit", ] @@ -646,9 +646,9 @@ dependencies = [ [[package]] name = "calloop" -version = "0.12.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50b5a44d59a98c55a9eeb518f39bf7499ba19fd98ee7d22618687f3f10adbf" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ "bitflags 2.6.0", "log", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "calloop-wayland-source" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", "rustix 0.38.21", @@ -1204,7 +1204,7 @@ dependencies = [ "percent-encoding", "pollster", "puffin", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "ron", "serde", "static_assertions", @@ -1264,7 +1264,7 @@ dependencies = [ "log", "nix", "puffin", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "serde", "smithay-clipboard", "web-time", @@ -1846,7 +1846,7 @@ dependencies = [ "objc2-app-kit", "objc2-foundation", "once_cell", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "wayland-sys", "windows-sys 0.52.0", "x11-dl", @@ -1860,7 +1860,7 @@ checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" dependencies = [ "cfg_aliases 0.2.1", "glutin", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "winit", ] @@ -2488,7 +2488,7 @@ dependencies = [ "log", "ndk-sys 0.6.0+11769913", "num_enum", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "thiserror", ] @@ -2626,6 +2626,30 @@ dependencies = [ "objc2-quartz-core", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-data" version = "0.2.2" @@ -2650,6 +2674,18 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + [[package]] name = "objc2-encode" version = "4.0.3" @@ -2669,6 +2705,18 @@ dependencies = [ "objc2", ] +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + [[package]] name = "objc2-metal" version = "0.2.2" @@ -2694,6 +2742,61 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "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", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "objc_id" version = "0.1.1" @@ -3094,9 +3197,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "raw-window-handle" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" @@ -3385,9 +3488,9 @@ dependencies = [ [[package]] name = "sctk-adwaita" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7555fcb4f753d095d734fdefebb0ad8c98478a21db500492d87c55913d3b0086" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", @@ -3522,9 +3625,9 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay-client-toolkit" -version = "0.18.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ "bitflags 2.6.0", "calloop", @@ -3547,9 +3650,9 @@ dependencies = [ [[package]] name = "smithay-clipboard" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ "libc", "smithay-client-toolkit", @@ -4217,9 +4320,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.31.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e253d7107ba913923dc253967f35e8561a3c65f914543e46843c88ddd729e21c" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4229,9 +4332,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4242,9 +4345,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4339,7 +4442,7 @@ dependencies = [ "naga", "parking_lot", "profiling", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "smallvec", "static_assertions", "wasm-bindgen", @@ -4367,7 +4470,7 @@ dependencies = [ "once_cell", "parking_lot", "profiling", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "rustc-hash", "smallvec", "thiserror", @@ -4406,7 +4509,7 @@ dependencies = [ "once_cell", "parking_lot", "profiling", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "renderdoc-sys", "rustc-hash", "smallvec", @@ -4744,14 +4847,15 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winit" -version = "0.30.0" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e6d5d66cbf702e0dd820302144f51b69a95acdc495dd98ca280ff206562b1" +checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.6.0", + "block2", "bytemuck", "calloop", "cfg_aliases 0.2.1", @@ -4767,10 +4871,11 @@ dependencies = [ "objc2", "objc2-app-kit", "objc2-foundation", + "objc2-ui-kit", "orbclient", "percent-encoding", "pin-project", - "raw-window-handle 0.6.0", + "raw-window-handle 0.6.2", "redox_syscall 0.4.1", "rustix 0.38.21", "sctk-adwaita", diff --git a/Cargo.toml b/Cargo.toml index f2ede437365..bfdaf70dc0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,7 +95,7 @@ wgpu = { version = "22.0.0", default-features = false, features = [ ] } # Version 0.30.1 and up unfortunately crash on macOS, see https://github.com/rust-windowing/winit/issues/3800 -winit = { version = "=0.30.0", default-features = false } +winit = { version = "0.30.4", default-features = false } [workspace.lints.rust] unsafe_code = "deny" diff --git a/crates/eframe/src/native/event_loop_context.rs b/crates/eframe/src/native/event_loop_context.rs new file mode 100644 index 00000000000..2bb9e42555a --- /dev/null +++ b/crates/eframe/src/native/event_loop_context.rs @@ -0,0 +1,54 @@ +use std::cell::Cell; +use winit::event_loop::ActiveEventLoop; + +thread_local! { + static CURRENT_EVENT_LOOP: Cell> = Cell::new(None); +} + +struct EventLoopGuard; + +impl EventLoopGuard { + fn new(event_loop: &ActiveEventLoop) -> Self { + CURRENT_EVENT_LOOP.with(|cell| { + assert!( + cell.get().is_none(), + "Attempted to set a new event loop while one is already set" + ); + cell.set(Some(event_loop as *const ActiveEventLoop)); + }); + Self + } +} + +impl Drop for EventLoopGuard { + fn drop(&mut self) { + CURRENT_EVENT_LOOP.with(|cell| cell.set(None)); + } +} + +// Helper function to safely use the current event loop +#[allow(unsafe_code)] +pub fn with_current_event_loop(f: F) -> Option +where + F: FnOnce(&ActiveEventLoop) -> R, +{ + CURRENT_EVENT_LOOP.with(|cell| { + cell.get().map(|ptr| { + // SAFETY: + // 1. The pointer is guaranteed to be valid when it's Some, as the EventLoopGuard that created it + // lives at least as long as the reference, and clears it when it's dropped. Only run_with_event_loop creates + // a new EventLoopGuard, and does not leak it. + // 2. Since the pointer was created from a borrow which lives at least as long as this pointer there are + // no mutable references to the ActiveEventLoop. + let event_loop = unsafe { &*ptr }; + f(event_loop) + }) + }) +} + +// The only public interface to use the event loop +pub fn with_event_loop_context(event_loop: &ActiveEventLoop, f: impl FnOnce()) { + // NOTE: For safety, this guard must NOT be leaked. + let _guard = EventLoopGuard::new(event_loop); + f(); +} diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 1d4c50a4c54..13c3a8e98bd 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -328,17 +328,9 @@ impl GlowWinitApp { let painter = Rc::downgrade(&painter); let beginning = integration.beginning; - let event_loop: *const ActiveEventLoop = event_loop; - egui::Context::set_immediate_viewport_renderer(move |egui_ctx, immediate_viewport| { if let (Some(glutin), Some(painter)) = (glutin.upgrade(), painter.upgrade()) { - // SAFETY: the event loop lives longer than - // the Rc:s we just upgraded above. - #[allow(unsafe_code)] - let event_loop = unsafe { event_loop.as_ref().unwrap() }; - render_immediate_viewport( - event_loop, egui_ctx, &glutin, &painter, @@ -1384,7 +1376,6 @@ fn initialize_or_update_viewport( /// This is called (via a callback) by user code to render immediate viewports, /// i.e. viewport that are directly nested inside a parent viewport. fn render_immediate_viewport( - event_loop: &ActiveEventLoop, egui_ctx: &egui::Context, glutin: &RefCell, painter: &RefCell, @@ -1412,7 +1403,11 @@ fn render_immediate_viewport( None, ); - if let Err(err) = glutin.initialize_window(viewport_id, event_loop) { + let event_ret = event_loop_context::with_current_event_loop(|event_loop| { + glutin.initialize_window(viewport_id, event_loop) + }); + + if let Some(Err(err)) = ret { log::error!( "Failed to initialize a window for immediate viewport {viewport_id:?}: {err}" ); @@ -1518,7 +1513,9 @@ fn render_immediate_viewport( egui_winit.handle_platform_output(window, platform_output); - glutin.handle_viewport_output(event_loop, egui_ctx, &viewport_output); + event_loop_context::with_current_event_loop(|event_loop| { + glutin.handle_viewport_output(event_loop, egui_ctx, &viewport_output); + }); } #[cfg(feature = "__screenshot")] diff --git a/crates/eframe/src/native/mod.rs b/crates/eframe/src/native/mod.rs index 5fadd561014..cc0bfd7fc56 100644 --- a/crates/eframe/src/native/mod.rs +++ b/crates/eframe/src/native/mod.rs @@ -1,5 +1,6 @@ mod app_icon; mod epi_integration; +mod event_loop_context; pub mod run; /// File storage which can be used by native backends. diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 9cb90f97336..32e247d94b8 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -9,7 +9,11 @@ use winit::{ use ahash::HashMap; use super::winit_integration::{UserEvent, WinitApp}; -use crate::{epi, native::winit_integration::EventResult, Result}; +use crate::{ + epi, + native::{event_loop_context, winit_integration::EventResult}, + Result, +}; // ---------------------------------------------------------------------------- fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result> { @@ -176,21 +180,30 @@ impl WinitAppWrapper { impl ApplicationHandler for WinitAppWrapper { fn suspended(&mut self, event_loop: &ActiveEventLoop) { crate::profile_function!("Event::Suspended"); - let event_result = self.winit_app.suspended(event_loop); - self.handle_event_result(event_loop, event_result); + + event_loop_context::with_event_loop_context(event_loop, move || { + let event_result = self.winit_app.suspended(event_loop); + self.handle_event_result(event_loop, event_result); + }); } fn resumed(&mut self, event_loop: &ActiveEventLoop) { crate::profile_function!("Event::Resumed"); - let event_result = self.winit_app.resumed(event_loop); - self.handle_event_result(event_loop, event_result); + + // Nb: Make sure this guard is dropped after this function returns. + event_loop_context::with_event_loop_context(event_loop, move || { + let event_result = self.winit_app.resumed(event_loop); + self.handle_event_result(event_loop, event_result); + }); } - fn exiting(&mut self, _: &ActiveEventLoop) { + fn exiting(&mut self, event_loop: &ActiveEventLoop) { // On Mac, Cmd-Q we get here and then `run_app_on_demand` doesn't return (despite its name), // so we need to save state now: log::debug!("Received Event::LoopExiting - saving app state…"); - self.winit_app.save_and_destroy(); + event_loop_context::with_event_loop_context(event_loop, move || { + self.winit_app.save_and_destroy(); + }); } fn device_event( @@ -200,8 +213,12 @@ impl ApplicationHandler for WinitAppWrapper { event: winit::event::DeviceEvent, ) { crate::profile_function!(egui_winit::short_device_event_description(&event)); - let event_result = self.winit_app.device_event(event_loop, device_id, event); - self.handle_event_result(event_loop, event_result); + + // Nb: Make sure this guard is dropped after this function returns. + event_loop_context::with_event_loop_context(event_loop, move || { + let event_result = self.winit_app.device_event(event_loop, device_id, event); + self.handle_event_result(event_loop, event_result); + }); } fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) { @@ -211,32 +228,35 @@ impl ApplicationHandler for WinitAppWrapper { UserEvent::AccessKitActionRequest(_) => "UserEvent::AccessKitActionRequest", }); - let event_result = match event { - UserEvent::RequestRepaint { - when, - frame_nr, - viewport_id, - } => { - let current_frame_nr = self.winit_app.frame_nr(viewport_id); - if current_frame_nr == frame_nr || current_frame_nr == frame_nr + 1 { - log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); - if let Some(window_id) = self.winit_app.window_id_from_viewport_id(viewport_id) - { - Ok(EventResult::RepaintAt(window_id, when)) + event_loop_context::with_event_loop_context(event_loop, move || { + let event_result = match event { + UserEvent::RequestRepaint { + when, + frame_nr, + viewport_id, + } => { + let current_frame_nr = self.winit_app.frame_nr(viewport_id); + if current_frame_nr == frame_nr || current_frame_nr == frame_nr + 1 { + log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}"); + if let Some(window_id) = + self.winit_app.window_id_from_viewport_id(viewport_id) + { + Ok(EventResult::RepaintAt(window_id, when)) + } else { + Ok(EventResult::Wait) + } } else { - Ok(EventResult::Wait) + log::trace!("Got outdated UserEvent::RequestRepaint"); + Ok(EventResult::Wait) // old request - we've already repainted } - } else { - log::trace!("Got outdated UserEvent::RequestRepaint"); - Ok(EventResult::Wait) // old request - we've already repainted } - } - #[cfg(feature = "accesskit")] - UserEvent::AccessKitActionRequest(request) => { - self.winit_app.on_accesskit_event(request) - } - }; - self.handle_event_result(event_loop, event_result); + #[cfg(feature = "accesskit")] + UserEvent::AccessKitActionRequest(request) => { + self.winit_app.on_accesskit_event(request) + } + }; + self.handle_event_result(event_loop, event_result); + }); } fn new_events(&mut self, _: &ActiveEventLoop, cause: winit::event::StartCause) { @@ -253,15 +273,18 @@ impl ApplicationHandler for WinitAppWrapper { ) { crate::profile_function!(egui_winit::short_window_event_description(&event)); - let event_result = match event { - winit::event::WindowEvent::RedrawRequested => { - self.windows_next_repaint_times.remove(&window_id); - self.winit_app.run_ui_and_paint(event_loop, window_id) - } - _ => self.winit_app.window_event(event_loop, window_id, event), - }; + // Nb: Make sure this guard is dropped after this function returns. + event_loop_context::with_event_loop_context(event_loop, move || { + let event_result = match event { + winit::event::WindowEvent::RedrawRequested => { + self.windows_next_repaint_times.remove(&window_id); + self.winit_app.run_ui_and_paint(event_loop, window_id) + } + _ => self.winit_app.window_event(event_loop, window_id, event), + }; - self.handle_event_result(event_loop, event_result); + self.handle_event_result(event_loop, event_result); + }); } } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index 9c3d6be6a90..74f4e957c70 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -308,16 +308,9 @@ impl WgpuWinitApp { let shared = Rc::downgrade(&shared); let beginning = integration.beginning; - let event_loop: *const ActiveEventLoop = event_loop; - egui::Context::set_immediate_viewport_renderer(move |_egui_ctx, immediate_viewport| { if let Some(shared) = shared.upgrade() { - // SAFETY: the event loop lives longer than - // the Rc:s we just upgraded above. - #[allow(unsafe_code)] - let event_loop = unsafe { event_loop.as_ref().unwrap() }; - - render_immediate_viewport(event_loop, beginning, &shared, immediate_viewport); + render_immediate_viewport(beginning, &shared, immediate_viewport); } else { log::warn!("render_sync_callback called after window closed"); } @@ -915,7 +908,6 @@ fn create_window( } fn render_immediate_viewport( - event_loop: &ActiveEventLoop, beginning: Instant, shared: &RefCell, immediate_viewport: ImmediateViewport<'_>, @@ -940,7 +932,9 @@ fn render_immediate_viewport( let viewport = initialize_or_update_viewport(viewports, ids, ViewportClass::Immediate, builder, None); if viewport.window.is_none() { - viewport.initialize_window(event_loop, egui_ctx, viewport_from_window, painter); + event_loop_context::with_current_event_loop(|event_loop| { + viewport.initialize_window(event_loop, egui_ctx, viewport_from_window, painter); + }); } let (Some(window), Some(egui_winit)) = (&viewport.window, &mut viewport.egui_winit) else { diff --git a/crates/egui-wgpu/Cargo.toml b/crates/egui-wgpu/Cargo.toml index 3eaac2e92f5..647016e302b 100644 --- a/crates/egui-wgpu/Cargo.toml +++ b/crates/egui-wgpu/Cargo.toml @@ -61,9 +61,7 @@ wgpu = { workspace = true, features = ["wgsl"] } # Optional dependencies: -winit = { workspace = true, optional = true, default-features = false, features = [ - "rwh_06", -] } +winit = { workspace = true, optional = true, default-features = false } # Native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 63339e164d9..23c3e8a2504 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -70,7 +70,7 @@ log.workspace = true nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true web-time.workspace = true -winit = { workspace = true, default-features = false, features = ["rwh_06"] } +winit = { workspace = true, default-features = false } #! ### Optional dependencies @@ -85,7 +85,7 @@ serde = { workspace = true, optional = true } webbrowser = { version = "1.0.0", optional = true } [target.'cfg(any(target_os="linux", target_os="dragonfly", target_os="freebsd", target_os="netbsd", target_os="openbsd"))'.dependencies] -smithay-clipboard = { version = "0.7.0", optional = true } +smithay-clipboard = { version = "0.7.2", optional = true } [target.'cfg(not(target_os = "android"))'.dependencies] arboard = { version = "3.3", optional = true, default-features = false } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index cbb137df77f..86959646140 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -3314,46 +3314,48 @@ impl Context { return viewport_ui_cb(self, ViewportClass::Embedded); } - IMMEDIATE_VIEWPORT_RENDERER.with(|immediate_viewport_renderer| { - let immediate_viewport_renderer = immediate_viewport_renderer.borrow(); - let Some(immediate_viewport_renderer) = immediate_viewport_renderer.as_ref() else { - // This egui backend does not support multiple viewports. - return viewport_ui_cb(self, ViewportClass::Embedded); - }; + self.0 + .IMMEDIATE_VIEWPORT_RENDERER + .with(|immediate_viewport_renderer| { + let immediate_viewport_renderer = immediate_viewport_renderer.borrow(); + let Some(immediate_viewport_renderer) = immediate_viewport_renderer.as_ref() else { + // This egui backend does not support multiple viewports. + return viewport_ui_cb(self, ViewportClass::Embedded); + }; - let ids = self.write(|ctx| { - let parent_viewport_id = ctx.viewport_id(); + let ids = self.write(|ctx| { + let parent_viewport_id = ctx.viewport_id(); - ctx.viewport_parents - .insert(new_viewport_id, parent_viewport_id); + ctx.viewport_parents + .insert(new_viewport_id, parent_viewport_id); - let viewport = ctx.viewports.entry(new_viewport_id).or_default(); - viewport.builder = builder.clone(); - viewport.used = true; - viewport.viewport_ui_cb = None; // it is immediate + let viewport = ctx.viewports.entry(new_viewport_id).or_default(); + viewport.builder = builder.clone(); + viewport.used = true; + viewport.viewport_ui_cb = None; // it is immediate - ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id) - }); + ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id) + }); - let mut out = None; - { - let out = &mut out; - - let viewport = ImmediateViewport { - ids, - builder, - viewport_ui_cb: Box::new(move |context| { - *out = Some(viewport_ui_cb(context, ViewportClass::Immediate)); - }), - }; + let mut out = None; + { + let out = &mut out; - immediate_viewport_renderer(self, viewport); - } + let viewport = ImmediateViewport { + ids, + builder, + viewport_ui_cb: Box::new(move |context| { + *out = Some(viewport_ui_cb(context, ViewportClass::Immediate)); + }), + }; - out.expect( - "egui backend is implemented incorrectly - the user callback was never called", - ) - }) + immediate_viewport_renderer(self, viewport); + } + + out.expect( + "egui backend is implemented incorrectly - the user callback was never called", + ) + }) } } diff --git a/crates/egui_glow/Cargo.toml b/crates/egui_glow/Cargo.toml index 567c348a166..615247fb07e 100644 --- a/crates/egui_glow/Cargo.toml +++ b/crates/egui_glow/Cargo.toml @@ -69,9 +69,7 @@ document-features = { workspace = true, optional = true } # Native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] puffin = { workspace = true, optional = true } -winit = { workspace = true, optional = true, default-features = false, features = [ - "rwh_06", # for compatibility with egui-winit -] } +winit = { workspace = true, optional = true, default-features = false } # Web: [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -85,4 +83,4 @@ glutin-winit.workspace = true [[example]] name = "pure_glow" -required-features = ["winit", "egui/default_fonts", "winit/rwh_06"] +required-features = ["winit", "egui/default_fonts"] From 2f4dbaf115eb2ff7f3880eb2119aa4d3e3115ebe Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 26 Jul 2024 01:47:45 +0100 Subject: [PATCH 14/23] Enable nix/fs feature workaround in x11 too --- crates/egui-winit/Cargo.toml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 23c3e8a2504..8e5c88c313e 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -51,11 +51,16 @@ puffin = ["dep:puffin", "egui/puffin"] ## Allow serialization of [`WindowSettings`] using [`serde`](https://docs.rs/serde). serde = ["egui/serde", "dep:serde"] +# wayland-cursor should enable the fs feature as it otherwise doesn't compile. +# This is fixed upstream post https://github.com/Smithay/wayland-rs/commit/edd0f60d0baf09604553525c2636df5d6ba05d44 or v0.31.1 +# so should be removed when winit upgrades past that version. +# Enable this feature manually for now (needed in both wayand and x11 backends). + ## Enables Wayland support. wayland = ["winit/wayland", "bytemuck", "nix/fs"] ## Enables compiling for x11. -x11 = ["winit/x11", "bytemuck"] +x11 = ["winit/x11", "bytemuck", "nix/fs"] [dependencies] egui = { workspace = true, default-features = false, features = ["log"] } @@ -63,10 +68,7 @@ egui = { workspace = true, default-features = false, features = ["log"] } ahash.workspace = true log.workspace = true -# wayland-cursor should enable the fs feature as it otherwise doesn't compile. -# This is fixed upstream post https://github.com/Smithay/wayland-rs/commit/edd0f60d0baf09604553525c2636df5d6ba05d44 or v0.31.1 -# so should be removed when winit upgrades past that version. -# Enable this feature manually for now. + nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true web-time.workspace = true From af1c89230c2eed9f8d47697510dd1b6469219552 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Fri, 26 Jul 2024 10:50:28 +0100 Subject: [PATCH 15/23] Remove leftover comment --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bfdaf70dc0c..505de564bb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,6 @@ wgpu = { version = "22.0.0", default-features = false, features = [ "fragile-send-sync-non-atomic-wasm", ] } -# Version 0.30.1 and up unfortunately crash on macOS, see https://github.com/rust-windowing/winit/issues/3800 winit = { version = "0.30.4", default-features = false } [workspace.lints.rust] From c10e3fbe39550ce0519b92ef0081f934dea1c737 Mon Sep 17 00:00:00 2001 From: ArthurBrussee Date: Fri, 26 Jul 2024 21:37:53 +0100 Subject: [PATCH 16/23] Managed to leave in some typos... --- crates/eframe/src/native/glow_integration.rs | 2 +- crates/egui/src/context.rs | 68 ++++++++++---------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 13c3a8e98bd..6e45ee75aad 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -1403,7 +1403,7 @@ fn render_immediate_viewport( None, ); - let event_ret = event_loop_context::with_current_event_loop(|event_loop| { + let ret = event_loop_context::with_current_event_loop(|event_loop| { glutin.initialize_window(viewport_id, event_loop) }); diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 86959646140..cbb137df77f 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -3314,48 +3314,46 @@ impl Context { return viewport_ui_cb(self, ViewportClass::Embedded); } - self.0 - .IMMEDIATE_VIEWPORT_RENDERER - .with(|immediate_viewport_renderer| { - let immediate_viewport_renderer = immediate_viewport_renderer.borrow(); - let Some(immediate_viewport_renderer) = immediate_viewport_renderer.as_ref() else { - // This egui backend does not support multiple viewports. - return viewport_ui_cb(self, ViewportClass::Embedded); - }; - - let ids = self.write(|ctx| { - let parent_viewport_id = ctx.viewport_id(); + IMMEDIATE_VIEWPORT_RENDERER.with(|immediate_viewport_renderer| { + let immediate_viewport_renderer = immediate_viewport_renderer.borrow(); + let Some(immediate_viewport_renderer) = immediate_viewport_renderer.as_ref() else { + // This egui backend does not support multiple viewports. + return viewport_ui_cb(self, ViewportClass::Embedded); + }; - ctx.viewport_parents - .insert(new_viewport_id, parent_viewport_id); + let ids = self.write(|ctx| { + let parent_viewport_id = ctx.viewport_id(); - let viewport = ctx.viewports.entry(new_viewport_id).or_default(); - viewport.builder = builder.clone(); - viewport.used = true; - viewport.viewport_ui_cb = None; // it is immediate + ctx.viewport_parents + .insert(new_viewport_id, parent_viewport_id); - ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id) - }); + let viewport = ctx.viewports.entry(new_viewport_id).or_default(); + viewport.builder = builder.clone(); + viewport.used = true; + viewport.viewport_ui_cb = None; // it is immediate - let mut out = None; - { - let out = &mut out; + ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id) + }); - let viewport = ImmediateViewport { - ids, - builder, - viewport_ui_cb: Box::new(move |context| { - *out = Some(viewport_ui_cb(context, ViewportClass::Immediate)); - }), - }; + let mut out = None; + { + let out = &mut out; + + let viewport = ImmediateViewport { + ids, + builder, + viewport_ui_cb: Box::new(move |context| { + *out = Some(viewport_ui_cb(context, ViewportClass::Immediate)); + }), + }; - immediate_viewport_renderer(self, viewport); - } + immediate_viewport_renderer(self, viewport); + } - out.expect( - "egui backend is implemented incorrectly - the user callback was never called", - ) - }) + out.expect( + "egui backend is implemented incorrectly - the user callback was never called", + ) + }) } } From f10cf80654a71c4cb71b1b0e7390cf6f094b2177 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Tue, 30 Jul 2024 10:40:28 +0100 Subject: [PATCH 17/23] Fix request_repaint_after In the previous code, new_events did check repaint times, this was lost in the translation. Seperate out this check from handle_event_result as we don't need the complexity of that whole shebang. --- crates/eframe/src/native/run.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 32e247d94b8..60b83cc9862 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -135,6 +135,10 @@ impl WinitAppWrapper { } } + self.check_redraw_requests(event_loop); + } + + fn check_redraw_requests(&mut self, event_loop: &ActiveEventLoop) { let mut next_repaint_time = self.windows_next_repaint_times.values().min().copied(); self.windows_next_repaint_times @@ -259,10 +263,12 @@ impl ApplicationHandler for WinitAppWrapper { }); } - fn new_events(&mut self, _: &ActiveEventLoop, cause: winit::event::StartCause) { + fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: winit::event::StartCause) { if let winit::event::StartCause::ResumeTimeReached { .. } = cause { log::trace!("Woke up to check next_repaint_time"); } + + self.check_redraw_requests(event_loop); } fn window_event( From 1bbb312d11c26fc7c9d7352eb28513bf39903251 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Tue, 30 Jul 2024 11:49:16 +0100 Subject: [PATCH 18/23] Adress some review comments. --- Cargo.lock | 11 +-- crates/eframe/src/native/glow_integration.rs | 13 ++-- crates/eframe/src/native/run.rs | 78 +++++++++++--------- crates/egui-winit/Cargo.toml | 15 ++-- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f4a7723ecc..6016c469ce3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1267,6 +1267,7 @@ dependencies = [ "raw-window-handle 0.6.2", "serde", "smithay-clipboard", + "wayland-cursor", "web-time", "webbrowser", "winit", @@ -2276,9 +2277,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -4309,11 +4310,11 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.0" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44aa20ae986659d6c77d64d808a046996a932aa763913864dc40c359ef7ad5b" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ - "nix", + "rustix 0.38.21", "wayland-client", "xcursor", ] diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 6e45ee75aad..366b71cfd7a 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -412,7 +412,7 @@ impl WinitApp for GlowWinitApp { .initialize_all_windows(event_loop); running } else { - // First resume event. Created our root window etc. + // First resume event. Create our root window etc. self.init_run_state(event_loop)? }; let window_id = running.glutin.borrow().window_from_viewport[&ViewportId::ROOT]; @@ -705,11 +705,12 @@ impl GlowWinitRunning { // vsync - don't count as frame-time: frame_timer.pause(); crate::profile_scope!("swap_buffers"); - let context = current_gl_context.as_ref().ok_or(std::convert::Into::< - egui_glow::PainterError, - >::into( - "failed to get current context to swap buffers".to_owned(), - ))?; + let context = current_gl_context + .as_ref() + .ok_or(egui_glow::PainterError::from( + "failed to get current context to swap buffers".to_owned(), + ))?; + gl_surface.swap_buffers(context)?; frame_timer.resume(); } diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 60b83cc9862..2d3a9dbe2b0 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -78,47 +78,54 @@ impl WinitAppWrapper { ) { let mut exit = false; - match event_result { - Ok(event_result) => { - log::trace!("event_result: {event_result:?}"); - match event_result { - EventResult::Wait => { - event_loop.set_control_flow(ControlFlow::Wait); - } - EventResult::RepaintNow(window_id) => { - log::trace!("RepaintNow of {window_id:?}",); - if cfg!(target_os = "windows") { - // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 - self.windows_next_repaint_times.remove(&window_id); + log::trace!("event_result: {event_result:?}"); - let _ = self.winit_app.run_ui_and_paint(event_loop, window_id); - } else { - // Fix for https://github.com/emilk/egui/issues/2425 - self.windows_next_repaint_times - .insert(window_id, Instant::now()); - } - } - EventResult::RepaintNext(window_id) => { - log::trace!("RepaintNext of {window_id:?}",); + let combined_result = event_result.and_then(|event_result| { + match event_result { + EventResult::Wait => { + event_loop.set_control_flow(ControlFlow::Wait); + Ok(event_result) + } + EventResult::RepaintNow(window_id) => { + log::trace!("RepaintNow of {window_id:?}",); + + if cfg!(target_os = "windows") { + // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 + self.windows_next_repaint_times.remove(&window_id); + self.winit_app.run_ui_and_paint(event_loop, window_id) + } else { + // Fix for https://github.com/emilk/egui/issues/2425 self.windows_next_repaint_times .insert(window_id, Instant::now()); + Ok(event_result) } - EventResult::RepaintAt(window_id, repaint_time) => { - self.windows_next_repaint_times.insert( - window_id, - self.windows_next_repaint_times - .get(&window_id) - .map_or(repaint_time, |last| (*last).min(repaint_time)), - ); - } - EventResult::Exit => exit = true, + } + EventResult::RepaintNext(window_id) => { + log::trace!("RepaintNext of {window_id:?}",); + self.windows_next_repaint_times + .insert(window_id, Instant::now()); + Ok(event_result) + } + EventResult::RepaintAt(window_id, repaint_time) => { + self.windows_next_repaint_times.insert( + window_id, + self.windows_next_repaint_times + .get(&window_id) + .map_or(repaint_time, |last| (*last).min(repaint_time)), + ); + Ok(event_result) + } + EventResult::Exit => { + exit = true; + Ok(event_result) } } - Err(err) => { - log::error!("Exiting because of error: {err}"); - exit = true; - self.return_result = Err(err); - } + }); + + if let Err(err) = combined_result { + log::error!("Exiting because of error: {err}"); + exit = true; + self.return_result = Err(err); }; if exit { @@ -130,6 +137,7 @@ impl WinitAppWrapper { self.winit_app.save_and_destroy(); log::debug!("Exiting with return code 0"); + #[allow(clippy::exit)] std::process::exit(0); } diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 8e5c88c313e..78f30ab7a33 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -51,16 +51,12 @@ puffin = ["dep:puffin", "egui/puffin"] ## Allow serialization of [`WindowSettings`] using [`serde`](https://docs.rs/serde). serde = ["egui/serde", "dep:serde"] -# wayland-cursor should enable the fs feature as it otherwise doesn't compile. -# This is fixed upstream post https://github.com/Smithay/wayland-rs/commit/edd0f60d0baf09604553525c2636df5d6ba05d44 or v0.31.1 -# so should be removed when winit upgrades past that version. -# Enable this feature manually for now (needed in both wayand and x11 backends). ## Enables Wayland support. -wayland = ["winit/wayland", "bytemuck", "nix/fs"] +wayland = ["winit/wayland", "bytemuck", "dep:wayland-cursor"] ## Enables compiling for x11. -x11 = ["winit/x11", "bytemuck", "nix/fs"] +x11 = ["winit/x11", "bytemuck"] [dependencies] egui = { workspace = true, default-features = false, features = ["log"] } @@ -68,9 +64,14 @@ egui = { workspace = true, default-features = false, features = ["log"] } ahash.workspace = true log.workspace = true - nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true + +# The wayland-cursor normally selected doesn't properly enable all the features it uses +# and thus doens't compile as it is used in egui-winit. This is fixed upstream, so force +# a slightly newer version. Remove this when winit upgrades past this version. +wayland-cursor = { version = "0.31.1", default-features = false, optional = true } + web-time.workspace = true winit = { workspace = true, default-features = false } From 81fd86ca1c4a3dad34ff0d87625d9b48b4d98430 Mon Sep 17 00:00:00 2001 From: Arthur Brussee Date: Tue, 30 Jul 2024 16:21:57 +0100 Subject: [PATCH 19/23] Pin winit, fix wayland dependency issues again. --- Cargo.lock | 36 ++++++++++++++++++------------------ Cargo.toml | 3 ++- crates/egui-winit/Cargo.toml | 5 ++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6016c469ce3..0a8d6f91b71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,9 +646,9 @@ dependencies = [ [[package]] name = "calloop" -version = "0.13.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ "bitflags 2.6.0", "log", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "calloop-wayland-source" -version = "0.3.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ "calloop", "rustix 0.38.21", @@ -3489,9 +3489,9 @@ dependencies = [ [[package]] name = "sctk-adwaita" -version = "0.10.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +checksum = "7555fcb4f753d095d734fdefebb0ad8c98478a21db500492d87c55913d3b0086" dependencies = [ "ab_glyph", "log", @@ -3626,9 +3626,9 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay-client-toolkit" -version = "0.19.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ "bitflags 2.6.0", "calloop", @@ -3651,9 +3651,9 @@ dependencies = [ [[package]] name = "smithay-clipboard" -version = "0.7.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" +checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" dependencies = [ "libc", "smithay-client-toolkit", @@ -4321,9 +4321,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.3" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4333,9 +4333,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4346,9 +4346,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4848,9 +4848,9 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winit" -version = "0.30.4" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" +checksum = "1dc930d6cfbf53c4fe0b95689cdc2e17b8658c3f4214b9953298ccb5a1a15c90" dependencies = [ "ahash", "android-activity", diff --git a/Cargo.toml b/Cargo.toml index 505de564bb6..f6b45737cd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,8 @@ wgpu = { version = "22.0.0", default-features = false, features = [ "fragile-send-sync-non-atomic-wasm", ] } -winit = { version = "0.30.4", default-features = false } +# Currently can't upgrade above 0.30.2 due to https://github.com/rust-windowing/winit/issues/3837 +winit = { version = "=0.30.2", default-features = false } [workspace.lints.rust] unsafe_code = "deny" diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index 78f30ab7a33..bb24fd63663 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -51,9 +51,8 @@ puffin = ["dep:puffin", "egui/puffin"] ## Allow serialization of [`WindowSettings`] using [`serde`](https://docs.rs/serde). serde = ["egui/serde", "dep:serde"] - ## Enables Wayland support. -wayland = ["winit/wayland", "bytemuck", "dep:wayland-cursor"] +wayland = ["winit/wayland", "bytemuck"] ## Enables compiling for x11. x11 = ["winit/x11", "bytemuck"] @@ -88,7 +87,7 @@ serde = { workspace = true, optional = true } webbrowser = { version = "1.0.0", optional = true } [target.'cfg(any(target_os="linux", target_os="dragonfly", target_os="freebsd", target_os="netbsd", target_os="openbsd"))'.dependencies] -smithay-clipboard = { version = "0.7.2", optional = true } +smithay-clipboard = { version = "0.7.0", optional = true } [target.'cfg(not(target_os = "android"))'.dependencies] arboard = { version = "3.3", optional = true, default-features = false } From e4fa5f9d7f411bb515a938d4cb44d667c8534c04 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 30 Jul 2024 19:30:12 +0200 Subject: [PATCH 20/23] Move `wayland-cursor` dependency to fix Windows build --- crates/egui-winit/Cargo.toml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index bb24fd63663..da33cb3da11 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -62,15 +62,8 @@ egui = { workspace = true, default-features = false, features = ["log"] } ahash.workspace = true log.workspace = true - nix = { version = "0.26.4", default-features = false, optional = true } raw-window-handle.workspace = true - -# The wayland-cursor normally selected doesn't properly enable all the features it uses -# and thus doens't compile as it is used in egui-winit. This is fixed upstream, so force -# a slightly newer version. Remove this when winit upgrades past this version. -wayland-cursor = { version = "0.31.1", default-features = false, optional = true } - web-time.workspace = true winit = { workspace = true, default-features = false } @@ -89,5 +82,10 @@ webbrowser = { version = "1.0.0", optional = true } [target.'cfg(any(target_os="linux", target_os="dragonfly", target_os="freebsd", target_os="netbsd", target_os="openbsd"))'.dependencies] smithay-clipboard = { version = "0.7.0", optional = true } +# The wayland-cursor normally selected doesn't properly enable all the features it uses +# and thus doens't compile as it is used in egui-winit. This is fixed upstream, so force +# a slightly newer version. Remove this when winit upgrades past this version. +wayland-cursor = { version = "0.31.1", default-features = false, optional = true } + [target.'cfg(not(target_os = "android"))'.dependencies] arboard = { version = "3.3", optional = true, default-features = false } From ba7cb001abc6ce8318b1a207da96e24e69df4beb Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 30 Jul 2024 19:30:55 +0200 Subject: [PATCH 21/23] fix typo --- crates/egui-winit/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index da33cb3da11..95e8215b7d9 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -83,7 +83,7 @@ webbrowser = { version = "1.0.0", optional = true } smithay-clipboard = { version = "0.7.0", optional = true } # The wayland-cursor normally selected doesn't properly enable all the features it uses -# and thus doens't compile as it is used in egui-winit. This is fixed upstream, so force +# and thus doesn't compile as it is used in egui-winit. This is fixed upstream, so force # a slightly newer version. Remove this when winit upgrades past this version. wayland-cursor = { version = "0.31.1", default-features = false, optional = true } From 48f402e829567448ea7521df5317ee7af300b6f9 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 30 Jul 2024 19:48:12 +0200 Subject: [PATCH 22/23] Remove duplicate dependency on `async-channel` --- Cargo.lock | 46 +++++++++++++++++++++------------------------- deny.toml | 1 - 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a8d6f91b71..d47e187e9ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,11 +74,11 @@ checksum = "b76c448cfd96d16131a9ad3ab786d06951eb341cdac1db908978ab010245a19d" dependencies = [ "accesskit", "accesskit_atspi_common", - "async-channel 2.3.1", + "async-channel", "async-executor", "async-task", "atspi", - "futures-lite", + "futures-lite 1.13.0", "futures-util", "serde", "zbus", @@ -267,17 +267,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.3.1" @@ -300,7 +289,7 @@ dependencies = [ "async-task", "concurrent-queue", "fastrand 2.0.1", - "futures-lite", + "futures-lite 1.13.0", "slab", ] @@ -313,7 +302,7 @@ dependencies = [ "async-lock", "autocfg", "blocking", - "futures-lite", + "futures-lite 1.13.0", ] [[package]] @@ -326,7 +315,7 @@ dependencies = [ "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", "polling 2.8.0", @@ -357,7 +346,7 @@ dependencies = [ "blocking", "cfg-if", "event-listener 3.0.0", - "futures-lite", + "futures-lite 1.13.0", "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -460,7 +449,7 @@ checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" dependencies = [ "atspi-common", "atspi-proxies", - "futures-lite", + "futures-lite 1.13.0", "zbus", ] @@ -582,18 +571,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c4ef1f913d78636d78d538eec1f18de81e481f44b1be0a81060090530846e1" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 1.9.0", - "async-lock", + "async-channel", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] @@ -1665,6 +1651,16 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.28" diff --git a/deny.toml b/deny.toml index 93973f8e7f4..c4fe981308c 100644 --- a/deny.toml +++ b/deny.toml @@ -46,7 +46,6 @@ deny = [ ] skip = [ - { name = "async-channel" }, # accesskit pulls in two versions of this 😭 { name = "bit-set" }, # wgpu's naga depends on 0.6, syntect's (used by egui_extras) fancy-regex depends on 0.5 { name = "bit-vec" }, # dependency of bit-set in turn, different between 0.6 and 0.5 { name = "bitflags" }, # old 1.0 version via glutin, png, spirv, … From 8f337c7c891782c0a7b8145b7f754df02f0ca221 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 30 Jul 2024 19:54:57 +0200 Subject: [PATCH 23/23] ignore duplicated crate futures-lite --- deny.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deny.toml b/deny.toml index c4fe981308c..5b3c546528d 100644 --- a/deny.toml +++ b/deny.toml @@ -50,9 +50,10 @@ skip = [ { name = "bit-vec" }, # dependency of bit-set in turn, different between 0.6 and 0.5 { name = "bitflags" }, # old 1.0 version via glutin, png, spirv, … { name = "cfg_aliases" }, # old version via wgpu - { name = "ndk-sys" }, # old version via wgpu, winit uses newer version { name = "event-listener" }, # TODO(emilk): rustls pulls in two versions of this 😭 + { name = "futures-lite" }, # old version via accesskit_unix and zbus { name = "memoffset" }, # tiny dependency + { name = "ndk-sys" }, # old version via wgpu, winit uses newer version { name = "quick-xml" }, # old version via wayland-scanner { name = "redox_syscall" }, # old version via winit { name = "time" }, # old version pulled in by unmaintianed crate 'chrono'