(chore): update codebase
This commit is contained in:
parent
fd15215f15
commit
4e8d46b20e
106 changed files with 29936 additions and 1023 deletions
1083
apps/tauri/src-tauri/vendor/tauri-runtime/CHANGELOG.md
vendored
Normal file
1083
apps/tauri/src-tauri/vendor/tauri-runtime/CHANGELOG.md
vendored
Normal file
File diff suppressed because it is too large
Load diff
62
apps/tauri/src-tauri/vendor/tauri-runtime/Cargo.toml
vendored
Normal file
62
apps/tauri/src-tauri/vendor/tauri-runtime/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
[package]
|
||||
name = "tauri-runtime"
|
||||
version = "2.11.0"
|
||||
description = "Runtime for Tauri applications"
|
||||
exclude = ["CHANGELOG.md", "/target"]
|
||||
readme = "README.md"
|
||||
authors.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
categories.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
default-target = "x86_64-unknown-linux-gnu"
|
||||
targets = [
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-linux-android",
|
||||
"x86_64-apple-ios",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
thiserror = "2"
|
||||
tauri-utils = { version = "2.9.0", path = "../tauri-utils" }
|
||||
http = "1"
|
||||
raw-window-handle = "0.6"
|
||||
url = { version = "2" }
|
||||
dpi = { version = "0.1", features = ["serde"] }
|
||||
# WARNING: cookie::Cookie is re-exported so bumping this is a breaking change, documented to be done as a minor bump
|
||||
cookie = "0.18"
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.61"
|
||||
features = ["Win32_Foundation", "Win32_System_WinRT"]
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
gtk = { version = "0.18", features = ["v3_24"] }
|
||||
|
||||
[target."cfg(target_os = \"android\")".dependencies]
|
||||
jni = "0.21"
|
||||
|
||||
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
|
||||
objc2 = "0.6"
|
||||
objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
|
||||
"UIView",
|
||||
"UIResponder",
|
||||
"UIScene",
|
||||
"UISceneOptions",
|
||||
] }
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
url = "2"
|
||||
objc2 = "0.6"
|
||||
[features]
|
||||
devtools = []
|
||||
macos-private-api = []
|
||||
177
apps/tauri/src-tauri/vendor/tauri-runtime/LICENSE_APACHE-2.0
vendored
Normal file
177
apps/tauri/src-tauri/vendor/tauri-runtime/LICENSE_APACHE-2.0
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
21
apps/tauri/src-tauri/vendor/tauri-runtime/LICENSE_MIT
vendored
Normal file
21
apps/tauri/src-tauri/vendor/tauri-runtime/LICENSE_MIT
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 - Present Tauri Apps Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
44
apps/tauri/src-tauri/vendor/tauri-runtime/README.md
vendored
Normal file
44
apps/tauri/src-tauri/vendor/tauri-runtime/README.md
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# tauri-runtime
|
||||
|
||||
<img align="right" src="https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png" height="128" width="128">
|
||||
|
||||
[](https://github.com/tauri-apps/tauri)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://tauri.app)
|
||||
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
[](https://opencollective.com/tauri)
|
||||
|
||||
| Component | Version |
|
||||
| ------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| tauri-runtime | [](https://crates.io/crates/tauri-runtime) |
|
||||
|
||||
## About Tauri
|
||||
|
||||
Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
|
||||
|
||||
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task.
|
||||
|
||||
## This module
|
||||
|
||||
This is the glue layer between tauri itself and lower level webview libraries.
|
||||
None of the exposed API of this crate is stable, and it may break semver
|
||||
compatibility in the future. The major version only signifies the intended Tauri version.
|
||||
|
||||
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
|
||||
|
||||
## Semver
|
||||
|
||||
**tauri** is following [Semantic Versioning 2.0](https://semver.org/).
|
||||
|
||||
## Licenses
|
||||
|
||||
Code: (c) 2021 - The Tauri Programme within The Commons Conservancy.
|
||||
|
||||
MIT or MIT/Apache 2.0 where applicable.
|
||||
|
||||
Logo: CC-BY-NC-ND
|
||||
|
||||
- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)
|
||||
19
apps/tauri/src-tauri/vendor/tauri-runtime/build.rs
vendored
Normal file
19
apps/tauri/src-tauri/vendor/tauri-runtime/build.rs
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// creates a cfg alias if `has_feature` is true.
|
||||
// `alias` must be a snake case string.
|
||||
fn alias(alias: &str, has_feature: bool) {
|
||||
println!("cargo:rustc-check-cfg=cfg({alias})");
|
||||
if has_feature {
|
||||
println!("cargo:rustc-cfg={alias}");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
alias("desktop", !mobile);
|
||||
alias("mobile", mobile);
|
||||
}
|
||||
60
apps/tauri/src-tauri/vendor/tauri-runtime/src/dpi.rs
vendored
Normal file
60
apps/tauri/src-tauri/vendor/tauri-runtime/src/dpi.rs
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pub use dpi::*;
|
||||
use serde::Serialize;
|
||||
|
||||
/// A rectangular region.
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
pub struct Rect {
|
||||
/// Rect position.
|
||||
pub position: dpi::Position,
|
||||
/// Rect size.
|
||||
pub size: dpi::Size,
|
||||
}
|
||||
|
||||
impl Default for Rect {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
position: Position::Logical((0, 0).into()),
|
||||
size: Size::Logical((0, 0).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A rectangular region in physical pixels.
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
pub struct PhysicalRect<P: dpi::Pixel, S: dpi::Pixel> {
|
||||
/// Rect position.
|
||||
pub position: dpi::PhysicalPosition<P>,
|
||||
/// Rect size.
|
||||
pub size: dpi::PhysicalSize<S>,
|
||||
}
|
||||
|
||||
impl<P: dpi::Pixel, S: dpi::Pixel> Default for PhysicalRect<P, S> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
position: (0, 0).into(),
|
||||
size: (0, 0).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A rectangular region in logical pixels.
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
pub struct LogicalRect<P: dpi::Pixel, S: dpi::Pixel> {
|
||||
/// Rect position.
|
||||
pub position: dpi::LogicalPosition<P>,
|
||||
/// Rect size.
|
||||
pub size: dpi::LogicalSize<S>,
|
||||
}
|
||||
|
||||
impl<P: dpi::Pixel, S: dpi::Pixel> Default for LogicalRect<P, S> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
position: (0, 0).into(),
|
||||
size: (0, 0).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
1048
apps/tauri/src-tauri/vendor/tauri-runtime/src/lib.rs
vendored
Normal file
1048
apps/tauri/src-tauri/vendor/tauri-runtime/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
21
apps/tauri/src-tauri/vendor/tauri-runtime/src/monitor.rs
vendored
Normal file
21
apps/tauri/src-tauri/vendor/tauri-runtime/src/monitor.rs
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::dpi::{PhysicalPosition, PhysicalRect, PhysicalSize};
|
||||
|
||||
/// Monitor descriptor.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Monitor {
|
||||
/// A human-readable name of the monitor.
|
||||
/// `None` if the monitor doesn't exist anymore.
|
||||
pub name: Option<String>,
|
||||
/// The monitor's resolution.
|
||||
pub size: PhysicalSize<u32>,
|
||||
/// The top-left corner position of the monitor relative to the larger full screen area.
|
||||
pub position: PhysicalPosition<i32>,
|
||||
/// The monitor's work_area.
|
||||
pub work_area: PhysicalRect<i32, u32>,
|
||||
/// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
|
||||
pub scale_factor: f64,
|
||||
}
|
||||
820
apps/tauri/src-tauri/vendor/tauri-runtime/src/webview.rs
vendored
Normal file
820
apps/tauri/src-tauri/vendor/tauri-runtime/src/webview.rs
vendored
Normal file
|
|
@ -0,0 +1,820 @@
|
|||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! A layer between raw [`Runtime`] webviews and Tauri.
|
||||
//!
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use crate::window::WindowId;
|
||||
use crate::{Rect, Runtime, UserEvent, window::is_label_valid};
|
||||
|
||||
use http::Request;
|
||||
use tauri_utils::config::{
|
||||
BackgroundThrottlingPolicy, Color, ScrollBarStyle as ConfigScrollBarStyle, WebviewUrl,
|
||||
WindowConfig, WindowEffectsConfig,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashMap,
|
||||
hash::{Hash, Hasher},
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub type UriSchemeProtocolHandler = dyn Fn(&str, http::Request<Vec<u8>>, Box<dyn FnOnce(http::Response<Cow<'static, [u8]>>) + Send>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static;
|
||||
|
||||
pub type WebResourceRequestHandler =
|
||||
dyn Fn(http::Request<Vec<u8>>, &mut http::Response<Cow<'static, [u8]>>) + Send + Sync;
|
||||
|
||||
pub type NavigationHandler = dyn Fn(&Url) -> bool + Send;
|
||||
|
||||
pub type NewWindowHandler<T, R> =
|
||||
dyn Fn(Url, NewWindowFeatures<T, R>) -> NewWindowResponse + Send + Sync;
|
||||
|
||||
pub type OnPageLoadHandler = dyn Fn(Url, PageLoadEvent) + Send;
|
||||
|
||||
pub type DocumentTitleChangedHandler = dyn Fn(String) + Send + 'static;
|
||||
|
||||
pub type AddressChangedHandler = dyn Fn(&Url) + Send + Sync + 'static;
|
||||
|
||||
pub type DownloadHandler = dyn Fn(DownloadEvent) -> bool + Send + Sync;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
type OnWebContentProcessTerminateHandler = dyn Fn() + Send;
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
type InputAccessoryViewBuilderFn = dyn Fn(&objc2_ui_kit::UIView) -> Option<objc2::rc::Retained<objc2_ui_kit::UIView>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static;
|
||||
|
||||
/// Download event.
|
||||
pub enum DownloadEvent<'a> {
|
||||
/// Download requested.
|
||||
Requested {
|
||||
/// The url being downloaded.
|
||||
url: Url,
|
||||
/// Represents where the file will be downloaded to.
|
||||
/// Can be used to set the download location by assigning a new path to it.
|
||||
/// The assigned path _must_ be absolute.
|
||||
destination: &'a mut PathBuf,
|
||||
},
|
||||
/// Download finished.
|
||||
Finished {
|
||||
/// The URL of the original download request.
|
||||
url: Url,
|
||||
/// Potentially representing the filesystem path the file was downloaded to.
|
||||
path: Option<PathBuf>,
|
||||
/// Indicates if the download succeeded or not.
|
||||
success: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub struct CreationContext<'a, 'b> {
|
||||
pub env: &'a mut jni::JNIEnv<'b>,
|
||||
pub activity: &'a jni::objects::JObject<'b>,
|
||||
pub webview: &'a jni::objects::JObject<'b>,
|
||||
}
|
||||
|
||||
/// Kind of event for the page load handler.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PageLoadEvent {
|
||||
/// Page started to load.
|
||||
Started,
|
||||
/// Page finished loading.
|
||||
Finished,
|
||||
}
|
||||
|
||||
/// Window features of a window requested to open.
|
||||
#[derive(Debug)]
|
||||
pub struct NewWindowFeatures<T: UserEvent, R: Runtime<T>> {
|
||||
pub(crate) size: Option<crate::dpi::LogicalSize<f64>>,
|
||||
pub(crate) position: Option<crate::dpi::LogicalPosition<f64>>,
|
||||
pub(crate) opener: R::WindowOpener,
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> NewWindowFeatures<T, R> {
|
||||
pub fn new(
|
||||
size: Option<crate::dpi::LogicalSize<f64>>,
|
||||
position: Option<crate::dpi::LogicalPosition<f64>>,
|
||||
opener: R::WindowOpener,
|
||||
) -> Self {
|
||||
Self {
|
||||
size,
|
||||
position,
|
||||
opener,
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the size of the content area
|
||||
/// as defined by the user's operating system where the new window will be generated.
|
||||
pub fn size(&self) -> Option<crate::dpi::LogicalSize<f64>> {
|
||||
self.size
|
||||
}
|
||||
|
||||
/// Specifies the position of the window relative to the work area
|
||||
/// as defined by the user's operating system where the new window will be generated.
|
||||
pub fn position(&self) -> Option<crate::dpi::LogicalPosition<f64>> {
|
||||
self.position
|
||||
}
|
||||
|
||||
/// Returns information about the webview that initiated a new window request.
|
||||
pub fn opener(&self) -> &R::WindowOpener {
|
||||
&self.opener
|
||||
}
|
||||
|
||||
/// Returns information about the webview that initiated a new window request.
|
||||
pub fn into_opener(self) -> R::WindowOpener {
|
||||
self.opener
|
||||
}
|
||||
}
|
||||
|
||||
/// Response for the new window request handler.
|
||||
pub enum NewWindowResponse {
|
||||
/// Allow the window to be opened with the default implementation.
|
||||
Allow,
|
||||
/// Allow the window to be opened, with the given window.
|
||||
///
|
||||
/// The window must be created referencing the opener window so it can inherit the appropriate attributes.
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
Create { window_id: WindowId },
|
||||
/// Deny the window from being opened.
|
||||
Deny,
|
||||
}
|
||||
|
||||
/// The scrollbar style to use in the webview.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows**: This option must be given the same value for all webviews that target the same data directory.
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub enum ScrollBarStyle {
|
||||
#[default]
|
||||
/// The default scrollbar style for the webview.
|
||||
Default,
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Fluent UI style overlay scrollbars. **Windows Only**
|
||||
///
|
||||
/// Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions,
|
||||
/// see <https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541>
|
||||
FluentOverlay,
|
||||
}
|
||||
|
||||
/// A webview that has yet to be built.
|
||||
pub struct PendingWebview<T: UserEvent, R: Runtime<T>> {
|
||||
/// The label that the webview will be named.
|
||||
pub label: String,
|
||||
|
||||
/// The [`WebviewAttributes`] that the webview will be created with.
|
||||
pub webview_attributes: WebviewAttributes,
|
||||
|
||||
/// Information about the webview that initiated a new window request.
|
||||
pub opener: Option<R::WindowOpener>,
|
||||
|
||||
/// Runtime specific attributes.
|
||||
pub platform_specific_attributes: Vec<R::PlatformSpecificWebviewAttribute>,
|
||||
|
||||
/// Custom protocols to register on the webview
|
||||
pub uri_scheme_protocols: HashMap<String, Box<UriSchemeProtocolHandler>>,
|
||||
|
||||
/// How to handle IPC calls on the webview.
|
||||
pub ipc_handler: Option<WebviewIpcHandler<T, R>>,
|
||||
|
||||
/// A handler to decide if incoming url is allowed to navigate.
|
||||
pub navigation_handler: Option<Box<NavigationHandler>>,
|
||||
|
||||
pub new_window_handler: Option<Box<NewWindowHandler<T, R>>>,
|
||||
|
||||
pub document_title_changed_handler: Option<Box<DocumentTitleChangedHandler>>,
|
||||
|
||||
pub address_changed_handler: Option<Box<AddressChangedHandler>>,
|
||||
|
||||
/// The resolved URL to load on the webview.
|
||||
pub url: String,
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub on_webview_created:
|
||||
Option<Box<dyn Fn(CreationContext<'_, '_>) -> Result<(), jni::errors::Error> + Send + Sync>>,
|
||||
|
||||
pub web_resource_request_handler: Option<Box<WebResourceRequestHandler>>,
|
||||
|
||||
pub on_page_load_handler: Option<Box<OnPageLoadHandler>>,
|
||||
|
||||
pub download_handler: Option<Arc<DownloadHandler>>,
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub on_web_content_process_terminate_handler: Option<Box<OnWebContentProcessTerminateHandler>>,
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> PendingWebview<T, R> {
|
||||
/// Create a new [`PendingWebview`] with a label from the given [`WebviewAttributes`].
|
||||
pub fn new(
|
||||
webview_attributes: WebviewAttributes,
|
||||
platform_specific_attributes: Vec<R::PlatformSpecificWebviewAttribute>,
|
||||
label: impl Into<String>,
|
||||
) -> crate::Result<Self> {
|
||||
let label = label.into();
|
||||
if !is_label_valid(&label) {
|
||||
Err(crate::Error::InvalidWindowLabel)
|
||||
} else {
|
||||
Ok(Self {
|
||||
webview_attributes,
|
||||
opener: None,
|
||||
platform_specific_attributes,
|
||||
uri_scheme_protocols: Default::default(),
|
||||
label,
|
||||
ipc_handler: None,
|
||||
navigation_handler: None,
|
||||
new_window_handler: None,
|
||||
document_title_changed_handler: None,
|
||||
address_changed_handler: None,
|
||||
url: "tauri://localhost".to_string(),
|
||||
#[cfg(target_os = "android")]
|
||||
on_webview_created: None,
|
||||
web_resource_request_handler: None,
|
||||
on_page_load_handler: None,
|
||||
download_handler: None,
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
on_web_content_process_terminate_handler: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_uri_scheme_protocol<
|
||||
N: Into<String>,
|
||||
H: Fn(&str, http::Request<Vec<u8>>, Box<dyn FnOnce(http::Response<Cow<'static, [u8]>>) + Send>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>(
|
||||
&mut self,
|
||||
uri_scheme: N,
|
||||
protocol_handler: H,
|
||||
) {
|
||||
let uri_scheme = uri_scheme.into();
|
||||
self
|
||||
.uri_scheme_protocols
|
||||
.insert(uri_scheme, Box::new(protocol_handler));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn on_webview_created<
|
||||
F: Fn(CreationContext<'_, '_>) -> Result<(), jni::errors::Error> + Send + Sync + 'static,
|
||||
>(
|
||||
mut self,
|
||||
f: F,
|
||||
) -> Self {
|
||||
self.on_webview_created.replace(Box::new(f));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A webview that is not yet managed by Tauri.
|
||||
#[derive(Debug)]
|
||||
pub struct DetachedWebview<T: UserEvent, R: Runtime<T>> {
|
||||
/// Name of the window
|
||||
pub label: String,
|
||||
|
||||
/// The [`crate::WebviewDispatch`] associated with the window.
|
||||
pub dispatcher: R::WebviewDispatcher,
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWebview<T, R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
label: self.label.clone(),
|
||||
dispatcher: self.dispatcher.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Hash for DetachedWebview<T, R> {
|
||||
/// Only use the [`DetachedWebview`]'s label to represent its hash.
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.label.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Eq for DetachedWebview<T, R> {}
|
||||
impl<T: UserEvent, R: Runtime<T>> PartialEq for DetachedWebview<T, R> {
|
||||
/// Only use the [`DetachedWebview`]'s label to compare equality.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.label.eq(&other.label)
|
||||
}
|
||||
}
|
||||
|
||||
/// The attributes used to create an webview.
|
||||
#[derive(Debug)]
|
||||
pub struct WebviewAttributes {
|
||||
pub url: WebviewUrl,
|
||||
pub user_agent: Option<String>,
|
||||
/// A list of initialization javascript scripts to run when loading new pages.
|
||||
/// When webview load a new page, this initialization code will be executed.
|
||||
/// It is guaranteed that code is executed before `window.onload`.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows:** scripts are always added to subframes.
|
||||
/// - **Android:** When [addDocumentStartJavaScript] is not supported,
|
||||
/// we prepend initialization scripts to each HTML head (implementation only supported on custom protocol URLs).
|
||||
/// For remote URLs, we use [onPageStarted] which is not guaranteed to run before other scripts.
|
||||
///
|
||||
/// [addDocumentStartJavaScript]: https://developer.android.com/reference/androidx/webkit/WebViewCompat#addDocumentStartJavaScript(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E)
|
||||
/// [onPageStarted]: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
||||
pub initialization_scripts: Vec<InitializationScript>,
|
||||
pub data_directory: Option<PathBuf>,
|
||||
pub drag_drop_handler_enabled: bool,
|
||||
pub clipboard: bool,
|
||||
pub accept_first_mouse: bool,
|
||||
pub additional_browser_args: Option<String>,
|
||||
pub window_effects: Option<WindowEffectsConfig>,
|
||||
pub incognito: bool,
|
||||
pub transparent: bool,
|
||||
pub focus: bool,
|
||||
pub bounds: Option<Rect>,
|
||||
pub auto_resize: bool,
|
||||
pub proxy_url: Option<Url>,
|
||||
pub zoom_hotkeys_enabled: bool,
|
||||
pub browser_extensions_enabled: bool,
|
||||
pub extensions_path: Option<PathBuf>,
|
||||
pub data_store_identifier: Option<[u8; 16]>,
|
||||
pub use_https_scheme: bool,
|
||||
pub devtools: Option<bool>,
|
||||
pub background_color: Option<Color>,
|
||||
pub traffic_light_position: Option<dpi::Position>,
|
||||
pub background_throttling: Option<BackgroundThrottlingPolicy>,
|
||||
pub javascript_disabled: bool,
|
||||
/// on macOS and iOS there is a link preview on long pressing links, this is enabled by default.
|
||||
/// see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview
|
||||
pub allow_link_preview: bool,
|
||||
pub scroll_bar_style: ScrollBarStyle,
|
||||
/// Controls the WebView's browser-level general autofill behavior.
|
||||
///
|
||||
/// **This option does not disable password or credit card autofill.**
|
||||
///
|
||||
/// When set to `false`, the WebView will not automatically populate
|
||||
/// general form fields using previously stored data such as addresses
|
||||
/// or contact information.
|
||||
///
|
||||
/// If not specified, this is `true` by default.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows**: Supported. WebView2's autofill feature (called
|
||||
/// "Suggestions") may not honor `autocomplete="off"` on input
|
||||
/// elements in some cases.
|
||||
/// - **Linux / Android / iOS / macOS**: Unsupported and performs no
|
||||
/// operation.
|
||||
pub general_autofill_enabled: bool,
|
||||
/// Allows overriding the keyboard accessory view on iOS.
|
||||
/// Returning `None` effectively removes the view.
|
||||
///
|
||||
/// The closure parameter is the webview instance.
|
||||
///
|
||||
/// The accessory view is the view that appears above the keyboard when a text input element is focused.
|
||||
/// It usually displays a view with "Done", "Next" buttons.
|
||||
///
|
||||
/// # Stability
|
||||
///
|
||||
/// This relies on [`objc2_ui_kit`] which does not provide a stable API yet, so it can receive breaking changes in minor releases.
|
||||
#[cfg(target_os = "ios")]
|
||||
pub input_accessory_view_builder: Option<InputAccessoryViewBuilder>,
|
||||
}
|
||||
|
||||
unsafe impl Send for WebviewAttributes {}
|
||||
unsafe impl Sync for WebviewAttributes {}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
#[non_exhaustive]
|
||||
pub struct InputAccessoryViewBuilder(pub Box<InputAccessoryViewBuilderFn>);
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
impl std::fmt::Debug for InputAccessoryViewBuilder {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
f.debug_struct("InputAccessoryViewBuilder").finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
impl InputAccessoryViewBuilder {
|
||||
pub fn new(builder: Box<InputAccessoryViewBuilderFn>) -> Self {
|
||||
Self(builder)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&WindowConfig> for WebviewAttributes {
|
||||
fn from(config: &WindowConfig) -> Self {
|
||||
let mut builder = Self::new(config.url.clone())
|
||||
.incognito(config.incognito)
|
||||
.focused(config.focus)
|
||||
.zoom_hotkeys_enabled(config.zoom_hotkeys_enabled)
|
||||
.use_https_scheme(config.use_https_scheme)
|
||||
.browser_extensions_enabled(config.browser_extensions_enabled)
|
||||
.background_throttling(config.background_throttling.clone())
|
||||
.devtools(config.devtools)
|
||||
.scroll_bar_style(match config.scroll_bar_style {
|
||||
ConfigScrollBarStyle::Default => ScrollBarStyle::Default,
|
||||
#[cfg(windows)]
|
||||
ConfigScrollBarStyle::FluentOverlay => ScrollBarStyle::FluentOverlay,
|
||||
_ => ScrollBarStyle::Default,
|
||||
})
|
||||
.general_autofill_enabled(config.general_autofill_enabled);
|
||||
|
||||
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
|
||||
{
|
||||
builder = builder.transparent(config.transparent);
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if let Some(position) = &config.traffic_light_position {
|
||||
builder =
|
||||
builder.traffic_light_position(dpi::LogicalPosition::new(position.x, position.y).into());
|
||||
}
|
||||
}
|
||||
builder = builder.accept_first_mouse(config.accept_first_mouse);
|
||||
if !config.drag_drop_enabled {
|
||||
builder = builder.disable_drag_drop_handler();
|
||||
}
|
||||
if let Some(user_agent) = &config.user_agent {
|
||||
builder = builder.user_agent(user_agent);
|
||||
}
|
||||
if let Some(additional_browser_args) = &config.additional_browser_args {
|
||||
builder = builder.additional_browser_args(additional_browser_args);
|
||||
}
|
||||
if let Some(effects) = &config.window_effects {
|
||||
builder = builder.window_effects(effects.clone());
|
||||
}
|
||||
if let Some(url) = &config.proxy_url {
|
||||
builder = builder.proxy_url(url.to_owned());
|
||||
}
|
||||
if let Some(color) = config.background_color {
|
||||
builder = builder.background_color(color);
|
||||
}
|
||||
builder.javascript_disabled = config.javascript_disabled;
|
||||
builder.allow_link_preview = config.allow_link_preview;
|
||||
#[cfg(target_os = "ios")]
|
||||
if config.disable_input_accessory_view {
|
||||
builder
|
||||
.input_accessory_view_builder
|
||||
.replace(InputAccessoryViewBuilder::new(Box::new(|_webview| None)));
|
||||
}
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
||||
impl WebviewAttributes {
|
||||
/// Initializes the default attributes for a webview.
|
||||
pub fn new(url: WebviewUrl) -> Self {
|
||||
Self {
|
||||
url,
|
||||
user_agent: None,
|
||||
initialization_scripts: Vec::new(),
|
||||
data_directory: None,
|
||||
drag_drop_handler_enabled: true,
|
||||
clipboard: false,
|
||||
accept_first_mouse: false,
|
||||
additional_browser_args: None,
|
||||
window_effects: None,
|
||||
incognito: false,
|
||||
transparent: false,
|
||||
focus: true,
|
||||
bounds: None,
|
||||
auto_resize: false,
|
||||
proxy_url: None,
|
||||
zoom_hotkeys_enabled: false,
|
||||
browser_extensions_enabled: false,
|
||||
data_store_identifier: None,
|
||||
extensions_path: None,
|
||||
use_https_scheme: false,
|
||||
devtools: None,
|
||||
background_color: None,
|
||||
traffic_light_position: None,
|
||||
background_throttling: None,
|
||||
javascript_disabled: false,
|
||||
allow_link_preview: true,
|
||||
scroll_bar_style: ScrollBarStyle::Default,
|
||||
general_autofill_enabled: true,
|
||||
#[cfg(target_os = "ios")]
|
||||
input_accessory_view_builder: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the user agent
|
||||
#[must_use]
|
||||
pub fn user_agent(mut self, user_agent: &str) -> Self {
|
||||
self.user_agent = Some(user_agent.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds an init script for the main frame.
|
||||
///
|
||||
/// When webview load a new page, this initialization code will be executed.
|
||||
/// It is guaranteed that code is executed before `window.onload`.
|
||||
///
|
||||
/// This is executed only on the main frame.
|
||||
/// If you only want to run it in all frames, use [`Self::initialization_script_on_all_frames`] instead.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows:** scripts are always added to subframes.
|
||||
/// - **Android:** When [addDocumentStartJavaScript] is not supported,
|
||||
/// we prepend initialization scripts to each HTML head (implementation only supported on custom protocol URLs).
|
||||
/// For remote URLs, we use [onPageStarted] which is not guaranteed to run before other scripts.
|
||||
///
|
||||
/// [addDocumentStartJavaScript]: https://developer.android.com/reference/androidx/webkit/WebViewCompat#addDocumentStartJavaScript(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E)
|
||||
/// [onPageStarted]: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
||||
#[must_use]
|
||||
pub fn initialization_script(mut self, script: impl Into<String>) -> Self {
|
||||
self.initialization_scripts.push(InitializationScript {
|
||||
script: script.into(),
|
||||
for_main_frame_only: true,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds an init script for all frames.
|
||||
///
|
||||
/// When webview load a new page, this initialization code will be executed.
|
||||
/// It is guaranteed that code is executed before `window.onload`.
|
||||
///
|
||||
/// This is executed on all frames, main frame and also sub frames.
|
||||
/// If you only want to run it in the main frame, use [`Self::initialization_script`] instead.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows:** scripts are always added to subframes.
|
||||
/// - **Android:** When [addDocumentStartJavaScript] is not supported,
|
||||
/// we prepend initialization scripts to each HTML head (implementation only supported on custom protocol URLs).
|
||||
/// For remote URLs, we use [onPageStarted] which is not guaranteed to run before other scripts.
|
||||
///
|
||||
/// [addDocumentStartJavaScript]: https://developer.android.com/reference/androidx/webkit/WebViewCompat#addDocumentStartJavaScript(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E)
|
||||
/// [onPageStarted]: https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)
|
||||
#[must_use]
|
||||
pub fn initialization_script_on_all_frames(mut self, script: impl Into<String>) -> Self {
|
||||
self.initialization_scripts.push(InitializationScript {
|
||||
script: script.into(),
|
||||
for_main_frame_only: false,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Data directory for the webview.
|
||||
#[must_use]
|
||||
pub fn data_directory(mut self, data_directory: PathBuf) -> Self {
|
||||
self.data_directory.replace(data_directory);
|
||||
self
|
||||
}
|
||||
|
||||
/// Disables the drag and drop handler. This is required to use HTML5 drag and drop APIs on the frontend on Windows.
|
||||
#[must_use]
|
||||
pub fn disable_drag_drop_handler(mut self) -> Self {
|
||||
self.drag_drop_handler_enabled = false;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables clipboard access for the page rendered on **Linux** and **Windows**.
|
||||
///
|
||||
/// **macOS** doesn't provide such method and is always enabled by default,
|
||||
/// but you still need to add menu item accelerators to use shortcuts.
|
||||
#[must_use]
|
||||
pub fn enable_clipboard_access(mut self) -> Self {
|
||||
self.clipboard = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether clicking an inactive window also clicks through to the webview.
|
||||
#[must_use]
|
||||
pub fn accept_first_mouse(mut self, accept: bool) -> Self {
|
||||
self.accept_first_mouse = accept;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets additional browser arguments. **Windows Only**
|
||||
#[must_use]
|
||||
pub fn additional_browser_args(mut self, additional_args: &str) -> Self {
|
||||
self.additional_browser_args = Some(additional_args.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets window effects
|
||||
#[must_use]
|
||||
pub fn window_effects(mut self, effects: WindowEffectsConfig) -> Self {
|
||||
self.window_effects = Some(effects);
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable or disable incognito mode for the WebView.
|
||||
#[must_use]
|
||||
pub fn incognito(mut self, incognito: bool) -> Self {
|
||||
self.incognito = incognito;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable or disable transparency for the WebView.
|
||||
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
|
||||
#[must_use]
|
||||
pub fn transparent(mut self, transparent: bool) -> Self {
|
||||
self.transparent = transparent;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether the webview should be focused or not.
|
||||
#[must_use]
|
||||
pub fn focused(mut self, focus: bool) -> Self {
|
||||
self.focus = focus;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the webview to automatically grow and shrink its size and position when the parent window resizes.
|
||||
#[must_use]
|
||||
pub fn auto_resize(mut self) -> Self {
|
||||
self.auto_resize = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable proxy for the WebView
|
||||
#[must_use]
|
||||
pub fn proxy_url(mut self, url: Url) -> Self {
|
||||
self.proxy_url = Some(url);
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether page zooming by hotkeys is enabled
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Windows**: Controls WebView2's [`IsZoomControlEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2settings?view=webview2-winrt-1.0.2420.47#iszoomcontrolenabled) setting.
|
||||
/// - **MacOS / Linux**: Injects a polyfill that zooms in and out with `ctrl/command` + `-/=`,
|
||||
/// 20% in each step, ranging from 20% to 1000%. Requires `webview:allow-set-webview-zoom` permission
|
||||
///
|
||||
/// - **Android / iOS**: Unsupported.
|
||||
#[must_use]
|
||||
pub fn zoom_hotkeys_enabled(mut self, enabled: bool) -> Self {
|
||||
self.zoom_hotkeys_enabled = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether browser extensions can be installed for the webview process
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)
|
||||
/// - **MacOS / Linux / iOS / Android** - Unsupported.
|
||||
#[must_use]
|
||||
pub fn browser_extensions_enabled(mut self, enabled: bool) -> Self {
|
||||
self.browser_extensions_enabled = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.
|
||||
///
|
||||
/// ## Note
|
||||
///
|
||||
/// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
|
||||
///
|
||||
/// ## Warning
|
||||
///
|
||||
/// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
|
||||
#[must_use]
|
||||
pub fn use_https_scheme(mut self, enabled: bool) -> Self {
|
||||
self.use_https_scheme = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default.
|
||||
///
|
||||
/// This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - macOS: This will call private functions on **macOS**.
|
||||
/// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android.
|
||||
/// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window.
|
||||
#[must_use]
|
||||
pub fn devtools(mut self, enabled: Option<bool>) -> Self {
|
||||
self.devtools = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the window and webview background color.
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.
|
||||
/// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored.
|
||||
#[must_use]
|
||||
pub fn background_color(mut self, color: Color) -> Self {
|
||||
self.background_color = Some(color);
|
||||
self
|
||||
}
|
||||
|
||||
/// Change the position of the window controls. Available on macOS only.
|
||||
///
|
||||
/// Requires titleBarStyle: Overlay and decorations: true.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / Windows / iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
pub fn traffic_light_position(mut self, position: dpi::Position) -> Self {
|
||||
self.traffic_light_position = Some(position);
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to show a link preview when long pressing on links. Available on macOS and iOS only.
|
||||
///
|
||||
/// Default is true.
|
||||
///
|
||||
/// See https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / Windows / Android:** Unsupported.
|
||||
#[must_use]
|
||||
pub fn allow_link_preview(mut self, allow_link_preview: bool) -> Self {
|
||||
self.allow_link_preview = allow_link_preview;
|
||||
self
|
||||
}
|
||||
|
||||
/// Change the default background throttling behavior.
|
||||
///
|
||||
/// By default, browsers use a suspend policy that will throttle timers and even unload
|
||||
/// the whole tab (view) to free resources after roughly 5 minutes when a view became
|
||||
/// minimized or hidden. This will pause all tasks until the documents visibility state
|
||||
/// changes back from hidden to visible by bringing the view back to the foreground.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice.
|
||||
/// - **iOS**: Supported since version 17.0+.
|
||||
/// - **macOS**: Supported since version 14.0+.
|
||||
///
|
||||
/// see <https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578>
|
||||
#[must_use]
|
||||
pub fn background_throttling(mut self, policy: Option<BackgroundThrottlingPolicy>) -> Self {
|
||||
self.background_throttling = policy;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specifies the native scrollbar style to use with the webview.
|
||||
/// CSS styles that modify the scrollbar are applied on top of the native appearance configured here.
|
||||
///
|
||||
/// Defaults to [`ScrollBarStyle::Default`], which is the browser default.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows**:
|
||||
/// - [`ScrollBarStyle::FluentOverlay`] requires WebView2 Runtime version 125.0.2535.41 or higher,
|
||||
/// and does nothing on older versions.
|
||||
/// - This option must be given the same value for all webviews that target the same data directory. Use
|
||||
/// [`WebviewAttributes::data_directory`] to change data directories if needed.
|
||||
/// - **Linux / Android / iOS / macOS**: Unsupported. Only supports `Default` and performs no operation.
|
||||
#[must_use]
|
||||
pub fn scroll_bar_style(mut self, style: ScrollBarStyle) -> Self {
|
||||
self.scroll_bar_style = style;
|
||||
self
|
||||
}
|
||||
|
||||
/// Controls the WebView's browser-level general autofill behavior.
|
||||
///
|
||||
/// **This option does not disable password or credit card autofill.**
|
||||
///
|
||||
/// When set to `false`, the WebView will not automatically populate
|
||||
/// general form fields using previously stored data such as addresses
|
||||
/// or contact information.
|
||||
///
|
||||
/// By default, this is `true`.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows**: Supported. WebView2's autofill feature (called
|
||||
/// "Suggestions") may not honor `autocomplete="off"` on input
|
||||
/// elements in some cases.
|
||||
/// - **Linux / Android / iOS / macOS**: Unsupported and performs no
|
||||
/// operation.
|
||||
#[must_use]
|
||||
pub fn general_autofill_enabled(mut self, enabled: bool) -> Self {
|
||||
self.general_autofill_enabled = enabled;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// IPC handler.
|
||||
pub type WebviewIpcHandler<T, R> = Box<dyn Fn(DetachedWebview<T, R>, Request<String>) + Send>;
|
||||
|
||||
/// An initialization script
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InitializationScript {
|
||||
/// The script to run
|
||||
pub script: String,
|
||||
/// Whether the script should be injected to main frame only
|
||||
pub for_main_frame_only: bool,
|
||||
}
|
||||
661
apps/tauri/src-tauri/vendor/tauri-runtime/src/window.rs
vendored
Normal file
661
apps/tauri/src-tauri/vendor/tauri-runtime/src/window.rs
vendored
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! A layer between raw [`Runtime`] windows and Tauri.
|
||||
|
||||
use crate::{
|
||||
Icon, Runtime, UserEvent, WindowDispatch,
|
||||
webview::{DetachedWebview, PendingWebview},
|
||||
};
|
||||
|
||||
use dpi::PixelUnit;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use tauri_utils::{
|
||||
Theme,
|
||||
config::{Color, WindowConfig},
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::Foundation::HWND;
|
||||
|
||||
use std::{
|
||||
hash::{Hash, Hasher},
|
||||
marker::PhantomData,
|
||||
path::PathBuf,
|
||||
sync::mpsc::Sender,
|
||||
};
|
||||
|
||||
/// An event from a window.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WindowEvent {
|
||||
/// The size of the window has changed. Contains the client area's new dimensions.
|
||||
Resized(dpi::PhysicalSize<u32>),
|
||||
/// The position of the window has changed. Contains the window's new position.
|
||||
Moved(dpi::PhysicalPosition<i32>),
|
||||
/// The window has been requested to close.
|
||||
CloseRequested {
|
||||
/// A signal sender. If a `true` value is emitted, the window won't be closed.
|
||||
signal_tx: Sender<bool>,
|
||||
},
|
||||
/// The window has been destroyed.
|
||||
Destroyed,
|
||||
/// The window gained or lost focus.
|
||||
///
|
||||
/// The parameter is true if the window has gained focus, and false if it has lost focus.
|
||||
Focused(bool),
|
||||
/// The window's scale factor has changed.
|
||||
///
|
||||
/// The following user actions can cause DPI changes:
|
||||
///
|
||||
/// - Changing the display's resolution.
|
||||
/// - Changing the display's scale factor (e.g. in Control Panel on Windows).
|
||||
/// - Moving the window to a display with a different scale factor.
|
||||
ScaleFactorChanged {
|
||||
/// The new scale factor.
|
||||
scale_factor: f64,
|
||||
/// The window inner size.
|
||||
new_inner_size: dpi::PhysicalSize<u32>,
|
||||
},
|
||||
/// An event associated with the drag and drop action.
|
||||
DragDrop(DragDropEvent),
|
||||
/// The system window theme has changed.
|
||||
///
|
||||
/// Applications might wish to react to this to change the theme of the content of the window when the system changes the window theme.
|
||||
ThemeChanged(Theme),
|
||||
|
||||
/// Emitted when the application has been suspended.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Android**: This is triggered by `onPause` method of the Activity.
|
||||
/// - **iOS**: This is triggered by `applicationWillResignActive` method of the UIApplicationDelegate.
|
||||
/// - **Linux / macOS / Windows**: Unsupported.
|
||||
#[cfg(mobile)]
|
||||
Suspended,
|
||||
|
||||
/// Emitted when the application has been resumed.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Android**: This is triggered by `onResume` method of the Activity. The first onResume() is ignored to match the iOS implementation, since that is called on activity creation.
|
||||
/// - **iOS**: This is triggered by `applicationWillEnterForeground` method of the UIApplicationDelegate.
|
||||
/// - **Linux / macOS / Windows**: Unsupported.
|
||||
#[cfg(mobile)]
|
||||
Resumed,
|
||||
}
|
||||
|
||||
/// An event from a window.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WebviewEvent {
|
||||
/// An event associated with the drag and drop action.
|
||||
DragDrop(DragDropEvent),
|
||||
}
|
||||
|
||||
/// The drag drop event payload.
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum DragDropEvent {
|
||||
/// A drag operation has entered the webview.
|
||||
Enter {
|
||||
/// List of paths that are being dragged onto the webview.
|
||||
paths: Vec<PathBuf>,
|
||||
/// The position of the mouse cursor.
|
||||
position: dpi::PhysicalPosition<f64>,
|
||||
},
|
||||
/// A drag operation is moving over the webview.
|
||||
Over {
|
||||
/// The position of the mouse cursor.
|
||||
position: dpi::PhysicalPosition<f64>,
|
||||
},
|
||||
/// The file(s) have been dropped onto the webview.
|
||||
Drop {
|
||||
/// List of paths that are being dropped onto the window.
|
||||
paths: Vec<PathBuf>,
|
||||
/// The position of the mouse cursor.
|
||||
position: dpi::PhysicalPosition<f64>,
|
||||
},
|
||||
/// The drag operation has been cancelled or left the window.
|
||||
Leave,
|
||||
}
|
||||
|
||||
/// Describes the appearance of the mouse cursor.
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum CursorIcon {
|
||||
/// The platform-dependent default cursor.
|
||||
#[default]
|
||||
Default,
|
||||
/// A simple crosshair.
|
||||
Crosshair,
|
||||
/// A hand (often used to indicate links in web browsers).
|
||||
Hand,
|
||||
/// Self explanatory.
|
||||
Arrow,
|
||||
/// Indicates something is to be moved.
|
||||
Move,
|
||||
/// Indicates text that may be selected or edited.
|
||||
Text,
|
||||
/// Program busy indicator.
|
||||
Wait,
|
||||
/// Help indicator (often rendered as a "?")
|
||||
Help,
|
||||
/// Progress indicator. Shows that processing is being done. But in contrast
|
||||
/// with "Wait" the user may still interact with the program. Often rendered
|
||||
/// as a spinning beach ball, or an arrow with a watch or hourglass.
|
||||
Progress,
|
||||
|
||||
/// Cursor showing that something cannot be done.
|
||||
NotAllowed,
|
||||
ContextMenu,
|
||||
Cell,
|
||||
VerticalText,
|
||||
Alias,
|
||||
Copy,
|
||||
NoDrop,
|
||||
/// Indicates something can be grabbed.
|
||||
Grab,
|
||||
/// Indicates something is grabbed.
|
||||
Grabbing,
|
||||
AllScroll,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
|
||||
/// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
|
||||
/// is used when the movement starts from the south-east corner of the box.
|
||||
EResize,
|
||||
NResize,
|
||||
NeResize,
|
||||
NwResize,
|
||||
SResize,
|
||||
SeResize,
|
||||
SwResize,
|
||||
WResize,
|
||||
EwResize,
|
||||
NsResize,
|
||||
NeswResize,
|
||||
NwseResize,
|
||||
ColResize,
|
||||
RowResize,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for CursorIcon {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Ok(match s.to_lowercase().as_str() {
|
||||
"default" => CursorIcon::Default,
|
||||
"crosshair" => CursorIcon::Crosshair,
|
||||
"hand" => CursorIcon::Hand,
|
||||
"arrow" => CursorIcon::Arrow,
|
||||
"move" => CursorIcon::Move,
|
||||
"text" => CursorIcon::Text,
|
||||
"wait" => CursorIcon::Wait,
|
||||
"help" => CursorIcon::Help,
|
||||
"progress" => CursorIcon::Progress,
|
||||
"notallowed" => CursorIcon::NotAllowed,
|
||||
"contextmenu" => CursorIcon::ContextMenu,
|
||||
"cell" => CursorIcon::Cell,
|
||||
"verticaltext" => CursorIcon::VerticalText,
|
||||
"alias" => CursorIcon::Alias,
|
||||
"copy" => CursorIcon::Copy,
|
||||
"nodrop" => CursorIcon::NoDrop,
|
||||
"grab" => CursorIcon::Grab,
|
||||
"grabbing" => CursorIcon::Grabbing,
|
||||
"allscroll" => CursorIcon::AllScroll,
|
||||
"zoomin" => CursorIcon::ZoomIn,
|
||||
"zoomout" => CursorIcon::ZoomOut,
|
||||
"eresize" => CursorIcon::EResize,
|
||||
"nresize" => CursorIcon::NResize,
|
||||
"neresize" => CursorIcon::NeResize,
|
||||
"nwresize" => CursorIcon::NwResize,
|
||||
"sresize" => CursorIcon::SResize,
|
||||
"seresize" => CursorIcon::SeResize,
|
||||
"swresize" => CursorIcon::SwResize,
|
||||
"wresize" => CursorIcon::WResize,
|
||||
"ewresize" => CursorIcon::EwResize,
|
||||
"nsresize" => CursorIcon::NsResize,
|
||||
"neswresize" => CursorIcon::NeswResize,
|
||||
"nwseresize" => CursorIcon::NwseResize,
|
||||
"colresize" => CursorIcon::ColResize,
|
||||
"rowresize" => CursorIcon::RowResize,
|
||||
_ => CursorIcon::Default,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Window size constraints
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WindowSizeConstraints {
|
||||
/// The minimum width a window can be, If this is `None`, the window will have no minimum width.
|
||||
///
|
||||
/// The default is `None`.
|
||||
pub min_width: Option<PixelUnit>,
|
||||
/// The minimum height a window can be, If this is `None`, the window will have no minimum height.
|
||||
///
|
||||
/// The default is `None`.
|
||||
pub min_height: Option<PixelUnit>,
|
||||
/// The maximum width a window can be, If this is `None`, the window will have no maximum width.
|
||||
///
|
||||
/// The default is `None`.
|
||||
pub max_width: Option<PixelUnit>,
|
||||
/// The maximum height a window can be, If this is `None`, the window will have no maximum height.
|
||||
///
|
||||
/// The default is `None`.
|
||||
pub max_height: Option<PixelUnit>,
|
||||
}
|
||||
|
||||
/// Do **NOT** implement this trait except for use in a custom [`Runtime`]
|
||||
///
|
||||
/// This trait is separate from [`WindowBuilder`] to prevent "accidental" implementation.
|
||||
pub trait WindowBuilderBase: std::fmt::Debug + Clone + Sized {}
|
||||
|
||||
/// A builder for all attributes related to a single window.
|
||||
///
|
||||
/// This trait is only meant to be implemented by a custom [`Runtime`]
|
||||
/// and not by applications.
|
||||
pub trait WindowBuilder: WindowBuilderBase {
|
||||
/// Initializes a new window attributes builder.
|
||||
fn new() -> Self;
|
||||
|
||||
/// Initializes a new window builder from a [`WindowConfig`]
|
||||
fn with_config(config: &WindowConfig) -> Self;
|
||||
|
||||
/// Show window in the center of the screen.
|
||||
#[must_use]
|
||||
fn center(self) -> Self;
|
||||
|
||||
/// The initial position of the window in logical pixels.
|
||||
#[must_use]
|
||||
fn position(self, x: f64, y: f64) -> Self;
|
||||
|
||||
/// Window size in logical pixels.
|
||||
#[must_use]
|
||||
fn inner_size(self, width: f64, height: f64) -> Self;
|
||||
|
||||
/// Window min inner size in logical pixels.
|
||||
#[must_use]
|
||||
fn min_inner_size(self, min_width: f64, min_height: f64) -> Self;
|
||||
|
||||
/// Window max inner size in logical pixels.
|
||||
#[must_use]
|
||||
fn max_inner_size(self, max_width: f64, max_height: f64) -> Self;
|
||||
|
||||
/// Window inner size constraints.
|
||||
#[must_use]
|
||||
fn inner_size_constraints(self, constraints: WindowSizeConstraints) -> Self;
|
||||
|
||||
/// Prevent the window from overflowing the working area (e.g. monitor size - taskbar size) on creation
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn prevent_overflow(self) -> Self;
|
||||
|
||||
/// Prevent the window from overflowing the working area (e.g. monitor size - taskbar size)
|
||||
/// on creation with a margin
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn prevent_overflow_with_margin(self, margin: dpi::Size) -> Self;
|
||||
|
||||
/// Whether the window is resizable or not.
|
||||
/// When resizable is set to false, native window's maximize button is automatically disabled.
|
||||
#[must_use]
|
||||
fn resizable(self, resizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native maximize button is enabled or not.
|
||||
/// If resizable is set to false, this setting is ignored.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn maximizable(self, maximizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native minimize button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux / iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn minimizable(self, minimizable: bool) -> Self;
|
||||
|
||||
/// Whether the window's native close button is enabled or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
|
||||
/// Depending on the system, this function may not have any effect when called on a window that is already visible"
|
||||
/// - **iOS / Android:** Unsupported.
|
||||
#[must_use]
|
||||
fn closable(self, closable: bool) -> Self;
|
||||
|
||||
/// The title of the window in the title bar.
|
||||
#[must_use]
|
||||
fn title<S: Into<String>>(self, title: S) -> Self;
|
||||
|
||||
/// Whether to start the window in fullscreen or not.
|
||||
#[must_use]
|
||||
fn fullscreen(self, fullscreen: bool) -> Self;
|
||||
|
||||
/// Whether the window will be initially focused or not.
|
||||
#[must_use]
|
||||
fn focused(self, focused: bool) -> Self;
|
||||
|
||||
/// Whether the window will be focusable or not.
|
||||
#[must_use]
|
||||
fn focusable(self, focusable: bool) -> Self;
|
||||
|
||||
/// Whether the window should be maximized upon creation.
|
||||
#[must_use]
|
||||
fn maximized(self, maximized: bool) -> Self;
|
||||
|
||||
/// Whether the window should be immediately visible upon creation.
|
||||
#[must_use]
|
||||
fn visible(self, visible: bool) -> Self;
|
||||
|
||||
/// Whether the window should be transparent. If this is true, writing colors
|
||||
/// with alpha values different than `1.0` will produce a transparent window.
|
||||
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api")))
|
||||
)]
|
||||
#[must_use]
|
||||
fn transparent(self, transparent: bool) -> Self;
|
||||
|
||||
/// Whether the window should have borders and bars.
|
||||
#[must_use]
|
||||
fn decorations(self, decorations: bool) -> Self;
|
||||
|
||||
/// Whether the window should always be below other windows.
|
||||
#[must_use]
|
||||
fn always_on_bottom(self, always_on_bottom: bool) -> Self;
|
||||
|
||||
/// Whether the window should always be on top of other windows.
|
||||
#[must_use]
|
||||
fn always_on_top(self, always_on_top: bool) -> Self;
|
||||
|
||||
/// Whether the window should be visible on all workspaces or virtual desktops.
|
||||
#[must_use]
|
||||
fn visible_on_all_workspaces(self, visible_on_all_workspaces: bool) -> Self;
|
||||
|
||||
/// Prevents the window contents from being captured by other apps.
|
||||
#[must_use]
|
||||
fn content_protected(self, protected: bool) -> Self;
|
||||
|
||||
/// Sets the window icon.
|
||||
fn icon(self, icon: Icon) -> crate::Result<Self>;
|
||||
|
||||
/// Sets whether or not the window icon should be added to the taskbar.
|
||||
#[must_use]
|
||||
fn skip_taskbar(self, skip: bool) -> Self;
|
||||
|
||||
/// Set the window background color.
|
||||
#[must_use]
|
||||
fn background_color(self, color: Color) -> Self;
|
||||
|
||||
/// Sets whether or not the window has shadow.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows:**
|
||||
/// - `false` has no effect on decorated window, shadows are always ON.
|
||||
/// - `true` will make undecorated window have a 1px white border,
|
||||
/// and on Windows 11, it will have a rounded corners.
|
||||
/// - **Linux:** Unsupported.
|
||||
#[must_use]
|
||||
fn shadow(self, enable: bool) -> 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.
|
||||
///
|
||||
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
|
||||
#[cfg(windows)]
|
||||
#[must_use]
|
||||
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(windows)]
|
||||
#[must_use]
|
||||
fn parent(self, parent: HWND) -> Self;
|
||||
|
||||
/// Sets a parent to the window to be created.
|
||||
///
|
||||
/// See <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
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)]
|
||||
#[must_use]
|
||||
fn drag_and_drop(self, enabled: bool) -> Self;
|
||||
|
||||
/// Hide the titlebar. Titlebar buttons will still be visible.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
fn title_bar_style(self, style: tauri_utils::TitleBarStyle) -> Self;
|
||||
|
||||
/// Change the position of the window controls on macOS.
|
||||
///
|
||||
/// Requires titleBarStyle: Overlay and decorations: true.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
fn traffic_light_position<P: Into<dpi::Position>>(self, position: P) -> Self;
|
||||
|
||||
/// Hide the window title.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
fn hidden_title(self, hidden: bool) -> Self;
|
||||
|
||||
/// Defines the window [tabbing identifier] for macOS.
|
||||
///
|
||||
/// Windows with matching tabbing identifiers will be grouped together.
|
||||
/// If the tabbing identifier is not set, automatic tabbing will be disabled.
|
||||
///
|
||||
/// [tabbing identifier]: <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
|
||||
#[cfg(target_os = "macos")]
|
||||
#[must_use]
|
||||
fn tabbing_identifier(self, identifier: &str) -> Self;
|
||||
|
||||
/// Forces a theme or uses the system settings if None was provided.
|
||||
fn theme(self, theme: Option<Theme>) -> Self;
|
||||
|
||||
/// Whether the icon was set or not.
|
||||
fn has_icon(&self) -> bool;
|
||||
|
||||
fn get_theme(&self) -> Option<Theme>;
|
||||
|
||||
/// Sets custom name for Windows' window class. **Windows only**.
|
||||
#[must_use]
|
||||
fn window_classname<S: Into<String>>(self, window_classname: S) -> Self;
|
||||
|
||||
/// The name of the activity to create for this webview window.
|
||||
#[cfg(target_os = "android")]
|
||||
fn activity_name<S: Into<String>>(self, class_name: S) -> Self;
|
||||
|
||||
/// Sets the name of the activity that is creating this webview window.
|
||||
///
|
||||
/// This is important to determine which stack the activity will belong to.
|
||||
#[cfg(target_os = "android")]
|
||||
fn created_by_activity_name<S: Into<String>>(self, class_name: S) -> Self;
|
||||
|
||||
/// Sets the identifier of the UIScene that is requesting the creation of this new scene,
|
||||
/// establishing a relationship between the two scenes.
|
||||
///
|
||||
/// By default the system uses the foreground scene.
|
||||
#[cfg(target_os = "ios")]
|
||||
fn requested_by_scene_identifier<S: Into<String>>(self, identifier: S) -> Self;
|
||||
}
|
||||
|
||||
/// A window that has yet to be built.
|
||||
pub struct PendingWindow<T: UserEvent, R: Runtime<T>> {
|
||||
/// The label that the window will be named.
|
||||
pub label: String,
|
||||
|
||||
/// The [`WindowBuilder`] that the window will be created with.
|
||||
pub window_builder: <R::WindowDispatcher as WindowDispatch<T>>::WindowBuilder,
|
||||
|
||||
/// The webview that gets added to the window. Optional in case you want to use child webviews or other window content instead.
|
||||
pub webview: Option<PendingWebview<T, R>>,
|
||||
}
|
||||
|
||||
pub fn is_label_valid(label: &str) -> bool {
|
||||
label
|
||||
.chars()
|
||||
.all(|c| char::is_alphanumeric(c) || c == '-' || c == '/' || c == ':' || c == '_')
|
||||
}
|
||||
|
||||
pub fn assert_label_is_valid(label: &str) {
|
||||
assert!(
|
||||
is_label_valid(label),
|
||||
"Window label must include only alphanumeric characters, `-`, `/`, `:` and `_`."
|
||||
);
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {
|
||||
/// Create a new [`PendingWindow`] with a label from the given [`WindowBuilder`].
|
||||
pub fn new(
|
||||
window_builder: <R::WindowDispatcher as WindowDispatch<T>>::WindowBuilder,
|
||||
label: impl Into<String>,
|
||||
) -> crate::Result<Self> {
|
||||
let label = label.into();
|
||||
if !is_label_valid(&label) {
|
||||
Err(crate::Error::InvalidWindowLabel)
|
||||
} else {
|
||||
Ok(Self {
|
||||
window_builder,
|
||||
label,
|
||||
webview: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a webview to be created on the window.
|
||||
pub fn set_webview(&mut self, webview: PendingWebview<T, R>) -> &mut Self {
|
||||
self.webview.replace(webview);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifier of a window.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct WindowId(u32);
|
||||
|
||||
impl From<u32> for WindowId {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// A window that is not yet managed by Tauri.
|
||||
#[derive(Debug)]
|
||||
pub struct DetachedWindow<T: UserEvent, R: Runtime<T>> {
|
||||
/// The identifier of the window.
|
||||
pub id: WindowId,
|
||||
/// Name of the window
|
||||
pub label: String,
|
||||
|
||||
/// The [`WindowDispatch`] associated with the window.
|
||||
pub dispatcher: R::WindowDispatcher,
|
||||
|
||||
/// The webview dispatcher in case this window has an attached webview.
|
||||
pub webview: Option<DetachedWindowWebview<T, R>>,
|
||||
}
|
||||
|
||||
/// A detached webview associated with a window.
|
||||
#[derive(Debug)]
|
||||
pub struct DetachedWindowWebview<T: UserEvent, R: Runtime<T>> {
|
||||
pub webview: DetachedWebview<T, R>,
|
||||
pub use_https_scheme: bool,
|
||||
/// Whether devtools was enabled in [`crate::webview::WebviewAttributes`]. `Some(false)` disables the inspector.
|
||||
pub devtools: Option<bool>,
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindowWebview<T, R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
webview: self.webview.clone(),
|
||||
use_https_scheme: self.use_https_scheme,
|
||||
devtools: self.devtools,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindow<T, R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
id: self.id,
|
||||
label: self.label.clone(),
|
||||
dispatcher: self.dispatcher.clone(),
|
||||
webview: self.webview.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Hash for DetachedWindow<T, R> {
|
||||
/// Only use the [`DetachedWindow`]'s label to represent its hash.
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.label.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UserEvent, R: Runtime<T>> Eq for DetachedWindow<T, R> {}
|
||||
impl<T: UserEvent, R: Runtime<T>> PartialEq for DetachedWindow<T, R> {
|
||||
/// Only use the [`DetachedWindow`]'s label to compare equality.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.label.eq(&other.label)
|
||||
}
|
||||
}
|
||||
|
||||
/// A raw window type that contains fields to access
|
||||
/// the HWND on Windows, gtk::ApplicationWindow on Linux
|
||||
pub struct RawWindow<'a> {
|
||||
#[cfg(windows)]
|
||||
pub hwnd: isize,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub gtk_window: &'a gtk::ApplicationWindow,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub default_vbox: Option<&'a gtk::Box>,
|
||||
pub _marker: &'a PhantomData<()>,
|
||||
}
|
||||
Loading…
Reference in a new issue