diff --git a/crates/processing_glfw/src/lib.rs b/crates/processing_glfw/src/lib.rs index 6b63c6b..cbfe8db 100644 --- a/crates/processing_glfw/src/lib.rs +++ b/crates/processing_glfw/src/lib.rs @@ -300,6 +300,10 @@ impl GlfwContext { WindowEvent::Focus(focused) => { input_set_focus(surface, focused).unwrap(); } + WindowEvent::Size(width, height) => { + processing_render::surface_resize(surface, width as u32, height as u32) + .unwrap(); + } _ => {} } } @@ -355,6 +359,9 @@ impl GlfwContext { Ok(()) }); self.last_applied.position = frame_pos; + + let (w, h) = self.window.get_size(); + self.last_applied.size = bevy::math::UVec2::new(w.max(0) as u32, h.max(0) as u32); } #[cfg(not(feature = "wayland"))] @@ -529,8 +536,8 @@ fn read_desired_window(surface: Entity) -> Option { _ => None, }, size: bevy::math::UVec2::new( - window.resolution.physical_width(), - window.resolution.physical_height(), + window.resolution.width() as u32, + window.resolution.height() as u32, ), visible: window.visible, resizable: window.resizable, diff --git a/crates/processing_pyo3/src/lib.rs b/crates/processing_pyo3/src/lib.rs index 59024d4..7bd7215 100644 --- a/crates/processing_pyo3/src/lib.rs +++ b/crates/processing_pyo3/src/lib.rs @@ -120,13 +120,12 @@ pub(crate) fn reset_tracked_globals() { fn sync_globals(module: &Bound<'_, PyModule>, globals: &Bound<'_, PyAny>) -> PyResult<()> { let graphics = get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?; - input::sync_globals( - globals, - graphics.surface.entity, - graphics.width, - graphics.height, - )?; - surface::sync_globals(globals, &graphics.surface, graphics.width, graphics.height)?; + let width = ::processing::prelude::surface_width(graphics.surface.entity) + .map_err(|e| PyRuntimeError::new_err(format!("{e}")))?; + let height = ::processing::prelude::surface_height(graphics.surface.entity) + .map_err(|e| PyRuntimeError::new_err(format!("{e}")))?; + input::sync_globals(globals, graphics.surface.entity, width, height)?; + surface::sync_globals(globals, &graphics.surface, width, height)?; time::sync_globals(globals)?; Ok(()) } diff --git a/crates/processing_render/src/graphics.rs b/crates/processing_render/src/graphics.rs index 001f9f5..8adc5e1 100644 --- a/crates/processing_render/src/graphics.rs +++ b/crates/processing_render/src/graphics.rs @@ -22,7 +22,7 @@ use bevy::{ sync_world::MainEntity, view::ViewTarget, }, - window::WindowRef, + window::{WindowRef, WindowResized}, }; use crate::{ @@ -118,6 +118,8 @@ impl CameraProjection for ProcessingProjection { // this gets called with the render target's physical dimensions (i.e. accounting for // scale factor), but our projection is in logical pixel units // TODO: handle resizes? + self.width = _width; + self.height = _height; } fn far(&self) -> f32 { @@ -258,6 +260,7 @@ pub fn sync_to_surface( mut graphics_query: Query<(&mut Graphics, &RenderTarget)>, windows: Query<&Window, (With, Changed)>, render_device: Res, + mut resize_messages: MessageWriter, ) { for (mut graphics, target) in graphics_query.iter_mut() { let RenderTarget::Window(WindowRef::Entity(surface_entity)) = *target else { @@ -271,6 +274,12 @@ pub fn sync_to_surface( if graphics.size.width == physical_w && graphics.size.height == physical_h { continue; } + //winit plugin disabled, so WindowResized is never triggered automatically + resize_messages.write(WindowResized { + window: surface_entity, + width: window.width(), + height: window.height(), + }); graphics.size = Extent3d { width: physical_w, height: physical_h, diff --git a/crates/processing_render/src/lib.rs b/crates/processing_render/src/lib.rs index f68f5d9..e6ac5d7 100644 --- a/crates/processing_render/src/lib.rs +++ b/crates/processing_render/src/lib.rs @@ -1702,6 +1702,24 @@ pub fn surface_physical_height(entity: Entity) -> error::Result { }) } +pub fn surface_width(entity: Entity) -> error::Result { + app_mut(|app| { + Ok(app + .world_mut() + .run_system_cached_with(surface::width, entity) + .unwrap()) + }) +} + +pub fn surface_height(entity: Entity) -> error::Result { + app_mut(|app| { + Ok(app + .world_mut() + .run_system_cached_with(surface::height, entity) + .unwrap()) + }) +} + pub fn monitor_list() -> error::Result> { app_mut(|app| Ok(app.world_mut().run_system_cached(monitor::list).unwrap())) } diff --git a/crates/processing_render/src/surface.rs b/crates/processing_render/src/surface.rs index 248ac1e..144dfd7 100644 --- a/crates/processing_render/src/surface.rs +++ b/crates/processing_render/src/surface.rs @@ -21,13 +21,14 @@ use bevy::{ app::{App, Plugin}, asset::Assets, + camera::RenderTarget, ecs::query::QueryEntityError, math::{IRect, IVec2}, prelude::{Commands, Component, Entity, In, Query, ResMut, Window, With, default}, render::render_resource::{Extent3d, TextureFormat}, window::{ CompositeAlphaMode, Monitor, RawHandleWrapper, WindowLevel, WindowMode, WindowPosition, - WindowResolution, WindowWrapper, + WindowRef, WindowResolution, WindowWrapper, }, }; use raw_window_handle::{ @@ -39,7 +40,7 @@ use processing_core::error::{self, ProcessingError, Result}; #[cfg(not(target_os = "windows"))] use std::ptr::NonNull; -use crate::image::Image; +use crate::{graphics::SurfaceSize, image::Image}; #[derive(Component, Debug, Clone)] pub struct Surface; @@ -394,7 +395,11 @@ pub fn destroy( pub fn resize( In((window_entity, width, height)): In<(Entity, u32, u32)>, mut windows: Query<&mut Window>, + mut graphics_query: Query<(&RenderTarget, &mut SurfaceSize)>, ) -> Result<()> { + let width = width.max(1); + let height = height.max(1); + if let Ok(mut window) = windows.get_mut(window_entity) { let scale = window.resolution.scale_factor(); let physical_w = (width as f32 * scale) as u32; @@ -403,6 +408,15 @@ pub fn resize( .resolution .set_physical_resolution(physical_w, physical_h); } + + // SurfaceSize changes on resize, if not handled will break APIs dependent on correct SurfaceSize + for (target, mut surface_size) in graphics_query.iter_mut() { + if let RenderTarget::Window(WindowRef::Entity(surface)) = *target + && surface == window_entity + { + *surface_size = SurfaceSize(width, height); + } + } Ok(()) } @@ -448,6 +462,20 @@ pub fn physical_height(In(entity): In, query: Query<&Window>) -> u32 { .unwrap_or(0) } +pub fn width(In(entity): In, query: Query<&Window>) -> u32 { + query + .get(entity) + .map(|w| w.resolution.width() as u32) + .unwrap_or(0) +} + +pub fn height(In(entity): In, query: Query<&Window>) -> u32 { + query + .get(entity) + .map(|w| w.resolution.height() as u32) + .unwrap_or(0) +} + pub fn set_title( In((entity, title)): In<(Entity, String)>, mut windows: Query<&mut Window>,