@@ -5,10 +5,12 @@ use crate::{
55 commands:: { layer_surface:: get_layer_surface, window:: get_window} ,
66 dpi:: { LogicalPosition , LogicalSize , PhysicalPosition , PhysicalSize } ,
77 error:: { self , Error } ,
8- event_loop:: { control_flow:: ControlFlow , proxy, SctkEventLoop } ,
8+ event_loop:: {
9+ control_flow:: ControlFlow , proxy, state:: SctkState , SctkEventLoop ,
10+ } ,
911 sctk_event:: {
1012 DataSourceEvent , IcedSctkEvent , KeyboardEventVariant ,
11- LayerSurfaceEventVariant , PopupEventVariant , SctkEvent ,
13+ LayerSurfaceEventVariant , PopupEventVariant , SctkEvent , StartCause ,
1214 } ,
1315 settings,
1416} ;
@@ -40,7 +42,7 @@ use iced_futures::{
4042use tracing:: error;
4143
4244use sctk:: {
43- reexports:: client:: { protocol:: wl_surface:: WlSurface , Proxy } ,
45+ reexports:: client:: { protocol:: wl_surface:: WlSurface , Proxy , QueueHandle } ,
4446 seat:: { keyboard:: Modifiers , pointer:: PointerEventKind } ,
4547} ;
4648use std:: { collections:: HashMap , ffi:: c_void, hash:: Hash , marker:: PhantomData } ;
@@ -251,6 +253,7 @@ where
251253
252254 // let (display, context, config, surface) = init_egl(&wl_surface, 100, 100);
253255 let backend = event_loop. state . connection . backend ( ) ;
256+ let qh = event_loop. state . queue_handle . clone ( ) ;
254257 let wrapper = SurfaceDisplayWrapper :: < C > {
255258 comp_surface : None ,
256259 backend : backend. clone ( ) ,
@@ -266,6 +269,7 @@ where
266269 let surface_ids = Default :: default ( ) ;
267270
268271 let ( mut sender, receiver) = mpsc:: unbounded :: < IcedSctkEvent < A :: Message > > ( ) ;
272+ let ( control_sender, mut control_receiver) = mpsc:: unbounded ( ) ;
269273
270274 let compositor_surfaces = HashMap :: new ( ) ;
271275 let mut instance = Box :: pin ( run_instance :: < A , E , C > (
@@ -276,6 +280,7 @@ where
276280 ev_proxy,
277281 debug,
278282 receiver,
283+ control_sender,
279284 compositor_surfaces,
280285 surface_ids,
281286 auto_size_surfaces,
@@ -285,6 +290,7 @@ where
285290 backend,
286291 init_command,
287292 exit_on_close_request,
293+ qh,
288294 ) ) ;
289295
290296 let mut context = task:: Context :: from_waker ( task:: noop_waker_ref ( ) ) ;
@@ -294,12 +300,18 @@ where
294300 return ;
295301 }
296302
297- sender. start_send ( event) . expect ( "Send event" ) ;
303+ sender. start_send ( event) . expect ( "Failed to send event" ) ;
298304
299305 let poll = instance. as_mut ( ) . poll ( & mut context) ;
300306
301307 * control_flow = match poll {
302- task:: Poll :: Pending => ControlFlow :: Wait ,
308+ task:: Poll :: Pending => {
309+ if let Ok ( Some ( flow) ) = control_receiver. try_next ( ) {
310+ flow
311+ } else {
312+ ControlFlow :: Wait
313+ }
314+ }
303315 task:: Poll :: Ready ( _) => ControlFlow :: ExitWithCode ( 1 ) ,
304316 } ;
305317 } ) ;
@@ -326,12 +338,14 @@ async fn run_instance<A, E, C>(
326338 mut ev_proxy : proxy:: Proxy < Event < A :: Message > > ,
327339 mut debug : Debug ,
328340 mut receiver : mpsc:: UnboundedReceiver < IcedSctkEvent < A :: Message > > ,
341+ mut control_sender : mpsc:: UnboundedSender < ControlFlow > ,
329342 mut compositor_surfaces : HashMap < SurfaceId , SurfaceDisplayWrapper < C > > ,
330343 mut surface_ids : HashMap < ObjectId , SurfaceIdWrapper > ,
331344 mut auto_size_surfaces : HashMap < SurfaceIdWrapper , ( u32 , u32 , Limits , bool ) > ,
332345 backend : wayland_backend:: client:: Backend ,
333346 init_command : Command < A :: Message > ,
334347 _exit_on_close_request : bool , // TODO Ashley
348+ queue_handle : QueueHandle < SctkState < <A as Program >:: Message > > ,
335349) -> Result < ( ) , Error >
336350where
337351 A : Application + ' static ,
@@ -381,6 +395,8 @@ where
381395 let mut messages: Vec < A :: Message > = Vec :: new ( ) ;
382396 #[ cfg( feature = "a11y" ) ]
383397 let mut commands: Vec < Command < A :: Message > > = Vec :: new ( ) ;
398+ let mut redraw_pending = false ;
399+
384400 debug. startup_finished ( ) ;
385401
386402 // let mut current_context_window = init_id_inner;
@@ -393,7 +409,14 @@ where
393409
394410 ' main: while let Some ( event) = receiver. next ( ) . await {
395411 match event {
396- IcedSctkEvent :: NewEvents ( _) => { } // TODO Ashley: Seems to be ignored in iced_winit so i'll ignore for now
412+ IcedSctkEvent :: NewEvents ( start_cause) => {
413+ redraw_pending = matches ! (
414+ start_cause,
415+ StartCause :: Init
416+ | StartCause :: Poll
417+ | StartCause :: ResumeTimeReached { .. }
418+ ) ;
419+ }
397420 IcedSctkEvent :: UserEvent ( message) => {
398421 messages. push ( message) ;
399422 }
@@ -679,9 +702,10 @@ where
679702 }
680703 SctkEvent :: Frame ( surface) => {
681704 if let Some ( id) = surface_ids. get ( & surface. id ( ) ) {
682- runtime. broadcast ( CoreEvent :: PlatformSpecific (
683- PlatformSpecific :: Wayland ( WaylandEvent :: Frame ( Instant :: now ( ) , surface, id. inner ( ) ) )
684- ) , Status :: Ignored ) ;
705+ if let Some ( state) = states. get_mut ( & id. inner ( ) ) {
706+ // TODO set this to the callback?
707+ state. set_frame ( Some ( surface) ) ;
708+ }
685709 }
686710 } ,
687711 SctkEvent :: ScaleFactorChanged { .. } => { }
@@ -873,16 +897,18 @@ where
873897 break ' main;
874898 }
875899 } else {
876- // TODO ensure that the surface_ids are
877- let mut needs_redraw = false ;
878900 for ( object_id, surface_id) in & surface_ids {
879901 if matches ! ( surface_id, SurfaceIdWrapper :: Dnd ( _) ) {
880902 continue ;
881903 }
904+ let state = match states. get_mut ( & surface_id. inner ( ) ) {
905+ Some ( s) => s,
906+ None => continue ,
907+ } ;
882908 let mut filtered_sctk =
883909 Vec :: with_capacity ( sctk_events. len ( ) ) ;
884-
885910 let mut i = 0 ;
911+
886912 while i < sctk_events. len ( ) {
887913 let has_kbd_focus =
888914 kbd_surface_id. as_ref ( ) == Some ( object_id) ;
@@ -897,12 +923,7 @@ where
897923 }
898924 }
899925 let has_events = !sctk_events. is_empty ( ) ;
900-
901- let cursor_position =
902- match states. get ( & surface_id. inner ( ) ) {
903- Some ( s) => s. cursor ( ) ,
904- None => continue ,
905- } ;
926+ let cursor_position = state. cursor ( ) ;
906927 debug. event_processing_started ( ) ;
907928 #[ allow( unused_mut) ]
908929 let mut native_events: Vec < _ > = filtered_sctk
@@ -966,11 +987,6 @@ where
966987 auto_size_surfaces. remove ( surface_id)
967988 {
968989 if dirty {
969- let state =
970- match states. get_mut ( & surface_id. inner ( ) ) {
971- Some ( s) => s,
972- None => continue ,
973- } ;
974990 state. set_logical_size ( w as f64 , h as f64 ) ;
975991 match surface_id {
976992 SurfaceIdWrapper :: Window ( id) => {
@@ -990,22 +1006,18 @@ where
9901006 }
9911007
9921008 // TODO ASHLEY if event is a configure which isn't a new size and has no other changes, don't redraw
993- if has_events
1009+ if redraw_pending
1010+ || has_events
9941011 || !messages. is_empty ( )
9951012 || matches ! (
9961013 interface_state,
9971014 user_interface:: State :: Outdated
9981015 )
9991016 {
1000- needs_redraw = true ;
1001- ev_proxy. send_event ( Event :: SctkEvent (
1002- IcedSctkEvent :: RedrawRequested (
1003- object_id. clone ( ) ,
1004- ) ,
1005- ) ) ;
1017+ state. set_needs_redraw ( true ) ;
10061018 }
10071019 }
1008- if needs_redraw {
1020+ if states . iter ( ) . any ( | ( _ , s ) | s . needs_redraw ) {
10091021 let mut pure_states: HashMap < _ , _ > =
10101022 ManuallyDrop :: into_inner ( interfaces)
10111023 . drain ( )
@@ -1017,7 +1029,13 @@ where
10171029 for surface_id in surface_ids. values ( ) {
10181030 let state =
10191031 match states. get_mut ( & surface_id. inner ( ) ) {
1020- Some ( s) => s,
1032+ Some ( s) => {
1033+ if !s. needs_redraw ( ) {
1034+ continue ;
1035+ } else {
1036+ s
1037+ }
1038+ }
10211039 None => continue ,
10221040 } ;
10231041 let mut cache =
@@ -1058,6 +1076,84 @@ where
10581076 & mut auto_size_surfaces,
10591077 & mut ev_proxy,
10601078 ) ) ;
1079+
1080+ for ( object_id, surface_id) in & surface_ids {
1081+ let state = match states
1082+ . get_mut ( & surface_id. inner ( ) )
1083+ {
1084+ Some ( s) => {
1085+ if !s. needs_redraw ( ) || s. frame ( ) . is_none ( )
1086+ {
1087+ continue ;
1088+ } else {
1089+ s
1090+ }
1091+ }
1092+ None => continue ,
1093+ } ;
1094+ let Some ( user_interface) = interfaces
1095+ . get_mut ( & surface_id. inner ( ) ) else {
1096+ continue ;
1097+ } ;
1098+ let redraw_event = CoreEvent :: Window (
1099+ surface_id. inner ( ) ,
1100+ crate :: core:: window:: Event :: RedrawRequested (
1101+ Instant :: now ( ) ,
1102+ ) ,
1103+ ) ;
1104+
1105+ let ( interface_state, _) = user_interface. update (
1106+ & [ redraw_event. clone ( ) ] ,
1107+ state. cursor ( ) ,
1108+ & mut renderer,
1109+ & mut simple_clipboard,
1110+ & mut messages,
1111+ ) ;
1112+
1113+ debug. draw_started ( ) ;
1114+ let new_mouse_interaction = user_interface. draw (
1115+ & mut renderer,
1116+ state. theme ( ) ,
1117+ & Style {
1118+ text_color : state. text_color ( ) ,
1119+ } ,
1120+ state. cursor ( ) ,
1121+ ) ;
1122+ debug. draw_finished ( ) ;
1123+
1124+ if new_mouse_interaction != mouse_interaction {
1125+ mouse_interaction = new_mouse_interaction;
1126+ ev_proxy. send_event ( Event :: SetCursor (
1127+ mouse_interaction,
1128+ ) ) ;
1129+ }
1130+
1131+ runtime. broadcast ( redraw_event, Status :: Ignored ) ;
1132+
1133+ ev_proxy. send_event ( Event :: SctkEvent (
1134+ IcedSctkEvent :: RedrawRequested (
1135+ object_id. clone ( ) ,
1136+ ) ,
1137+ ) ) ;
1138+
1139+ let _ =
1140+ control_sender
1141+ . start_send ( match interface_state {
1142+ user_interface:: State :: Updated {
1143+ redraw_request : Some ( redraw_request) ,
1144+ } => match redraw_request {
1145+ crate :: core:: window:: RedrawRequest :: NextFrame => {
1146+ ControlFlow :: Poll
1147+ }
1148+ crate :: core:: window:: RedrawRequest :: At ( at) => {
1149+ ControlFlow :: WaitUntil ( at)
1150+ }
1151+ } ,
1152+ _ => ControlFlow :: Wait ,
1153+ } ) ;
1154+ state. set_needs_redraw ( false ) ;
1155+ redraw_pending = false ;
1156+ }
10611157 }
10621158 }
10631159 sctk_events. clear ( ) ;
@@ -1079,6 +1175,14 @@ where
10791175 let state = states. get_mut ( & id. inner ( ) ) ;
10801176 Some ( ( * id, surface, interface, state) )
10811177 } ) {
1178+ // request a new frame
1179+ // NOTE Ashley: this is done here only after a redraw
1180+ // to prevent more events from being produced after repeatedly requesting redraws
1181+ if let Some ( surface) = state. frame . take ( ) {
1182+ surface. frame ( & queue_handle, surface. clone ( ) ) ;
1183+ surface. commit ( ) ;
1184+ }
1185+
10821186 debug. render_started ( ) ;
10831187 #[ cfg( feature = "a11y" ) ]
10841188 if let Some ( Some ( adapter) ) = a11y_enabled
@@ -1387,6 +1491,8 @@ where
13871491 theme : <A :: Renderer as Renderer >:: Theme ,
13881492 appearance : application:: Appearance ,
13891493 application : PhantomData < A > ,
1494+ frame : Option < WlSurface > ,
1495+ needs_redraw : bool ,
13901496}
13911497
13921498impl < A : Application > State < A >
@@ -1414,9 +1520,27 @@ where
14141520 theme,
14151521 appearance,
14161522 application : PhantomData ,
1523+ frame : None ,
1524+ needs_redraw : false ,
14171525 }
14181526 }
14191527
1528+ pub ( crate ) fn set_needs_redraw ( & mut self , needs_redraw : bool ) {
1529+ self . needs_redraw = needs_redraw;
1530+ }
1531+
1532+ pub ( crate ) fn needs_redraw ( & self ) -> bool {
1533+ self . needs_redraw
1534+ }
1535+
1536+ pub ( crate ) fn set_frame ( & mut self , frame : Option < WlSurface > ) {
1537+ self . frame = frame;
1538+ }
1539+
1540+ pub ( crate ) fn frame ( & self ) -> Option < & WlSurface > {
1541+ self . frame . as_ref ( )
1542+ }
1543+
14201544 /// Returns the current [`Viewport`] of the [`State`].
14211545 pub fn viewport ( & self ) -> & Viewport {
14221546 & self . viewport
0 commit comments