mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-02-06 15:56:51 +00:00
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com> Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
d36c8e0322
commit
4e807a53e2
5
.changes/parent-window-hwnd.md
Normal file
5
.changes/parent-window-hwnd.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
**Breaking change:** The `Window::hwnd` method now returns *HWND* from `windows-rs` crate instead of *c_void* on Windows.
|
||||
7
.changes/parent-window-macos.md
Normal file
7
.changes/parent-window-macos.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"tauri-runtime-wry": minor
|
||||
"tauri-runtime": minor
|
||||
"tauri": minor
|
||||
---
|
||||
|
||||
Support window parenting on macOS
|
||||
@ -877,6 +877,14 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn parent_window(mut self, parent: *mut std::ffi::c_void) -> Self {
|
||||
use wry::application::platform::macos::WindowBuilderExtMacOS;
|
||||
|
||||
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);
|
||||
|
||||
@ -165,6 +165,15 @@ pub trait WindowBuilder: WindowBuilderBase {
|
||||
#[must_use]
|
||||
fn parent_window(self, parent: 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")]
|
||||
#[must_use]
|
||||
fn parent_window(self, parent: *mut std::ffi::c_void) -> Self;
|
||||
|
||||
/// Set an owner to the window to be created.
|
||||
///
|
||||
/// From MSDN:
|
||||
|
||||
@ -277,6 +277,10 @@ name = "multiwindow"
|
||||
path = "../../examples/multiwindow/src-tauri/src/main.rs"
|
||||
required-features = [ "window-create" ]
|
||||
|
||||
[[example]]
|
||||
name = "parent-window"
|
||||
path = "../../examples/parent-window/src-tauri/src/main.rs"
|
||||
|
||||
[[example]]
|
||||
name = "navigation"
|
||||
path = "../../examples/navigation/src-tauri/src/main.rs"
|
||||
|
||||
@ -238,6 +238,11 @@ impl WindowBuilder for MockWindowBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn parent_window(self, parent: *mut std::ffi::c_void) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn owner_window(self, owner: HWND) -> Self {
|
||||
self
|
||||
|
||||
@ -387,6 +387,14 @@ impl<R: Runtime> WindowBuilder<R> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a parent to the window to be created.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
pub fn parent_window(mut self, parent: *mut std::ffi::c_void) -> Self {
|
||||
self.window_builder = self.window_builder.parent_window(parent);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set an owner to the window to be created.
|
||||
///
|
||||
/// From MSDN:
|
||||
@ -463,7 +471,7 @@ unsafe impl<R: Runtime> raw_window_handle::HasRawWindowHandle for Window<R> {
|
||||
#[cfg(windows)]
|
||||
fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
|
||||
let mut handle = raw_window_handle::Win32Handle::empty();
|
||||
handle.hwnd = self.hwnd().expect("failed to get window `hwnd`");
|
||||
handle.hwnd = self.hwnd().expect("failed to get window `hwnd`").0 as *mut _;
|
||||
raw_window_handle::RawWindowHandle::Win32(handle)
|
||||
}
|
||||
|
||||
@ -909,13 +917,8 @@ impl<R: Runtime> Window<R> {
|
||||
}
|
||||
/// Returns the native handle that is used by this window.
|
||||
#[cfg(windows)]
|
||||
pub fn hwnd(&self) -> crate::Result<*mut std::ffi::c_void> {
|
||||
self
|
||||
.window
|
||||
.dispatcher
|
||||
.hwnd()
|
||||
.map(|hwnd| hwnd.0 as *mut _)
|
||||
.map_err(Into::into)
|
||||
pub fn hwnd(&self) -> crate::Result<HWND> {
|
||||
self.window.dispatcher.hwnd().map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the `ApplicatonWindow` from gtk crate that is used by this window.
|
||||
|
||||
3
examples/parent-window/README.md
Normal file
3
examples/parent-window/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Parent Window Example
|
||||
|
||||
Run the following at the root directory of the repository to try it out: `cargo run --example parent-window`.
|
||||
53
examples/parent-window/index.html
Normal file
53
examples/parent-window/index.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<style>
|
||||
#response {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="window-label"></div>
|
||||
<div id="container"></div>
|
||||
<div id="response"></div>
|
||||
|
||||
<script>
|
||||
var WebviewWindow = window.__TAURI__.window.WebviewWindow
|
||||
var thisTauriWindow = window.__TAURI__.window.getCurrent()
|
||||
var windowLabel = thisTauriWindow.label
|
||||
var windowLabelContainer = document.getElementById('window-label')
|
||||
windowLabelContainer.innerText = 'This is the ' + windowLabel + ' window.'
|
||||
|
||||
var container = document.getElementById('container')
|
||||
|
||||
var responseContainer = document.getElementById('response')
|
||||
function runCommand(commandName, args, optional) {
|
||||
window.__TAURI__
|
||||
.invoke(commandName, args)
|
||||
.then((response) => {
|
||||
responseContainer.innerText += `Ok(${response})\n\n`
|
||||
})
|
||||
.catch((error) => {
|
||||
responseContainer.innerText += `Err(${error})\n\n`
|
||||
})
|
||||
}
|
||||
window.__TAURI__.event.listen('tauri://window-created', function (event) {
|
||||
responseContainer.innerText += 'Got window-created event\n\n'
|
||||
})
|
||||
|
||||
var createWindowButton = document.createElement('button')
|
||||
var windowNumber = 1
|
||||
createWindowButton.innerHTML = 'Create child window '+windowNumber
|
||||
createWindowButton.addEventListener('click', function () {
|
||||
runCommand('create_child_window', { id: 'child-'+windowNumber })
|
||||
windowNumber += 1
|
||||
createWindowButton.innerHTML = 'Create child window '+windowNumber
|
||||
})
|
||||
container.appendChild(createWindowButton)
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
4
examples/parent-window/src-tauri/.gitignore
vendored
Normal file
4
examples/parent-window/src-tauri/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
WixTools
|
||||
3
examples/parent-window/src-tauri/.license_template
Normal file
3
examples/parent-window/src-tauri/.license_template
Normal file
@ -0,0 +1,3 @@
|
||||
// Copyright {20\d{2}(-20\d{2})?} Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
17
examples/parent-window/src-tauri/Cargo.toml
Normal file
17
examples/parent-window/src-tauri/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "parent-window"
|
||||
version = "0.1.0"
|
||||
description = "An example Tauri Multi-Window Application"
|
||||
edition = "2021"
|
||||
rust-version = "1.57"
|
||||
license = "Apache-2.0 OR MIT"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { path = "../../../core/tauri-build" }
|
||||
|
||||
[dependencies]
|
||||
tauri = { path = "../../../core/tauri" }
|
||||
|
||||
[features]
|
||||
default = [ "custom-protocol" ]
|
||||
custom-protocol = [ "tauri/custom-protocol" ]
|
||||
14
examples/parent-window/src-tauri/build.rs
Normal file
14
examples/parent-window/src-tauri/build.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use tauri_build::{try_build, Attributes, WindowsAttributes};
|
||||
|
||||
fn main() {
|
||||
if let Err(error) = try_build(
|
||||
Attributes::new()
|
||||
.windows_attributes(WindowsAttributes::new().window_icon_path("../../.icons/icon.ico")),
|
||||
) {
|
||||
panic!("error found during tauri-build: {:#?}", error);
|
||||
}
|
||||
}
|
||||
22
examples/parent-window/src-tauri/src/commands.rs
Normal file
22
examples/parent-window/src-tauri/src/commands.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use tauri::{command, window, AppHandle, Manager, WindowUrl};
|
||||
|
||||
#[command]
|
||||
pub fn create_child_window(id: String, app: AppHandle) {
|
||||
#[cfg(any(windows, target_os = "macos"))]
|
||||
let main = app.get_window("main").unwrap();
|
||||
|
||||
let child = window::WindowBuilder::new(&app, id, WindowUrl::default())
|
||||
.title("Child")
|
||||
.inner_size(400.0, 300.0);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let child = child.parent_window(main.ns_window().unwrap());
|
||||
#[cfg(windows)]
|
||||
let child = child.parent_window(main.hwnd().unwrap());
|
||||
|
||||
child.build().unwrap();
|
||||
}
|
||||
38
examples/parent-window/src-tauri/src/main.rs
Normal file
38
examples/parent-window/src-tauri/src/main.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![cfg_attr(
|
||||
all(not(debug_assertions), target_os = "windows"),
|
||||
windows_subsystem = "windows"
|
||||
)]
|
||||
|
||||
use tauri::{WindowBuilder, WindowUrl};
|
||||
|
||||
mod commands;
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.on_page_load(|window, _payload| {
|
||||
let label = window.label().to_string();
|
||||
window.listen("clicked".to_string(), move |_payload| {
|
||||
println!("got 'clicked' event on window '{}'", label);
|
||||
});
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![commands::create_child_window])
|
||||
.create_window(
|
||||
"main".to_string(),
|
||||
WindowUrl::default(),
|
||||
|window_builder, webview_attributes| {
|
||||
(
|
||||
window_builder.title("Main").inner_size(600.0, 400.0),
|
||||
webview_attributes,
|
||||
)
|
||||
},
|
||||
)
|
||||
.unwrap() // safe to unwrap: window label is valid
|
||||
.run(tauri::generate_context!(
|
||||
"../../examples/parent-window/src-tauri/tauri.conf.json"
|
||||
))
|
||||
.expect("failed to run tauri application");
|
||||
}
|
||||
36
examples/parent-window/src-tauri/tauri.conf.json
Normal file
36
examples/parent-window/src-tauri/tauri.conf.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"build": {
|
||||
"distDir": [
|
||||
"../index.html"
|
||||
],
|
||||
"devPath": [
|
||||
"../index.html"
|
||||
],
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
"tauri": {
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "com.tauri.dev",
|
||||
"icon": [
|
||||
"../../.icons/32x32.png",
|
||||
"../../.icons/128x128.png",
|
||||
"../../.icons/128x128@2x.png",
|
||||
"../../.icons/icon.icns",
|
||||
"../../.icons/icon.ico"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "",
|
||||
"category": "DeveloperTool"
|
||||
},
|
||||
"allowlist": {},
|
||||
"security": {
|
||||
"csp": "default-src 'self'"
|
||||
},
|
||||
"updater": {
|
||||
"active": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user