egui_winit_platform icon indicating copy to clipboard operation
egui_winit_platform copied to clipboard

Platform API is tricky to use on mobile

Open rib opened this issue 2 years ago • 4 comments

Trying to use egui_winit_platform on Android (and I guess the same might be true on iOS) we can only create a winit Window once the application receives a Resumed lifecycle event, even though, ideally, the Platform could be constructed once when initializing the app.

This is awkward because it leads to passing in dummy scale_factor and physical_width/height Descriptor values while we don't yet know anything about the Window we'll be rendering with.

If Platform is initialized with these dummy values then it's also necessary to explicitly update RawInput pixels_per_point and screen_rect to make up for this, which works against the way in which handle_event is designed to handle updating this state automatically in general.

The biggest difficulty though is that the private Platform scale_factor is practically inaccessible and the only (awkward) way this state can be corrected later is by passing a fake ScaleFactorChanged changed event to `handle_events.

All in all I currently do the following to update the Platform state that can't always be determined until the app is Resumed and we get a Window...

                let mut size = window.inner_size();
                let scale_factor = window.scale_factor() as f32;
                let raw_input = platform.raw_input_mut();
                raw_input.pixels_per_point = Some(scale_factor);
                raw_input.screen_rect = Some(egui::Rect::from_min_size(
                    egui::Pos2::default(),
                    egui::vec2(
                        size.width as f32,
                        size.height as f32,
                    ) / scale_factor,
                ));
                platform.handle_event::<Event>(&winit::event::Event::WindowEvent {
                    window_id: window.id(),
                    event: winit::event::WindowEvent::ScaleFactorChanged {
                        scale_factor: scale_factor as f64,
                        new_inner_size: &mut size }
                });

which is uncomfortably dependent on implementation details of egui_winit_platform.

I wonder if it could be best to remove the physical_width/height and scale_factor arguments from Platform::new() considering that this state can't be assumed to be available early on for all platforms.

Maybe there could a set_window API that could be used for associating the Platform with a winit Window which would be an opportunity to initialize both the physical width/height and scale factor which can then be correctly maintained by handle_event.

Perhaps though it's also possible to remove the separate scale_factor state internally and just refer to RawInput::pixels_per_point which seems to be the same scale factor?

rib avatar May 11 '22 19:05 rib