1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Items specific to the [`Runtime`](crate::Runtime)'s webview.
use crate::{menu::Menu, window::DetachedWindow, Icon};
#[cfg(target_os = "macos")]
use tauri_utils::TitleBarStyle;
use tauri_utils::{
config::{WindowConfig, WindowUrl},
Theme,
};
#[cfg(windows)]
use windows::Win32::Foundation::HWND;
use std::{fmt, path::PathBuf};
/// The attributes used to create an webview.
#[derive(Debug, Clone)]
pub struct WebviewAttributes {
pub url: WindowUrl,
pub user_agent: Option<String>,
pub initialization_scripts: Vec<String>,
pub data_directory: Option<PathBuf>,
pub file_drop_handler_enabled: bool,
pub clipboard: bool,
pub accept_first_mouse: bool,
pub additional_browser_args: Option<String>,
}
impl From<&WindowConfig> for WebviewAttributes {
fn from(config: &WindowConfig) -> Self {
let mut builder = Self::new(config.url.clone());
builder = builder.accept_first_mouse(config.accept_first_mouse);
if !config.file_drop_enabled {
builder = builder.disable_file_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);
}
builder
}
}
impl WebviewAttributes {
/// Initializes the default attributes for a webview.
pub fn new(url: WindowUrl) -> Self {
Self {
url,
user_agent: None,
initialization_scripts: Vec::new(),
data_directory: None,
file_drop_handler_enabled: true,
clipboard: false,
accept_first_mouse: false,
additional_browser_args: 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
}
/// Sets the init script.
#[must_use]
pub fn initialization_script(mut self, script: &str) -> Self {
self.initialization_scripts.push(script.to_string());
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 file drop handler. This is required to use drag and drop APIs on the front end on Windows.
#[must_use]
pub fn disable_file_drop_handler(mut self) -> Self {
self.file_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
}
}
/// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::Runtime).
///
/// This trait is separate from [`WindowBuilder`] to prevent "accidental" implementation.
pub trait WindowBuilderBase: fmt::Debug + Clone + Sized {}
/// A builder for all attributes related to a single webview.
///
/// This trait is only meant to be implemented by a custom [`Runtime`](crate::Runtime)
/// and not by applications.
pub trait WindowBuilder: WindowBuilderBase {
/// Initializes a new window attributes builder.
fn new() -> Self;
/// Initializes a new webview builder from a [`WindowConfig`]
fn with_config(config: WindowConfig) -> Self;
/// Sets the menu for the window.
#[must_use]
fn menu(self, menu: Menu) -> Self;
/// Show window in the center of the screen.
#[must_use]
fn center(self) -> Self;
/// The initial position of the window's.
#[must_use]
fn position(self, x: f64, y: f64) -> Self;
/// Window size.
#[must_use]
fn inner_size(self, width: f64, height: f64) -> Self;
/// Window min inner size.
#[must_use]
fn min_inner_size(self, min_width: f64, min_height: f64) -> Self;
/// Window max inner size.
#[must_use]
fn max_inner_size(self, max_width: f64, max_height: f64) -> 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 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(
doc_cfg,
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 on top of other windows.
#[must_use]
fn always_on_top(self, always_on_top: 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;
/// 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_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:
/// - 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_window(self, owner: HWND) -> Self;
/// Hide the titlebar. Titlebar buttons will still be visible.
#[cfg(target_os = "macos")]
#[must_use]
fn title_bar_style(self, style: TitleBarStyle) -> 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;
/// Gets the window menu.
fn get_menu(&self) -> Option<&Menu>;
}
/// IPC handler.
pub type WebviewIpcHandler<T, R> = Box<dyn Fn(DetachedWindow<T, R>, String) + Send>;