This commit is contained in:
aloucks 2025-07-17 02:52:00 -04:00 committed by GitHub
commit ca2ae64029
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 139 additions and 6 deletions

View File

@ -3813,6 +3813,15 @@ doc-scrape-examples = true
[package.metadata.example.minimizing]
hidden = true
[[example]]
name = "desktop_request_redraw"
path = "tests/window/desktop_request_redraw.rs"
doc-scrape-examples = true
required-features = ["bevy_dev_tools"]
[package.metadata.example.desktop_request_redraw]
hidden = true
[[example]]
name = "window_resizing"
path = "examples/window/window_resizing.rs"

View File

@ -552,16 +552,11 @@ impl<T: BufferedEvent> ApplicationHandler<T> for WinitAppRunnerState<T> {
impl<T: BufferedEvent> WinitAppRunnerState<T> {
fn redraw_requested(&mut self, event_loop: &ActiveEventLoop) {
let mut redraw_event_reader = EventCursor::<RequestRedraw>::default();
let mut close_event_reader = EventCursor::<WindowCloseRequested>::default();
let mut focused_windows_state: SystemState<(Res<WinitSettings>, Query<(Entity, &Window)>)> =
SystemState::new(self.world_mut());
if let Some(app_redraw_events) = self.world().get_resource::<Events<RequestRedraw>>() {
if redraw_event_reader.read(app_redraw_events).last().is_some() {
self.redraw_requested = true;
}
}
let (config, windows) = focused_windows_state.get(self.world());
let focused = windows.iter().any(|(_, window)| window.focused);
@ -671,6 +666,26 @@ impl<T: BufferedEvent> WinitAppRunnerState<T> {
self.redraw_requested = true;
}
// Read RequestRedraw events that may have been sent during the update
if let Some(app_redraw_events) = self.world().get_resource::<Events<RequestRedraw>>() {
if redraw_event_reader.read(app_redraw_events).last().is_some() {
self.redraw_requested = true;
}
}
// Running the app may have produced WindowCloseRequested events that should be processed
if let Some(close_request_events) =
self.world().get_resource::<Events<WindowCloseRequested>>()
{
if close_event_reader
.read(close_request_events)
.last()
.is_some()
{
self.redraw_requested = true;
}
}
// Running the app may have changed the WinitSettings resource, so we have to re-extract it.
let (config, windows) = focused_windows_state.get(self.world());
let focused = windows.iter().any(|(_, window)| window.focused);

View File

@ -0,0 +1,109 @@
//! Desktop request redraw
use bevy::{
dev_tools::fps_overlay::{FpsOverlayConfig, FpsOverlayPlugin},
prelude::*,
window::RequestRedraw,
winit::WinitSettings,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MeshPickingPlugin)
// Enable the FPS overlay with a high resolution refresh interval. This makes it
// easier to validate that UpdateMode is behaving correctly when desktop_app is used.
// The FPS counter should essentially pause when the cube is not rotating and should
// update rapidly when the cube is rotating or there is input (e.g. moving the mouse).
//
// Left and Right clicking the cube should roggle rotation on/off.
.add_plugins(FpsOverlayPlugin {
config: FpsOverlayConfig {
text_config: TextFont {
font_size: 12.0,
..default()
},
text_color: Color::srgb(0.0, 1.0, 0.0),
refresh_interval: core::time::Duration::from_millis(16),
..default()
},
})
.insert_resource(WinitSettings::desktop_app())
.add_systems(Startup, setup)
.add_systems(Update, (update, redraw.after(update)))
.run();
}
#[derive(Component)]
struct AnimationActive;
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0.0, 5.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
));
commands.spawn((
PointLight {
intensity: 1e6,
..Default::default()
},
Transform::from_xyz(-1.0, 5.0, 1.0),
));
let node = Node {
display: Display::Block,
padding: UiRect::all(Val::Px(10.0)),
row_gap: Val::Px(10.0),
..Default::default()
};
commands.spawn((
node.clone(),
children![
(
node.clone(),
children![Text::new("Right click cube to pause animation")]
),
(
node.clone(),
children![Text::new("Left click cube to start animation")]
)
],
));
commands
.spawn((
Mesh3d(meshes.add(Cuboid::from_length(1.0))),
MeshMaterial3d(materials.add(Color::WHITE)),
AnimationActive,
))
.observe(
|trigger: Trigger<Pointer<Click>>, mut commands: Commands| match trigger.button {
PointerButton::Primary => {
commands.entity(trigger.target()).insert(AnimationActive);
}
PointerButton::Secondary => {
commands
.entity(trigger.target())
.remove::<AnimationActive>();
}
_ => {}
},
);
}
fn update(time: Res<Time>, mut query: Query<&mut Transform, With<AnimationActive>>) {
if let Ok(mut transform) = query.single_mut() {
transform.rotate_x(time.delta_secs().min(1.0 / 60.0));
}
}
fn redraw(mut commands: Commands, query: Query<Entity, With<AnimationActive>>) {
if query.iter().next().is_some() {
commands.send_event(RequestRedraw);
}
}