@@ -66,8 +66,7 @@ fn main() -> Result<(), Box<dyn Error>> {
66
66
} ) ;
67
67
}
68
68
69
- let app = Application :: new ( & event_loop, receiver, sender) ;
70
- Ok ( event_loop. run_app ( app) ?)
69
+ Ok ( event_loop. run ( |event_loop| Application :: new ( event_loop, receiver, sender) ) ?)
71
70
}
72
71
73
72
/// Application state and event handling.
@@ -84,21 +83,24 @@ struct Application {
84
83
///
85
84
/// With OpenGL it could be EGLDisplay.
86
85
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
87
- context : Option < Context < DisplayHandle < ' static > > > ,
86
+ context : Context < DisplayHandle < ' static > > ,
88
87
}
89
88
90
89
impl Application {
91
- fn new ( event_loop : & EventLoop , receiver : Receiver < Action > , sender : Sender < Action > ) -> Self {
92
- // SAFETY: we drop the context right before the event loop is stopped, thus making it safe.
90
+ fn new (
91
+ event_loop : & dyn ActiveEventLoop ,
92
+ receiver : Receiver < Action > ,
93
+ sender : Sender < Action > ,
94
+ ) -> Self {
95
+ // SAFETY: The context is stored in the application, which is dropped right before the event
96
+ // loop is stopped, thus making it safe.
93
97
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
94
- let context = Some (
95
- Context :: new ( unsafe {
96
- std:: mem:: transmute :: < DisplayHandle < ' _ > , DisplayHandle < ' static > > (
97
- event_loop. display_handle ( ) . unwrap ( ) ,
98
- )
99
- } )
100
- . unwrap ( ) ,
101
- ) ;
98
+ let context = Context :: new ( unsafe {
99
+ std:: mem:: transmute :: < DisplayHandle < ' _ > , DisplayHandle < ' static > > (
100
+ event_loop. display_handle ( ) . unwrap ( ) ,
101
+ )
102
+ } )
103
+ . unwrap ( ) ;
102
104
103
105
// You'll have to choose an icon size at your own discretion. On X11, the desired size
104
106
// varies by WM, and on Windows, you still have to account for screen scaling. Here
@@ -116,15 +118,24 @@ impl Application {
116
118
. into_iter ( )
117
119
. collect ( ) ;
118
120
119
- Self {
121
+ let mut app = Self {
120
122
receiver,
121
123
sender,
122
124
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
123
125
context,
124
126
custom_cursors,
125
127
icon,
126
128
windows : Default :: default ( ) ,
127
- }
129
+ } ;
130
+
131
+ app. dump_monitors ( event_loop) ;
132
+
133
+ // Create initial window.
134
+ app. create_window ( event_loop, None ) . expect ( "failed to create initial window" ) ;
135
+
136
+ app. print_help ( ) ;
137
+
138
+ app
128
139
}
129
140
130
141
fn create_window (
@@ -528,16 +539,6 @@ impl ApplicationHandler for Application {
528
539
info ! ( "Device {device_id:?} event: {event:?}" ) ;
529
540
}
530
541
531
- fn can_create_surfaces ( & mut self , event_loop : & dyn ActiveEventLoop ) {
532
- info ! ( "Ready to create surfaces" ) ;
533
- self . dump_monitors ( event_loop) ;
534
-
535
- // Create initial window.
536
- self . create_window ( event_loop, None ) . expect ( "failed to create initial window" ) ;
537
-
538
- self . print_help ( ) ;
539
- }
540
-
541
542
fn about_to_wait ( & mut self , event_loop : & dyn ActiveEventLoop ) {
542
543
if self . windows . is_empty ( ) {
543
544
info ! ( "No windows left, exiting..." ) ;
@@ -546,9 +547,17 @@ impl ApplicationHandler for Application {
546
547
}
547
548
548
549
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
549
- fn exiting ( & mut self , _event_loop : & dyn ActiveEventLoop ) {
550
- // We must drop the context here.
551
- self . context = None ;
550
+ fn destroy_surfaces ( & mut self , _event_loop : & dyn ActiveEventLoop ) {
551
+ for window in self . windows . values_mut ( ) {
552
+ window. surface = None ;
553
+ }
554
+ }
555
+
556
+ #[ cfg( not( any( android_platform, ios_platform) ) ) ]
557
+ fn recreate_surfaces ( & mut self , _event_loop : & dyn ActiveEventLoop ) {
558
+ for window in self . windows . values_mut ( ) {
559
+ window. surface = Some ( Surface :: new ( & self . context , Arc :: clone ( & window. window ) ) . unwrap ( ) ) ;
560
+ }
552
561
}
553
562
}
554
563
@@ -557,10 +566,8 @@ struct WindowState {
557
566
/// IME input.
558
567
ime : bool ,
559
568
/// Render surface.
560
- ///
561
- /// NOTE: This surface must be dropped before the `Window`.
562
569
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
563
- surface : Surface < DisplayHandle < ' static > , Arc < dyn Window > > ,
570
+ surface : Option < Surface < DisplayHandle < ' static > , Arc < dyn Window > > > ,
564
571
/// The actual winit Window.
565
572
window : Arc < dyn Window > ,
566
573
/// The window theme we're drawing with.
@@ -593,10 +600,8 @@ impl WindowState {
593
600
fn new ( app : & Application , window : Box < dyn Window > ) -> Result < Self , Box < dyn Error > > {
594
601
let window: Arc < dyn Window > = Arc :: from ( window) ;
595
602
596
- // SAFETY: the surface is dropped before the `window` which provided it with handle, thus
597
- // it doesn't outlive it.
598
603
#[ cfg( not( any( android_platform, ios_platform) ) ) ]
599
- let surface = Surface :: new ( app. context . as_ref ( ) . unwrap ( ) , Arc :: clone ( & window) ) ?;
604
+ let surface = Some ( Surface :: new ( & app. context , Arc :: clone ( & window) ) ?) ;
600
605
601
606
let theme = window. theme ( ) . unwrap_or ( Theme :: Dark ) ;
602
607
info ! ( "Theme: {theme:?}" ) ;
@@ -803,7 +808,11 @@ impl WindowState {
803
808
( Some ( width) , Some ( height) ) => ( width, height) ,
804
809
_ => return ,
805
810
} ;
806
- self . surface . resize ( width, height) . expect ( "failed to resize inner buffer" ) ;
811
+ self . surface
812
+ . as_mut ( )
813
+ . unwrap ( )
814
+ . resize ( width, height)
815
+ . expect ( "failed to resize inner buffer" ) ;
807
816
}
808
817
self . window . request_redraw ( ) ;
809
818
}
@@ -904,7 +913,7 @@ impl WindowState {
904
913
Theme :: Dark => DARK_GRAY ,
905
914
} ;
906
915
907
- let mut buffer = self . surface . buffer_mut ( ) ?;
916
+ let mut buffer = self . surface . as_mut ( ) . unwrap ( ) . buffer_mut ( ) ?;
908
917
buffer. fill ( color) ;
909
918
self . window . pre_present_notify ( ) ;
910
919
buffer. present ( ) ?;
0 commit comments