diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index 56a6f8769..06f3963b0 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -1908,24 +1908,29 @@ impl Runtime for Wry { } #[cfg(feature = "egui")] - handle_gl_loop( - &event, - event_loop, - control_flow, - EventLoopIterationContext { - callback: &mut callback, - windows: windows.clone(), - window_event_listeners: &window_event_listeners, - global_shortcut_manager: global_shortcut_manager.clone(), - global_shortcut_manager_handle: &global_shortcut_manager_handle, - clipboard_manager: clipboard_manager.clone(), - menu_event_listeners: &menu_event_listeners, - #[cfg(feature = "system-tray")] - tray_context: &tray_context, - }, - &web_context, - &mut is_focused, - ); + { + let prevent_default = handle_gl_loop( + &event, + event_loop, + control_flow, + EventLoopIterationContext { + callback: &mut callback, + windows: windows.clone(), + window_event_listeners: &window_event_listeners, + global_shortcut_manager: global_shortcut_manager.clone(), + global_shortcut_manager_handle: &global_shortcut_manager_handle, + clipboard_manager: clipboard_manager.clone(), + menu_event_listeners: &menu_event_listeners, + #[cfg(feature = "system-tray")] + tray_context: &tray_context, + }, + &web_context, + &mut is_focused, + ); + if prevent_default { + return; + } + } iteration = handle_event_loop( event, event_loop, @@ -1964,24 +1969,29 @@ impl Runtime for Wry { self.event_loop.run(move |event, event_loop, control_flow| { #[cfg(feature = "egui")] - handle_gl_loop( - &event, - event_loop, - control_flow, - EventLoopIterationContext { - callback: &mut callback, - windows: windows.clone(), - window_event_listeners: &window_event_listeners, - global_shortcut_manager: global_shortcut_manager.clone(), - global_shortcut_manager_handle: &global_shortcut_manager_handle, - clipboard_manager: clipboard_manager.clone(), - menu_event_listeners: &menu_event_listeners, - #[cfg(feature = "system-tray")] - tray_context: &tray_context, - }, - &web_context, - &mut is_focused, - ); + { + let prevent_default = handle_gl_loop( + &event, + event_loop, + control_flow, + EventLoopIterationContext { + callback: &mut callback, + windows: windows.clone(), + window_event_listeners: &window_event_listeners, + global_shortcut_manager: global_shortcut_manager.clone(), + global_shortcut_manager_handle: &global_shortcut_manager_handle, + clipboard_manager: clipboard_manager.clone(), + menu_event_listeners: &menu_event_listeners, + #[cfg(feature = "system-tray")] + tray_context: &tray_context, + }, + &web_context, + &mut is_focused, + ); + if prevent_default { + return; + } + } handle_event_loop( event, event_loop, @@ -2641,42 +2651,14 @@ fn handle_event_loop( match event { WryWindowEvent::CloseRequested => { - let (tx, rx) = channel(); - let windows_guard = windows.lock().expect("poisoned webview collection"); - if let Some(w) = windows_guard.get(&window_id) { - let label = w.label.clone(); - drop(windows_guard); - for handler in window_event_listeners - .lock() - .unwrap() - .get(&window_id) - .unwrap() - .lock() - .unwrap() - .values() - { - handler(&WindowEvent::CloseRequested { - label: label.clone(), - signal_tx: tx.clone(), - }); - } - callback(RunEvent::CloseRequested { - label, - signal_tx: tx, - }); - if let Ok(true) = rx.try_recv() { - } else { - on_window_close( - callback, - window_id, - windows.lock().expect("poisoned webview collection"), - control_flow, - #[cfg(target_os = "linux")] - window_event_listeners, - menu_event_listeners.clone(), - ); - } - } + on_close_requested( + callback, + window_id, + windows.clone(), + control_flow, + window_event_listeners, + menu_event_listeners.clone(), + ); } WryWindowEvent::Resized(_) => { if let Some(WindowHandle::Webview(webview)) = windows @@ -2740,10 +2722,12 @@ fn handle_gl_loop( context: EventLoopIterationContext<'_>, _web_context: &WebContextStore, is_focused: &mut bool, -) { +) -> bool { + let mut prevent_default = false; let EventLoopIterationContext { callback, windows, + window_event_listeners, menu_event_listeners, #[cfg(feature = "system-tray")] tray_context, @@ -2751,9 +2735,9 @@ fn handle_gl_loop( } = context; let egui_id = EGUI_ID.lock().unwrap(); if let Some(id) = *egui_id { - let mut windows = windows.lock().unwrap(); + let mut windows_lock = windows.lock().unwrap(); let mut should_quit = false; - if let Some(win) = windows.get_mut(&id) { + if let Some(win) = windows_lock.get_mut(&id) { if let WindowHandle::GLWindow(gl_window, gl, painter, integration) = &mut win.inner { let mut redraw = || { if !*is_focused { @@ -2820,21 +2804,49 @@ fn handle_gl_loop( event, window_id, .. } => { if window_id == &id { - if let glutin::event::WindowEvent::Focused(new_focused) = event { - *is_focused = *new_focused; + match event { + glutin::event::WindowEvent::Focused(new_focused) => { + *is_focused = *new_focused; + } + glutin::event::WindowEvent::Resized(physical_size) => { + gl_window.resize(*physical_size); + } + _ => (), } - if let glutin::event::WindowEvent::Resized(physical_size) = event { - gl_window.resize(*physical_size); + if let glutin::event::WindowEvent::CloseRequested = event { + drop(windows_lock); + let w = on_close_requested( + callback, + *window_id, + windows.clone(), + control_flow, + window_event_listeners, + menu_event_listeners.clone(), + ); + if let Some(mut win) = w { + if let WindowHandle::GLWindow(gl_window, _gl, _painter, integration) = + &mut win.inner + { + // marker + integration.on_event(&event); + if integration.should_quit() { + should_quit = true; + *control_flow = glutin::event_loop::ControlFlow::Wait; + } + gl_window.window().request_redraw(); + } + } + prevent_default = true; + } else { + // same as the `marker` above + integration.on_event(&event); + if integration.should_quit() { + should_quit = true; + *control_flow = glutin::event_loop::ControlFlow::Wait; + } + gl_window.window().request_redraw(); } - - integration.on_event(&event); - if integration.should_quit() { - should_quit = true; - *control_flow = glutin::event_loop::ControlFlow::Wait; - } - - gl_window.window().request_redraw(); } } _ => (), @@ -2847,12 +2859,14 @@ fn handle_gl_loop( on_window_close( callback, id, - windows, + windows.lock().unwrap(), control_flow, menu_event_listeners.clone(), ); } } + + prevent_default } #[allow(dead_code)] @@ -2865,7 +2879,8 @@ fn handle_gl_loop( context: EventLoopIterationContext<'_>, _web_context: &WebContextStore, is_focused: &mut bool, -) { +) -> bool { + let mut prevent_default = false; let EventLoopIterationContext { callback, windows, @@ -2875,13 +2890,12 @@ fn handle_gl_loop( } = context; let egui_id = EGUI_ID.lock().unwrap(); if let Some(id) = *egui_id { - let mut windows = windows.lock().unwrap(); + let mut windows_lock = windows.lock().unwrap(); let mut should_quit = false; - if let Some(win) = windows.get_mut(&id) { + if let Some(win) = windows_lock.get_mut(&id) { if let WindowHandle::GLWindow(gl_window, _gl, _painter, integration, render_flow) = &mut win.inner { - let mut integration = integration.borrow_mut(); let area = unsafe { gl_window.raw_handle() }; match event { glutin::event::Event::MainEventsCleared => { @@ -2897,21 +2911,57 @@ fn handle_gl_loop( event, window_id, .. } => { if window_id == &id { - if let glutin::event::WindowEvent::Focused(new_focused) = event { - *is_focused = *new_focused; + match event { + glutin::event::WindowEvent::Focused(new_focused) => { + *is_focused = *new_focused; + } + glutin::event::WindowEvent::Resized(physical_size) => { + gl_window.resize(*physical_size); + } + _ => (), } - if let glutin::event::WindowEvent::Resized(physical_size) = event { - gl_window.resize(*physical_size); - } + if let glutin::event::WindowEvent::CloseRequested = event { + drop(windows_lock); + let w = on_close_requested( + callback, + *window_id, + windows.clone(), + control_flow, + window_event_listeners, + menu_event_listeners.clone(), + ); + if let Some(mut win) = w { + if let WindowHandle::GLWindow( + gl_window, + _gl, + _painter, + integration, + _render_flow, + ) = &mut win.inner + { + // marker + let mut integration = integration.borrow_mut(); + integration.on_event(&event); + if integration.should_quit() { + should_quit = true; + *control_flow = glutin::event_loop::ControlFlow::Wait; + } + gl_window.window().request_redraw(); + } + } + prevent_default = true; + } else { + // same as the `marker` above + let mut integration = integration.borrow_mut(); - integration.on_event(event); - if integration.should_quit() { - should_quit = true; - *control_flow = glutin::event_loop::ControlFlow::Wait; + integration.on_event(&event); + if integration.should_quit() { + should_quit = true; + *control_flow = glutin::event_loop::ControlFlow::Wait; + } + gl_window.window().request_redraw(); } - - gl_window.window().request_redraw(); } } _ => (), @@ -2924,13 +2974,63 @@ fn handle_gl_loop( on_window_close( callback, id, - windows, + windows.lock().unwrap(), control_flow, window_event_listeners, menu_event_listeners.clone(), ); } } + prevent_default +} + +fn on_close_requested<'a>( + callback: &'a mut (dyn FnMut(RunEvent) + 'static), + window_id: WindowId, + windows: Arc>>, + control_flow: &mut ControlFlow, + window_event_listeners: &WindowEventListeners, + menu_event_listeners: MenuEventListeners, +) -> Option { + let (tx, rx) = channel(); + let windows_guard = windows.lock().expect("poisoned webview collection"); + if let Some(w) = windows_guard.get(&window_id) { + let label = w.label.clone(); + drop(windows_guard); + for handler in window_event_listeners + .lock() + .unwrap() + .get(&window_id) + .unwrap() + .lock() + .unwrap() + .values() + { + handler(&WindowEvent::CloseRequested { + label: label.clone(), + signal_tx: tx.clone(), + }); + } + callback(RunEvent::CloseRequested { + label, + signal_tx: tx, + }); + if let Ok(true) = rx.try_recv() { + None + } else { + on_window_close( + callback, + window_id, + windows.lock().expect("poisoned webview collection"), + control_flow, + #[cfg(target_os = "linux")] + window_event_listeners, + menu_event_listeners, + ) + } + } else { + None + } } fn on_window_close<'a>( @@ -2940,8 +3040,9 @@ fn on_window_close<'a>( control_flow: &mut ControlFlow, #[cfg(target_os = "linux")] window_event_listeners: &WindowEventListeners, menu_event_listeners: MenuEventListeners, -) { - if let Some(webview) = windows.remove(&window_id) { +) -> Option { + #[allow(unused_mut)] + let w = if let Some(mut webview) = windows.remove(&window_id) { #[cfg(feature = "egui")] { // Destrooy GL context if its a GLWindow @@ -2949,15 +3050,17 @@ fn on_window_close<'a>( if let Some(id) = *egui_id { if id == window_id { #[cfg(not(target_os = "linux"))] - if let WindowHandle::GLWindow(gl_window, gl, mut painter, mut integration, ..) = - webview.inner + if let WindowHandle::GLWindow(gl_window, gl, ref mut painter, ref mut integration, ..) = + &mut webview.inner { integration.on_exit(gl_window.window()); painter.destroy(&gl); *egui_id = None; } #[cfg(target_os = "linux")] - if let WindowHandle::GLWindow(gl_window, gl, painter, integration, ..) = webview.inner { + if let WindowHandle::GLWindow(gl_window, gl, painter, integration, ..) = + &mut webview.inner + { let mut integration = integration.borrow_mut(); let mut painter = painter.borrow_mut(); integration.on_exit(gl_window.window()); @@ -2976,7 +3079,7 @@ fn on_window_close<'a>( if is_empty { let (tx, rx) = channel(); callback(RunEvent::ExitRequested { - window_label: webview.label, + window_label: webview.label.clone(), tx, }); @@ -2988,7 +3091,10 @@ fn on_window_close<'a>( callback(RunEvent::Exit); } } - } + Some(webview) + } else { + None + }; // TODO: tao does not fire the destroyed event properly #[cfg(target_os = "linux")] { @@ -3004,6 +3110,7 @@ fn on_window_close<'a>( handler(&WindowEvent::Destroyed); } } + w } fn center_window(window: &Window, window_size: WryPhysicalSize) -> Result<()> {