mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 23:13:13 -04:00
WIP: Update to winit 0.29
This commit is contained in:
685
Cargo.lock
generated
685
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -127,7 +127,7 @@ image = { version = "0.24", default-features = false, features = [
|
||||
"png",
|
||||
] } # Needed for app icon
|
||||
raw-window-handle.workspace = true
|
||||
winit = { version = "0.28.1", default-features = false }
|
||||
winit = { version = "0.29", default-features = false, features = ["rwh_05"] }
|
||||
|
||||
# optional native:
|
||||
directories-next = { version = "2", optional = true }
|
||||
@@ -138,8 +138,8 @@ pollster = { version = "0.3", optional = true } # needed for wgpu
|
||||
|
||||
# we can expose these to user so that they can select which backends they want to enable to avoid compiling useless deps.
|
||||
# this can be done at the same time we expose x11/wayland features of winit crate.
|
||||
glutin = { version = "0.30", optional = true }
|
||||
glutin-winit = { version = "0.3.0", optional = true }
|
||||
glutin = { version = "0.31", optional = true }
|
||||
glutin-winit = { version = "0.4", optional = true }
|
||||
puffin = { workspace = true, optional = true }
|
||||
wgpu = { workspace = true, optional = true }
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ impl EpiIntegration {
|
||||
pub fn on_window_event(
|
||||
&mut self,
|
||||
app: &mut dyn epi::App,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
event: &winit::event::WindowEvent,
|
||||
egui_winit: &mut egui_winit::State,
|
||||
viewport_id: ViewportId,
|
||||
) -> EventResponse {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant};
|
||||
|
||||
use glutin::{
|
||||
context::NotCurrentGlContext,
|
||||
display::GetGlDisplay,
|
||||
prelude::{GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentGlContext},
|
||||
prelude::{GlDisplay, PossiblyCurrentGlContext},
|
||||
surface::GlSurface,
|
||||
};
|
||||
use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
|
||||
@@ -391,7 +392,7 @@ impl WinitApp for GlowWinitApp {
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||
event: &winit::event::Event<'_, UserEvent>,
|
||||
event: &winit::event::Event<UserEvent>,
|
||||
) -> Result<EventResult> {
|
||||
crate::profile_function!(winit_integration::short_event_description(event));
|
||||
|
||||
@@ -423,15 +424,6 @@ impl WinitApp for GlowWinitApp {
|
||||
EventResult::Wait
|
||||
}
|
||||
|
||||
winit::event::Event::MainEventsCleared => {
|
||||
if let Some(running) = &self.running {
|
||||
if let Err(err) = running.glutin.borrow_mut().on_resume(event_loop) {
|
||||
log::warn!("on_resume failed {err}");
|
||||
}
|
||||
}
|
||||
EventResult::Wait
|
||||
}
|
||||
|
||||
winit::event::Event::WindowEvent { event, window_id } => {
|
||||
if let Some(running) = &mut self.running {
|
||||
running.on_window_event(*window_id, event)
|
||||
@@ -652,7 +644,7 @@ impl GlowWinitRunning {
|
||||
fn on_window_event(
|
||||
&mut self,
|
||||
window_id: WindowId,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
event: &winit::event::WindowEvent,
|
||||
) -> EventResult {
|
||||
crate::profile_function!(egui_winit::short_window_event_description(event));
|
||||
|
||||
@@ -691,10 +683,9 @@ impl GlowWinitRunning {
|
||||
}
|
||||
}
|
||||
|
||||
winit::event::WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
if let Some(viewport_id) = viewport_id {
|
||||
winit::event::WindowEvent::ScaleFactorChanged { .. } => {
|
||||
if viewport_id.is_some() {
|
||||
repaint_asap = true;
|
||||
glutin.resize(viewport_id, **new_inner_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -811,7 +802,7 @@ impl GlutinWindowContext {
|
||||
// Create GL display. This may probably create a window too on most platforms. Definitely on `MS windows`. Never on Android.
|
||||
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::ApiPrefence::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150
|
||||
.with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150
|
||||
.with_window_builder(Some(create_winit_window_builder(viewport_builder.clone())));
|
||||
|
||||
let (window, gl_config) = {
|
||||
|
||||
@@ -39,7 +39,7 @@ fn create_event_loop(native_options: &mut epi::NativeOptions) -> EventLoop<UserE
|
||||
let mut builder = create_event_loop_builder(native_options);
|
||||
|
||||
crate::profile_scope!("EventLoopBuilder::build");
|
||||
builder.build()
|
||||
builder.build().unwrap()
|
||||
}
|
||||
|
||||
/// Access a thread-local event loop.
|
||||
@@ -67,7 +67,7 @@ fn run_and_return(
|
||||
event_loop: &mut EventLoop<UserEvent>,
|
||||
mut winit_app: impl WinitApp,
|
||||
) -> Result<()> {
|
||||
use winit::{event_loop::ControlFlow, platform::run_return::EventLoopExtRunReturn as _};
|
||||
use winit::{event_loop::ControlFlow, platform::run_on_demand::EventLoopExtRunOnDemand};
|
||||
|
||||
log::debug!("Entering the winit event loop (run_return)…");
|
||||
|
||||
@@ -76,20 +76,22 @@ fn run_and_return(
|
||||
|
||||
let mut returned_result = Ok(());
|
||||
|
||||
event_loop.run_return(|event, event_loop, control_flow| {
|
||||
let _ = event_loop.run_on_demand(|event, event_loop_window_target| {
|
||||
crate::profile_scope!("winit_event", short_event_description(&event));
|
||||
|
||||
let event_result = match &event {
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
// On Mac, Cmd-Q we get here and then `run_return` doesn't return (despite its name),
|
||||
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::LoopDestroyed - saving app state…");
|
||||
log::debug!("Received Event::LoopExiting - saving app state…");
|
||||
winit_app.save_and_destroy();
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
}
|
||||
|
||||
winit::event::Event::RedrawRequested(window_id) => {
|
||||
winit::event::Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::RedrawRequested,
|
||||
window_id,
|
||||
} => {
|
||||
windows_next_repaint_times.remove(window_id);
|
||||
winit_app.run_ui_and_paint(*window_id)
|
||||
}
|
||||
@@ -120,7 +122,7 @@ fn run_and_return(
|
||||
EventResult::Wait
|
||||
}
|
||||
|
||||
event => match winit_app.on_event(event_loop, event) {
|
||||
event => match winit_app.on_event(event_loop_window_target, event) {
|
||||
Ok(event_result) => event_result,
|
||||
Err(err) => {
|
||||
log::error!("Exiting because of error: {err} during event {event:?}");
|
||||
@@ -132,7 +134,7 @@ fn run_and_return(
|
||||
|
||||
match event_result {
|
||||
EventResult::Wait => {
|
||||
control_flow.set_wait();
|
||||
event_loop_window_target.set_control_flow(ControlFlow::Wait);
|
||||
}
|
||||
EventResult::RepaintNow(window_id) => {
|
||||
log::trace!("Repaint caused by {}", short_event_description(&event));
|
||||
@@ -160,7 +162,7 @@ fn run_and_return(
|
||||
EventResult::Exit => {
|
||||
log::debug!("Asking to exit event loop…");
|
||||
winit_app.save_and_destroy();
|
||||
*control_flow = ControlFlow::Exit;
|
||||
event_loop_window_target.exit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -171,7 +173,10 @@ fn run_and_return(
|
||||
use winit::event::Event;
|
||||
if matches!(
|
||||
event,
|
||||
Event::RedrawEventsCleared | Event::RedrawRequested(_) | Event::Resumed
|
||||
Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::RedrawRequested,
|
||||
..
|
||||
} | Event::Resumed
|
||||
) {
|
||||
windows_next_repaint_times.retain(|window_id, repaint_time| {
|
||||
if Instant::now() < *repaint_time {
|
||||
@@ -179,7 +184,7 @@ fn run_and_return(
|
||||
};
|
||||
|
||||
next_repaint_time = None;
|
||||
control_flow.set_poll();
|
||||
event_loop_window_target.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
if let Some(window) = winit_app.window(*window_id) {
|
||||
log::trace!("request_redraw for {window_id:?}");
|
||||
@@ -196,7 +201,7 @@ fn run_and_return(
|
||||
if time_until_next < std::time::Duration::from_secs(10_000) {
|
||||
log::trace!("WaitUntil {time_until_next:?}");
|
||||
}
|
||||
control_flow.set_wait_until(next_repaint_time);
|
||||
event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time));
|
||||
};
|
||||
});
|
||||
|
||||
@@ -220,21 +225,25 @@ fn run_and_return(
|
||||
}
|
||||
|
||||
fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp + 'static) -> ! {
|
||||
use winit::event_loop::ControlFlow;
|
||||
log::debug!("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, control_flow| {
|
||||
let result = event_loop.run(move |event, event_loop_window_target| {
|
||||
crate::profile_scope!("winit_event", short_event_description(&event));
|
||||
|
||||
let event_result = match &event {
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
log::debug!("Received Event::LoopDestroyed");
|
||||
winit::event::Event::LoopExiting => {
|
||||
log::debug!("Received Event::LoopExiting");
|
||||
EventResult::Exit
|
||||
}
|
||||
|
||||
winit::event::Event::RedrawRequested(window_id) => {
|
||||
winit::event::Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::RedrawRequested,
|
||||
window_id,
|
||||
} => {
|
||||
windows_next_repaint_times.remove(window_id);
|
||||
winit_app.run_ui_and_paint(*window_id)
|
||||
}
|
||||
@@ -264,7 +273,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
||||
EventResult::Wait
|
||||
}
|
||||
|
||||
event => match winit_app.on_event(event_loop, event) {
|
||||
event => match winit_app.on_event(event_loop_window_target, event) {
|
||||
Ok(event_result) => event_result,
|
||||
Err(err) => {
|
||||
panic!("eframe encountered a fatal error: {err} during event {event:?}");
|
||||
@@ -274,7 +283,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
||||
|
||||
match event_result {
|
||||
EventResult::Wait => {
|
||||
control_flow.set_wait();
|
||||
event_loop_window_target.set_control_flow(ControlFlow::Wait);
|
||||
}
|
||||
EventResult::RepaintNow(window_id) => {
|
||||
log::trace!("Repaint caused by {}", short_event_description(&event));
|
||||
@@ -314,7 +323,10 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
||||
use winit::event::Event;
|
||||
if matches!(
|
||||
event,
|
||||
Event::RedrawEventsCleared | Event::RedrawRequested(_) | Event::Resumed
|
||||
Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::RedrawRequested,
|
||||
..
|
||||
} | Event::Resumed
|
||||
) {
|
||||
windows_next_repaint_times.retain(|window_id, repaint_time| {
|
||||
if Instant::now() < *repaint_time {
|
||||
@@ -322,7 +334,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
||||
}
|
||||
|
||||
next_repaint_time = None;
|
||||
control_flow.set_poll();
|
||||
event_loop_window_target.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
if let Some(window) = winit_app.window(*window_id) {
|
||||
log::trace!("request_redraw for {window_id:?}");
|
||||
@@ -350,9 +362,16 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
||||
.map(|window| window.request_redraw())
|
||||
});
|
||||
|
||||
control_flow.set_wait_until(next_repaint_time);
|
||||
event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time));
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
std::process::exit(if let Err(e) = result {
|
||||
log::warn!("Error from event loop: {e}");
|
||||
1
|
||||
} else {
|
||||
0
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -355,7 +355,7 @@ impl WinitApp for WgpuWinitApp {
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||
event: &winit::event::Event<'_, UserEvent>,
|
||||
event: &winit::event::Event<UserEvent>,
|
||||
) -> Result<EventResult> {
|
||||
crate::profile_function!(winit_integration::short_event_description(event));
|
||||
|
||||
@@ -643,7 +643,7 @@ impl WgpuWinitRunning {
|
||||
fn on_window_event(
|
||||
&mut self,
|
||||
window_id: WindowId,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
event: &winit::event::WindowEvent,
|
||||
) -> EventResult {
|
||||
crate::profile_function!(egui_winit::short_window_event_description(event));
|
||||
|
||||
@@ -692,18 +692,9 @@ impl WgpuWinitRunning {
|
||||
}
|
||||
}
|
||||
|
||||
winit::event::WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
use std::num::NonZeroU32;
|
||||
if let (Some(width), Some(height), Some(viewport_id)) = (
|
||||
NonZeroU32::new(new_inner_size.width),
|
||||
NonZeroU32::new(new_inner_size.height),
|
||||
viewport_id,
|
||||
) {
|
||||
repaint_asap = true;
|
||||
shared.painter.on_window_resized(viewport_id, width, height);
|
||||
}
|
||||
winit::event::WindowEvent::ScaleFactorChanged { .. } => {
|
||||
repaint_asap = true;
|
||||
}
|
||||
|
||||
winit::event::WindowEvent::CloseRequested => {
|
||||
if viewport_id == Some(ViewportId::ROOT) && integration.should_close() {
|
||||
log::debug!(
|
||||
|
||||
@@ -65,7 +65,7 @@ pub trait WinitApp {
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||
event: &winit::event::Event<'_, UserEvent>,
|
||||
event: &winit::event::Event<UserEvent>,
|
||||
) -> crate::Result<EventResult>;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ pub fn system_theme(window: &Window, options: &crate::NativeOptions) -> Option<c
|
||||
|
||||
/// Short and fast description of an event.
|
||||
/// Useful for logging and profiling.
|
||||
pub fn short_event_description(event: &winit::event::Event<'_, UserEvent>) -> &'static str {
|
||||
pub fn short_event_description(event: &winit::event::Event<UserEvent>) -> &'static str {
|
||||
use winit::event::Event;
|
||||
|
||||
match event {
|
||||
|
||||
@@ -51,7 +51,7 @@ wgpu.workspace = true
|
||||
## Enable this when generating docs.
|
||||
document-features = { version = "0.2", optional = true }
|
||||
|
||||
winit = { version = "0.28", default-features = false, optional = true }
|
||||
winit = { version = "0.29", default-features = false, optional = true, features = ["rwh_05"] }
|
||||
|
||||
# Native:
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
|
||||
@@ -61,12 +61,12 @@ egui = { version = "0.23.0", path = "../egui", default-features = false, feature
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
raw-window-handle.workspace = true
|
||||
web-time = { version = "0.2" } # We use web-time so we can (maybe) compile for web
|
||||
winit = { version = "0.28", default-features = false }
|
||||
winit = { version = "0.29", default-features = false, features = ["rwh_05"] }
|
||||
|
||||
#! ### Optional dependencies
|
||||
|
||||
# feature accesskit
|
||||
accesskit_winit = { version = "0.15.0", optional = true }
|
||||
accesskit_winit = { version = "0.16.0", optional = true }
|
||||
|
||||
## Enable this when generating docs.
|
||||
document-features = { version = "0.2", optional = true }
|
||||
|
||||
@@ -209,12 +209,6 @@ impl State {
|
||||
|
||||
self.egui_input.time = Some(self.start_time.elapsed().as_secs_f64());
|
||||
|
||||
// TODO remove this in winit 0.29
|
||||
// This hack make the window outer_position and size to be valid, X11 Only
|
||||
// That was happending because winit get the window state before the compositor adds decorations!
|
||||
#[cfg(all(feature = "x11", target_os = "linux"))]
|
||||
window.set_maximized(window.is_maximized());
|
||||
|
||||
// On Windows, a minimized window will have 0 width and height.
|
||||
// See: https://github.com/rust-windowing/winit/issues/208
|
||||
// This solves an issue where egui window positions would be changed when minimizing on Windows.
|
||||
@@ -237,7 +231,7 @@ impl State {
|
||||
pub fn on_window_event(
|
||||
&mut self,
|
||||
egui_ctx: &egui::Context,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
event: &winit::event::WindowEvent,
|
||||
) -> EventResponse {
|
||||
crate::profile_function!(short_window_event_description(event));
|
||||
|
||||
@@ -295,25 +289,6 @@ impl State {
|
||||
consumed,
|
||||
}
|
||||
}
|
||||
WindowEvent::ReceivedCharacter(ch) => {
|
||||
// On Mac we get here when the user presses Cmd-C (copy), ctrl-W, etc.
|
||||
// We need to ignore these characters that are side-effects of commands.
|
||||
let is_mac_cmd = cfg!(target_os = "macos")
|
||||
&& (self.egui_input.modifiers.ctrl || self.egui_input.modifiers.mac_cmd);
|
||||
|
||||
let consumed = if is_printable_char(*ch) && !is_mac_cmd {
|
||||
self.egui_input
|
||||
.events
|
||||
.push(egui::Event::Text(ch.to_string()));
|
||||
egui_ctx.wants_keyboard_input()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed,
|
||||
}
|
||||
}
|
||||
WindowEvent::Ime(ime) => {
|
||||
// on Mac even Cmd-C is pressed during ime, a `c` is pushed to Preedit.
|
||||
// So no need to check is_mac_cmd.
|
||||
@@ -353,11 +328,12 @@ impl State {
|
||||
consumed: egui_ctx.wants_keyboard_input(),
|
||||
}
|
||||
}
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
self.on_keyboard_input(input);
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
// When pressing the Tab key, egui focuses the first focusable element, hence Tab always consumes.
|
||||
let consumed = egui_ctx.wants_keyboard_input()
|
||||
|| input.virtual_keycode == Some(winit::event::VirtualKeyCode::Tab);
|
||||
let consumed = self.on_keyboard_input(event)
|
||||
|| egui_ctx.wants_keyboard_input()
|
||||
|| event.logical_key
|
||||
== winit::keyboard::Key::Named(winit::keyboard::NamedKey::Tab);
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed,
|
||||
@@ -405,14 +381,20 @@ impl State {
|
||||
}
|
||||
}
|
||||
WindowEvent::ModifiersChanged(state) => {
|
||||
self.egui_input.modifiers.alt = state.alt();
|
||||
self.egui_input.modifiers.ctrl = state.ctrl();
|
||||
self.egui_input.modifiers.shift = state.shift();
|
||||
self.egui_input.modifiers.mac_cmd = cfg!(target_os = "macos") && state.logo();
|
||||
use winit::keyboard::ModifiersKeyState::Pressed;
|
||||
self.egui_input.modifiers.alt =
|
||||
state.lalt_state() == Pressed || state.ralt_state() == Pressed;
|
||||
self.egui_input.modifiers.ctrl =
|
||||
state.lcontrol_state() == Pressed || state.rcontrol_state() == Pressed;
|
||||
self.egui_input.modifiers.shift =
|
||||
state.lshift_state() == Pressed || state.rshift_state() == Pressed;
|
||||
self.egui_input.modifiers.mac_cmd = cfg!(target_os = "macos")
|
||||
&& (state.lsuper_state() == Pressed || state.rsuper_state() == Pressed);
|
||||
|
||||
self.egui_input.modifiers.command = if cfg!(target_os = "macos") {
|
||||
state.logo()
|
||||
state.lsuper_state() == Pressed || state.rsuper_state() == Pressed
|
||||
} else {
|
||||
state.ctrl()
|
||||
state.lcontrol_state() == Pressed || state.rcontrol_state() == Pressed
|
||||
};
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
@@ -420,6 +402,16 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
winit::event::WindowEvent::RedrawRequested => EventResponse {
|
||||
repaint: true,
|
||||
consumed: false,
|
||||
},
|
||||
|
||||
winit::event::WindowEvent::ActivationTokenDone { .. } => EventResponse {
|
||||
repaint: false,
|
||||
consumed: false,
|
||||
},
|
||||
|
||||
// Things that may require repaint:
|
||||
WindowEvent::CloseRequested => EventResponse {
|
||||
consumed: true,
|
||||
@@ -649,17 +641,19 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_keyboard_input(&mut self, input: &winit::event::KeyboardInput) {
|
||||
if let Some(keycode) = input.virtual_keycode {
|
||||
fn on_keyboard_input(&mut self, input: &winit::event::KeyEvent) -> bool {
|
||||
if let winit::keyboard::PhysicalKey::Code(keycode) = input.physical_key {
|
||||
let pressed = input.state == winit::event::ElementState::Pressed;
|
||||
|
||||
if pressed {
|
||||
// VirtualKeyCode::Paste etc in winit are broken/untrustworthy,
|
||||
// KeyCode::Paste etc in winit are broken/untrustworthy,
|
||||
// so we detect these things manually:
|
||||
if is_cut_command(self.egui_input.modifiers, keycode) {
|
||||
self.egui_input.events.push(egui::Event::Cut);
|
||||
return true;
|
||||
} else if is_copy_command(self.egui_input.modifiers, keycode) {
|
||||
self.egui_input.events.push(egui::Event::Copy);
|
||||
return true;
|
||||
} else if is_paste_command(self.egui_input.modifiers, keycode) {
|
||||
if let Some(contents) = self.clipboard.get() {
|
||||
let contents = contents.replace("\r\n", "\n");
|
||||
@@ -667,10 +661,11 @@ impl State {
|
||||
self.egui_input.events.push(egui::Event::Paste(contents));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(key) = translate_virtual_key_code(keycode) {
|
||||
if let Some(key) = translate_key_code(keycode) {
|
||||
self.egui_input.events.push(egui::Event::Key {
|
||||
key,
|
||||
pressed,
|
||||
@@ -679,6 +674,14 @@ impl State {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(text) = &input.text {
|
||||
self.egui_input
|
||||
.events
|
||||
.push(egui::Event::Text(text.to_string()));
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Call with the output given by `egui`.
|
||||
@@ -728,7 +731,14 @@ impl State {
|
||||
}
|
||||
|
||||
if let Some(egui::Pos2 { x, y }) = text_cursor_pos {
|
||||
window.set_ime_position(winit::dpi::LogicalPosition { x, y });
|
||||
window.set_ime_cursor_area(
|
||||
winit::dpi::LogicalPosition { x, y },
|
||||
winit::dpi::LogicalSize {
|
||||
// TODO: What size to use? New size arg in winit 0.29
|
||||
width: 10,
|
||||
height: 10,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
@@ -851,37 +861,25 @@ fn open_url_in_browser(_url: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Winit sends special keys (backspace, delete, F1, …) as characters.
|
||||
/// Ignore those.
|
||||
/// We also ignore '\r', '\n', '\t'.
|
||||
/// Newlines are handled by the `Key::Enter` event.
|
||||
fn is_printable_char(chr: char) -> bool {
|
||||
let is_in_private_use_area = '\u{e000}' <= chr && chr <= '\u{f8ff}'
|
||||
|| '\u{f0000}' <= chr && chr <= '\u{ffffd}'
|
||||
|| '\u{100000}' <= chr && chr <= '\u{10fffd}';
|
||||
|
||||
!is_in_private_use_area && !chr.is_ascii_control()
|
||||
}
|
||||
|
||||
fn is_cut_command(modifiers: egui::Modifiers, keycode: winit::event::VirtualKeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::event::VirtualKeyCode::X)
|
||||
fn is_cut_command(modifiers: egui::Modifiers, keycode: winit::keyboard::KeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::keyboard::KeyCode::KeyX)
|
||||
|| (cfg!(target_os = "windows")
|
||||
&& modifiers.shift
|
||||
&& keycode == winit::event::VirtualKeyCode::Delete)
|
||||
&& keycode == winit::keyboard::KeyCode::Delete)
|
||||
}
|
||||
|
||||
fn is_copy_command(modifiers: egui::Modifiers, keycode: winit::event::VirtualKeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::event::VirtualKeyCode::C)
|
||||
fn is_copy_command(modifiers: egui::Modifiers, keycode: winit::keyboard::KeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::keyboard::KeyCode::KeyC)
|
||||
|| (cfg!(target_os = "windows")
|
||||
&& modifiers.ctrl
|
||||
&& keycode == winit::event::VirtualKeyCode::Insert)
|
||||
&& keycode == winit::keyboard::KeyCode::Insert)
|
||||
}
|
||||
|
||||
fn is_paste_command(modifiers: egui::Modifiers, keycode: winit::event::VirtualKeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::event::VirtualKeyCode::V)
|
||||
fn is_paste_command(modifiers: egui::Modifiers, keycode: winit::keyboard::KeyCode) -> bool {
|
||||
(modifiers.command && keycode == winit::keyboard::KeyCode::KeyV)
|
||||
|| (cfg!(target_os = "windows")
|
||||
&& modifiers.shift
|
||||
&& keycode == winit::event::VirtualKeyCode::Insert)
|
||||
&& keycode == winit::keyboard::KeyCode::Insert)
|
||||
}
|
||||
|
||||
fn translate_mouse_button(button: winit::event::MouseButton) -> Option<egui::PointerButton> {
|
||||
@@ -889,100 +887,99 @@ fn translate_mouse_button(button: winit::event::MouseButton) -> Option<egui::Poi
|
||||
winit::event::MouseButton::Left => Some(egui::PointerButton::Primary),
|
||||
winit::event::MouseButton::Right => Some(egui::PointerButton::Secondary),
|
||||
winit::event::MouseButton::Middle => Some(egui::PointerButton::Middle),
|
||||
winit::event::MouseButton::Other(1) => Some(egui::PointerButton::Extra1),
|
||||
winit::event::MouseButton::Other(2) => Some(egui::PointerButton::Extra2),
|
||||
winit::event::MouseButton::Back => Some(egui::PointerButton::Extra1),
|
||||
winit::event::MouseButton::Forward => Some(egui::PointerButton::Extra2),
|
||||
winit::event::MouseButton::Other(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_virtual_key_code(key: winit::event::VirtualKeyCode) -> Option<egui::Key> {
|
||||
fn translate_key_code(key: winit::keyboard::KeyCode) -> Option<egui::Key> {
|
||||
use egui::Key;
|
||||
use winit::event::VirtualKeyCode;
|
||||
use winit::keyboard::KeyCode;
|
||||
|
||||
Some(match key {
|
||||
VirtualKeyCode::Down => Key::ArrowDown,
|
||||
VirtualKeyCode::Left => Key::ArrowLeft,
|
||||
VirtualKeyCode::Right => Key::ArrowRight,
|
||||
VirtualKeyCode::Up => Key::ArrowUp,
|
||||
KeyCode::ArrowDown => Key::ArrowDown,
|
||||
KeyCode::ArrowLeft => Key::ArrowLeft,
|
||||
KeyCode::ArrowRight => Key::ArrowRight,
|
||||
KeyCode::ArrowUp => Key::ArrowUp,
|
||||
|
||||
VirtualKeyCode::Escape => Key::Escape,
|
||||
VirtualKeyCode::Tab => Key::Tab,
|
||||
VirtualKeyCode::Back => Key::Backspace,
|
||||
VirtualKeyCode::Return | VirtualKeyCode::NumpadEnter => Key::Enter,
|
||||
VirtualKeyCode::Space => Key::Space,
|
||||
KeyCode::Escape => Key::Escape,
|
||||
KeyCode::Tab => Key::Tab,
|
||||
KeyCode::Backspace => Key::Backspace,
|
||||
KeyCode::Enter | KeyCode::NumpadEnter => Key::Enter,
|
||||
KeyCode::Space => Key::Space,
|
||||
|
||||
VirtualKeyCode::Insert => Key::Insert,
|
||||
VirtualKeyCode::Delete => Key::Delete,
|
||||
VirtualKeyCode::Home => Key::Home,
|
||||
VirtualKeyCode::End => Key::End,
|
||||
VirtualKeyCode::PageUp => Key::PageUp,
|
||||
VirtualKeyCode::PageDown => Key::PageDown,
|
||||
KeyCode::Insert => Key::Insert,
|
||||
KeyCode::Delete => Key::Delete,
|
||||
KeyCode::Home => Key::Home,
|
||||
KeyCode::End => Key::End,
|
||||
KeyCode::PageUp => Key::PageUp,
|
||||
KeyCode::PageDown => Key::PageDown,
|
||||
|
||||
KeyCode::Minus | KeyCode::NumpadSubtract => Key::Minus,
|
||||
|
||||
VirtualKeyCode::Minus | VirtualKeyCode::NumpadSubtract => Key::Minus,
|
||||
// Using Mac the key with the Plus sign on it is reported as the Equals key
|
||||
// (with both English and Swedish keyboard).
|
||||
VirtualKeyCode::Equals | VirtualKeyCode::Plus | VirtualKeyCode::NumpadAdd => {
|
||||
Key::PlusEquals
|
||||
}
|
||||
KeyCode::Equal | KeyCode::NumpadAdd => Key::PlusEquals,
|
||||
|
||||
VirtualKeyCode::Key0 | VirtualKeyCode::Numpad0 => Key::Num0,
|
||||
VirtualKeyCode::Key1 | VirtualKeyCode::Numpad1 => Key::Num1,
|
||||
VirtualKeyCode::Key2 | VirtualKeyCode::Numpad2 => Key::Num2,
|
||||
VirtualKeyCode::Key3 | VirtualKeyCode::Numpad3 => Key::Num3,
|
||||
VirtualKeyCode::Key4 | VirtualKeyCode::Numpad4 => Key::Num4,
|
||||
VirtualKeyCode::Key5 | VirtualKeyCode::Numpad5 => Key::Num5,
|
||||
VirtualKeyCode::Key6 | VirtualKeyCode::Numpad6 => Key::Num6,
|
||||
VirtualKeyCode::Key7 | VirtualKeyCode::Numpad7 => Key::Num7,
|
||||
VirtualKeyCode::Key8 | VirtualKeyCode::Numpad8 => Key::Num8,
|
||||
VirtualKeyCode::Key9 | VirtualKeyCode::Numpad9 => Key::Num9,
|
||||
KeyCode::Digit0 | KeyCode::Numpad0 => Key::Num0,
|
||||
KeyCode::Digit1 | KeyCode::Numpad1 => Key::Num1,
|
||||
KeyCode::Digit2 | KeyCode::Numpad2 => Key::Num2,
|
||||
KeyCode::Digit3 | KeyCode::Numpad3 => Key::Num3,
|
||||
KeyCode::Digit4 | KeyCode::Numpad4 => Key::Num4,
|
||||
KeyCode::Digit5 | KeyCode::Numpad5 => Key::Num5,
|
||||
KeyCode::Digit6 | KeyCode::Numpad6 => Key::Num6,
|
||||
KeyCode::Digit7 | KeyCode::Numpad7 => Key::Num7,
|
||||
KeyCode::Digit8 | KeyCode::Numpad8 => Key::Num8,
|
||||
KeyCode::Digit9 | KeyCode::Numpad9 => Key::Num9,
|
||||
|
||||
VirtualKeyCode::A => Key::A,
|
||||
VirtualKeyCode::B => Key::B,
|
||||
VirtualKeyCode::C => Key::C,
|
||||
VirtualKeyCode::D => Key::D,
|
||||
VirtualKeyCode::E => Key::E,
|
||||
VirtualKeyCode::F => Key::F,
|
||||
VirtualKeyCode::G => Key::G,
|
||||
VirtualKeyCode::H => Key::H,
|
||||
VirtualKeyCode::I => Key::I,
|
||||
VirtualKeyCode::J => Key::J,
|
||||
VirtualKeyCode::K => Key::K,
|
||||
VirtualKeyCode::L => Key::L,
|
||||
VirtualKeyCode::M => Key::M,
|
||||
VirtualKeyCode::N => Key::N,
|
||||
VirtualKeyCode::O => Key::O,
|
||||
VirtualKeyCode::P => Key::P,
|
||||
VirtualKeyCode::Q => Key::Q,
|
||||
VirtualKeyCode::R => Key::R,
|
||||
VirtualKeyCode::S => Key::S,
|
||||
VirtualKeyCode::T => Key::T,
|
||||
VirtualKeyCode::U => Key::U,
|
||||
VirtualKeyCode::V => Key::V,
|
||||
VirtualKeyCode::W => Key::W,
|
||||
VirtualKeyCode::X => Key::X,
|
||||
VirtualKeyCode::Y => Key::Y,
|
||||
VirtualKeyCode::Z => Key::Z,
|
||||
KeyCode::KeyA => Key::A,
|
||||
KeyCode::KeyB => Key::B,
|
||||
KeyCode::KeyC => Key::C,
|
||||
KeyCode::KeyD => Key::D,
|
||||
KeyCode::KeyE => Key::E,
|
||||
KeyCode::KeyF => Key::F,
|
||||
KeyCode::KeyG => Key::G,
|
||||
KeyCode::KeyH => Key::H,
|
||||
KeyCode::KeyI => Key::I,
|
||||
KeyCode::KeyJ => Key::J,
|
||||
KeyCode::KeyK => Key::K,
|
||||
KeyCode::KeyL => Key::L,
|
||||
KeyCode::KeyM => Key::M,
|
||||
KeyCode::KeyN => Key::N,
|
||||
KeyCode::KeyO => Key::O,
|
||||
KeyCode::KeyP => Key::P,
|
||||
KeyCode::KeyQ => Key::Q,
|
||||
KeyCode::KeyR => Key::R,
|
||||
KeyCode::KeyS => Key::S,
|
||||
KeyCode::KeyT => Key::T,
|
||||
KeyCode::KeyU => Key::U,
|
||||
KeyCode::KeyV => Key::V,
|
||||
KeyCode::KeyW => Key::W,
|
||||
KeyCode::KeyX => Key::X,
|
||||
KeyCode::KeyY => Key::Y,
|
||||
KeyCode::KeyZ => Key::Z,
|
||||
|
||||
VirtualKeyCode::F1 => Key::F1,
|
||||
VirtualKeyCode::F2 => Key::F2,
|
||||
VirtualKeyCode::F3 => Key::F3,
|
||||
VirtualKeyCode::F4 => Key::F4,
|
||||
VirtualKeyCode::F5 => Key::F5,
|
||||
VirtualKeyCode::F6 => Key::F6,
|
||||
VirtualKeyCode::F7 => Key::F7,
|
||||
VirtualKeyCode::F8 => Key::F8,
|
||||
VirtualKeyCode::F9 => Key::F9,
|
||||
VirtualKeyCode::F10 => Key::F10,
|
||||
VirtualKeyCode::F11 => Key::F11,
|
||||
VirtualKeyCode::F12 => Key::F12,
|
||||
VirtualKeyCode::F13 => Key::F13,
|
||||
VirtualKeyCode::F14 => Key::F14,
|
||||
VirtualKeyCode::F15 => Key::F15,
|
||||
VirtualKeyCode::F16 => Key::F16,
|
||||
VirtualKeyCode::F17 => Key::F17,
|
||||
VirtualKeyCode::F18 => Key::F18,
|
||||
VirtualKeyCode::F19 => Key::F19,
|
||||
VirtualKeyCode::F20 => Key::F20,
|
||||
KeyCode::F1 => Key::F1,
|
||||
KeyCode::F2 => Key::F2,
|
||||
KeyCode::F3 => Key::F3,
|
||||
KeyCode::F4 => Key::F4,
|
||||
KeyCode::F5 => Key::F5,
|
||||
KeyCode::F6 => Key::F6,
|
||||
KeyCode::F7 => Key::F7,
|
||||
KeyCode::F8 => Key::F8,
|
||||
KeyCode::F9 => Key::F9,
|
||||
KeyCode::F10 => Key::F10,
|
||||
KeyCode::F11 => Key::F11,
|
||||
KeyCode::F12 => Key::F12,
|
||||
KeyCode::F13 => Key::F13,
|
||||
KeyCode::F14 => Key::F14,
|
||||
KeyCode::F15 => Key::F15,
|
||||
KeyCode::F16 => Key::F16,
|
||||
KeyCode::F17 => Key::F17,
|
||||
KeyCode::F18 => Key::F18,
|
||||
KeyCode::F19 => Key::F19,
|
||||
KeyCode::F20 => Key::F20,
|
||||
|
||||
_ => {
|
||||
return None;
|
||||
@@ -1007,7 +1004,7 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
|
||||
egui::CursorIcon::Move => Some(winit::window::CursorIcon::Move),
|
||||
egui::CursorIcon::NoDrop => Some(winit::window::CursorIcon::NoDrop),
|
||||
egui::CursorIcon::NotAllowed => Some(winit::window::CursorIcon::NotAllowed),
|
||||
egui::CursorIcon::PointingHand => Some(winit::window::CursorIcon::Hand),
|
||||
egui::CursorIcon::PointingHand => Some(winit::window::CursorIcon::Pointer),
|
||||
egui::CursorIcon::Progress => Some(winit::window::CursorIcon::Progress),
|
||||
|
||||
egui::CursorIcon::ResizeHorizontal => Some(winit::window::CursorIcon::EwResize),
|
||||
@@ -1068,7 +1065,7 @@ pub fn process_viewport_commands(
|
||||
ViewportCommand::InnerSize(size) => {
|
||||
let width = size.x.max(1.0);
|
||||
let height = size.y.max(1.0);
|
||||
window.set_inner_size(LogicalSize::new(width, height));
|
||||
let _ = window.request_inner_size(LogicalSize::new(width, height));
|
||||
}
|
||||
ViewportCommand::BeginResize(direction) => {
|
||||
if let Err(err) = window.drag_resize_window(match direction {
|
||||
@@ -1148,7 +1145,14 @@ pub fn process_viewport_commands(
|
||||
}));
|
||||
}
|
||||
ViewportCommand::IMEPosition(pos) => {
|
||||
window.set_ime_position(LogicalPosition::new(pos.x, pos.y));
|
||||
window.set_ime_cursor_area(
|
||||
LogicalPosition::new(pos.x, pos.y),
|
||||
winit::dpi::LogicalSize {
|
||||
// TODO: What size to use? New size arg in winit 0.29
|
||||
width: 10,
|
||||
height: 10,
|
||||
},
|
||||
);
|
||||
}
|
||||
ViewportCommand::IMEAllowed(v) => window.set_ime_allowed(v),
|
||||
ViewportCommand::IMEPurpose(p) => window.set_ime_purpose(match p {
|
||||
@@ -1337,16 +1341,15 @@ pub fn apply_viewport_builder_to_new_window(window: &Window, builder: &ViewportB
|
||||
|
||||
/// Short and fast description of an event.
|
||||
/// Useful for logging and profiling.
|
||||
pub fn short_generic_event_description<T>(event: &winit::event::Event<'_, T>) -> &'static str {
|
||||
pub fn short_generic_event_description<T>(event: &winit::event::Event<T>) -> &'static str {
|
||||
use winit::event::{DeviceEvent, Event, StartCause};
|
||||
|
||||
match event {
|
||||
Event::AboutToWait => "Event::AboutToWait",
|
||||
Event::LoopExiting => "Event::LoopExiting",
|
||||
Event::Suspended => "Event::Suspended",
|
||||
Event::Resumed => "Event::Resumed",
|
||||
Event::MainEventsCleared => "Event::MainEventsCleared",
|
||||
Event::RedrawRequested(_) => "Event::RedrawRequested",
|
||||
Event::RedrawEventsCleared => "Event::RedrawEventsCleared",
|
||||
Event::LoopDestroyed => "Event::LoopDestroyed",
|
||||
Event::MemoryWarning => "Event::MemoryWarning",
|
||||
Event::UserEvent(_) => "UserEvent",
|
||||
Event::DeviceEvent { event, .. } => match event {
|
||||
DeviceEvent::Added { .. } => "DeviceEvent::Added",
|
||||
@@ -1356,7 +1359,6 @@ pub fn short_generic_event_description<T>(event: &winit::event::Event<'_, T>) ->
|
||||
DeviceEvent::Motion { .. } => "DeviceEvent::Motion",
|
||||
DeviceEvent::Button { .. } => "DeviceEvent::Button",
|
||||
DeviceEvent::Key { .. } => "DeviceEvent::Key",
|
||||
DeviceEvent::Text { .. } => "DeviceEvent::Text",
|
||||
},
|
||||
Event::NewEvents(start_cause) => match start_cause {
|
||||
StartCause::ResumeTimeReached { .. } => "NewEvents::ResumeTimeReached",
|
||||
@@ -1370,10 +1372,11 @@ pub fn short_generic_event_description<T>(event: &winit::event::Event<'_, T>) ->
|
||||
|
||||
/// Short and fast description of an event.
|
||||
/// Useful for logging and profiling.
|
||||
pub fn short_window_event_description(event: &winit::event::WindowEvent<'_>) -> &'static str {
|
||||
pub fn short_window_event_description(event: &winit::event::WindowEvent) -> &'static str {
|
||||
use winit::event::WindowEvent;
|
||||
|
||||
match event {
|
||||
WindowEvent::ActivationTokenDone { .. } => "WindowEvent::ActivationTokenDone",
|
||||
WindowEvent::Resized { .. } => "WindowEvent::Resized",
|
||||
WindowEvent::Moved { .. } => "WindowEvent::Moved",
|
||||
WindowEvent::CloseRequested { .. } => "WindowEvent::CloseRequested",
|
||||
@@ -1381,7 +1384,6 @@ pub fn short_window_event_description(event: &winit::event::WindowEvent<'_>) ->
|
||||
WindowEvent::DroppedFile { .. } => "WindowEvent::DroppedFile",
|
||||
WindowEvent::HoveredFile { .. } => "WindowEvent::HoveredFile",
|
||||
WindowEvent::HoveredFileCancelled { .. } => "WindowEvent::HoveredFileCancelled",
|
||||
WindowEvent::ReceivedCharacter { .. } => "WindowEvent::ReceivedCharacter",
|
||||
WindowEvent::Focused { .. } => "WindowEvent::Focused",
|
||||
WindowEvent::KeyboardInput { .. } => "WindowEvent::KeyboardInput",
|
||||
WindowEvent::ModifiersChanged { .. } => "WindowEvent::ModifiersChanged",
|
||||
@@ -1392,6 +1394,7 @@ pub fn short_window_event_description(event: &winit::event::WindowEvent<'_>) ->
|
||||
WindowEvent::MouseWheel { .. } => "WindowEvent::MouseWheel",
|
||||
WindowEvent::MouseInput { .. } => "WindowEvent::MouseInput",
|
||||
WindowEvent::TouchpadMagnify { .. } => "WindowEvent::TouchpadMagnify",
|
||||
WindowEvent::RedrawRequested { .. } => "WindowEvent::RedrawRequested",
|
||||
WindowEvent::SmartMagnify { .. } => "WindowEvent::SmartMagnify",
|
||||
WindowEvent::TouchpadRotate { .. } => "WindowEvent::TouchpadRotate",
|
||||
WindowEvent::TouchpadPressure { .. } => "WindowEvent::TouchpadPressure",
|
||||
|
||||
@@ -69,9 +69,9 @@ wasm-bindgen = "0.2"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
glutin = "0.30" # examples/pure_glow
|
||||
glutin = "0.31" # examples/pure_glow
|
||||
raw-window-handle.workspace = true
|
||||
glutin-winit = "0.3.0"
|
||||
glutin-winit = "0.4.0"
|
||||
|
||||
|
||||
[[example]]
|
||||
|
||||
@@ -19,7 +19,7 @@ impl GlutinWindowContext {
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn new(event_loop: &winit::event_loop::EventLoopWindowTarget<UserEvent>) -> Self {
|
||||
use egui::NumExt;
|
||||
use glutin::context::NotCurrentGlContextSurfaceAccessor;
|
||||
use glutin::context::NotCurrentGlContext;
|
||||
use glutin::display::GetGlDisplay;
|
||||
use glutin::display::GlDisplay;
|
||||
use glutin::prelude::GlSurface;
|
||||
@@ -42,7 +42,7 @@ impl GlutinWindowContext {
|
||||
log::debug!("trying to get gl_config");
|
||||
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::ApiPrefence::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150
|
||||
.with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150
|
||||
.with_window_builder(Some(winit_window_builder.clone()))
|
||||
.build(
|
||||
event_loop,
|
||||
@@ -150,7 +150,9 @@ pub enum UserEvent {
|
||||
fn main() {
|
||||
let mut clear_color = [0.1, 0.1, 0.1];
|
||||
|
||||
let event_loop = winit::event_loop::EventLoopBuilder::<UserEvent>::with_user_event().build();
|
||||
let event_loop = winit::event_loop::EventLoopBuilder::<UserEvent>::with_user_event()
|
||||
.build()
|
||||
.unwrap();
|
||||
let (gl_window, gl) = create_display(&event_loop);
|
||||
let gl = std::rc::Rc::new(gl);
|
||||
|
||||
@@ -168,7 +170,7 @@ fn main() {
|
||||
|
||||
let mut repaint_delay = std::time::Duration::MAX;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
let _ = event_loop.run(move |event, event_loop_window_target| {
|
||||
let mut redraw = || {
|
||||
let mut quit = false;
|
||||
|
||||
@@ -182,18 +184,20 @@ fn main() {
|
||||
});
|
||||
});
|
||||
|
||||
*control_flow = if quit {
|
||||
winit::event_loop::ControlFlow::Exit
|
||||
} else if repaint_delay.is_zero() {
|
||||
gl_window.window().request_redraw();
|
||||
winit::event_loop::ControlFlow::Poll
|
||||
} else if let Some(repaint_delay_instant) =
|
||||
std::time::Instant::now().checked_add(repaint_delay)
|
||||
{
|
||||
winit::event_loop::ControlFlow::WaitUntil(repaint_delay_instant)
|
||||
if quit {
|
||||
event_loop_window_target.exit();
|
||||
} else {
|
||||
winit::event_loop::ControlFlow::Wait
|
||||
};
|
||||
event_loop_window_target.set_control_flow(if repaint_delay.is_zero() {
|
||||
gl_window.window().request_redraw();
|
||||
winit::event_loop::ControlFlow::Poll
|
||||
} else if let Some(repaint_after_instant) =
|
||||
std::time::Instant::now().checked_add(repaint_delay)
|
||||
{
|
||||
winit::event_loop::ControlFlow::WaitUntil(repaint_after_instant)
|
||||
} else {
|
||||
winit::event_loop::ControlFlow::Wait
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
unsafe {
|
||||
@@ -217,22 +221,23 @@ fn main() {
|
||||
// Platform-dependent event handlers to workaround a winit bug
|
||||
// See: https://github.com/rust-windowing/winit/issues/987
|
||||
// See: https://github.com/rust-windowing/winit/issues/1619
|
||||
winit::event::Event::RedrawEventsCleared if cfg!(target_os = "windows") => redraw(),
|
||||
winit::event::Event::RedrawRequested(_) if !cfg!(target_os = "windows") => redraw(),
|
||||
|
||||
// winit::event::Event::RedrawEventsCleared if cfg!(target_os = "windows") => redraw(),
|
||||
// winit::event::Event::RedrawRequested(_) if !cfg!(target_os = "windows") => redraw(),
|
||||
// TODO: Adopt to above comment (if still relevant)
|
||||
winit::event::Event::WindowEvent { event, .. } => {
|
||||
use winit::event::WindowEvent;
|
||||
if matches!(event, WindowEvent::CloseRequested | WindowEvent::Destroyed) {
|
||||
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||
event_loop_window_target.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(event, WindowEvent::RedrawRequested) {
|
||||
redraw();
|
||||
return;
|
||||
}
|
||||
|
||||
if let winit::event::WindowEvent::Resized(physical_size) = &event {
|
||||
gl_window.resize(*physical_size);
|
||||
} else if let winit::event::WindowEvent::ScaleFactorChanged {
|
||||
new_inner_size, ..
|
||||
} = &event
|
||||
{
|
||||
gl_window.resize(**new_inner_size);
|
||||
}
|
||||
|
||||
let event_response = egui_glow.on_window_event(&event);
|
||||
@@ -245,7 +250,7 @@ fn main() {
|
||||
winit::event::Event::UserEvent(UserEvent::Redraw(delay)) => {
|
||||
repaint_delay = delay;
|
||||
}
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
winit::event::Event::LoopExiting => {
|
||||
egui_glow.destroy();
|
||||
}
|
||||
winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached {
|
||||
|
||||
@@ -52,7 +52,7 @@ impl EguiGlow {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_window_event(&mut self, event: &winit::event::WindowEvent<'_>) -> EventResponse {
|
||||
pub fn on_window_event(&mut self, event: &winit::event::WindowEvent) -> EventResponse {
|
||||
self.egui_winit.on_window_event(&self.egui_ctx, event)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user