@@ -202,6 +202,87 @@ fn take_focus() {
202202 } )
203203}
204204
205+ #[ test]
206+ fn focus_changed ( ) {
207+ const TAKE_FOCUS : Selector = Selector :: new ( "druid-tests.take-focus" ) ;
208+
209+ fn make_focus_container ( children : Vec < WidgetPod < ( ) , Box < dyn Widget < ( ) > > > > ) -> impl Widget < ( ) > {
210+ ModularWidget :: new ( children)
211+ . event_fn ( |children, ctx, event, data, env| {
212+ if let Event :: Command ( cmd) = event {
213+ if cmd. selector == TAKE_FOCUS {
214+ ctx. request_focus ( ) ;
215+ // Stop propagating this command so children
216+ // aren't requesting focus too.
217+ ctx. set_handled ( ) ;
218+ }
219+ }
220+ children
221+ . iter_mut ( )
222+ . for_each ( |a| a. event ( ctx, event, data, env) ) ;
223+ } )
224+ . lifecycle_fn ( |children, ctx, event, data, env| {
225+ children
226+ . iter_mut ( )
227+ . for_each ( |a| a. lifecycle ( ctx, event, data, env) ) ;
228+ } )
229+ }
230+
231+ let a_rec = Recording :: default ( ) ;
232+ let b_rec = Recording :: default ( ) ;
233+ let c_rec = Recording :: default ( ) ;
234+
235+ let ( id_a, id_b, id_c) = widget_id3 ( ) ;
236+
237+ // a contains b which contains c
238+ let c = make_focus_container ( vec ! [ ] ) . record ( & c_rec) . with_id ( id_c) ;
239+ let b = make_focus_container ( vec ! [ WidgetPod :: new( c) . boxed( ) ] )
240+ . record ( & b_rec)
241+ . with_id ( id_b) ;
242+ let a = make_focus_container ( vec ! [ WidgetPod :: new( b) . boxed( ) ] )
243+ . record ( & a_rec)
244+ . with_id ( id_a) ;
245+
246+ let f = |a| match a {
247+ Record :: L ( LifeCycle :: FocusChanged ( c) ) => Some ( c) ,
248+ _ => None ,
249+ } ;
250+ let no_change = |a : & Recording | a. drain ( ) . filter_map ( f) . count ( ) == 0 ;
251+ let changed = |a : & Recording , b| a. drain ( ) . filter_map ( f) . eq ( std:: iter:: once ( b) ) ;
252+
253+ Harness :: create_simple ( ( ) , a, |harness| {
254+ harness. send_initial_events ( ) ;
255+
256+ // focus none -> a
257+ harness. submit_command ( TAKE_FOCUS , id_a) ;
258+ assert_eq ! ( harness. window( ) . focus, Some ( id_a) ) ;
259+ assert ! ( changed( & a_rec, true ) ) ;
260+ assert ! ( no_change( & b_rec) ) ;
261+ assert ! ( no_change( & c_rec) ) ;
262+
263+ // focus a -> b
264+ harness. submit_command ( TAKE_FOCUS , id_b) ;
265+ assert_eq ! ( harness. window( ) . focus, Some ( id_b) ) ;
266+ assert ! ( changed( & a_rec, false ) ) ;
267+ assert ! ( changed( & b_rec, true ) ) ;
268+ assert ! ( no_change( & c_rec) ) ;
269+
270+ // focus b -> c
271+ harness. submit_command ( TAKE_FOCUS , id_c) ;
272+ assert_eq ! ( harness. window( ) . focus, Some ( id_c) ) ;
273+ assert ! ( no_change( & a_rec) ) ;
274+ assert ! ( changed( & b_rec, false ) ) ;
275+ assert ! ( changed( & c_rec, true ) ) ;
276+
277+ // focus c -> a
278+ harness. submit_command ( TAKE_FOCUS , id_a) ;
279+ assert_eq ! ( harness. window( ) . focus, Some ( id_a) ) ;
280+ assert ! ( changed( & a_rec, true ) ) ;
281+ assert ! ( no_change( & b_rec) ) ;
282+ assert ! ( changed( & c_rec, false ) ) ;
283+ } )
284+ }
285+
205286#[ test]
206287fn simple_lifecyle ( ) {
207288 let record = Recording :: default ( ) ;
0 commit comments