Skip to content

Commit

Permalink
refactor: refactor parent APIs on WindowBuilder (#8622)
Browse files Browse the repository at this point in the history
* refactor: refactor parent APIs on `WindowBuilder`

closes #8587 #1643

* fix build

* clippy

* support parent in JS and config

* change files

* fix build

* clippy

* fix doctests

* fix linux build

* fix doctests

* update docs

* fix api, update example to use JS API

* fix merge

* lint

* fix tests on windows

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
amrbashir and lucasfernog authored Jan 31, 2024
1 parent a2fc3a6 commit 9eaeb5a
Show file tree
Hide file tree
Showing 28 changed files with 453 additions and 139 deletions.
5 changes: 5 additions & 0 deletions .changes/api-window-parent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tauri-apps/api': 'patch:feat'
---

Add `parent` option when creating a window.
5 changes: 5 additions & 0 deletions .changes/tauri-parent-owner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:feat'
---

Add `WindowBuilder::parent` which is a convenient wrapper around parent functionality for Windows, Linux and macOS. Also added `WindowBuilder::owner` on Windows only. Also added `WindowBuilder::transient_for` and `WindowBuilder::transient_for_raw` on Linux only.
5 changes: 5 additions & 0 deletions .changes/tauri-remove-parent-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:breaking'
---

Renamed `WindowBuilder::owner_window` to `WindowBuilder::owner_raw` and `WindowBuilder::parent_window` to `WindowBuilder::parent_raw`.
6 changes: 6 additions & 0 deletions .changes/tauri-runtime-remove-parent-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'tauri-runtime': 'patch'
'tauri-runtime-wry': 'patch'
---

Added `WindowBuilder::transient_for` and Renamed `WindowBuilder::owner_window` to `WindowBuilder::owner` and `WindowBuilder::parent_window` to `WindowBuilder::parent`.
5 changes: 5 additions & 0 deletions .changes/tauri-utils-config-parent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-utils': 'patch:feat'
---

Add `parent` option for window config.
5 changes: 5 additions & 0 deletions .changes/tauri-window-builder-from-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:breaking'
---

Changed `WindowBuilder::from_config` to return a `Result<Self>`.
6 changes: 6 additions & 0 deletions .changes/tauri-window-builder-with-config-ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'tauri-runtime': 'patch:breaking'
'tauri-runtime-wry': 'patch:breaking'
---

Changed `WindowBuilder::with_config` to take a reference to a `WindowConfig` instead of an owned value.
7 changes: 7 additions & 0 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,13 @@
"description": "Whether or not the webview should be launched in incognito mode.\n\n## Platform-specific:\n\n- **Android**: Unsupported.",
"default": false,
"type": "boolean"
},
"parent": {
"description": "Sets the window associated with this label to be the parent of the window to be created.\n\n## Platform-specific\n\n- **Windows**: This sets the passed parent as an owner window to the window to be created. From [MSDN owned windows docs](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows): - An owned window is always above its owner in the z-order. - The system automatically destroys an owned window when its owner is destroyed. - An owned window is hidden when its owner is minimized. - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html> - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = { workspace = true }

[dependencies]
wry = { version = "0.35.2", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
tao = { version = "0.24", default-features = false, features = [ "rwh_05", "rwh_06" ] }
tao = { git = "https://github.com/tauri-apps/tao", branch = "dev", default-features = false, features = [ "rwh_05", "rwh_06" ] }
tauri-runtime = { version = "1.0.0-alpha.8", path = "../tauri-runtime" }
tauri-utils = { version = "2.0.0-alpha.13", path = "../tauri-utils" }
raw-window-handle = "0.5"
Expand Down
24 changes: 18 additions & 6 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ impl WindowBuilder for WindowBuilderWrapper {
Self::default().focused(true)
}

fn with_config(config: WindowConfig) -> Self {
fn with_config(config: &WindowConfig) -> Self {
let mut window = WindowBuilderWrapper::new();

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -878,20 +878,32 @@ impl WindowBuilder for WindowBuilderWrapper {
}

#[cfg(windows)]
fn parent_window(mut self, parent: HWND) -> Self {
fn owner(mut self, owner: HWND) -> Self {
self.inner = self.inner.with_owner_window(owner.0);
self
}

#[cfg(windows)]
fn parent(mut self, parent: HWND) -> Self {
self.inner = self.inner.with_parent_window(parent.0);
self
}

#[cfg(target_os = "macos")]
fn parent_window(mut self, parent: *mut std::ffi::c_void) -> Self {
fn parent(mut self, parent: *mut std::ffi::c_void) -> Self {
self.inner = self.inner.with_parent_window(parent);
self
}

#[cfg(windows)]
fn owner_window(mut self, owner: HWND) -> Self {
self.inner = self.inner.with_owner_window(owner.0);
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn transient_for(mut self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
self.inner = self.inner.with_transient_for(parent);
self
}

Expand Down
42 changes: 26 additions & 16 deletions core/tauri-runtime/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ pub trait WindowBuilder: WindowBuilderBase {
fn new() -> Self;

/// Initializes a new window builder from a [`WindowConfig`]
fn with_config(config: WindowConfig) -> Self;
fn with_config(config: &WindowConfig) -> Self;

/// Show window in the center of the screen.
#[must_use]
Expand Down Expand Up @@ -330,35 +330,45 @@ pub trait WindowBuilder: WindowBuilderBase {
#[must_use]
fn shadow(self, enable: bool) -> Self;

/// Sets a parent to the window to be created.
/// Set an owner to the window to be created.
///
/// A child window has the WS_CHILD style and is confined to the client area of its parent window.
/// From MSDN:
/// - An owned window is always above its owner in the z-order.
/// - The system automatically destroys an owned window when its owner is destroyed.
/// - An owned window is hidden when its owner is minimized.
///
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows>
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
#[cfg(windows)]
#[must_use]
fn parent_window(self, parent: HWND) -> Self;
fn owner(self, owner: HWND) -> Self;

/// Sets a parent to the window to be created.
///
/// A child window has the WS_CHILD style and is confined to the client area of its parent window.
///
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows>
#[cfg(target_os = "macos")]
#[cfg(windows)]
#[must_use]
fn parent_window(self, parent: *mut std::ffi::c_void) -> Self;
fn parent(self, parent: HWND) -> Self;

/// Set an owner to the window to be created.
///
/// From MSDN:
/// - An owned window is always above its owner in the z-order.
/// - The system automatically destroys an owned window when its owner is destroyed.
/// - An owned window is hidden when its owner is minimized.
/// Sets a parent to the window to be created.
///
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
#[cfg(windows)]
/// See <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
#[cfg(target_os = "macos")]
#[must_use]
fn owner_window(self, owner: HWND) -> Self;
fn parent(self, parent: *mut std::ffi::c_void) -> Self;

/// Sets the window to be created transient for parent.
///
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn transient_for(self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self;

/// Enables or disables drag and drop support.
#[cfg(windows)]
Expand Down
17 changes: 16 additions & 1 deletion core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,18 @@ pub struct WindowConfig {
/// - **Android**: Unsupported.
#[serde(default)]
pub incognito: bool,
/// Sets the window associated with this label to be the parent of the window to be created.
///
/// ## Platform-specific
///
/// - **Windows**: This sets the passed parent as an owner window to the window to be created.
/// From [MSDN owned windows docs](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows):
/// - An owned window is always above its owner in the z-order.
/// - The system automatically destroys an owned window when its owner is destroyed.
/// - An owned window is hidden when its owner is minimized.
/// - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
/// - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
pub parent: Option<String>,
}

impl Default for WindowConfig {
Expand Down Expand Up @@ -1295,6 +1307,7 @@ impl Default for WindowConfig {
shadow: true,
window_effects: None,
incognito: false,
parent: None,
}
}
}
Expand Down Expand Up @@ -2310,6 +2323,7 @@ mod build {
let shadow = self.shadow;
let window_effects = opt_lit(self.window_effects.as_ref());
let incognito = self.incognito;
let parent = opt_str_lit(self.parent.as_ref());

literal_struct!(
tokens,
Expand Down Expand Up @@ -2351,7 +2365,8 @@ mod build {
additional_browser_args,
shadow,
window_effects,
incognito
incognito,
parent
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ mod window_effects {
pub use window_effects::{WindowEffect, WindowEffectState};

/// How the window title bar should be displayed on macOS.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum TitleBarStyle {
/// A normal title bar.
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1706,7 +1706,7 @@ fn setup<R: Runtime>(app: &mut App<R>) -> crate::Result<()> {
.collect::<Vec<_>>();

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

Expand Down
11 changes: 11 additions & 0 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,17 @@ impl<A: Assets> Context<A> {
&self.pattern
}

/// A mutable reference to the resolved ACL.
///
/// # Stability
///
/// This API is unstable.
#[doc(hidden)]
#[inline(always)]
pub fn resolved_acl(&mut self) -> &mut Resolved {
&mut self.resolved_acl
}

/// Create a new [`Context`] from the minimal required items.
#[inline(always)]
#[allow(clippy::too_many_arguments)]
Expand Down
21 changes: 16 additions & 5 deletions core/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl WindowBuilder for MockWindowBuilder {
Self {}
}

fn with_config(config: WindowConfig) -> Self {
fn with_config(config: &WindowConfig) -> Self {
Self {}
}

Expand Down Expand Up @@ -376,17 +376,28 @@ impl WindowBuilder for MockWindowBuilder {
}

#[cfg(windows)]
fn parent_window(self, parent: HWND) -> Self {
fn owner(self, owner: HWND) -> Self {
self
}

#[cfg(windows)]
fn parent(self, parent: HWND) -> Self {
self
}

#[cfg(target_os = "macos")]
fn parent_window(self, parent: *mut std::ffi::c_void) -> Self {
fn parent(self, parent: *mut std::ffi::c_void) -> Self {
self
}

#[cfg(windows)]
fn owner_window(self, owner: HWND) -> Self {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn transient_for(self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
self
}

Expand Down
7 changes: 4 additions & 3 deletions core/tauri/src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ async fn create_window(app: tauri::AppHandle) {
```
#[tauri::command]
async fn reopen_window(app: tauri::AppHandle) {
let window = tauri::window::WindowBuilder::from_config(&app, app.config().tauri.windows.get(0).unwrap().clone())
let window = tauri::window::WindowBuilder::from_config(&app, &app.config().tauri.windows.get(0).unwrap().clone())
.unwrap()
.build()
.unwrap();
}
Expand All @@ -363,10 +364,10 @@ async fn reopen_window(app: tauri::AppHandle) {
)]
///
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
pub fn from_config(config: WindowConfig) -> Self {
pub fn from_config(config: &WindowConfig) -> Self {
Self {
label: config.label.clone(),
webview_attributes: WebviewAttributes::from(&config),
webview_attributes: WebviewAttributes::from(config),
web_resource_request_handler: None,
navigation_handler: None,
on_page_load_handler: None,
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/src/webview/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod desktop_commands {
app: AppHandle<R>,
options: WindowConfig,
) -> crate::Result<()> {
WebviewWindowBuilder::from_config(&app, options).build()?;
WebviewWindowBuilder::from_config(&app, &options)?.build()?;
Ok(())
}
#[cfg(not(feature = "unstable"))]
Expand Down
Loading

0 comments on commit 9eaeb5a

Please sign in to comment.