From 565616622bd3d7a801492c8300452ce87da19404 Mon Sep 17 00:00:00 2001 From: Friz64 Date: Sat, 2 Nov 2024 02:47:32 +0100 Subject: [PATCH] Correctly feature gate `custom_cursor` (#16093) # Objective Currently there's no way to change the window's cursor icon with the `custom_cursor` feature **disabled**. You should still be able to set system cursor icons. Connections: - https://github.com/bevyengine/bevy/pull/15649 ## Solution Move some `custom_cursor` feature gates around, as to expose the `CursorIcon` type again. Note this refactoring was mainly piloted by hunting after the compiler warnings -- I shouldn't have missed anything, but FYI. ## Testing Disabled the `custom_cursor` feature, ran the `window_settings` example. --- crates/bevy_winit/src/converters.rs | 2 -- crates/bevy_winit/src/cursor.rs | 30 +++++++++++++++++++++++------ crates/bevy_winit/src/lib.rs | 2 -- crates/bevy_winit/src/state.rs | 20 +++++++++++++++---- examples/window/window_settings.rs | 10 ++++++++-- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/crates/bevy_winit/src/converters.rs b/crates/bevy_winit/src/converters.rs index 9a9c33ef36..f96f8003b0 100644 --- a/crates/bevy_winit/src/converters.rs +++ b/crates/bevy_winit/src/converters.rs @@ -6,7 +6,6 @@ use bevy_input::{ ButtonState, }; use bevy_math::{CompassOctant, Vec2}; -#[cfg(feature = "custom_cursor")] use bevy_window::SystemCursorIcon; use bevy_window::{EnabledButtons, WindowLevel, WindowTheme}; use winit::keyboard::{Key, NamedKey, NativeKey}; @@ -630,7 +629,6 @@ pub fn convert_native_key(native_key: &NativeKey) -> bevy_input::keyboard::Nativ } } -#[cfg(feature = "custom_cursor")] /// Converts a [`SystemCursorIcon`] to a [`winit::window::CursorIcon`]. pub fn convert_system_cursor_icon(cursor_icon: SystemCursorIcon) -> winit::window::CursorIcon { match cursor_icon { diff --git a/crates/bevy_winit/src/cursor.rs b/crates/bevy_winit/src/cursor.rs index 524a6ceb3c..63e298c0c0 100644 --- a/crates/bevy_winit/src/cursor.rs +++ b/crates/bevy_winit/src/cursor.rs @@ -2,11 +2,18 @@ use crate::{ converters::convert_system_cursor_icon, - state::{CursorSource, CustomCursorCache, CustomCursorCacheKey, PendingCursor}, + state::{CursorSource, PendingCursor}, +}; +#[cfg(feature = "custom_cursor")] +use crate::{ + state::{CustomCursorCache, CustomCursorCacheKey}, WinitCustomCursor, }; use bevy_app::{App, Last, Plugin}; +#[cfg(feature = "custom_cursor")] use bevy_asset::{Assets, Handle}; +#[cfg(feature = "custom_cursor")] +use bevy_ecs::system::Res; use bevy_ecs::{ change_detection::DetectChanges, component::Component, @@ -14,21 +21,27 @@ use bevy_ecs::{ observer::Trigger, query::With, reflect::ReflectComponent, - system::{Commands, Local, Query, Res}, + system::{Commands, Local, Query}, world::{OnRemove, Ref}, }; +#[cfg(feature = "custom_cursor")] use bevy_image::Image; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_utils::{tracing::warn, HashSet}; +#[cfg(feature = "custom_cursor")] +use bevy_utils::tracing::warn; +use bevy_utils::HashSet; use bevy_window::{SystemCursorIcon, Window}; +#[cfg(feature = "custom_cursor")] use wgpu_types::TextureFormat; pub(crate) struct CursorPlugin; impl Plugin for CursorPlugin { fn build(&self, app: &mut App) { + #[cfg(feature = "custom_cursor")] + app.init_resource::(); + app.register_type::() - .init_resource::() .add_systems(Last, update_cursors); app.add_observer(on_remove_cursor_icon); @@ -39,6 +52,7 @@ impl Plugin for CursorPlugin { #[derive(Component, Debug, Clone, Reflect, PartialEq, Eq)] #[reflect(Component, Debug, Default, PartialEq)] pub enum CursorIcon { + #[cfg(feature = "custom_cursor")] /// Custom cursor image. Custom(CustomCursor), /// System provided cursor icon. @@ -57,12 +71,14 @@ impl From for CursorIcon { } } +#[cfg(feature = "custom_cursor")] impl From for CursorIcon { fn from(cursor: CustomCursor) -> Self { CursorIcon::Custom(cursor) } } +#[cfg(feature = "custom_cursor")] /// Custom cursor image data. #[derive(Debug, Clone, Reflect, PartialEq, Eq, Hash)] pub enum CustomCursor { @@ -90,8 +106,8 @@ pub enum CustomCursor { fn update_cursors( mut commands: Commands, windows: Query<(Entity, Ref), With>, - cursor_cache: Res, - images: Res>, + #[cfg(feature = "custom_cursor")] cursor_cache: Res, + #[cfg(feature = "custom_cursor")] images: Res>, mut queue: Local>, ) { for (entity, cursor) in windows.iter() { @@ -100,6 +116,7 @@ fn update_cursors( } let cursor_source = match cursor.as_ref() { + #[cfg(feature = "custom_cursor")] CursorIcon::Custom(CustomCursor::Image { handle, hotspot }) => { let cache_key = CustomCursorCacheKey::Asset(handle.id()); @@ -170,6 +187,7 @@ fn on_remove_cursor_icon(trigger: Trigger, mut commands: C )))); } +#[cfg(feature = "custom_cursor")] /// 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_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 2d1953699f..80b04b0de7 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -44,7 +44,6 @@ use crate::{ pub mod accessibility; mod converters; -#[cfg(feature = "custom_cursor")] pub mod cursor; mod state; mod system; @@ -136,7 +135,6 @@ impl Plugin for WinitPlugin { ); app.add_plugins(AccessKitPlugin); - #[cfg(feature = "custom_cursor")] app.add_plugins(cursor::CursorPlugin); let event_loop = event_loop_builder diff --git a/crates/bevy_winit/src/state.rs b/crates/bevy_winit/src/state.rs index 9217968d31..a9d4831592 100644 --- a/crates/bevy_winit/src/state.rs +++ b/crates/bevy_winit/src/state.rs @@ -158,19 +158,19 @@ pub enum CustomCursorCacheKey { #[derive(Debug, Clone, Default, Resource)] pub struct CustomCursorCache(pub HashMap); -#[cfg(feature = "custom_cursor")] /// A source for a cursor. Consumed by the winit event loop. #[derive(Debug)] pub enum CursorSource { + #[cfg(feature = "custom_cursor")] /// A custom cursor was identified to be cached, no reason to recreate it. CustomCached(CustomCursorCacheKey), + #[cfg(feature = "custom_cursor")] /// A custom cursor was not cached, so it needs to be created by the winit event loop. Custom((CustomCursorCacheKey, winit::window::CustomCursorSource)), /// A system cursor was requested. System(winit::window::CursorIcon), } -#[cfg(feature = "custom_cursor")] /// Component that indicates what cursor should be used for a window. Inserted /// automatically after changing `CursorIcon` and consumed by the winit event /// loop. @@ -560,6 +560,8 @@ impl ApplicationHandler for WinitAppRunnerState { self.run_app_update(); #[cfg(feature = "custom_cursor")] self.update_cursors(event_loop); + #[cfg(not(feature = "custom_cursor"))] + self.update_cursors(); self.ran_update_since_last_redraw = true; } else { self.redraw_requested = true; @@ -787,15 +789,23 @@ impl WinitAppRunnerState { .send_batch(buffered_events); } - #[cfg(feature = "custom_cursor")] - fn update_cursors(&mut self, event_loop: &ActiveEventLoop) { + fn update_cursors(&mut self, #[cfg(feature = "custom_cursor")] event_loop: &ActiveEventLoop) { + #[cfg(feature = "custom_cursor")] let mut windows_state: SystemState<( NonSendMut, ResMut, Query<(Entity, &mut PendingCursor), Changed>, )> = SystemState::new(self.world_mut()); + #[cfg(feature = "custom_cursor")] let (winit_windows, mut cursor_cache, mut windows) = windows_state.get_mut(self.world_mut()); + #[cfg(not(feature = "custom_cursor"))] + let mut windows_state: SystemState<( + NonSendMut, + Query<(Entity, &mut PendingCursor), Changed>, + )> = SystemState::new(self.world_mut()); + #[cfg(not(feature = "custom_cursor"))] + let (winit_windows, mut windows) = windows_state.get_mut(self.world_mut()); for (entity, mut pending_cursor) in windows.iter_mut() { let Some(winit_window) = winit_windows.get_window(entity) else { @@ -806,6 +816,7 @@ impl WinitAppRunnerState { }; let final_cursor: winit::window::Cursor = match pending_cursor { + #[cfg(feature = "custom_cursor")] CursorSource::CustomCached(cache_key) => { let Some(cached_cursor) = cursor_cache.0.get(&cache_key) else { error!("Cursor should have been cached, but was not found"); @@ -813,6 +824,7 @@ impl WinitAppRunnerState { }; cached_cursor.clone().into() } + #[cfg(feature = "custom_cursor")] CursorSource::Custom((cache_key, cursor)) => { let custom_cursor = event_loop.create_custom_cursor(cursor); cursor_cache.0.insert(cache_key, custom_cursor.clone()); diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index defcce0e3d..c70d39a307 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -1,12 +1,14 @@ //! Illustrates how to change window settings and shows how to affect //! the mouse pointer in various ways. +#[cfg(feature = "custom_cursor")] +use bevy::winit::cursor::CustomCursor; use bevy::{ core::FrameCount, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, window::{CursorGrabMode, PresentMode, SystemCursorIcon, WindowLevel, WindowTheme}, - winit::cursor::{CursorIcon, CustomCursor}, + winit::cursor::CursorIcon, }; fn main() { @@ -152,12 +154,16 @@ fn toggle_theme(mut window: Single<&mut Window>, input: Res #[derive(Resource)] struct CursorIcons(Vec); -fn init_cursor_icons(mut commands: Commands, asset_server: Res) { +fn init_cursor_icons( + mut commands: Commands, + #[cfg(feature = "custom_cursor")] asset_server: Res, +) { commands.insert_resource(CursorIcons(vec![ SystemCursorIcon::Default.into(), SystemCursorIcon::Pointer.into(), SystemCursorIcon::Wait.into(), SystemCursorIcon::Text.into(), + #[cfg(feature = "custom_cursor")] CustomCursor::Image { handle: asset_server.load("branding/icon.png"), hotspot: (128, 128),