mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Fix LSP server staying alive when closing preview window
* Provide an internal behavior parameter to run_event_loop() that we can use from the preview to not quit when the last window was closed. * Fix Drop for the winit event loop GraphicsWindow to drop the backend window correctly when unmapping, not when the graphics window dies. Otherwise QuitOnLastWindowClosed doesn't work.
This commit is contained in:
parent
b81803774b
commit
1e4921de13
9 changed files with 55 additions and 24 deletions
|
@ -34,7 +34,8 @@ pub unsafe extern "C" fn sixtyfps_component_window_init(out: *mut ComponentWindo
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_run_event_loop() {
|
||||
crate::backend().run_event_loop();
|
||||
crate::backend()
|
||||
.run_event_loop(sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -241,7 +241,8 @@ pub fn create_window() -> re_exports::ComponentWindow {
|
|||
/// events from the windowing system in order to render to the screen
|
||||
/// and react to user input.
|
||||
pub fn run_event_loop() {
|
||||
sixtyfps_rendering_backend_default::backend().run_event_loop();
|
||||
sixtyfps_rendering_backend_default::backend()
|
||||
.run_event_loop(sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed);
|
||||
}
|
||||
|
||||
/// This trait describes the common public API of a strongly referenced SixtyFPS component,
|
||||
|
|
|
@ -15,6 +15,14 @@ use std::path::Path;
|
|||
|
||||
use crate::window::ComponentWindow;
|
||||
|
||||
/// Behavior describing how the event loop should terminate.
|
||||
pub enum EventLoopQuitBehavior {
|
||||
/// Terminate the event loop when the last window was closed.
|
||||
QuitOnLastWindowClosed,
|
||||
/// Keep the event loop running until [`Backend::quit_event_loop()`] is called.
|
||||
QuitOnlyExplicitly,
|
||||
}
|
||||
|
||||
/// Interface implemented by backends
|
||||
pub trait Backend: Send + Sync {
|
||||
/// Instentiate a window for a component.
|
||||
|
@ -22,7 +30,7 @@ pub trait Backend: Send + Sync {
|
|||
fn create_window(&'static self) -> ComponentWindow;
|
||||
|
||||
/// Spins an event loop and renders the visible windows.
|
||||
fn run_event_loop(&'static self);
|
||||
fn run_event_loop(&'static self, behavior: EventLoopQuitBehavior);
|
||||
|
||||
/// Exits the event loop.
|
||||
fn quit_event_loop(&'static self);
|
||||
|
|
|
@ -744,7 +744,9 @@ impl ComponentInstance {
|
|||
/// and [`Self::hide`].
|
||||
pub fn run(&self) {
|
||||
self.show();
|
||||
sixtyfps_rendering_backend_default::backend().run_event_loop();
|
||||
sixtyfps_rendering_backend_default::backend().run_event_loop(
|
||||
sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed,
|
||||
);
|
||||
self.hide();
|
||||
}
|
||||
|
||||
|
@ -837,7 +839,8 @@ pub enum CallCallbackError {
|
|||
/// events from the windowing system in order to render to the screen
|
||||
/// and react to user input.
|
||||
pub fn run_event_loop() {
|
||||
sixtyfps_rendering_backend_default::backend().run_event_loop();
|
||||
sixtyfps_rendering_backend_default::backend()
|
||||
.run_event_loop(sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed);
|
||||
}
|
||||
|
||||
/// This module constains a few function use by tests
|
||||
|
|
|
@ -159,7 +159,7 @@ pub enum CustomEvent {
|
|||
/// Runs the event loop and renders the items in the provided `component` in its
|
||||
/// own window.
|
||||
#[allow(unused_mut)] // mut need changes for wasm
|
||||
pub fn run() {
|
||||
pub fn run(quit_behavior: sixtyfps_corelib::backend::EventLoopQuitBehavior) {
|
||||
use winit::event::Event;
|
||||
use winit::event_loop::{ControlFlow, EventLoopWindowTarget};
|
||||
|
||||
|
@ -193,8 +193,25 @@ pub fn run() {
|
|||
match event {
|
||||
winit::event::Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = winit::event_loop::ControlFlow::Exit,
|
||||
window_id,
|
||||
} => {
|
||||
ALL_WINDOWS
|
||||
.with(|windows| {
|
||||
windows.borrow().get(&window_id).and_then(|weakref| weakref.upgrade())
|
||||
})
|
||||
.map(|window_rc| {
|
||||
window_rc.hide();
|
||||
});
|
||||
match quit_behavior {
|
||||
corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed => {
|
||||
let window_count = ALL_WINDOWS.with(|windows| windows.borrow().len());
|
||||
if window_count == 0 {
|
||||
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||
}
|
||||
}
|
||||
corelib::backend::EventLoopQuitBehavior::QuitOnlyExplicitly => {}
|
||||
}
|
||||
}
|
||||
winit::event::Event::RedrawRequested(id) => {
|
||||
corelib::animations::update_animations();
|
||||
ALL_WINDOWS.with(|windows| {
|
||||
|
|
|
@ -257,17 +257,6 @@ impl GraphicsWindow {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for GraphicsWindow {
|
||||
fn drop(&mut self) {
|
||||
match &*self.map_state.borrow() {
|
||||
GraphicsWindowBackendState::Unmapped => {}
|
||||
GraphicsWindowBackendState::Mapped(mw) => {
|
||||
crate::eventloop::unregister_window(mw.backend.borrow().window().id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GraphicsWindow {
|
||||
/// Draw the items of the specified `component` in the given window.
|
||||
pub fn draw(self: Rc<Self>) {
|
||||
|
@ -534,6 +523,12 @@ struct MappedWindow {
|
|||
constraints: Cell<corelib::layout::LayoutInfo>,
|
||||
}
|
||||
|
||||
impl Drop for MappedWindow {
|
||||
fn drop(&mut self) {
|
||||
crate::eventloop::unregister_window(self.backend.borrow().window().id());
|
||||
}
|
||||
}
|
||||
|
||||
enum GraphicsWindowBackendState {
|
||||
Unmapped,
|
||||
Mapped(MappedWindow),
|
||||
|
|
|
@ -1483,8 +1483,8 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
|||
ComponentWindow(window)
|
||||
}
|
||||
|
||||
fn run_event_loop(&'static self) {
|
||||
crate::eventloop::run();
|
||||
fn run_event_loop(&'static self, behavior: sixtyfps_corelib::backend::EventLoopQuitBehavior) {
|
||||
crate::eventloop::run(behavior);
|
||||
}
|
||||
|
||||
fn quit_event_loop(&'static self) {
|
||||
|
|
|
@ -111,14 +111,19 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
|||
}
|
||||
}
|
||||
|
||||
fn run_event_loop(&'static self) {
|
||||
fn run_event_loop(&'static self, _behavior: sixtyfps_corelib::backend::EventLoopQuitBehavior) {
|
||||
#[cfg(not(no_qt))]
|
||||
{
|
||||
let quit_on_last_window_closed = match _behavior {
|
||||
sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnLastWindowClosed => true,
|
||||
sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnlyExplicitly => false,
|
||||
};
|
||||
// Schedule any timers with Qt that were set up before this event loop start.
|
||||
crate::qt_window::timer_event();
|
||||
use cpp::cpp;
|
||||
cpp! {unsafe [] {
|
||||
cpp! {unsafe [quit_on_last_window_closed as "bool"] {
|
||||
ensure_initialized();
|
||||
qApp->setQuitOnLastWindowClosed(quit_on_last_window_closed);
|
||||
qApp->exec();
|
||||
} }
|
||||
};
|
||||
|
|
|
@ -50,7 +50,8 @@ pub fn run_in_ui_thread(f: Box<dyn FnOnce() + Send>) {
|
|||
}
|
||||
|
||||
pub fn start_ui_event_loop() {
|
||||
sixtyfps_interpreter::run_event_loop();
|
||||
sixtyfps_rendering_backend_default::backend()
|
||||
.run_event_loop(sixtyfps_corelib::backend::EventLoopQuitBehavior::QuitOnlyExplicitly);
|
||||
}
|
||||
|
||||
pub fn quit_ui_event_loop() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue