Skip to content

Commit

Permalink
refactor(api)!: change window label getters to be async ref #5380 (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Aug 15, 2024
1 parent b160f93 commit b6dca99
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 181 deletions.
9 changes: 9 additions & 0 deletions .changes/get-window-async.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@tauri-apps/api": patch:breaking
---

Changed `WebviewWindow.getAll`, `WebviewWindow.getByLabel`, `getAllWebviewWindows`,
`Window.getAll`, `Window.getByLabel`, `getAllWindows`,
`Webview.getAll`, `Webview.getByLabel`, `getAllWebviews`
to be async so their return value are synchronized with the state from the Rust side,
meaning new and destroyed windows are reflected.
2 changes: 2 additions & 0 deletions core/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
&[
("create", false),
// getters
("get_all_windows", true),
("scale_factor", true),
("inner_position", true),
("outer_position", true),
Expand Down Expand Up @@ -120,6 +121,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
("create_webview", false),
("create_webview_window", false),
// getters
("get_all_webviews", true),
("webview_position", true),
("webview_size", true),
// setters
Expand Down
27 changes: 27 additions & 0 deletions core/tauri/permissions/webview/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Default permissions for the plugin.

- `allow-get-all-webviews`
- `allow-webview-position`
- `allow-webview-size`
- `allow-internal-toggle-devtools`
Expand Down Expand Up @@ -70,6 +71,32 @@ Denies the create_webview_window command without any pre-configured scope.
<tr>
<td>

`core:webview:allow-get-all-webviews`

</td>
<td>

Enables the get_all_webviews command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:webview:deny-get-all-webviews`

</td>
<td>

Denies the get_all_webviews command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:webview:allow-internal-toggle-devtools`

</td>
Expand Down
27 changes: 27 additions & 0 deletions core/tauri/permissions/window/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Default permissions for the plugin.

- `allow-get-all-windows`
- `allow-scale-factor`
- `allow-inner-position`
- `allow-outer-position`
Expand Down Expand Up @@ -220,6 +221,32 @@ Denies the destroy command without any pre-configured scope.
<tr>
<td>

`core:window:allow-get-all-windows`

</td>
<td>

Enables the get_all_windows command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:deny-get-all-windows`

</td>
<td>

Denies the get_all_windows command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:allow-hide`

</td>
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

23 changes: 2 additions & 21 deletions core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use crate::{
channel::ChannelDataIpcQueue, CallbackFn, CommandArg, CommandItem, Invoke, InvokeError,
InvokeHandler, InvokeResponder, InvokeResponse,
},
manager::{
webview::{UriSchemeProtocol, WebviewLabelDef},
AppManager, Asset,
},
manager::{webview::UriSchemeProtocol, AppManager, Asset},
plugin::{Plugin, PluginStore},
resources::ResourceTable,
runtime::{
Expand Down Expand Up @@ -1961,24 +1958,8 @@ impl<R: Runtime> HasDisplayHandle for App<R> {
fn setup<R: Runtime>(app: &mut App<R>) -> crate::Result<()> {
app.ran_setup = true;

let window_labels = app
.config()
.app
.windows
.iter()
.map(|p| p.label.clone())
.collect::<Vec<_>>();
let webview_labels = window_labels
.iter()
.map(|label| WebviewLabelDef {
window_label: label.clone(),
label: label.clone(),
})
.collect::<Vec<_>>();

for window_config in app.config().app.windows.clone() {
WebviewWindowBuilder::from_config(app.handle(), &window_config)?
.build_internal(&window_labels, &webview_labels)?;
WebviewWindowBuilder::from_config(app.handle(), &window_config)?.build()?;
}

app.manager.assets.setup(app);
Expand Down
37 changes: 1 addition & 36 deletions core/tauri/src/manager/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,6 @@ pub struct UriSchemeProtocol<R: Runtime> {
Box<dyn Fn(&AppHandle<R>, http::Request<Vec<u8>>, UriSchemeResponder) + Send + Sync>,
}

#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WebviewLabelDef {
pub window_label: String,
pub label: String,
}

pub struct WebviewManager<R: Runtime> {
pub webviews: Mutex<HashMap<String, Webview<R>>>,
/// The JS message handler.
Expand Down Expand Up @@ -127,8 +120,6 @@ impl<R: Runtime> WebviewManager<R> {
mut pending: PendingWebview<EventLoopMessage, R>,
label: &str,
window_label: &str,
window_labels: &[String],
webview_labels: &[WebviewLabelDef],
manager: &M,
) -> crate::Result<PendingWebview<EventLoopMessage, R>> {
let app_manager = manager.manager();
Expand Down Expand Up @@ -156,13 +147,6 @@ impl<R: Runtime> WebviewManager<R> {
}
.render_default(&Default::default())?;

let mut webview_labels = webview_labels.to_vec();
if !webview_labels.iter().any(|w| w.label == label) {
webview_labels.push(WebviewLabelDef {
window_label: window_label.to_string(),
label: label.to_string(),
});
}
webview_attributes = webview_attributes
.initialization_script(
r"
Expand All @@ -184,15 +168,11 @@ impl<R: Runtime> WebviewManager<R> {
r#"
Object.defineProperty(window.__TAURI_INTERNALS__, 'metadata', {{
value: {{
windows: {window_labels_array}.map(function (label) {{ return {{ label: label }} }}),
webviews: {webview_labels_array},
currentWindow: {{ label: {current_window_label} }},
currentWebview: {{ label: {current_webview_label} }}
}}
}})
"#,
window_labels_array = serde_json::to_string(&window_labels)?,
webview_labels_array = serde_json::to_string(&webview_labels)?,
current_window_label = serde_json::to_string(window_label)?,
current_webview_label = serde_json::to_string(&label)?,
))
Expand Down Expand Up @@ -415,8 +395,6 @@ impl<R: Runtime> WebviewManager<R> {
manager: &M,
mut pending: PendingWebview<EventLoopMessage, R>,
window_label: &str,
window_labels: &[String],
webview_labels: &[WebviewLabelDef],
) -> crate::Result<PendingWebview<EventLoopMessage, R>> {
if self.webviews_lock().contains_key(&pending.label) {
return Err(crate::Error::WebviewLabelAlreadyExists(pending.label));
Expand Down Expand Up @@ -509,14 +487,7 @@ impl<R: Runtime> WebviewManager<R> {
}

let label = pending.label.clone();
pending = self.prepare_pending_webview(
pending,
&label,
window_label,
window_labels,
webview_labels,
manager,
)?;
pending = self.prepare_pending_webview(pending, &label, window_label, manager)?;

pending.ipc_handler = Some(crate::ipc::protocol::message_handler(
manager.manager_owned(),
Expand Down Expand Up @@ -638,12 +609,6 @@ impl<R: Runtime> WebviewManager<R> {
.expect("failed to run on_webview_created hook");
}

if let Ok(webview_labels_array) = serde_json::to_string(&webview.manager.webview.labels()) {
let _ = webview.manager.webview.eval_script_all(format!(
"window.__TAURI_INTERNALS__.metadata.webviews = {webview_labels_array}.map(function (label) {{ return {{ label: label }} }})",
));
}

let _ = webview.manager.emit(
"tauri://webview-created",
Some(crate::webview::CreatedEvent {
Expand Down
7 changes: 0 additions & 7 deletions core/tauri/src/manager/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,6 @@ fn on_window_event<R: Runtime>(window: &Window<R>, event: &WindowEvent) -> crate
}
WindowEvent::Destroyed => {
window.emit_to_window(WINDOW_DESTROYED_EVENT, ())?;
let label = window.label();

if let Ok(webview_labels_array) = serde_json::to_string(&window.manager().webview.labels()) {
let _ = window.manager().webview.eval_script_all(format!(
r#"(function () {{ const metadata = window.__TAURI_INTERNALS__.metadata; if (metadata != null) {{ metadata.windows = window.__TAURI_INTERNALS__.metadata.windows.filter(w => w.label !== "{label}"); metadata.webviews = {webview_labels_array}.map(function (label) {{ return {{ label: label }} }}) }} }})()"#,
));
}
}
WindowEvent::Focused(focused) => window.emit_to_window(
if *focused {
Expand Down
35 changes: 6 additions & 29 deletions core/tauri/src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::{
CallbackFn, CommandArg, CommandItem, Invoke, InvokeBody, InvokeError, InvokeMessage,
InvokeResolver, Origin, OwnedInvokeResponder,
},
manager::{webview::WebviewLabelDef, AppManager},
manager::AppManager,
sealed::{ManagerBase, RuntimeOrDispatch},
AppHandle, Emitter, Event, EventId, EventLoopMessage, Listener, Manager, ResourceTable, Runtime,
Window,
Expand Down Expand Up @@ -548,8 +548,6 @@ tauri::Builder::default()
mut self,
manager: &M,
window_label: &str,
window_labels: &[String],
webview_labels: &[WebviewLabelDef],
) -> crate::Result<PendingWebview<EventLoopMessage, R>> {
let mut pending = PendingWebview::new(self.webview_attributes, self.label.clone())?;
pending.navigation_handler = self.navigation_handler.take();
Expand Down Expand Up @@ -589,13 +587,10 @@ tauri::Builder::default()
}
}));

manager.manager().webview.prepare_webview(
manager,
pending,
window_label,
window_labels,
webview_labels,
)
manager
.manager()
.webview
.prepare_webview(manager, pending, window_label)
}

/// Creates a new webview on the given window.
Expand All @@ -606,27 +601,9 @@ tauri::Builder::default()
position: Position,
size: Size,
) -> crate::Result<Webview<R>> {
let window_labels = window
.manager()
.window
.labels()
.into_iter()
.collect::<Vec<_>>();
let webview_labels = window
.manager()
.webview
.webviews_lock()
.values()
.map(|w| WebviewLabelDef {
window_label: w.window().label().to_string(),
label: w.label().to_string(),
})
.collect::<Vec<_>>();

let app_manager = window.manager();

let mut pending =
self.into_pending_webview(&window, window.label(), &window_labels, &webview_labels)?;
let mut pending = self.into_pending_webview(&window, window.label())?;

pending.webview_attributes.bounds = Some(Rect { size, position });

Expand Down
22 changes: 21 additions & 1 deletion core/tauri/src/webview/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
#[cfg(desktop)]
mod desktop_commands {

use serde::Deserialize;
use serde::{Deserialize, Serialize};
use tauri_runtime::dpi::{Position, Size};
use tauri_utils::config::{WebviewUrl, WindowConfig};

Expand Down Expand Up @@ -44,6 +44,25 @@ mod desktop_commands {
zoom_hotkeys_enabled: bool,
}

#[derive(Serialize)]
pub struct WebviewRef {
window_label: String,
label: String,
}

#[command(root = "crate")]
pub async fn get_all_webviews<R: Runtime>(app: AppHandle<R>) -> Vec<WebviewRef> {
app
.manager()
.webviews()
.values()
.map(|webview| WebviewRef {
window_label: webview.window().label().into(),
label: webview.label().into(),
})
.collect()
}

#[command(root = "crate")]
pub async fn create_webview_window<R: Runtime>(
app: AppHandle<R>,
Expand Down Expand Up @@ -232,6 +251,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
desktop_commands::create_webview,
desktop_commands::create_webview_window,
// getters
desktop_commands::get_all_webviews,
desktop_commands::webview_position,
desktop_commands::webview_size,
// setters
Expand Down
15 changes: 1 addition & 14 deletions core/tauri/src/webview/webview_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use url::Url;

use crate::{
ipc::{CommandArg, CommandItem, InvokeError, OwnedInvokeResponder},
manager::{webview::WebviewLabelDef, AppManager},
manager::AppManager,
sealed::{ManagerBase, RuntimeOrDispatch},
webview::PageLoadPayload,
webview::WebviewBuilder,
Expand Down Expand Up @@ -347,19 +347,6 @@ tauri::Builder::default()
let (_window, webview) = self.window_builder.with_webview(self.webview_builder)?;
Ok(WebviewWindow { webview })
}

pub(crate) fn build_internal(
self,
window_labels: &[String],
webview_labels: &[WebviewLabelDef],
) -> crate::Result<WebviewWindow<R>> {
let (_window, webview) = self.window_builder.with_webview_internal(
self.webview_builder,
window_labels,
webview_labels,
)?;
Ok(WebviewWindow { webview })
}
}

/// Desktop APIs.
Expand Down
Loading

0 comments on commit b6dca99

Please sign in to comment.