@@ -41,19 +41,25 @@ struct MouseState {
41
41
middle_button : Cell < bool > ,
42
42
}
43
43
44
+ struct Context2D {
45
+ context : CanvasRenderingContext2d ,
46
+ img_data : ImageData ,
47
+ }
48
+
44
49
// IDEA(stefano): possibly have this contain a "document" field, so not to recompute it every time
45
50
pub struct Window {
46
51
width : u32 ,
47
52
height : u32 ,
48
53
bg_color : u32 ,
49
54
window_scale : usize ,
50
- img_data : ImageData ,
51
55
canvas : HtmlCanvasElement ,
52
- context : Rc < CanvasRenderingContext2d > ,
56
+ // 2D context is created lazily since its creation preculdes creation of webgl & webgpu contexts.
57
+ context2d : Option < Context2D > ,
53
58
mouse_state : Rc < MouseState > ,
54
59
key_handler : Rc < RefCell < KeyHandler > > ,
55
60
menu_counter : MenuHandle ,
56
61
menus : Vec < UnixMenu > ,
62
+ raw_handle_id : u32 ,
57
63
}
58
64
59
65
impl Window {
@@ -83,6 +89,13 @@ impl Window {
83
89
. dyn_into :: < HtmlCanvasElement > ( )
84
90
. unwrap ( ) ;
85
91
92
+ // Raw handle requires to inject an id into the canvas' data attributes.
93
+ // TODO assign a different ID to each window
94
+ let raw_handle_id = 0 ;
95
+ canvas
96
+ . set_attribute ( "data-raw-handle" , & raw_handle_id. to_string ( ) )
97
+ . unwrap ( ) ;
98
+
86
99
let container = document
87
100
. get_element_by_id ( container)
88
101
. unwrap ( )
@@ -97,15 +110,6 @@ impl Window {
97
110
canvas. set_tab_index ( 0 ) ;
98
111
99
112
// Create an image buffer
100
- let context: CanvasRenderingContext2d = canvas
101
- . get_context ( "2d" )
102
- . unwrap ( )
103
- . unwrap ( )
104
- . dyn_into :: < CanvasRenderingContext2d > ( )
105
- . unwrap ( ) ;
106
- context. set_image_smoothing_enabled ( false ) ;
107
- let img_data = ImageData :: new_with_sw ( width as u32 , height as u32 ) . unwrap ( ) ;
108
- let context = Rc :: new ( context) ;
109
113
let key_handler = Rc :: new ( RefCell :: new ( KeyHandler :: new ( ) ) ) ;
110
114
let mouse_struct = MouseState {
111
115
pos : Cell :: new ( None ) ,
@@ -180,21 +184,31 @@ impl Window {
180
184
closure. forget ( ) ;
181
185
}
182
186
183
- let mut window = Window {
187
+ Ok ( Window {
184
188
width : width as u32 ,
185
189
height : height as u32 ,
186
190
bg_color : 0 ,
187
191
window_scale,
188
- img_data,
189
192
canvas,
190
- context : context . clone ( ) ,
193
+ context2d : None ,
191
194
key_handler,
192
195
mouse_state,
193
196
menu_counter : MenuHandle ( 0 ) ,
194
197
menus : Vec :: new ( ) ,
195
- } ;
198
+ raw_handle_id,
199
+ } )
200
+ }
196
201
197
- Ok ( window)
202
+ fn create_2d_context ( & self ) -> CanvasRenderingContext2d {
203
+ let context: CanvasRenderingContext2d = self
204
+ . canvas
205
+ . get_context ( "2d" )
206
+ . unwrap ( )
207
+ . unwrap ( )
208
+ . dyn_into :: < CanvasRenderingContext2d > ( )
209
+ . unwrap ( ) ;
210
+ context. set_image_smoothing_enabled ( false ) ;
211
+ context
198
212
}
199
213
200
214
#[ inline]
@@ -204,7 +218,7 @@ impl Window {
204
218
}
205
219
206
220
#[ inline]
207
- pub fn set_rate ( & mut self , rate : Option < Duration > ) { }
221
+ pub fn set_rate ( & mut self , _rate : Option < Duration > ) { }
208
222
209
223
#[ inline]
210
224
pub fn update_rate ( & mut self ) { }
@@ -215,7 +229,7 @@ impl Window {
215
229
}
216
230
217
231
#[ inline]
218
- pub fn topmost ( & self , topmost : bool ) {
232
+ pub fn topmost ( & self , _topmost : bool ) {
219
233
// TODO?
220
234
}
221
235
@@ -262,13 +276,22 @@ impl Window {
262
276
) ?;
263
277
let mut data = u32_as_u8 ( buffer) ;
264
278
265
- self . img_data = ImageData :: new_with_u8_clamped_array_and_sh (
279
+ let image_data = ImageData :: new_with_u8_clamped_array_and_sh (
266
280
Clamped ( & mut data) ,
267
281
self . width ,
268
282
self . height ,
269
283
)
270
284
. unwrap ( ) ;
271
285
286
+ if let Some ( context2d) = & mut self . context2d {
287
+ context2d. img_data = image_data;
288
+ } else {
289
+ self . context2d = Some ( Context2D {
290
+ context : self . create_2d_context ( ) ,
291
+ img_data : image_data,
292
+ } ) ;
293
+ }
294
+
272
295
self . update ( ) ;
273
296
274
297
Ok ( ( ) )
@@ -277,16 +300,20 @@ impl Window {
277
300
#[ inline]
278
301
pub fn update ( & mut self ) {
279
302
self . key_handler . borrow_mut ( ) . update ( ) ;
280
- self . context
281
- . put_image_data ( & self . img_data , 0.0 , 0.0 )
282
- . unwrap ( ) ;
303
+
304
+ if let Some ( context2d) = & self . context2d {
305
+ context2d
306
+ . context
307
+ . put_image_data ( & context2d. img_data , 0.0 , 0.0 )
308
+ . unwrap ( ) ;
309
+ }
283
310
}
284
311
285
312
#[ inline]
286
- pub fn set_icon ( & mut self , icon : Icon ) { }
313
+ pub fn set_icon ( & mut self , _icon : Icon ) { }
287
314
288
315
#[ inline]
289
- pub fn set_position ( & mut self , x : isize , y : isize ) { }
316
+ pub fn set_position ( & mut self , _x : isize , _y : isize ) { }
290
317
291
318
#[ inline]
292
319
pub fn get_position ( & self ) -> ( isize , isize ) {
@@ -343,7 +370,7 @@ impl Window {
343
370
}
344
371
345
372
#[ inline]
346
- pub fn set_cursor_style ( & mut self , cursor : CursorStyle ) { }
373
+ pub fn set_cursor_style ( & mut self , _cursor : CursorStyle ) { }
347
374
348
375
#[ inline]
349
376
pub fn get_keys ( & self ) -> Vec < Key > {
@@ -397,8 +424,10 @@ impl Window {
397
424
398
425
#[ inline]
399
426
pub fn is_active ( & mut self ) -> bool {
400
- let document = window ( ) . unwrap ( ) . document ( ) . unwrap ( ) ;
401
- document. active_element ( ) . unwrap_or ( return false ) == * * self . canvas
427
+ window ( )
428
+ . and_then ( |window| window. document ( ) )
429
+ . and_then ( |document| document. active_element ( ) )
430
+ . map_or ( false , |element| element == * * self . canvas )
402
431
}
403
432
404
433
#[ inline]
@@ -445,7 +474,7 @@ impl Menu {
445
474
}
446
475
447
476
#[ inline]
448
- pub fn add_sub_menu ( & mut self , name : & str , sub_menu : & Menu ) { }
477
+ pub fn add_sub_menu ( & mut self , _name : & str , _sub_menu : & Menu ) { }
449
478
450
479
#[ inline]
451
480
fn next_item_handle ( & mut self ) -> MenuItemHandle {
@@ -470,13 +499,12 @@ impl Menu {
470
499
}
471
500
472
501
#[ inline]
473
- pub fn remove_item ( & mut self , handle : & MenuItemHandle ) { }
502
+ pub fn remove_item ( & mut self , _handle : & MenuItemHandle ) { }
474
503
}
475
504
476
505
impl HasWindowHandle for Window {
477
506
fn window_handle ( & self ) -> std:: result:: Result < WindowHandle , HandleError > {
478
- // TODO assign a different ID to each window
479
- let handle = WebWindowHandle :: new ( 0 ) ;
507
+ let handle = WebWindowHandle :: new ( self . raw_handle_id ) ;
480
508
let raw_handle = RawWindowHandle :: Web ( handle) ;
481
509
unsafe { Ok ( WindowHandle :: borrow_raw ( raw_handle) ) }
482
510
}
0 commit comments