mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-01 03:02:28 +03:00
refactor(app): run setup and window creation when event loop is ready (#4914)
This commit is contained in:
parent
6119f4582e
commit
b4622ea4d3
@ -3,7 +3,6 @@
|
|||||||
"timeout": 3600000,
|
"timeout": 3600000,
|
||||||
"pkgManagers": {
|
"pkgManagers": {
|
||||||
"rust": {
|
"rust": {
|
||||||
"errorOnVersionRange": "^2.0.0-0",
|
|
||||||
"version": true,
|
"version": true,
|
||||||
"getPublishedVersion": "cargo search ${ pkgFile.pkg.package.name } --limit 1 | sed -nE \"s/^[^\\\"]*\\\"//; s/\\\".*//1p\"",
|
"getPublishedVersion": "cargo search ${ pkgFile.pkg.package.name } --limit 1 | sed -nE \"s/^[^\\\"]*\\\"//; s/\\\".*//1p\"",
|
||||||
"prepublish": [
|
"prepublish": [
|
||||||
@ -78,7 +77,6 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"errorOnVersionRange": "^2.0.0-0",
|
|
||||||
"version": true,
|
"version": true,
|
||||||
"getPublishedVersion": "npm view ${ pkgFile.pkg.name } version",
|
"getPublishedVersion": "npm view ${ pkgFile.pkg.name } version",
|
||||||
"prepublish": [
|
"prepublish": [
|
||||||
|
5
.changes/refactor-setup.md
Normal file
5
.changes/refactor-setup.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"tauri": major
|
||||||
|
---
|
||||||
|
|
||||||
|
**Breaking change:** The window creation and setup hook are now called when the event loop is ready.
|
@ -40,6 +40,7 @@ use tauri_utils::PackageInfo;
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
fmt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{mpsc::Sender, Arc, Weak},
|
sync::{mpsc::Sender, Arc, Weak},
|
||||||
};
|
};
|
||||||
@ -526,9 +527,10 @@ impl<R: Runtime> ManagerBase<R> for AppHandle<R> {
|
|||||||
///
|
///
|
||||||
/// This type implements [`Manager`] which allows for manipulation of global application items.
|
/// This type implements [`Manager`] which allows for manipulation of global application items.
|
||||||
#[default_runtime(crate::Wry, wry)]
|
#[default_runtime(crate::Wry, wry)]
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct App<R: Runtime> {
|
pub struct App<R: Runtime> {
|
||||||
runtime: Option<R>,
|
runtime: Option<R>,
|
||||||
|
pending_windows: Option<Vec<PendingWindow<EventLoopMessage, R>>>,
|
||||||
|
setup: Option<SetupHook<R>>,
|
||||||
manager: WindowManager<R>,
|
manager: WindowManager<R>,
|
||||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||||
global_shortcut_manager: R::GlobalShortcutManager,
|
global_shortcut_manager: R::GlobalShortcutManager,
|
||||||
@ -537,6 +539,22 @@ pub struct App<R: Runtime> {
|
|||||||
handle: AppHandle<R>,
|
handle: AppHandle<R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Runtime> fmt::Debug for App<R> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let mut d = f.debug_struct("App");
|
||||||
|
d.field("runtime", &self.runtime)
|
||||||
|
.field("manager", &self.manager)
|
||||||
|
.field("handle", &self.handle);
|
||||||
|
|
||||||
|
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||||
|
d.field("global_shortcut_manager", &self.global_shortcut_manager);
|
||||||
|
#[cfg(feature = "clipboard")]
|
||||||
|
d.field("clipboard_manager", &self.clipboard_manager);
|
||||||
|
|
||||||
|
d.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<R: Runtime> Manager<R> for App<R> {}
|
impl<R: Runtime> Manager<R> for App<R> {}
|
||||||
impl<R: Runtime> ManagerBase<R> for App<R> {
|
impl<R: Runtime> ManagerBase<R> for App<R> {
|
||||||
fn manager(&self) -> &WindowManager<R> {
|
fn manager(&self) -> &WindowManager<R> {
|
||||||
@ -544,7 +562,11 @@ impl<R: Runtime> ManagerBase<R> for App<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn runtime(&self) -> RuntimeOrDispatch<'_, R> {
|
fn runtime(&self) -> RuntimeOrDispatch<'_, R> {
|
||||||
RuntimeOrDispatch::Runtime(self.runtime.as_ref().unwrap())
|
if let Some(runtime) = self.runtime.as_ref() {
|
||||||
|
RuntimeOrDispatch::Runtime(runtime)
|
||||||
|
} else {
|
||||||
|
self.handle.runtime()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn managed_app_handle(&self) -> AppHandle<R> {
|
fn managed_app_handle(&self) -> AppHandle<R> {
|
||||||
@ -775,6 +797,17 @@ impl<R: Runtime> App<R> {
|
|||||||
let app_handle = self.handle();
|
let app_handle = self.handle();
|
||||||
let manager = self.manager.clone();
|
let manager = self.manager.clone();
|
||||||
self.runtime.take().unwrap().run(move |event| match event {
|
self.runtime.take().unwrap().run(move |event| match event {
|
||||||
|
RuntimeRunEvent::Ready => {
|
||||||
|
if let Err(e) = setup(&mut self) {
|
||||||
|
panic!("Failed to setup app: {}", e);
|
||||||
|
}
|
||||||
|
on_event_loop_event(
|
||||||
|
&app_handle,
|
||||||
|
RuntimeRunEvent::Ready,
|
||||||
|
&manager,
|
||||||
|
Some(&mut callback),
|
||||||
|
);
|
||||||
|
}
|
||||||
RuntimeRunEvent::Exit => {
|
RuntimeRunEvent::Exit => {
|
||||||
on_event_loop_event(
|
on_event_loop_event(
|
||||||
&app_handle,
|
&app_handle,
|
||||||
@ -1460,8 +1493,11 @@ impl<R: Runtime> Builder<R> {
|
|||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
let clipboard_manager = runtime.clipboard_manager();
|
let clipboard_manager = runtime.clipboard_manager();
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut app = App {
|
let mut app = App {
|
||||||
runtime: Some(runtime),
|
runtime: Some(runtime),
|
||||||
|
pending_windows: Some(self.pending_windows),
|
||||||
|
setup: Some(self.setup),
|
||||||
manager: manager.clone(),
|
manager: manager.clone(),
|
||||||
#[cfg(all(desktop, feature = "global-shortcut"))]
|
#[cfg(all(desktop, feature = "global-shortcut"))]
|
||||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||||
@ -1551,26 +1587,6 @@ impl<R: Runtime> Builder<R> {
|
|||||||
|
|
||||||
app.manager.initialize_plugins(&app.handle())?;
|
app.manager.initialize_plugins(&app.handle())?;
|
||||||
|
|
||||||
let window_labels = self
|
|
||||||
.pending_windows
|
|
||||||
.iter()
|
|
||||||
.map(|p| p.label.clone())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for pending in self.pending_windows {
|
|
||||||
let pending =
|
|
||||||
app
|
|
||||||
.manager
|
|
||||||
.prepare_window(app.handle.clone(), pending, &window_labels, None)?;
|
|
||||||
let detached = app.runtime.as_ref().unwrap().create_window(pending)?;
|
|
||||||
let _window = app.manager.attach_window(app.handle(), detached);
|
|
||||||
}
|
|
||||||
|
|
||||||
(self.setup)(&mut app).map_err(|e| crate::Error::Setup(e.into()))?;
|
|
||||||
|
|
||||||
#[cfg(updater)]
|
|
||||||
app.run_updater();
|
|
||||||
|
|
||||||
Ok(app)
|
Ok(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1593,6 +1609,38 @@ unsafe impl HasRawDisplayHandle for App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup<R: Runtime>(app: &mut App<R>) -> crate::Result<()> {
|
||||||
|
let pending_windows = app.pending_windows.take();
|
||||||
|
if let Some(pending_windows) = pending_windows {
|
||||||
|
let window_labels = pending_windows
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.label.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for pending in pending_windows {
|
||||||
|
let pending =
|
||||||
|
app
|
||||||
|
.manager
|
||||||
|
.prepare_window(app.handle.clone(), pending, &window_labels, None)?;
|
||||||
|
let detached = if let RuntimeOrDispatch::RuntimeHandle(runtime) = app.handle().runtime() {
|
||||||
|
runtime.create_window(pending)?
|
||||||
|
} else {
|
||||||
|
// the AppHandle's runtime is always RuntimeOrDispatch::RuntimeHandle
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
let _window = app.manager.attach_window(app.handle(), detached);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(setup) = app.setup.take() {
|
||||||
|
(setup)(app).map_err(|e| crate::Error::Setup(e.into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(updater)]
|
||||||
|
app.run_updater();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
|
fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
|
||||||
app_handle: &AppHandle<R>,
|
app_handle: &AppHandle<R>,
|
||||||
event: RuntimeRunEvent<EventLoopMessage>,
|
event: RuntimeRunEvent<EventLoopMessage>,
|
||||||
|
@ -13,10 +13,10 @@ use std::{borrow::Cow, sync::Arc};
|
|||||||
|
|
||||||
#[cfg(shell_scope)]
|
#[cfg(shell_scope)]
|
||||||
use crate::ShellScopeConfig;
|
use crate::ShellScopeConfig;
|
||||||
use crate::{Manager, Pattern};
|
use crate::{Manager, Pattern, WindowBuilder};
|
||||||
use tauri_utils::{
|
use tauri_utils::{
|
||||||
assets::{AssetKey, Assets, CspHash},
|
assets::{AssetKey, Assets, CspHash},
|
||||||
config::{CliConfig, Config, PatternKind, TauriConfig},
|
config::{CliConfig, Config, PatternKind, TauriConfig, WindowUrl},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct NoopAsset {
|
pub struct NoopAsset {
|
||||||
@ -46,7 +46,7 @@ pub fn mock_context<A: Assets>(assets: A) -> crate::Context<A> {
|
|||||||
package: Default::default(),
|
package: Default::default(),
|
||||||
tauri: TauriConfig {
|
tauri: TauriConfig {
|
||||||
pattern: PatternKind::Brownfield,
|
pattern: PatternKind::Brownfield,
|
||||||
windows: vec![Default::default()],
|
windows: Vec::new(),
|
||||||
cli: Some(CliConfig {
|
cli: Some(CliConfig {
|
||||||
description: None,
|
description: None,
|
||||||
long_description: None,
|
long_description: None,
|
||||||
@ -86,9 +86,15 @@ pub fn mock_context<A: Assets>(assets: A) -> crate::Context<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn mock_app() -> crate::App<MockRuntime> {
|
pub fn mock_app() -> crate::App<MockRuntime> {
|
||||||
crate::Builder::<MockRuntime>::new()
|
let app = crate::Builder::<MockRuntime>::new()
|
||||||
.build(mock_context(noop_assets()))
|
.build(mock_context(noop_assets()))
|
||||||
.unwrap()
|
.unwrap();
|
||||||
|
|
||||||
|
WindowBuilder::new(&app, "main", WindowUrl::App("index.html".into()))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mock_invoke_context() -> crate::endpoints::InvokeContext<MockRuntime> {
|
pub(crate) fn mock_invoke_context() -> crate::endpoints::InvokeContext<MockRuntime> {
|
||||||
|
Loading…
Reference in New Issue
Block a user