From 4091e1ea09a281232ae41fcf2a0e3d0af52bf25d Mon Sep 17 00:00:00 2001 From: eri Date: Thu, 21 Dec 2023 15:30:22 +0100 Subject: [PATCH 01/13] Updates for bevy 0.13 --- Cargo.toml | 4 +- examples/render_to_image_widget.rs | 5 +- examples/ui.rs | 4 +- src/egui_node.rs | 86 +++++++++++++------------- src/lib.rs | 4 +- src/systems.rs | 96 +++++++++++++++--------------- 6 files changed, 99 insertions(+), 100 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fce483f3f..9665940cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ name = "ui" required-features = ["render"] [dependencies] -bevy = { version = "0.12", default-features = false, features = [ +bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = [ "bevy_asset", ] } egui = { version = "0.24.0", default-features = false, features = ["bytemuck"] } @@ -52,7 +52,7 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] once_cell = "1.16.0" version-sync = "0.9.4" -bevy = { version = "0.12", default-features = false, features = [ +bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = [ "x11", "png", "bevy_pbr", diff --git a/examples/render_to_image_widget.rs b/examples/render_to_image_widget.rs index 9f1f10c17..8cbad31cd 100644 --- a/examples/render_to_image_widget.rs +++ b/examples/render_to_image_widget.rs @@ -210,13 +210,12 @@ fn color_picker_widget(ui: &mut egui::Ui, color: &mut Color) -> egui::Response { egui::color_picker::Alpha::Opaque, ); let [r, g, b, a] = egui_color.to_srgba_unmultiplied(); - *color = [ + *color = Color::rgba( r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, a as f32 / 255.0, - ] - .into(); + ); res } diff --git a/examples/ui.rs b/examples/ui.rs index 689f4156f..692546b8e 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -55,7 +55,7 @@ fn configure_ui_state_system(mut ui_state: ResMut) { } fn update_ui_scale_factor_system( - keyboard_input: Res>, + keyboard_input: Res>, mut toggle_scale_factor: Local>, mut egui_settings: ResMut, windows: Query<&Window, With>, @@ -69,7 +69,7 @@ fn update_ui_scale_factor_system( } else { 1.0 / window.scale_factor() }; - egui_settings.scale_factor = scale_factor; + egui_settings.scale_factor = scale_factor as f64; } } } diff --git a/src/egui_node.rs b/src/egui_node.rs index ff6f76550..eb7351e06 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -11,14 +11,14 @@ use bevy::{ render::{ render_graph::{Node, NodeRunError, RenderGraphContext}, render_resource::{ - BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, - BlendComponent, BlendFactor, BlendOperation, BlendState, Buffer, BufferAddress, - BufferBindingType, BufferDescriptor, BufferUsages, ColorTargetState, ColorWrites, - Extent3d, FragmentState, FrontFace, IndexFormat, LoadOp, MultisampleState, Operations, - PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor, - RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType, - SpecializedRenderPipeline, TextureDimension, TextureFormat, TextureSampleType, - TextureViewDimension, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, + BindGroupLayout, BindGroupLayoutEntry, BindingType, BlendComponent, BlendFactor, + BlendOperation, BlendState, Buffer, BufferAddress, BufferBindingType, BufferDescriptor, + BufferUsages, ColorTargetState, ColorWrites, Extent3d, FragmentState, FrontFace, + IndexFormat, LoadOp, MultisampleState, Operations, PipelineCache, PrimitiveState, + RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, + SamplerBindingType, Shader, ShaderStages, ShaderType, SpecializedRenderPipeline, + StoreOp, TextureDimension, TextureFormat, TextureSampleType, TextureViewDimension, + VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, }, renderer::{RenderContext, RenderDevice, RenderQueue}, texture::{Image, ImageSampler}, @@ -42,43 +42,41 @@ impl FromWorld for EguiPipeline { fn from_world(render_world: &mut World) -> Self { let render_device = render_world.get_resource::().unwrap(); - let transform_bind_group_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("egui transform bind group layout"), - entries: &[BindGroupLayoutEntry { + let transform_bind_group_layout = render_device.create_bind_group_layout( + "egui transform bind group layout", + &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::VERTEX, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: Some(EguiTransform::min_size()), + }, + count: None, + }], + ); + + let texture_bind_group_layout = render_device.create_bind_group_layout( + "egui texture bind group layout", + &[ + BindGroupLayoutEntry { binding: 0, - visibility: ShaderStages::VERTEX, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: Some(EguiTransform::min_size()), + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: true }, + view_dimension: TextureViewDimension::D2, + multisampled: false, }, count: None, - }], - }); - - let texture_bind_group_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("egui texture bind group layout"), - entries: &[ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - sample_type: TextureSampleType::Float { filterable: true }, - view_dimension: TextureViewDimension::D2, - multisampled: false, - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::Filtering), - count: None, - }, - ], - }); + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::Filtering), + count: None, + }, + ], + ); EguiPipeline { transform_bind_group_layout, @@ -345,10 +343,12 @@ impl Node for EguiNode { resolve_target: None, ops: Operations { load: LoadOp::Load, - store: true, + store: StoreOp::Store, }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); let Some(pipeline_id) = egui_pipelines.get(&extracted_window.entity) else { diff --git a/src/lib.rs b/src/lib.rs index 47e28765a..f3c1fb879 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -731,8 +731,8 @@ impl Plugin for EguiPlugin { } /// Queries all the Egui related components. -#[derive(WorldQuery)] -#[world_query(mutable)] +#[derive(QueryData)] +#[query_data(mutable)] pub struct EguiContextQuery { /// Window entity. pub window_entity: Entity, diff --git a/src/systems.rs b/src/systems.rs index 7fa589bdc..69c97dbba 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -12,7 +12,7 @@ use bevy::{ keyboard::{KeyCode, KeyboardInput}, mouse::{MouseButton, MouseButtonInput, MouseScrollUnit, MouseWheel}, touch::TouchInput, - ButtonState, Input, + ButtonInput, ButtonState, }, prelude::{Entity, EventReader, Query, Resource, Time}, time::Real, @@ -63,7 +63,7 @@ pub struct TouchId(pub Option); pub struct InputResources<'w, 's> { #[cfg(all(feature = "manage_clipboard", not(target_os = "android")))] pub egui_clipboard: Res<'w, crate::EguiClipboard>, - pub keyboard_input: Res<'w, Input>, + pub keyboard_input: Res<'w, ButtonInput>, #[system_param(ignore)] _marker: PhantomData<&'s ()>, } @@ -222,7 +222,7 @@ pub fn process_input_system( if !command || cfg!(target_os = "windows") && ctrl && alt { for event in input_events.ev_received_character.read() { - if !event.char.is_control() { + if event.char.matches(char::is_control).count() == 0 { let mut context = context_params.contexts.get_mut(event.window).unwrap(); context .egui_input @@ -244,7 +244,7 @@ pub fn process_input_system( }) { for ev in input_events.ev_keyboard_input.read() { - if let Some(key) = ev.key_code.and_then(bevy_to_egui_key) { + if let Some(key) = bevy_to_egui_key(ev.key_code) { let pressed = match ev.state { ButtonState::Pressed => true, ButtonState::Released => false, @@ -376,7 +376,7 @@ pub fn update_window_contexts_system( let new_window_size = WindowSize::new( context.window.physical_width() as f32, context.window.physical_height() as f32, - context.window.scale_factor() as f32, + context.window.scale_factor(), ); let width = new_window_size.physical_width / new_window_size.scale_factor @@ -487,7 +487,7 @@ pub fn process_output_system( fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> Option { match cursor_icon { egui::CursorIcon::Default => Some(bevy::window::CursorIcon::Default), - egui::CursorIcon::PointingHand => Some(bevy::window::CursorIcon::Hand), + egui::CursorIcon::PointingHand => Some(bevy::window::CursorIcon::Pointer), egui::CursorIcon::ResizeHorizontal => Some(bevy::window::CursorIcon::EwResize), egui::CursorIcon::ResizeNeSw => Some(bevy::window::CursorIcon::NeswResize), egui::CursorIcon::ResizeNwSe => Some(bevy::window::CursorIcon::NwseResize), @@ -526,14 +526,14 @@ fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> Option Option { let key = match key_code { - KeyCode::Down => egui::Key::ArrowDown, - KeyCode::Left => egui::Key::ArrowLeft, - KeyCode::Right => egui::Key::ArrowRight, - KeyCode::Up => egui::Key::ArrowUp, + KeyCode::ArrowDown => egui::Key::ArrowDown, + KeyCode::ArrowLeft => egui::Key::ArrowLeft, + KeyCode::ArrowRight => egui::Key::ArrowRight, + KeyCode::ArrowUp => egui::Key::ArrowUp, KeyCode::Escape => egui::Key::Escape, KeyCode::Tab => egui::Key::Tab, - KeyCode::Back => egui::Key::Backspace, - KeyCode::Return => egui::Key::Enter, + KeyCode::Backspace => egui::Key::Backspace, + KeyCode::Enter => egui::Key::Enter, KeyCode::NumpadEnter => egui::Key::Enter, KeyCode::Space => egui::Key::Space, KeyCode::Insert => egui::Key::Insert, @@ -542,42 +542,42 @@ fn bevy_to_egui_key(key_code: KeyCode) -> Option { KeyCode::End => egui::Key::End, KeyCode::PageUp => egui::Key::PageUp, KeyCode::PageDown => egui::Key::PageDown, - KeyCode::Numpad0 | KeyCode::Key0 => egui::Key::Num0, - KeyCode::Numpad1 | KeyCode::Key1 => egui::Key::Num1, - KeyCode::Numpad2 | KeyCode::Key2 => egui::Key::Num2, - KeyCode::Numpad3 | KeyCode::Key3 => egui::Key::Num3, - KeyCode::Numpad4 | KeyCode::Key4 => egui::Key::Num4, - KeyCode::Numpad5 | KeyCode::Key5 => egui::Key::Num5, - KeyCode::Numpad6 | KeyCode::Key6 => egui::Key::Num6, - KeyCode::Numpad7 | KeyCode::Key7 => egui::Key::Num7, - KeyCode::Numpad8 | KeyCode::Key8 => egui::Key::Num8, - KeyCode::Numpad9 | KeyCode::Key9 => egui::Key::Num9, - KeyCode::A => egui::Key::A, - KeyCode::B => egui::Key::B, - KeyCode::C => egui::Key::C, - KeyCode::D => egui::Key::D, - KeyCode::E => egui::Key::E, - KeyCode::F => egui::Key::F, - KeyCode::G => egui::Key::G, - KeyCode::H => egui::Key::H, - KeyCode::I => egui::Key::I, - KeyCode::J => egui::Key::J, - KeyCode::K => egui::Key::K, - KeyCode::L => egui::Key::L, - KeyCode::M => egui::Key::M, - KeyCode::N => egui::Key::N, - KeyCode::O => egui::Key::O, - KeyCode::P => egui::Key::P, - KeyCode::Q => egui::Key::Q, - KeyCode::R => egui::Key::R, - KeyCode::S => egui::Key::S, - KeyCode::T => egui::Key::T, - KeyCode::U => egui::Key::U, - KeyCode::V => egui::Key::V, - KeyCode::W => egui::Key::W, - KeyCode::X => egui::Key::X, - KeyCode::Y => egui::Key::Y, - KeyCode::Z => egui::Key::Z, + KeyCode::Numpad0 | KeyCode::Digit0 => egui::Key::Num0, + KeyCode::Numpad1 | KeyCode::Digit1 => egui::Key::Num1, + KeyCode::Numpad2 | KeyCode::Digit2 => egui::Key::Num2, + KeyCode::Numpad3 | KeyCode::Digit3 => egui::Key::Num3, + KeyCode::Numpad4 | KeyCode::Digit4 => egui::Key::Num4, + KeyCode::Numpad5 | KeyCode::Digit5 => egui::Key::Num5, + KeyCode::Numpad6 | KeyCode::Digit6 => egui::Key::Num6, + KeyCode::Numpad7 | KeyCode::Digit7 => egui::Key::Num7, + KeyCode::Numpad8 | KeyCode::Digit8 => egui::Key::Num8, + KeyCode::Numpad9 | KeyCode::Digit9 => egui::Key::Num9, + KeyCode::KeyA => egui::Key::A, + KeyCode::KeyB => egui::Key::B, + KeyCode::KeyC => egui::Key::C, + KeyCode::KeyD => egui::Key::D, + KeyCode::KeyE => egui::Key::E, + KeyCode::KeyF => egui::Key::F, + KeyCode::KeyG => egui::Key::G, + KeyCode::KeyH => egui::Key::H, + KeyCode::KeyI => egui::Key::I, + KeyCode::KeyJ => egui::Key::J, + KeyCode::KeyK => egui::Key::K, + KeyCode::KeyL => egui::Key::L, + KeyCode::KeyM => egui::Key::M, + KeyCode::KeyN => egui::Key::N, + KeyCode::KeyO => egui::Key::O, + KeyCode::KeyP => egui::Key::P, + KeyCode::KeyQ => egui::Key::Q, + KeyCode::KeyR => egui::Key::R, + KeyCode::KeyS => egui::Key::S, + KeyCode::KeyT => egui::Key::T, + KeyCode::KeyU => egui::Key::U, + KeyCode::KeyV => egui::Key::V, + KeyCode::KeyW => egui::Key::W, + KeyCode::KeyX => egui::Key::X, + KeyCode::KeyY => egui::Key::Y, + KeyCode::KeyZ => egui::Key::Z, _ => return None, }; Some(key) From 6c64c06f97edca34e760567464356c6a58557675 Mon Sep 17 00:00:00 2001 From: Ivy Date: Sat, 6 Jan 2024 16:41:15 -0800 Subject: [PATCH 02/13] using new render_asset::RenderAssetPersistencePolicy --- src/egui_node.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/egui_node.rs b/src/egui_node.rs index eb7351e06..b0ee5ab5c 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -9,6 +9,7 @@ use bevy::{ ecs::world::{FromWorld, World}, prelude::{Entity, Handle, Resource}, render::{ + render_asset::RenderAssetPersistencePolicy, render_graph::{Node, NodeRunError, RenderGraphContext}, render_resource::{ BindGroupLayout, BindGroupLayoutEntry, BindingType, BlendComponent, BlendFactor, @@ -450,6 +451,7 @@ pub(crate) fn color_image_as_bevy_image( TextureDimension::D2, pixels, TextureFormat::Rgba8UnormSrgb, + RenderAssetPersistencePolicy::Keep, ) } } From 6821f8520f750596c54f0cb072d558cb55d7be08 Mon Sep 17 00:00:00 2001 From: eri Date: Wed, 17 Jan 2024 16:21:50 +0100 Subject: [PATCH 03/13] Pass EguiTransform by reference --- src/render_systems.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/render_systems.rs b/src/render_systems.rs index 742d2efc0..802f9203c 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -140,10 +140,12 @@ pub fn prepare_egui_transforms_system( egui_transforms.offsets.clear(); for (window, size) in window_sizes.iter() { - let offset = egui_transforms.buffer.push(EguiTransform::from_window_size( - *size, - egui_settings.scale_factor as f32, - )); + let offset = egui_transforms + .buffer + .push(&EguiTransform::from_window_size( + *size, + egui_settings.scale_factor as f32, + )); egui_transforms.offsets.insert(window, offset); } From fb8aae6b68d1c0722d86538d8fb6d09f29cfae8a Mon Sep 17 00:00:00 2001 From: eri Date: Wed, 17 Jan 2024 16:27:43 +0100 Subject: [PATCH 04/13] Fix clear color and material colors --- examples/render_to_image_widget.rs | 8 ++------ examples/side_panel.rs | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/render_to_image_widget.rs b/examples/render_to_image_widget.rs index 8cbad31cd..7f9a60fd4 100644 --- a/examples/render_to_image_widget.rs +++ b/examples/render_to_image_widget.rs @@ -1,8 +1,7 @@ use bevy::{ - core_pipeline::clear_color::ClearColorConfig, prelude::*, render::{ - camera::RenderTarget, + camera::{ClearColorConfig, RenderTarget}, render_resource::{ Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, }, @@ -102,14 +101,11 @@ fn setup( commands .spawn(Camera3dBundle { - camera_3d: Camera3d { - clear_color: ClearColorConfig::Custom(Color::rgba(1.0, 1.0, 1.0, 0.0)), - ..default() - }, camera: Camera { // render before the "main pass" camera order: -1, target: RenderTarget::Image(image_handle), + clear_color: ClearColorConfig::Custom(Color::rgba(1.0, 1.0, 1.0, 0.0)), ..default() }, transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) diff --git a/examples/side_panel.rs b/examples/side_panel.rs index c2b3446bf..45ad2968f 100644 --- a/examples/side_panel.rs +++ b/examples/side_panel.rs @@ -79,12 +79,12 @@ fn setup_system( size: 5.0, subdivisions: 0, })), - material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + material: materials.add(Color::rgb(0.3, 0.5, 0.3)), ..Default::default() }); commands.spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), - material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), + material: materials.add(Color::rgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..Default::default() }); From 42a4826a79f736b512bbdae13b90ae43a7a7e931 Mon Sep 17 00:00:00 2001 From: eri Date: Wed, 17 Jan 2024 16:36:37 +0100 Subject: [PATCH 05/13] Change scale_factor to f32 to match with bevy --- examples/ui.rs | 2 +- src/egui_node.rs | 2 +- src/lib.rs | 4 ++-- src/render_systems.rs | 2 +- src/systems.rs | 12 ++++++------ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/ui.rs b/examples/ui.rs index 692546b8e..91d8174bb 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -69,7 +69,7 @@ fn update_ui_scale_factor_system( } else { 1.0 / window.scale_factor() }; - egui_settings.scale_factor = scale_factor as f64; + egui_settings.scale_factor = scale_factor; } } } diff --git a/src/egui_node.rs b/src/egui_node.rs index b0ee5ab5c..bb51dae50 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -199,7 +199,7 @@ impl Node for EguiNode { let render_device = world.get_resource::().unwrap(); - let scale_factor = window_size.scale_factor * egui_settings.scale_factor as f32; + let scale_factor = window_size.scale_factor * egui_settings.scale_factor; if window_size.physical_width == 0.0 || window_size.physical_height == 0.0 { return; } diff --git a/src/lib.rs b/src/lib.rs index f3c1fb879..2326f9252 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,7 +96,7 @@ use bevy::{ use bevy::{ app::{App, Plugin, PostUpdate, PreStartup, PreUpdate}, ecs::{ - query::{QueryEntityError, WorldQuery}, + query::{QueryData, QueryEntityError}, schedule::apply_deferred, system::SystemParam, }, @@ -140,7 +140,7 @@ pub struct EguiSettings { /// } /// } /// ``` - pub scale_factor: f64, + pub scale_factor: f32, /// Will be used as a default value for hyperlink [target](https://www.w3schools.com/tags/att_a_target.asp) hints. /// If not specified, `_self` will be used. Only matters in a web browser. #[cfg(feature = "open_url")] diff --git a/src/render_systems.rs b/src/render_systems.rs index 802f9203c..9da4bc14f 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -144,7 +144,7 @@ pub fn prepare_egui_transforms_system( .buffer .push(&EguiTransform::from_window_size( *size, - egui_settings.scale_factor as f32, + egui_settings.scale_factor, )); egui_transforms.offsets.insert(window, offset); } diff --git a/src/systems.rs b/src/systems.rs index 69c97dbba..42dbb4cce 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -153,7 +153,7 @@ pub fn process_input_system( // window this exact frame, so we are safe to ignore all `CursorMoved` events for the window // that has been left. if cursor_left_window != Some(cursor_moved.window) { - let scale_factor = egui_settings.scale_factor as f32; + let scale_factor = egui_settings.scale_factor; let mouse_position: (f32, f32) = (cursor_moved.position / scale_factor).into(); let mut context = context_params .contexts @@ -280,7 +280,7 @@ pub fn process_input_system( } for touch in input_events.ev_touch.read() { - let scale_factor = egui_settings.scale_factor as f32; + let scale_factor = egui_settings.scale_factor; let touch_position: (f32, f32) = (touch.position / scale_factor).into(); // Emit touch event @@ -380,10 +380,10 @@ pub fn update_window_contexts_system( ); let width = new_window_size.physical_width / new_window_size.scale_factor - / egui_settings.scale_factor as f32; + / egui_settings.scale_factor; let height = new_window_size.physical_height / new_window_size.scale_factor - / egui_settings.scale_factor as f32; + / egui_settings.scale_factor; if width < 1.0 || height < 1.0 { continue; @@ -397,7 +397,7 @@ pub fn update_window_contexts_system( context .ctx .0 - .set_pixels_per_point(new_window_size.scale_factor * egui_settings.scale_factor as f32); + .set_pixels_per_point(new_window_size.scale_factor * egui_settings.scale_factor); *context.window_size = new_window_size; } @@ -460,7 +460,7 @@ pub fn process_output_system( set_icon(); if ctx.has_requested_repaint() { - event.send(RequestRedraw) + event.send(RequestRedraw); } #[cfg(feature = "open_url")] From 4c7458e3fe755c36c09052d4a1afe05ccc2ca401 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Sat, 3 Feb 2024 21:59:17 +0100 Subject: [PATCH 06/13] fix compilation to bevy main as of 55493a823eeda6bb43ea74975f2f484bfd88fe69 --- src/egui_node.rs | 4 ++-- src/render_systems.rs | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index bb51dae50..43d81041a 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -9,7 +9,7 @@ use bevy::{ ecs::world::{FromWorld, World}, prelude::{Entity, Handle, Resource}, render::{ - render_asset::RenderAssetPersistencePolicy, + render_asset::RenderAssetUsages, render_graph::{Node, NodeRunError, RenderGraphContext}, render_resource::{ BindGroupLayout, BindGroupLayoutEntry, BindingType, BlendComponent, BlendFactor, @@ -451,7 +451,7 @@ pub(crate) fn color_image_as_bevy_image( TextureDimension::D2, pixels, TextureFormat::Rgba8UnormSrgb, - RenderAssetPersistencePolicy::Keep, + RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD, ) } } diff --git a/src/render_systems.rs b/src/render_systems.rs index 9da4bc14f..5c145e072 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -8,7 +8,7 @@ use bevy::{ render::{ extract_resource::ExtractResource, render_asset::RenderAssets, - render_graph::RenderGraph, + render_graph::{RenderGraph, RenderLabel}, render_resource::{ BindGroup, BindGroupEntry, BindingResource, BufferId, CachedRenderPipelineId, DynamicUniformBuffer, PipelineCache, ShaderType, SpecializedRenderPipelines, @@ -54,6 +54,14 @@ pub struct ExtractedEguiTextures<'w> { pub user_textures: Res<'w, EguiUserTextures>, } +/// RenderLabel type for the egui pass +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] +pub struct EguiPass { + window_index: u32, + window_generation: u32, +} + + impl ExtractedEguiTextures<'_> { /// Returns an iterator over all textures (both Egui and Bevy managed). pub fn handles(&self) -> impl Iterator)> + '_ { @@ -78,15 +86,18 @@ pub fn setup_new_windows_render_system( mut render_graph: ResMut, ) { for window in windows.iter() { - let egui_pass = format!("egui-{}-{}", window.index(), window.generation()); + let egui_pass = EguiPass{ + window_index: window.index(), + window_generation: window.generation() + }; let new_node = EguiNode::new(window); render_graph.add_node(egui_pass.clone(), new_node); render_graph.add_node_edge( - bevy::render::main_graph::node::CAMERA_DRIVER, - egui_pass.to_string(), + bevy::render::graph::CameraDriverLabel, + egui_pass, ); } } From 886395c3a7e3f84e080c1861543bb5177fe5aba0 Mon Sep 17 00:00:00 2001 From: eri Date: Sun, 4 Feb 2024 11:44:25 +0100 Subject: [PATCH 07/13] Fix formatting --- src/render_systems.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/render_systems.rs b/src/render_systems.rs index 5c145e072..ae5572c5e 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -61,7 +61,6 @@ pub struct EguiPass { window_generation: u32, } - impl ExtractedEguiTextures<'_> { /// Returns an iterator over all textures (both Egui and Bevy managed). pub fn handles(&self) -> impl Iterator)> + '_ { @@ -86,19 +85,16 @@ pub fn setup_new_windows_render_system( mut render_graph: ResMut, ) { for window in windows.iter() { - let egui_pass = EguiPass{ + let egui_pass = EguiPass { window_index: window.index(), - window_generation: window.generation() + window_generation: window.generation(), }; let new_node = EguiNode::new(window); render_graph.add_node(egui_pass.clone(), new_node); - render_graph.add_node_edge( - bevy::render::graph::CameraDriverLabel, - egui_pass, - ); + render_graph.add_node_edge(bevy::render::graph::CameraDriverLabel, egui_pass); } } From e7701acb01606289d18030eef20b0e635fa67ba1 Mon Sep 17 00:00:00 2001 From: eri Date: Wed, 14 Feb 2024 13:01:53 +0100 Subject: [PATCH 08/13] Fix deprecated shapes --- examples/render_to_image_widget.rs | 4 +- examples/side_panel.rs | 7 +- src/systems.rs | 114 +++++++++++++++-------------- 3 files changed, 62 insertions(+), 63 deletions(-) diff --git a/examples/render_to_image_widget.rs b/examples/render_to_image_widget.rs index 7f9a60fd4..1d24862df 100644 --- a/examples/render_to_image_widget.rs +++ b/examples/render_to_image_widget.rs @@ -69,7 +69,7 @@ fn setup( egui_user_textures.add_image(image_handle.clone()); commands.insert_resource(CubePreviewImage(image_handle.clone())); - let cube_handle = meshes.add(Mesh::from(shape::Cube { size: 4.0 })); + let cube_handle = meshes.add(Mesh::from(Cuboid::new(4.0, 4.0, 4.0))); let default_material = StandardMaterial { base_color: Color::rgb(0.8, 0.7, 0.6), reflectance: 0.02, @@ -115,7 +115,7 @@ fn setup( .insert(preview_pass_layer); let cube_size = 4.0; - let cube_handle = meshes.add(Mesh::from(shape::Box::new(cube_size, cube_size, cube_size))); + let cube_handle = meshes.add(Mesh::from(Cuboid::new(cube_size, cube_size, cube_size))); let main_material_handle = materials.add(default_material); diff --git a/examples/side_panel.rs b/examples/side_panel.rs index 45ad2968f..b65649a19 100644 --- a/examples/side_panel.rs +++ b/examples/side_panel.rs @@ -75,15 +75,12 @@ fn setup_system( mut materials: ResMut>, ) { commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { - size: 5.0, - subdivisions: 0, - })), + mesh: meshes.add(Mesh::from(Plane3d::default().mesh().size(5.0, 5.0))), material: materials.add(Color::rgb(0.3, 0.5, 0.3)), ..Default::default() }); commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), + mesh: meshes.add(Mesh::from(Cuboid::new(1.0, 1.0, 1.0))), material: materials.add(Color::rgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..Default::default() diff --git a/src/systems.rs b/src/systems.rs index 42dbb4cce..d0c9ee5f5 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -9,7 +9,7 @@ use bevy::{ system::{Local, Res, ResMut, SystemParam}, }, input::{ - keyboard::{KeyCode, KeyboardInput}, + keyboard::{Key, KeyCode, KeyboardInput}, mouse::{MouseButton, MouseButtonInput, MouseScrollUnit, MouseWheel}, touch::TouchInput, ButtonInput, ButtonState, @@ -244,7 +244,7 @@ pub fn process_input_system( }) { for ev in input_events.ev_keyboard_input.read() { - if let Some(key) = bevy_to_egui_key(ev.key_code) { + if let Some(key) = bevy_to_egui_key(&ev.logical_key) { let pressed = match ev.state { ButtonState::Pressed => true, ButtonState::Released => false, @@ -524,60 +524,62 @@ fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> Option Option { - let key = match key_code { - KeyCode::ArrowDown => egui::Key::ArrowDown, - KeyCode::ArrowLeft => egui::Key::ArrowLeft, - KeyCode::ArrowRight => egui::Key::ArrowRight, - KeyCode::ArrowUp => egui::Key::ArrowUp, - KeyCode::Escape => egui::Key::Escape, - KeyCode::Tab => egui::Key::Tab, - KeyCode::Backspace => egui::Key::Backspace, - KeyCode::Enter => egui::Key::Enter, - KeyCode::NumpadEnter => egui::Key::Enter, - KeyCode::Space => egui::Key::Space, - KeyCode::Insert => egui::Key::Insert, - KeyCode::Delete => egui::Key::Delete, - KeyCode::Home => egui::Key::Home, - KeyCode::End => egui::Key::End, - KeyCode::PageUp => egui::Key::PageUp, - KeyCode::PageDown => egui::Key::PageDown, - KeyCode::Numpad0 | KeyCode::Digit0 => egui::Key::Num0, - KeyCode::Numpad1 | KeyCode::Digit1 => egui::Key::Num1, - KeyCode::Numpad2 | KeyCode::Digit2 => egui::Key::Num2, - KeyCode::Numpad3 | KeyCode::Digit3 => egui::Key::Num3, - KeyCode::Numpad4 | KeyCode::Digit4 => egui::Key::Num4, - KeyCode::Numpad5 | KeyCode::Digit5 => egui::Key::Num5, - KeyCode::Numpad6 | KeyCode::Digit6 => egui::Key::Num6, - KeyCode::Numpad7 | KeyCode::Digit7 => egui::Key::Num7, - KeyCode::Numpad8 | KeyCode::Digit8 => egui::Key::Num8, - KeyCode::Numpad9 | KeyCode::Digit9 => egui::Key::Num9, - KeyCode::KeyA => egui::Key::A, - KeyCode::KeyB => egui::Key::B, - KeyCode::KeyC => egui::Key::C, - KeyCode::KeyD => egui::Key::D, - KeyCode::KeyE => egui::Key::E, - KeyCode::KeyF => egui::Key::F, - KeyCode::KeyG => egui::Key::G, - KeyCode::KeyH => egui::Key::H, - KeyCode::KeyI => egui::Key::I, - KeyCode::KeyJ => egui::Key::J, - KeyCode::KeyK => egui::Key::K, - KeyCode::KeyL => egui::Key::L, - KeyCode::KeyM => egui::Key::M, - KeyCode::KeyN => egui::Key::N, - KeyCode::KeyO => egui::Key::O, - KeyCode::KeyP => egui::Key::P, - KeyCode::KeyQ => egui::Key::Q, - KeyCode::KeyR => egui::Key::R, - KeyCode::KeyS => egui::Key::S, - KeyCode::KeyT => egui::Key::T, - KeyCode::KeyU => egui::Key::U, - KeyCode::KeyV => egui::Key::V, - KeyCode::KeyW => egui::Key::W, - KeyCode::KeyX => egui::Key::X, - KeyCode::KeyY => egui::Key::Y, - KeyCode::KeyZ => egui::Key::Z, +fn bevy_to_egui_key(key: &Key) -> Option { + let key = match key { + Key::ArrowDown => egui::Key::ArrowDown, + Key::ArrowLeft => egui::Key::ArrowLeft, + Key::ArrowRight => egui::Key::ArrowRight, + Key::ArrowUp => egui::Key::ArrowUp, + Key::Escape => egui::Key::Escape, + Key::Tab => egui::Key::Tab, + Key::Backspace => egui::Key::Backspace, + Key::Enter => egui::Key::Enter, + Key::Space => egui::Key::Space, + Key::Insert => egui::Key::Insert, + Key::Delete => egui::Key::Delete, + Key::Home => egui::Key::Home, + Key::End => egui::Key::End, + Key::PageUp => egui::Key::PageUp, + Key::PageDown => egui::Key::PageDown, + Key::Character(c) => match c.to_string().to_lowercase().as_str() { + "0" => egui::Key::Num0, + "1" => egui::Key::Num1, + "2" => egui::Key::Num2, + "3" => egui::Key::Num3, + "4" => egui::Key::Num4, + "5" => egui::Key::Num5, + "6" => egui::Key::Num6, + "7" => egui::Key::Num7, + "8" => egui::Key::Num8, + "9" => egui::Key::Num9, + "a" => egui::Key::A, + "b" => egui::Key::B, + "c" => egui::Key::C, + "d" => egui::Key::D, + "e" => egui::Key::E, + "f" => egui::Key::F, + "g" => egui::Key::G, + "h" => egui::Key::H, + "i" => egui::Key::I, + "j" => egui::Key::J, + "k" => egui::Key::K, + "l" => egui::Key::L, + "m" => egui::Key::M, + "n" => egui::Key::N, + "o" => egui::Key::O, + "p" => egui::Key::P, + "q" => egui::Key::Q, + "r" => egui::Key::R, + "s" => egui::Key::S, + "t" => egui::Key::T, + "u" => egui::Key::U, + "v" => egui::Key::V, + "w" => egui::Key::W, + "x" => egui::Key::X, + "y" => egui::Key::Y, + "z" => egui::Key::Z, + _ => return None, + }, _ => return None, }; Some(key) From 8cda13da66bab41ccd4bfab6dde733d111deb5fc Mon Sep 17 00:00:00 2001 From: mvlabat Date: Mon, 19 Feb 2024 12:41:33 +0200 Subject: [PATCH 09/13] Update to Bevy 0.13 --- Cargo.toml | 4 ++-- src/lib.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9665940cd..dce38100c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ name = "ui" required-features = ["render"] [dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = [ +bevy = { version = "0.13", default-features = false, features = [ "bevy_asset", ] } egui = { version = "0.24.0", default-features = false, features = ["bytemuck"] } @@ -52,7 +52,7 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] once_cell = "1.16.0" version-sync = "0.9.4" -bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = [ +bevy = { version = "0.13", default-features = false, features = [ "x11", "png", "bevy_pbr", diff --git a/src/lib.rs b/src/lib.rs index 2326f9252..8ec6924b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -904,6 +904,7 @@ mod tests { ..Default::default() }, ), + ..Default::default() }) .build() .disable::(), From 583710a3f8d7a4a5438e29a845c5fc216d4eb2fa Mon Sep 17 00:00:00 2001 From: mvlabat Date: Mon, 19 Feb 2024 13:56:32 +0200 Subject: [PATCH 10/13] Read modifiers state from logical key codes --- src/systems.rs | 68 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/systems.rs b/src/systems.rs index d0c9ee5f5..2f1f402e6 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -9,10 +9,10 @@ use bevy::{ system::{Local, Res, ResMut, SystemParam}, }, input::{ - keyboard::{Key, KeyCode, KeyboardInput}, + keyboard::{Key, KeyboardInput}, mouse::{MouseButton, MouseButtonInput, MouseScrollUnit, MouseWheel}, touch::TouchInput, - ButtonInput, ButtonState, + ButtonState, }, prelude::{Entity, EventReader, Query, Resource, Time}, time::Real, @@ -58,12 +58,22 @@ impl<'w, 's> InputEvents<'w, 's> { #[derive(Resource, Default)] pub struct TouchId(pub Option); +/// Stores "pressed" state of modifier keys. +/// Will be removed if Bevy adds support for `ButtonInput` (logical keys). +#[derive(Resource, Default, Clone, Copy, Debug)] +pub struct ModifierKeysState { + shift: bool, + ctrl: bool, + alt: bool, + win: bool, +} + #[allow(missing_docs)] #[derive(SystemParam)] pub struct InputResources<'w, 's> { #[cfg(all(feature = "manage_clipboard", not(target_os = "android")))] pub egui_clipboard: Res<'w, crate::EguiClipboard>, - pub keyboard_input: Res<'w, ButtonInput>, + pub modifier_keys_state: Local<'s, ModifierKeysState>, #[system_param(ignore)] _marker: PhantomData<&'s ()>, } @@ -81,7 +91,7 @@ pub struct ContextSystemParams<'w, 's> { /// Processes Bevy input and feeds it to Egui. pub fn process_input_system( mut input_events: InputEvents, - input_resources: InputResources, + mut input_resources: InputResources, mut context_params: ContextSystemParams, egui_settings: Res, mut egui_mouse_position: ResMut, @@ -101,17 +111,37 @@ pub fn process_input_system( }; } - let shift = input_resources.keyboard_input.pressed(KeyCode::ShiftLeft) - || input_resources.keyboard_input.pressed(KeyCode::ShiftRight); - let ctrl = input_resources.keyboard_input.pressed(KeyCode::ControlLeft) - || input_resources - .keyboard_input - .pressed(KeyCode::ControlRight); - let alt = input_resources.keyboard_input.pressed(KeyCode::AltLeft) - || input_resources.keyboard_input.pressed(KeyCode::AltRight); - let win = input_resources.keyboard_input.pressed(KeyCode::SuperLeft) - || input_resources.keyboard_input.pressed(KeyCode::SuperRight); + let mut keyboard_input_events = Vec::new(); + for event in input_events.ev_keyboard_input.read() { + // Copy the events as we might want to pass them to an Egui context later. + keyboard_input_events.push(event.clone()); + + let KeyboardInput { + logical_key, state, .. + } = event; + match logical_key { + Key::Shift => { + input_resources.modifier_keys_state.shift = state.is_pressed(); + } + Key::Control => { + input_resources.modifier_keys_state.ctrl = state.is_pressed(); + } + Key::Alt => { + input_resources.modifier_keys_state.alt = state.is_pressed(); + } + Key::Super => { + input_resources.modifier_keys_state.win = state.is_pressed(); + } + _ => {} + }; + } + let ModifierKeysState { + shift, + ctrl, + alt, + win, + } = *input_resources.modifier_keys_state; let mac_cmd = if cfg!(target_os = "macos") { win } else { @@ -243,15 +273,11 @@ pub fn process_input_system( } }) { - for ev in input_events.ev_keyboard_input.read() { + for ev in keyboard_input_events { if let Some(key) = bevy_to_egui_key(&ev.logical_key) { - let pressed = match ev.state { - ButtonState::Pressed => true, - ButtonState::Released => false, - }; let egui_event = egui::Event::Key { key, - pressed, + pressed: ev.state.is_pressed(), repeat: false, modifiers, }; @@ -260,7 +286,7 @@ pub fn process_input_system( // We also check that it's an `ButtonState::Pressed` event, as we don't want to // copy, cut or paste on the key release. #[cfg(all(feature = "manage_clipboard", not(target_os = "android")))] - if command && pressed { + if command && ev.state.is_pressed() { match key { egui::Key::C => { focused_input.events.push(egui::Event::Copy); From 357822ac5c404352eb60f057d1677ae2761af73f Mon Sep 17 00:00:00 2001 From: mvlabat Date: Mon, 19 Feb 2024 14:00:01 +0200 Subject: [PATCH 11/13] Fix lifetimes in InputResources --- src/systems.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems.rs b/src/systems.rs index 2f1f402e6..2c79b3d5f 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -75,7 +75,7 @@ pub struct InputResources<'w, 's> { pub egui_clipboard: Res<'w, crate::EguiClipboard>, pub modifier_keys_state: Local<'s, ModifierKeysState>, #[system_param(ignore)] - _marker: PhantomData<&'s ()>, + _marker: PhantomData<&'w ()>, } #[allow(missing_docs)] From aa1b23e37c56f018289f7b8a1b9326feef2cec80 Mon Sep 17 00:00:00 2001 From: Vladyslav Batyrenko Date: Mon, 19 Feb 2024 18:40:11 +0200 Subject: [PATCH 12/13] Simplify how meshes are created MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: FĂ©lix Lescaudey de Maneville --- examples/render_to_image_widget.rs | 4 ++-- examples/side_panel.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/render_to_image_widget.rs b/examples/render_to_image_widget.rs index 1d24862df..e8ba75e07 100644 --- a/examples/render_to_image_widget.rs +++ b/examples/render_to_image_widget.rs @@ -69,7 +69,7 @@ fn setup( egui_user_textures.add_image(image_handle.clone()); commands.insert_resource(CubePreviewImage(image_handle.clone())); - let cube_handle = meshes.add(Mesh::from(Cuboid::new(4.0, 4.0, 4.0))); + let cube_handle = meshes.add(Cuboid::new(4.0, 4.0, 4.0)); let default_material = StandardMaterial { base_color: Color::rgb(0.8, 0.7, 0.6), reflectance: 0.02, @@ -115,7 +115,7 @@ fn setup( .insert(preview_pass_layer); let cube_size = 4.0; - let cube_handle = meshes.add(Mesh::from(Cuboid::new(cube_size, cube_size, cube_size))); + let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size)); let main_material_handle = materials.add(default_material); diff --git a/examples/side_panel.rs b/examples/side_panel.rs index b65649a19..ff739a82c 100644 --- a/examples/side_panel.rs +++ b/examples/side_panel.rs @@ -75,12 +75,12 @@ fn setup_system( mut materials: ResMut>, ) { commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(Plane3d::default().mesh().size(5.0, 5.0))), + mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)), material: materials.add(Color::rgb(0.3, 0.5, 0.3)), ..Default::default() }); commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(Cuboid::new(1.0, 1.0, 1.0))), + mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)), material: materials.add(Color::rgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..Default::default() From 5a5d34c7e988ac76f4311bed0754b52197fe7ee0 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Mon, 19 Feb 2024 20:28:17 +0200 Subject: [PATCH 13/13] Fix comments, fields visibility and documentation --- src/render_systems.rs | 8 +++++--- src/systems.rs | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/render_systems.rs b/src/render_systems.rs index ae5572c5e..939699351 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -54,11 +54,13 @@ pub struct ExtractedEguiTextures<'w> { pub user_textures: Res<'w, EguiUserTextures>, } -/// RenderLabel type for the egui pass +/// [`RenderLabel`] type for the Egui pass. #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] pub struct EguiPass { - window_index: u32, - window_generation: u32, + /// Index of the window entity. + pub window_index: u32, + /// Generation of the window entity. + pub window_generation: u32, } impl ExtractedEguiTextures<'_> { diff --git a/src/systems.rs b/src/systems.rs index 2c79b3d5f..145e04a47 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -25,6 +25,7 @@ use std::marker::PhantomData; #[allow(missing_docs)] #[derive(SystemParam)] +// IMPORTANT: remember to add the logic to clear event readers to the `clear` method. pub struct InputEvents<'w, 's> { pub ev_cursor_entered: EventReader<'w, 's, CursorEntered>, pub ev_cursor_left: EventReader<'w, 's, CursorLeft>, @@ -41,7 +42,6 @@ pub struct InputEvents<'w, 's> { impl<'w, 's> InputEvents<'w, 's> { /// Consumes all the events. pub fn clear(&mut self) { - self.ev_touch.read().last(); self.ev_cursor_entered.read().last(); self.ev_cursor_left.read().last(); self.ev_cursor.read().last(); @@ -51,6 +51,7 @@ impl<'w, 's> InputEvents<'w, 's> { self.ev_keyboard_input.read().last(); self.ev_window_focused.read().last(); self.ev_window_created.read().last(); + self.ev_touch.read().last(); } }