@@ -909,6 +909,20 @@ impl WindowDelegate {
909909 } ) ;
910910 }
911911
912+ fn defer_if_handling_event ( & self , f : impl FnOnce ( Retained < Self > ) + ' static ) -> bool {
913+ // AppKit state transitions such as zoom/fullscreen can synchronously run resize/display
914+ // callbacks. Starting them from inside a winit event callback prevents those callbacks
915+ // from being delivered immediately, so defer the transition to the next run-loop turn.
916+ if !self . ivars ( ) . app_state . is_handling_event ( ) {
917+ return false ;
918+ }
919+
920+ let mtm = MainThreadMarker :: from ( self ) ;
921+ let this = self . retain ( ) ;
922+ MainRunLoop :: get ( mtm) . queue_closure ( move || f ( this) ) ;
923+ true
924+ }
925+
912926 fn handle_scale_factor_changed ( & self , scale_factor : CGFloat ) {
913927 let window = self . window ( ) ;
914928
@@ -1378,6 +1392,10 @@ impl WindowDelegate {
13781392
13791393 #[ inline]
13801394 pub fn set_maximized ( & self , maximized : bool ) {
1395+ if self . defer_if_handling_event ( move |this| this. set_maximized ( maximized) ) {
1396+ return ;
1397+ }
1398+
13811399 let mtm = MainThreadMarker :: from ( self ) ;
13821400 let is_zoomed = self . is_zoomed ( ) ;
13831401 if is_zoomed == maximized {
@@ -1423,9 +1441,6 @@ impl WindowDelegate {
14231441
14241442 #[ inline]
14251443 pub ( crate ) fn set_fullscreen ( & self , fullscreen : Option < Fullscreen > ) {
1426- let mtm = MainThreadMarker :: from ( self ) ;
1427- let app = NSApplication :: sharedApplication ( mtm) ;
1428-
14291444 if self . ivars ( ) . is_simple_fullscreen . get ( ) {
14301445 return ;
14311446 }
@@ -1440,6 +1455,18 @@ impl WindowDelegate {
14401455 return ;
14411456 }
14421457
1458+ if !self . ivars ( ) . initial_fullscreen . get ( )
1459+ && self . defer_if_handling_event ( {
1460+ let fullscreen = fullscreen. clone ( ) ;
1461+ move |this| this. set_fullscreen ( fullscreen)
1462+ } )
1463+ {
1464+ return ;
1465+ }
1466+
1467+ let mtm = MainThreadMarker :: from ( self ) ;
1468+ let app = NSApplication :: sharedApplication ( mtm) ;
1469+
14431470 // If the fullscreen is on a different monitor, we must move the window
14441471 // to that monitor before we toggle fullscreen (as `toggleFullScreen`
14451472 // does not take a screen parameter, but uses the current screen)
0 commit comments