From d257b3bfd318cf6d1e29d15c4e8bd7066196609c Mon Sep 17 00:00:00 2001 From: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:40:18 +0900 Subject: [PATCH 1/5] Resets the cursor to the default icon when `CursorIcon` is removed --- crates/bevy_render/src/view/window/cursor.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/bevy_render/src/view/window/cursor.rs b/crates/bevy_render/src/view/window/cursor.rs index eed41cec114be..aa02f387f8d03 100644 --- a/crates/bevy_render/src/view/window/cursor.rs +++ b/crates/bevy_render/src/view/window/cursor.rs @@ -5,6 +5,7 @@ use bevy_ecs::{ entity::Entity, query::With, reflect::ReflectComponent, + removal_detection::RemovedComponents, system::{Commands, Local, Query, Res}, world::Ref, }; @@ -74,10 +75,20 @@ pub enum CustomCursor { pub fn update_cursors( mut commands: Commands, mut windows: Query<(Entity, Ref), With>, + mut icon_removed: RemovedComponents, cursor_cache: Res, images: Res>, mut queue: Local>, ) { + // Resets the cursor to the default icon when `CursorIcon` is removed + for entity in icon_removed.read() { + commands + .entity(entity) + .insert(PendingCursor(Some(CursorSource::System( + convert_system_cursor_icon(SystemCursorIcon::Default), + )))); + } + for (entity, cursor) in windows.iter_mut() { if !(queue.remove(&entity) || cursor.is_changed()) { continue; From 11979fb5323fd324db91045b1d2f94405a297acb Mon Sep 17 00:00:00 2001 From: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:42:11 +0900 Subject: [PATCH 2/5] Remove unnecessary mut (drive-by cleanup) --- crates/bevy_render/src/view/window/cursor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/view/window/cursor.rs b/crates/bevy_render/src/view/window/cursor.rs index aa02f387f8d03..9290204ce138b 100644 --- a/crates/bevy_render/src/view/window/cursor.rs +++ b/crates/bevy_render/src/view/window/cursor.rs @@ -74,7 +74,7 @@ pub enum CustomCursor { pub fn update_cursors( mut commands: Commands, - mut windows: Query<(Entity, Ref), With>, + windows: Query<(Entity, Ref), With>, mut icon_removed: RemovedComponents, cursor_cache: Res, images: Res>, @@ -89,7 +89,7 @@ pub fn update_cursors( )))); } - for (entity, cursor) in windows.iter_mut() { + for (entity, cursor) in windows.iter() { if !(queue.remove(&entity) || cursor.is_changed()) { continue; } From 6f679ca3d956bdad9d4ee675f16370b7b79680a1 Mon Sep 17 00:00:00 2001 From: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:44:25 +0900 Subject: [PATCH 3/5] Check existence of window --- examples/window/screenshot.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/window/screenshot.rs b/examples/window/screenshot.rs index 1bf800d18c16c..806478bd0804a 100644 --- a/examples/window/screenshot.rs +++ b/examples/window/screenshot.rs @@ -32,7 +32,9 @@ fn screenshot_saving( screenshot_saving: Query>, windows: Query>, ) { - let window = windows.single(); + let Ok(window) = windows.get_single() else { + return; + }; match screenshot_saving.iter().count() { 0 => { commands.entity(window).remove::(); From 822f3c32b1e0c59b630d1c1079446b0035f90d1b Mon Sep 17 00:00:00 2001 From: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:30:15 +0900 Subject: [PATCH 4/5] Use observer --- crates/bevy_render/src/view/window/cursor.rs | 23 ++++++++++---------- crates/bevy_render/src/view/window/mod.rs | 4 +++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/crates/bevy_render/src/view/window/cursor.rs b/crates/bevy_render/src/view/window/cursor.rs index 9290204ce138b..0cd82c381a424 100644 --- a/crates/bevy_render/src/view/window/cursor.rs +++ b/crates/bevy_render/src/view/window/cursor.rs @@ -3,11 +3,11 @@ use bevy_ecs::{ change_detection::DetectChanges, component::Component, entity::Entity, + observer::Trigger, query::With, reflect::ReflectComponent, - removal_detection::RemovedComponents, system::{Commands, Local, Query, Res}, - world::Ref, + world::{OnRemove, Ref}, }; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::{tracing::warn, HashSet}; @@ -75,20 +75,10 @@ pub enum CustomCursor { pub fn update_cursors( mut commands: Commands, windows: Query<(Entity, Ref), With>, - mut icon_removed: RemovedComponents, cursor_cache: Res, images: Res>, mut queue: Local>, ) { - // Resets the cursor to the default icon when `CursorIcon` is removed - for entity in icon_removed.read() { - commands - .entity(entity) - .insert(PendingCursor(Some(CursorSource::System( - convert_system_cursor_icon(SystemCursorIcon::Default), - )))); - } - for (entity, cursor) in windows.iter() { if !(queue.remove(&entity) || cursor.is_changed()) { continue; @@ -161,6 +151,15 @@ pub fn update_cursors( } } +/// Resets the cursor to the default icon when `CursorIcon` is removed. +pub fn on_remove_cursor_icon(trigger: Trigger, mut commands: Commands) { + commands + .entity(trigger.entity()) + .insert(PendingCursor(Some(CursorSource::System( + convert_system_cursor_icon(SystemCursorIcon::Default), + )))); +} + /// Returns the image data as a `Vec`. /// Only supports rgba8 and rgba32float formats. fn image_to_rgba_pixels(image: &Image) -> Option> { diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index d9d30d440dcf5..96fff7da75f60 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -23,7 +23,7 @@ use wgpu::{ pub mod cursor; pub mod screenshot; -use self::cursor::update_cursors; +use self::cursor::{on_remove_cursor_icon, update_cursors}; use screenshot::{ScreenshotPlugin, ScreenshotToScreenPipeline}; pub struct WindowRenderPlugin; @@ -34,6 +34,8 @@ impl Plugin for WindowRenderPlugin { .init_resource::() .add_systems(Last, update_cursors); + app.observe(on_remove_cursor_icon); + if let Some(render_app) = app.get_sub_app_mut(RenderApp) { render_app .init_resource::() From e86e2b224c2eba43a76f349cf2256cb43bfe86b5 Mon Sep 17 00:00:00 2001 From: akimakinai <105044389+akimakinai@users.noreply.github.com> Date: Tue, 10 Sep 2024 01:34:19 +0900 Subject: [PATCH 5/5] Migrate to CursorPlugin --- crates/bevy_render/src/view/window/cursor.rs | 2 ++ crates/bevy_render/src/view/window/mod.rs | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/view/window/cursor.rs b/crates/bevy_render/src/view/window/cursor.rs index 07e4933fa08db..dbc5ebda3510d 100644 --- a/crates/bevy_render/src/view/window/cursor.rs +++ b/crates/bevy_render/src/view/window/cursor.rs @@ -28,6 +28,8 @@ impl Plugin for CursorPlugin { app.register_type::() .init_resource::() .add_systems(Last, update_cursors); + + app.observe(on_remove_cursor_icon); } } diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index 8b98b8b36f4fc..0eb9e95d8718e 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -23,7 +23,6 @@ use wgpu::{ pub mod cursor; pub mod screenshot; -use self::cursor::{on_remove_cursor_icon, update_cursors}; use screenshot::{ScreenshotPlugin, ScreenshotToScreenPipeline}; pub struct WindowRenderPlugin; @@ -32,8 +31,6 @@ impl Plugin for WindowRenderPlugin { fn build(&self, app: &mut App) { app.add_plugins((ScreenshotPlugin, CursorPlugin)); - app.observe(on_remove_cursor_icon); - if let Some(render_app) = app.get_sub_app_mut(RenderApp) { render_app .init_resource::()