mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
winit: replace special private function to spawn event loop with public API in the winit backend builder
This means the event loop spawning goes through the backend, which will permit for state from the Backend struct to be available when spinning the event loop even when spawning it merely.
This commit is contained in:
parent
33561b0457
commit
ac256d61d8
5 changed files with 48 additions and 23 deletions
|
@ -72,9 +72,6 @@ pub async fn compile_from_string_with_style(
|
|||
style: String,
|
||||
optional_import_callback: Option<ImportCallbackFunction>,
|
||||
) -> Result<CompilationResult, JsValue> {
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
#[allow(deprecated)]
|
||||
let mut compiler = slint_interpreter::ComponentCompiler::default();
|
||||
if !style.is_empty() {
|
||||
|
@ -162,7 +159,8 @@ impl WrappedCompiledComp {
|
|||
});
|
||||
let component = self.0.create().unwrap();
|
||||
component.show().unwrap();
|
||||
slint_interpreter::spawn_event_loop().unwrap();
|
||||
// Merely spawns the event loop, but does not block.
|
||||
slint_interpreter::run_event_loop().unwrap();
|
||||
}
|
||||
/// Creates this compiled component in a canvas, wrapped in a promise.
|
||||
/// The HTML must contains a <canvas> element with the given `canvas_id`
|
||||
|
@ -319,7 +317,8 @@ impl WrappedInstance {
|
|||
/// to ignore.
|
||||
#[wasm_bindgen]
|
||||
pub fn run_event_loop() -> Result<(), JsValue> {
|
||||
slint_interpreter::spawn_event_loop().map_err(|e| -> JsValue { format!("{e}").into() })?;
|
||||
// Merely spawns the event loop, but does not block.
|
||||
slint_interpreter::run_event_loop().map_err(|e| -> JsValue { format!("{e}").into() })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -329,7 +328,10 @@ thread_local!(
|
|||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn init() -> Result<(), JsValue> {
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
let backend = i_slint_backend_winit::Backend::builder()
|
||||
.with_spawn_event_loop(true)
|
||||
.with_window_attributes_hook(|mut attrs| {
|
||||
NEXT_CANVAS_ID.with(|next_id| {
|
||||
if let Some(canvas_id) = next_id.borrow_mut().take() {
|
||||
|
|
|
@ -164,6 +164,8 @@ pub struct BackendBuilder {
|
|||
event_loop_builder: Option<winit::event_loop::EventLoopBuilder<SlintUserEvent>>,
|
||||
#[cfg(all(muda, target_os = "macos"))]
|
||||
muda_enable_default_menu_bar_bar: bool,
|
||||
#[cfg(target_family = "wasm")]
|
||||
spawn_event_loop: bool,
|
||||
}
|
||||
|
||||
impl BackendBuilder {
|
||||
|
@ -227,6 +229,14 @@ impl BackendBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
/// Configures this builder to spawn the event loop using [`winit::platform::web::EventLoopExtWebSys::spawn()`]
|
||||
/// run `run_event_loop()` is called.
|
||||
pub fn with_spawn_event_loop(mut self, enable: bool) -> Self {
|
||||
self.spawn_event_loop = enable;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the backend with the parameters configured previously. Set the resulting backend
|
||||
/// with `slint::platform::set_platform()`:
|
||||
///
|
||||
|
@ -333,6 +343,8 @@ impl BackendBuilder {
|
|||
proxy,
|
||||
#[cfg(all(muda, target_os = "macos"))]
|
||||
muda_enable_default_menu_bar_bar: self.muda_enable_default_menu_bar_bar,
|
||||
#[cfg(target_family = "wasm")]
|
||||
spawn_event_loop: self.spawn_event_loop,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -373,6 +385,9 @@ pub struct Backend {
|
|||
|
||||
#[cfg(all(muda, target_os = "macos"))]
|
||||
muda_enable_default_menu_bar_bar: bool,
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
spawn_event_loop: bool,
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
|
@ -409,6 +424,8 @@ impl Backend {
|
|||
event_loop_builder: None,
|
||||
#[cfg(all(muda, target_os = "macos"))]
|
||||
muda_enable_default_menu_bar_bar: true,
|
||||
#[cfg(target_family = "wasm")]
|
||||
spawn_event_loop: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -474,6 +491,12 @@ impl i_slint_core::platform::Platform for Backend {
|
|||
}
|
||||
|
||||
fn run_event_loop(&self) -> Result<(), PlatformError> {
|
||||
#[cfg(target_family = "wasm")]
|
||||
{
|
||||
if self.spawn_event_loop {
|
||||
return crate::event_loop::spawn();
|
||||
}
|
||||
}
|
||||
let loop_state = self.event_loop_state.borrow_mut().take().unwrap_or_default();
|
||||
let new_state = loop_state.run()?;
|
||||
*self.event_loop_state.borrow_mut() = Some(new_state);
|
||||
|
@ -548,12 +571,6 @@ impl i_slint_core::platform::Platform for Backend {
|
|||
}
|
||||
}
|
||||
|
||||
/// Spawn the event loop, using [`winit::platform::web::EventLoopExtWebSys::spawn()`]
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn spawn_event_loop() -> Result<(), PlatformError> {
|
||||
crate::event_loop::spawn()
|
||||
}
|
||||
|
||||
mod private {
|
||||
pub trait WinitWindowAccessorSealed {}
|
||||
}
|
||||
|
|
|
@ -1644,15 +1644,6 @@ pub fn spawn_local<F: Future + 'static>(fut: F) -> Result<JoinHandle<F::Output>,
|
|||
.map_err(|_| EventLoopError::NoEventLoopProvider)?
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "internal", target_arch = "wasm32"))]
|
||||
/// Spawn the event loop.
|
||||
///
|
||||
/// Like [`run_event_loop()`], but returns immediately as the loop is running within
|
||||
/// the browser's runtime
|
||||
pub fn spawn_event_loop() -> Result<(), PlatformError> {
|
||||
i_slint_backend_selector::with_platform(|_| i_slint_backend_winit::spawn_event_loop())
|
||||
}
|
||||
|
||||
/// This module contains a few functions used by the tests
|
||||
#[doc(hidden)]
|
||||
pub mod testing {
|
||||
|
|
|
@ -131,6 +131,7 @@ send_wrapper = { workspace = true }
|
|||
serde-wasm-bindgen = "0.6.0"
|
||||
wasm-bindgen = "0.2.80"
|
||||
wasm-bindgen-futures = "0.4.30"
|
||||
i-slint-backend-winit = { workspace = true }
|
||||
|
||||
[target.'cfg(target_vendor = "apple")'.dependencies]
|
||||
i-slint-backend-winit = { workspace = true, optional = true }
|
||||
|
|
|
@ -39,12 +39,26 @@ struct WasmCallbacks {
|
|||
|
||||
thread_local! {static WASM_CALLBACKS: RefCell<Option<WasmCallbacks>> = Default::default();}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn init_backend() -> Result<(), JsValue> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
// Initialize the winit backend when we're used in the browser's main thread.
|
||||
if web_sys::window().is_some() {
|
||||
let backend =
|
||||
i_slint_backend_winit::Backend::builder().with_spawn_event_loop(true).build().unwrap();
|
||||
i_slint_core::platform::set_platform(Box::new(backend))
|
||||
.map_err(|e| -> JsValue { format!("{e}").into() })?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register DOM event handlers on all instance and set up the event loop for that.
|
||||
/// You can call this function only once. It will throw an exception but that is safe
|
||||
/// to ignore.
|
||||
/// You can call this function only once.
|
||||
#[wasm_bindgen]
|
||||
pub fn run_event_loop() -> Result<(), JsValue> {
|
||||
slint_interpreter::spawn_event_loop().map_err(|e| -> JsValue { format!("{e}").into() })
|
||||
slint_interpreter::run_event_loop().map_err(|e| -> JsValue { format!("{e}").into() })
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue