@@ -3,7 +3,7 @@ use bevy_app::{App, AppExit, PluginsState};
33use bevy_ecs:: {
44 change_detection:: { DetectChanges , Res } ,
55 entity:: Entity ,
6- message:: { MessageCursor , MessageWriter } ,
6+ message:: MessageCursor ,
77 prelude:: * ,
88 system:: SystemState ,
99 world:: FromWorld ,
@@ -79,10 +79,7 @@ pub(crate) struct WinitAppRunnerState {
7979 /// Raw Winit window events to send
8080 raw_winit_events : Vec < RawWinitWindowEvent > ,
8181
82- message_writer_system_state : SystemState < (
83- MessageWriter < ' static , WindowResized > ,
84- MessageWriter < ' static , WindowBackendScaleFactorChanged > ,
85- MessageWriter < ' static , WindowScaleFactorChanged > ,
82+ windows_system_state : SystemState <
8683 Query <
8784 ' static ,
8885 ' static ,
@@ -92,19 +89,16 @@ pub(crate) struct WinitAppRunnerState {
9289 & ' static mut WinitWindowPressedKeys ,
9390 ) ,
9491 > ,
95- ) > ,
92+ > ,
9693 /// time at which next tick is scheduled to run when `update_mode` is [`UpdateMode::Reactive`]
9794 scheduled_tick_start : Option < Instant > ,
9895}
9996
10097impl WinitAppRunnerState {
10198 fn new ( mut app : App ) -> Self {
102- let message_writer_system_state: SystemState < (
103- MessageWriter < WindowResized > ,
104- MessageWriter < WindowBackendScaleFactorChanged > ,
105- MessageWriter < WindowScaleFactorChanged > ,
99+ let windows_system_state: SystemState <
106100 Query < ( & mut Window , & mut CachedWindow , & mut WinitWindowPressedKeys ) > ,
107- ) > = SystemState :: new ( app. world_mut ( ) ) ;
101+ > = SystemState :: new ( app. world_mut ( ) ) ;
108102
109103 Self {
110104 app,
@@ -122,7 +116,7 @@ impl WinitAppRunnerState {
122116 startup_forced_updates : 5 ,
123117 bevy_window_events : Vec :: new ( ) ,
124118 raw_winit_events : Vec :: new ( ) ,
125- message_writer_system_state ,
119+ windows_system_state ,
126120 scheduled_tick_start : None ,
127121 }
128122 }
@@ -219,13 +213,8 @@ impl ApplicationHandler<WinitUserEvent> for WinitAppRunnerState {
219213
220214 WINIT_WINDOWS . with_borrow ( |winit_windows| {
221215 ACCESS_KIT_ADAPTERS . with_borrow_mut ( |access_kit_adapters| {
222- let (
223- mut window_resized,
224- mut window_backend_scale_factor_changed,
225- mut window_scale_factor_changed,
226- mut windows,
227- ) = self
228- . message_writer_system_state
216+ let mut windows = self
217+ . windows_system_state
229218 . get_mut ( self . app . world_mut ( ) )
230219 . unwrap ( ) ;
231220
@@ -256,17 +245,18 @@ impl ApplicationHandler<WinitUserEvent> for WinitAppRunnerState {
256245 }
257246
258247 match event {
259- WindowEvent :: Resized ( size) => {
260- react_to_resize ( window , & mut win , size , & mut window_resized ) ;
261- }
248+ WindowEvent :: Resized ( size) => self
249+ . bevy_window_events
250+ . send ( react_to_resize ( window , & mut win , size ) ) ,
262251 WindowEvent :: ScaleFactorChanged { scale_factor, .. } => {
263- react_to_scale_factor_change (
264- window,
265- & mut win,
266- scale_factor,
267- & mut window_backend_scale_factor_changed,
268- & mut window_scale_factor_changed,
269- ) ;
252+ let ( window_backend_scale_factor_changed, window_scale_factor_changed) =
253+ react_to_scale_factor_change ( window, & mut win, scale_factor) ;
254+
255+ self . bevy_window_events
256+ . send ( window_backend_scale_factor_changed) ;
257+ if let Some ( window_scale_factor_changed) = window_scale_factor_changed {
258+ self . bevy_window_events . send ( window_scale_factor_changed) ;
259+ }
270260 }
271261 WindowEvent :: CloseRequested => self
272262 . bevy_window_events
@@ -926,42 +916,51 @@ pub(crate) fn react_to_resize(
926916 window_entity : Entity ,
927917 window : & mut Window ,
928918 size : PhysicalSize < u32 > ,
929- window_resized : & mut MessageWriter < WindowResized > ,
930- ) {
919+ ) -> WindowResized {
931920 window
932921 . resolution
933922 . set_physical_resolution ( size. width , size. height ) ;
934923
935- window_resized . write ( WindowResized {
924+ WindowResized {
936925 window : window_entity,
937926 width : window. width ( ) ,
938927 height : window. height ( ) ,
939- } ) ;
928+ }
940929}
941930
942931pub ( crate ) fn react_to_scale_factor_change (
943932 window_entity : Entity ,
944933 window : & mut Window ,
945934 scale_factor : f64 ,
946- window_backend_scale_factor_changed : & mut MessageWriter < WindowBackendScaleFactorChanged > ,
947- window_scale_factor_changed : & mut MessageWriter < WindowScaleFactorChanged > ,
935+ ) -> (
936+ WindowBackendScaleFactorChanged ,
937+ Option < WindowScaleFactorChanged > ,
948938) {
949939 let prior_factor = window. resolution . scale_factor ( ) ;
950940 window. resolution . set_scale_factor ( scale_factor as f32 ) ;
951941
952- window_backend_scale_factor_changed. write ( WindowBackendScaleFactorChanged {
942+ let window_backend_scale_factor_changed = WindowBackendScaleFactorChanged {
953943 window : window_entity,
954944 scale_factor,
955- } ) ;
945+ } ;
956946
957947 let scale_factor_override = window. resolution . scale_factor_override ( ) ;
958948
959- if scale_factor_override. is_none ( ) && !relative_eq ! ( scale_factor as f32 , prior_factor) {
960- window_scale_factor_changed. write ( WindowScaleFactorChanged {
961- window : window_entity,
962- scale_factor,
963- } ) ;
964- }
949+ let window_scale_factor_changed =
950+ if scale_factor_override. is_none ( ) && !relative_eq ! ( scale_factor as f32 , prior_factor) {
951+ let window_scale_factor_changed = WindowScaleFactorChanged {
952+ window : window_entity,
953+ scale_factor,
954+ } ;
955+ Some ( window_scale_factor_changed)
956+ } else {
957+ None
958+ } ;
959+
960+ (
961+ window_backend_scale_factor_changed,
962+ window_scale_factor_changed,
963+ )
965964}
966965
967966#[ cfg( test) ]
@@ -1011,6 +1010,30 @@ mod tests {
10111010 } )
10121011 ) ;
10131012 assert_eq ! ( window_scale_factor_changed_messages_iter. next( ) , None ) ;
1013+
1014+ let window_event_messages = app. world ( ) . resource :: < Messages < BevyWindowEvent > > ( ) ;
1015+ assert_eq ! ( window_event_messages. len( ) , 2 ) ;
1016+
1017+ let mut window_event_messages_iter = window_event_messages. iter_current_update_messages ( ) ;
1018+ assert_eq ! (
1019+ window_event_messages_iter. next( ) ,
1020+ Some ( & BevyWindowEvent :: WindowBackendScaleFactorChanged (
1021+ WindowBackendScaleFactorChanged {
1022+ window: window_entity,
1023+ scale_factor: 2.0
1024+ }
1025+ ) )
1026+ ) ;
1027+ assert_eq ! (
1028+ window_event_messages_iter. next( ) ,
1029+ Some ( & BevyWindowEvent :: WindowScaleFactorChanged (
1030+ WindowScaleFactorChanged {
1031+ window: window_entity,
1032+ scale_factor: 2.0
1033+ }
1034+ ) )
1035+ ) ;
1036+ assert_eq ! ( window_event_messages_iter. next( ) , None ) ;
10141037 }
10151038
10161039 #[ test]
@@ -1043,6 +1066,21 @@ mod tests {
10431066 let window_scale_factor_changed_messages =
10441067 app. world ( ) . resource :: < Messages < WindowScaleFactorChanged > > ( ) ;
10451068 assert ! ( window_scale_factor_changed_messages. is_empty( ) ) ;
1069+
1070+ let window_event_messages = app. world ( ) . resource :: < Messages < BevyWindowEvent > > ( ) ;
1071+ assert_eq ! ( window_event_messages. len( ) , 1 ) ;
1072+
1073+ let mut window_event_messages_iter = window_event_messages. iter_current_update_messages ( ) ;
1074+ assert_eq ! (
1075+ window_event_messages_iter. next( ) ,
1076+ Some ( & BevyWindowEvent :: WindowBackendScaleFactorChanged (
1077+ WindowBackendScaleFactorChanged {
1078+ window: window_entity,
1079+ scale_factor: 1.0
1080+ }
1081+ ) )
1082+ ) ;
1083+ assert_eq ! ( window_event_messages_iter. next( ) , None ) ;
10461084 }
10471085
10481086 fn setup_react_to_scale_factor_change_test_app (
@@ -1052,20 +1090,30 @@ mod tests {
10521090 let mut app = App :: new ( ) ;
10531091 app. add_message :: < WindowBackendScaleFactorChanged > ( ) ;
10541092 app. add_message :: < WindowScaleFactorChanged > ( ) ;
1093+ app. add_message :: < BevyWindowEvent > ( ) ;
10551094 app. add_systems (
10561095 Update ,
10571096 move |mut window : Single < ( Entity , & mut Window ) > ,
1058- mut window_backend_scale_factor_changed : MessageWriter <
1059- WindowBackendScaleFactorChanged ,
1060- > ,
1061- mut window_scale_factor_changed : MessageWriter < WindowScaleFactorChanged > | {
1062- react_to_scale_factor_change (
1063- window. 0 ,
1064- & mut window. 1 ,
1065- changed_scale_factor,
1066- & mut window_backend_scale_factor_changed,
1067- & mut window_scale_factor_changed,
1068- ) ;
1097+ mut window_backend_scale_factor_changed_writer : MessageWriter <
1098+ WindowBackendScaleFactorChanged ,
1099+ > ,
1100+ mut window_scale_factor_changed_writer : MessageWriter <
1101+ WindowScaleFactorChanged ,
1102+ > ,
1103+ mut window_event : MessageWriter < BevyWindowEvent > | {
1104+ let ( window_backend_scale_factor_changed, window_scale_factor_changed) =
1105+ react_to_scale_factor_change ( window. 0 , & mut window. 1 , changed_scale_factor) ;
1106+ window_backend_scale_factor_changed_writer
1107+ . write ( window_backend_scale_factor_changed. clone ( ) ) ;
1108+ window_event. write ( BevyWindowEvent :: WindowBackendScaleFactorChanged (
1109+ window_backend_scale_factor_changed,
1110+ ) ) ;
1111+ if let Some ( window_scale_factor_changed) = window_scale_factor_changed {
1112+ window_scale_factor_changed_writer. write ( window_scale_factor_changed. clone ( ) ) ;
1113+ window_event. write ( BevyWindowEvent :: WindowScaleFactorChanged (
1114+ window_scale_factor_changed,
1115+ ) ) ;
1116+ }
10691117 } ,
10701118 ) ;
10711119
@@ -1075,4 +1123,111 @@ mod tests {
10751123
10761124 ( app, window_entity)
10771125 }
1126+
1127+ #[ test]
1128+ fn test_react_to_resize_with_changed_size ( ) {
1129+ let ( mut app, window_entity) =
1130+ setup_react_to_resize ( PhysicalSize :: new ( 1280 , 720 ) , PhysicalSize :: new ( 1920 , 1080 ) ) ;
1131+ app. update ( ) ;
1132+
1133+ let window = app. world ( ) . get :: < Window > ( window_entity) . unwrap ( ) ;
1134+ assert_eq ! ( window. resolution. physical_width( ) , 1920 ) ;
1135+ assert_eq ! ( window. resolution. physical_height( ) , 1080 ) ;
1136+
1137+ let window_resized_messages = app. world ( ) . resource :: < Messages < WindowResized > > ( ) ;
1138+ assert_eq ! ( window_resized_messages. len( ) , 1 ) ;
1139+
1140+ let mut window_resized_messages_iter =
1141+ window_resized_messages. iter_current_update_messages ( ) ;
1142+ assert_eq ! (
1143+ window_resized_messages_iter. next( ) ,
1144+ Some ( & WindowResized {
1145+ window: window_entity,
1146+ width: 1920.0 ,
1147+ height: 1080.0
1148+ } )
1149+ ) ;
1150+ assert_eq ! ( window_resized_messages_iter. next( ) , None ) ;
1151+
1152+ let window_event_messages = app. world ( ) . resource :: < Messages < BevyWindowEvent > > ( ) ;
1153+ assert_eq ! ( window_event_messages. len( ) , 1 ) ;
1154+
1155+ let mut window_event_messages_iter = window_event_messages. iter_current_update_messages ( ) ;
1156+ assert_eq ! (
1157+ window_event_messages_iter. next( ) ,
1158+ Some ( & BevyWindowEvent :: WindowResized ( WindowResized {
1159+ window: window_entity,
1160+ width: 1920.0 ,
1161+ height: 1080.0
1162+ } ) )
1163+ ) ;
1164+ assert_eq ! ( window_event_messages_iter. next( ) , None ) ;
1165+ }
1166+
1167+ #[ test]
1168+ fn test_react_to_resize_with_same_size ( ) {
1169+ let ( mut app, window_entity) =
1170+ setup_react_to_resize ( PhysicalSize :: new ( 1280 , 720 ) , PhysicalSize :: new ( 1280 , 720 ) ) ;
1171+ app. update ( ) ;
1172+
1173+ let window = app. world ( ) . get :: < Window > ( window_entity) . unwrap ( ) ;
1174+ assert_eq ! ( window. resolution. physical_width( ) , 1280 ) ;
1175+ assert_eq ! ( window. resolution. physical_height( ) , 720 ) ;
1176+
1177+ let window_resized_messages = app. world ( ) . resource :: < Messages < WindowResized > > ( ) ;
1178+ assert_eq ! ( window_resized_messages. len( ) , 1 ) ;
1179+
1180+ let mut window_resized_messages_iter =
1181+ window_resized_messages. iter_current_update_messages ( ) ;
1182+ assert_eq ! (
1183+ window_resized_messages_iter. next( ) ,
1184+ Some ( & WindowResized {
1185+ window: window_entity,
1186+ width: 1280.0 ,
1187+ height: 720.0
1188+ } )
1189+ ) ;
1190+ assert_eq ! ( window_resized_messages_iter. next( ) , None ) ;
1191+
1192+ let window_event_messages = app. world ( ) . resource :: < Messages < BevyWindowEvent > > ( ) ;
1193+ assert_eq ! ( window_event_messages. len( ) , 1 ) ;
1194+
1195+ let mut window_event_messages_iter = window_event_messages. iter_current_update_messages ( ) ;
1196+ assert_eq ! (
1197+ window_event_messages_iter. next( ) ,
1198+ Some ( & BevyWindowEvent :: WindowResized ( WindowResized {
1199+ window: window_entity,
1200+ width: 1280.0 ,
1201+ height: 720.0
1202+ } ) )
1203+ ) ;
1204+ assert_eq ! ( window_event_messages_iter. next( ) , None ) ;
1205+ }
1206+
1207+ fn setup_react_to_resize (
1208+ initial_size : PhysicalSize < u32 > ,
1209+ changed_size : PhysicalSize < u32 > ,
1210+ ) -> ( App , Entity ) {
1211+ let mut app = App :: new ( ) ;
1212+ app. add_message :: < WindowResized > ( ) ;
1213+ app. add_message :: < BevyWindowEvent > ( ) ;
1214+ app. add_systems (
1215+ Update ,
1216+ move |mut window : Single < ( Entity , & mut Window ) > ,
1217+ mut window_resized_writer : MessageWriter < WindowResized > ,
1218+ mut window_event : MessageWriter < BevyWindowEvent > | {
1219+ let window_resized = react_to_resize ( window. 0 , & mut window. 1 , changed_size) ;
1220+ window_resized_writer. write ( window_resized. clone ( ) ) ;
1221+ window_event. write ( BevyWindowEvent :: WindowResized ( window_resized) ) ;
1222+ } ,
1223+ ) ;
1224+
1225+ let mut window = Window :: default ( ) ;
1226+ window
1227+ . resolution
1228+ . set_physical_resolution ( initial_size. width , initial_size. height ) ;
1229+ let window_entity = app. world_mut ( ) . spawn ( window) . id ( ) ;
1230+
1231+ ( app, window_entity)
1232+ }
10781233}
0 commit comments