@@ -268,13 +268,25 @@ pub enum ActiveTracingSpan {
268268 } ,
269269}
270270
271+ #[ derive( Debug ) ]
272+ pub struct WindowsStore ( RefCell < HashMap < WebviewId , WindowWrapper > > ) ;
273+
274+ // SAFETY: we ensure this type is only used on the main thread.
275+ #[ allow( clippy:: non_send_fields_in_send_ty) ]
276+ unsafe impl Send for WindowsStore { }
277+
278+ // SAFETY: we ensure this type is only used on the main thread.
279+ #[ allow( clippy:: non_send_fields_in_send_ty) ]
280+ unsafe impl Sync for WindowsStore { }
281+
271282#[ derive( Debug , Clone ) ]
272283pub struct DispatcherMainThreadContext < T : UserEvent > {
273284 pub window_target : EventLoopWindowTarget < Message < T > > ,
274285 pub web_context : WebContextStore ,
275286 #[ cfg( all( desktop, feature = "global-shortcut" ) ) ]
276287 pub global_shortcut_manager : Rc < Mutex < WryShortcutManager > > ,
277- pub windows : Rc < RefCell < HashMap < WebviewId , WindowWrapper > > > ,
288+ // changing this to an Rc will cause frequent app crashes.
289+ pub windows : Arc < WindowsStore > ,
278290 #[ cfg( all( desktop, feature = "system-tray" ) ) ]
279291 system_tray_manager : SystemTrayManager ,
280292 #[ cfg( feature = "tracing" ) ]
@@ -1973,7 +1985,7 @@ impl<T: UserEvent> Wry<T> {
19731985 #[ cfg( all( desktop, feature = "global-shortcut" ) ) ]
19741986 let global_shortcut_manager = Rc :: new ( Mutex :: new ( WryShortcutManager :: new ( & event_loop) ) ) ;
19751987
1976- let windows = Rc :: new ( RefCell :: new ( HashMap :: default ( ) ) ) ;
1988+ let windows = Arc :: new ( WindowsStore ( RefCell :: new ( HashMap :: default ( ) ) ) ) ;
19771989 let webview_id_map = WebviewIdStore :: default ( ) ;
19781990
19791991 #[ cfg( all( desktop, feature = "system-tray" ) ) ]
@@ -2104,6 +2116,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
21042116 . context
21052117 . main_thread
21062118 . windows
2119+ . 0
21072120 . borrow_mut ( )
21082121 . insert ( window_id, webview) ;
21092122
@@ -2337,7 +2350,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
23372350pub struct EventLoopIterationContext < ' a , T : UserEvent > {
23382351 pub callback : & ' a mut ( dyn FnMut ( RunEvent < T > ) + ' static ) ,
23392352 pub webview_id_map : WebviewIdStore ,
2340- pub windows : Rc < RefCell < HashMap < WebviewId , WindowWrapper > > > ,
2353+ pub windows : Arc < WindowsStore > ,
23412354 #[ cfg( all( desktop, feature = "global-shortcut" ) ) ]
23422355 pub global_shortcut_manager : Rc < Mutex < WryShortcutManager > > ,
23432356 #[ cfg( all( desktop, feature = "global-shortcut" ) ) ]
@@ -2349,7 +2362,7 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
23492362}
23502363
23512364struct UserMessageContext {
2352- windows : Rc < RefCell < HashMap < WebviewId , WindowWrapper > > > ,
2365+ windows : Arc < WindowsStore > ,
23532366 webview_id_map : WebviewIdStore ,
23542367 #[ cfg( all( desktop, feature = "global-shortcut" ) ) ]
23552368 global_shortcut_manager : Rc < Mutex < WryShortcutManager > > ,
@@ -2384,7 +2397,12 @@ fn handle_user_message<T: UserEvent>(
23842397 } ,
23852398 Message :: Window ( id, window_message) => {
23862399 if let WindowMessage :: UpdateMenuItem ( item_id, update) = window_message {
2387- if let Some ( menu_items) = windows. borrow_mut ( ) . get_mut ( & id) . map ( |w| & mut w. menu_items ) {
2400+ if let Some ( menu_items) = windows
2401+ . 0
2402+ . borrow_mut ( )
2403+ . get_mut ( & id)
2404+ . map ( |w| & mut w. menu_items )
2405+ {
23882406 if let Some ( menu_items) = menu_items. as_mut ( ) {
23892407 let item = menu_items. get_mut ( & item_id) . expect ( "menu item not found" ) ;
23902408 match update {
@@ -2399,7 +2417,7 @@ fn handle_user_message<T: UserEvent>(
23992417 }
24002418 }
24012419 } else {
2402- let w = windows. borrow ( ) . get ( & id) . map ( |w| {
2420+ let w = windows. 0 . borrow ( ) . get ( & id) . map ( |w| {
24032421 (
24042422 w. inner . clone ( ) ,
24052423 w. window_event_listeners . clone ( ) ,
@@ -2622,7 +2640,7 @@ fn handle_user_message<T: UserEvent>(
26222640 WebviewMessage :: EvaluateScript ( script, tx, span) => {
26232641 let _span = span. entered ( ) ;
26242642 if let Some ( WindowHandle :: Webview { inner : webview, .. } ) =
2625- windows. borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
2643+ windows. 0 . borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
26262644 {
26272645 if let Err ( e) = webview. evaluate_script ( & script) {
26282646 debug_eprintln ! ( "{}" , e) ;
@@ -2633,7 +2651,7 @@ fn handle_user_message<T: UserEvent>(
26332651 #[ cfg( not( feature = "tracing" ) ) ]
26342652 WebviewMessage :: EvaluateScript ( script) => {
26352653 if let Some ( WindowHandle :: Webview { inner : webview, .. } ) =
2636- windows. borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
2654+ windows. 0 . borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
26372655 {
26382656 if let Err ( e) = webview. evaluate_script ( & script) {
26392657 debug_eprintln ! ( "{}" , e) ;
@@ -2642,7 +2660,7 @@ fn handle_user_message<T: UserEvent>(
26422660 }
26432661 WebviewMessage :: Print => {
26442662 if let Some ( WindowHandle :: Webview { inner : webview, .. } ) =
2645- windows. borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
2663+ windows. 0 . borrow ( ) . get ( & id) . and_then ( |w| w. inner . as_ref ( ) )
26462664 {
26472665 let _ = webview. print ( ) ;
26482666 }
@@ -2651,7 +2669,7 @@ fn handle_user_message<T: UserEvent>(
26512669 } ,
26522670 Message :: CreateWebview ( window_id, handler) => match handler ( event_loop, web_context) {
26532671 Ok ( webview) => {
2654- windows. borrow_mut ( ) . insert ( window_id, webview) ;
2672+ windows. 0 . borrow_mut ( ) . insert ( window_id, webview) ;
26552673 }
26562674 Err ( e) => {
26572675 debug_eprintln ! ( "{}" , e) ;
@@ -2664,7 +2682,7 @@ fn handle_user_message<T: UserEvent>(
26642682
26652683 let w = Arc :: new ( window) ;
26662684
2667- windows. borrow_mut ( ) . insert (
2685+ windows. 0 . borrow_mut ( ) . insert (
26682686 window_id,
26692687 WindowWrapper {
26702688 label,
@@ -2773,7 +2791,7 @@ fn handle_user_message<T: UserEvent>(
27732791 }
27742792
27752793 let it = RunIteration {
2776- window_count : windows. borrow ( ) . len ( ) ,
2794+ window_count : windows. 0 . borrow ( ) . len ( ) ,
27772795 } ;
27782796 it
27792797}
@@ -2861,6 +2879,7 @@ fn handle_event_loop<T: UserEvent>(
28612879 * webview_id_map. 0 . lock ( ) . unwrap ( ) . values ( ) . next ( ) . unwrap ( )
28622880 } ;
28632881 windows
2882+ . 0
28642883 . borrow ( )
28652884 . get ( & window_id)
28662885 . unwrap ( )
@@ -2946,7 +2965,7 @@ fn handle_event_loop<T: UserEvent>(
29462965 }
29472966 Event :: UserEvent ( Message :: Webview ( id, WebviewMessage :: WebviewEvent ( event) ) ) => {
29482967 if let Some ( event) = WindowEventWrapper :: from ( & event) . 0 {
2949- let windows = windows. borrow ( ) ;
2968+ let windows = windows. 0 . borrow ( ) ;
29502969 let window = windows. get ( & id) ;
29512970 if let Some ( window) = window {
29522971 callback ( RunEvent :: WindowEvent {
@@ -2967,7 +2986,7 @@ fn handle_event_loop<T: UserEvent>(
29672986 } => {
29682987 if let Some ( window_id) = webview_id_map. get ( & window_id) {
29692988 {
2970- let windows_ref = windows. borrow ( ) ;
2989+ let windows_ref = windows. 0 . borrow ( ) ;
29712990 if let Some ( window) = windows_ref. get ( & window_id) {
29722991 if let Some ( event) = WindowEventWrapper :: parse ( & window. inner , & event) . 0 {
29732992 let label = window. label . clone ( ) ;
@@ -2991,7 +3010,7 @@ fn handle_event_loop<T: UserEvent>(
29913010 match event {
29923011 #[ cfg( windows) ]
29933012 WryWindowEvent :: ThemeChanged ( theme) => {
2994- if let Some ( window) = windows. borrow ( ) . get ( & window_id) {
3013+ if let Some ( window) = windows. 0 . borrow ( ) . get ( & window_id) {
29953014 if let Some ( WindowHandle :: Webview { inner, .. } ) = & window. inner {
29963015 let theme = match theme {
29973016 WryTheme :: Dark => wry:: webview:: Theme :: Dark ,
@@ -3006,9 +3025,9 @@ fn handle_event_loop<T: UserEvent>(
30063025 on_close_requested ( callback, window_id, windows. clone ( ) ) ;
30073026 }
30083027 WryWindowEvent :: Destroyed => {
3009- let removed = windows. borrow_mut ( ) . remove ( & window_id) . is_some ( ) ;
3028+ let removed = windows. 0 . borrow_mut ( ) . remove ( & window_id) . is_some ( ) ;
30103029 if removed {
3011- let is_empty = windows. borrow ( ) . is_empty ( ) ;
3030+ let is_empty = windows. 0 . borrow ( ) . is_empty ( ) ;
30123031 if is_empty {
30133032 let ( tx, rx) = channel ( ) ;
30143033 callback ( RunEvent :: ExitRequested { tx } ) ;
@@ -3051,18 +3070,18 @@ fn handle_event_loop<T: UserEvent>(
30513070 }
30523071
30533072 let it = RunIteration {
3054- window_count : windows. borrow ( ) . len ( ) ,
3073+ window_count : windows. 0 . borrow ( ) . len ( ) ,
30553074 } ;
30563075 it
30573076}
30583077
30593078fn on_close_requested < ' a , T : UserEvent > (
30603079 callback : & ' a mut ( dyn FnMut ( RunEvent < T > ) + ' static ) ,
30613080 window_id : WebviewId ,
3062- windows : Rc < RefCell < HashMap < WebviewId , WindowWrapper > > > ,
3081+ windows : Arc < WindowsStore > ,
30633082) {
30643083 let ( tx, rx) = channel ( ) ;
3065- let windows_ref = windows. borrow ( ) ;
3084+ let windows_ref = windows. 0 . borrow ( ) ;
30663085 if let Some ( w) = windows_ref. get ( & window_id) {
30673086 let label = w. label . clone ( ) ;
30683087 let window_event_listeners = w. window_event_listeners . clone ( ) ;
@@ -3087,8 +3106,8 @@ fn on_close_requested<'a, T: UserEvent>(
30873106 }
30883107}
30893108
3090- fn on_window_close ( window_id : WebviewId , windows : Rc < RefCell < HashMap < WebviewId , WindowWrapper > > > ) {
3091- if let Some ( window_wrapper) = windows. borrow_mut ( ) . get_mut ( & window_id) {
3109+ fn on_window_close ( window_id : WebviewId , windows : Arc < WindowsStore > ) {
3110+ if let Some ( window_wrapper) = windows. 0 . borrow_mut ( ) . get_mut ( & window_id) {
30923111 window_wrapper. inner = None ;
30933112 }
30943113}
0 commit comments