Skip to content

Commit 6f2f006

Browse files
ArthurBrusseemwcampbellj-axaDataTrinyemilk
authored
Upgrade winit to 0.30.2 (#4849)
* Closes #1918 * Closes #4437 * Closes #4709 * [x] I have followed the instructions in the PR template Hiya, I need new winit for a specific fix for a android_native_actvity. There are already two PRs, but both don't seem to have a lot of movement, or are entirely complete: #4466 Seems to have gone stale & is missing some bits. #4702 Also seems stale (if less so), and is missing a refactor to run_on_demand. I also *think* the accesskit integration has a mistake and can't be enabled. I've marked them as a co-author on this as I started from this branch. (I think! Haven't done that on git before...). Sorry for the wall of text but just dumping some details / thoughts here: - There's an issue with creating child windows in winit 0.30.1 and up on macOS. The multiple_viewports, "create immediate viewport" example crashes on anything later 0.30.1, with a stack overflow in unsafe code. I've create [a winit issue](rust-windowing/winit#3800), it *might* already be fixed in 0.31.0 but I can't test as 0.31 will likely require another refactoring. For now I have just pinned things to 0.30.0 exatly. - Winit has deprecated run_on_demand, instead requiring the ApplicationHandler interface. In 0.31.0 run_on_demand is removed. I've refactored both the integration and the WinitApp trait to follow this pattern. I've left user_events a bit more opaque, as it seems 0.31.0 is doing a rework of UserEvents too. - I've used the new lazy init approach for access kit from this branch https://github.com/mwcampbell/egui/tree/accesskit-new-lazy-init and marked Matt as co-author, thanks Matt! - There was very similair but not quite the same code for run_and_return and run_and_exit. I've merged them, but looking at the github issues graveyard it seems vey finnicky. I *hope* this is more robust than before but it's a bit scary. - when receiving new_events this also used to check the redraw timing dictionary. That doesn't seem necesarry so left this out, but that is a slight behaviour change? - I have reeneabled serial_windows on macOS. I wondered whether it was fixed after this PR and does seem to be! However, even before this PR it seems to work, so maybe winit has sorted things out before that... Windows also works fine now without the extra hack. - I've done a very basic test of AccessKit on Windows and screen reader seems ok but I'm really not knowleadgable enough to say whether it's all good or not. - I've tested cargo tests & all examples on Windows & macOS, and ran a basic Android app. Still, testing native platforms is wel... hard so if anyone can test linux / iOs / older mac versions / windows 10 would probably be a good idea! - For consistencys sake I've made all event like functions in WinitApp return a `Result<EventResult>`. There's quite a bit of Ok-wrapping now, maybe too annoying? Not sure. Thank you for having a look! # Tested on * [x] macOS * [x] Windows * [x] Wayland (thanks [SiebenCorgie](https://github.com/SiebenCorgie)) * [x] X11 (thanks [crumblingstatue](https://github.com/crumblingstatue)!, [SiebenCorgie](https://github.com/SiebenCorgie)) # TODO * [x] Fix "follow system theme" not working on initial startup (winit issue, pinning to 0.30.2 for now). * [x] Fix `request_repaint_after` --------- Co-authored-by: mwcampbell <mattcampbell@pobox.com> Co-authored-by: j-axa <josef.axa@gmail.com> Co-authored-by: DataTriny <datatriny@gmail.com> Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
1 parent 37b1e15 commit 6f2f006

25 files changed

+1272
-1124
lines changed

Cargo.lock

+421-248
Large diffs are not rendered by default.

Cargo.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ bytemuck = "1.7.2"
7373
criterion = { version = "0.5.1", default-features = false }
7474
document-features = " 0.2.8"
7575
glow = "0.13"
76-
glutin = "0.31"
77-
glutin-winit = "0.4"
76+
glutin = "0.32.0"
77+
glutin-winit = "0.5.0"
7878
image = { version = "0.25", default-features = false }
7979
log = { version = "0.4", features = ["std"] }
8080
nohash-hasher = "0.2"
@@ -85,16 +85,17 @@ ron = "0.8"
8585
raw-window-handle = "0.6.0"
8686
serde = { version = "1", features = ["derive"] }
8787
thiserror = "1.0.37"
88-
web-time = "0.2" # Timekeeping for native and web
88+
web-time = "1.1.0" # Timekeeping for native and web
8989
wasm-bindgen = "0.2"
9090
wasm-bindgen-futures = "0.4"
9191
web-sys = "0.3.58"
9292
wgpu = { version = "22.0.0", default-features = false, features = [
9393
# Make the renderer `Sync` even on wasm32, because it makes the code simpler:
9494
"fragile-send-sync-non-atomic-wasm",
9595
] }
96-
winit = { version = "0.29.4", default-features = false }
9796

97+
# Currently can't upgrade above 0.30.2 due to https://github.com/rust-windowing/winit/issues/3837
98+
winit = { version = "=0.30.2", default-features = false }
9899

99100
[workspace.lints.rust]
100101
unsafe_code = "deny"

crates/eframe/Cargo.toml

+1-12
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,7 @@ android-native-activity = ["egui-winit/android-native-activity"]
5959
default_fonts = ["egui/default_fonts"]
6060

6161
## Use [`glow`](https://github.com/grovesNL/glow) for painting, via [`egui_glow`](https://github.com/emilk/egui/tree/master/crates/egui_glow).
62-
glow = [
63-
"dep:egui_glow",
64-
"dep:glow",
65-
"dep:glutin-winit",
66-
"dep:glutin",
67-
"dep:rwh_05",
68-
"winit/rwh_05",
69-
]
62+
glow = ["dep:egui_glow", "dep:glow", "dep:glutin-winit", "dep:glutin"]
7063

7164
## Enable saving app state to disk.
7265
persistence = [
@@ -141,10 +134,6 @@ web-time.workspace = true
141134

142135
egui_glow = { workspace = true, optional = true, default-features = false }
143136
glow = { workspace = true, optional = true }
144-
# glutin stuck on old version of raw-window-handle:
145-
rwh_05 = { package = "raw-window-handle", version = "0.5.2", optional = true, features = [
146-
"std",
147-
] }
148137
ron = { workspace = true, optional = true, features = ["integer128"] }
149138
serde = { workspace = true, optional = true }
150139

crates/eframe/src/epi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use static_assertions::assert_not_impl_any;
2323

2424
#[cfg(not(target_arch = "wasm32"))]
2525
#[cfg(any(feature = "glow", feature = "wgpu"))]
26-
pub use winit::{event_loop::EventLoopBuilder, window::WindowBuilder};
26+
pub use winit::{event_loop::EventLoopBuilder, window::WindowAttributes};
2727

2828
/// Hook into the building of an event loop before it is run
2929
///

crates/eframe/src/native/epi_integration.rs

+4-28
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use web_time::Instant;
44

55
use std::path::PathBuf;
6-
use winit::event_loop::EventLoopWindowTarget;
6+
use winit::event_loop::ActiveEventLoop;
77

88
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
99

@@ -12,9 +12,9 @@ use egui_winit::{EventResponse, WindowSettings};
1212

1313
use crate::{epi, Theme};
1414

15-
pub fn viewport_builder<E>(
15+
pub fn viewport_builder(
1616
egui_zoom_factor: f32,
17-
event_loop: &EventLoopWindowTarget<E>,
17+
event_loop: &ActiveEventLoop,
1818
native_options: &mut epi::NativeOptions,
1919
window_settings: Option<WindowSettings>,
2020
) -> ViewportBuilder {
@@ -95,10 +95,7 @@ pub fn apply_window_settings(
9595
}
9696
}
9797

98-
fn largest_monitor_point_size<E>(
99-
egui_zoom_factor: f32,
100-
event_loop: &EventLoopWindowTarget<E>,
101-
) -> egui::Vec2 {
98+
fn largest_monitor_point_size(egui_zoom_factor: f32, event_loop: &ActiveEventLoop) -> egui::Vec2 {
10299
crate::profile_function!();
103100

104101
let mut max_size = egui::Vec2::ZERO;
@@ -229,27 +226,6 @@ impl EpiIntegration {
229226
}
230227
}
231228

232-
#[cfg(feature = "accesskit")]
233-
pub fn init_accesskit<E: From<egui_winit::accesskit_winit::ActionRequestEvent> + Send>(
234-
&self,
235-
egui_winit: &mut egui_winit::State,
236-
window: &winit::window::Window,
237-
event_loop_proxy: winit::event_loop::EventLoopProxy<E>,
238-
) {
239-
crate::profile_function!();
240-
241-
let egui_ctx = self.egui_ctx.clone();
242-
egui_winit.init_accesskit(window, event_loop_proxy, move || {
243-
// This function is called when an accessibility client
244-
// (e.g. screen reader) makes its first request. If we got here,
245-
// we know that an accessibility tree is actually wanted.
246-
egui_ctx.enable_accesskit();
247-
// Enqueue a repaint so we'll receive a full tree update soon.
248-
egui_ctx.request_repaint();
249-
egui_ctx.accesskit_placeholder_tree_update()
250-
});
251-
}
252-
253229
/// If `true`, it is time to close the native window.
254230
pub fn should_close(&self) -> bool {
255231
self.close
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::cell::Cell;
2+
use winit::event_loop::ActiveEventLoop;
3+
4+
thread_local! {
5+
static CURRENT_EVENT_LOOP: Cell<Option<*const ActiveEventLoop>> = Cell::new(None);
6+
}
7+
8+
struct EventLoopGuard;
9+
10+
impl EventLoopGuard {
11+
fn new(event_loop: &ActiveEventLoop) -> Self {
12+
CURRENT_EVENT_LOOP.with(|cell| {
13+
assert!(
14+
cell.get().is_none(),
15+
"Attempted to set a new event loop while one is already set"
16+
);
17+
cell.set(Some(event_loop as *const ActiveEventLoop));
18+
});
19+
Self
20+
}
21+
}
22+
23+
impl Drop for EventLoopGuard {
24+
fn drop(&mut self) {
25+
CURRENT_EVENT_LOOP.with(|cell| cell.set(None));
26+
}
27+
}
28+
29+
// Helper function to safely use the current event loop
30+
#[allow(unsafe_code)]
31+
pub fn with_current_event_loop<F, R>(f: F) -> Option<R>
32+
where
33+
F: FnOnce(&ActiveEventLoop) -> R,
34+
{
35+
CURRENT_EVENT_LOOP.with(|cell| {
36+
cell.get().map(|ptr| {
37+
// SAFETY:
38+
// 1. The pointer is guaranteed to be valid when it's Some, as the EventLoopGuard that created it
39+
// lives at least as long as the reference, and clears it when it's dropped. Only run_with_event_loop creates
40+
// a new EventLoopGuard, and does not leak it.
41+
// 2. Since the pointer was created from a borrow which lives at least as long as this pointer there are
42+
// no mutable references to the ActiveEventLoop.
43+
let event_loop = unsafe { &*ptr };
44+
f(event_loop)
45+
})
46+
})
47+
}
48+
49+
// The only public interface to use the event loop
50+
pub fn with_event_loop_context(event_loop: &ActiveEventLoop, f: impl FnOnce()) {
51+
// NOTE: For safety, this guard must NOT be leaked.
52+
let _guard = EventLoopGuard::new(event_loop);
53+
f();
54+
}

0 commit comments

Comments
 (0)