#![allow(unused_imports)]
use super::{InvokeContext, InvokeResponse};
#[cfg(window_create)]
use crate::runtime::{webview::WindowBuilder, Dispatch};
use crate::{
runtime::{
window::dpi::{Position, Size},
UserAttentionType,
},
utils::config::WindowConfig,
CursorIcon, Icon, Manager, Runtime,
};
use serde::Deserialize;
use tauri_macros::{command_enum, module_command_handler, CommandModule};
#[derive(Deserialize)]
#[serde(untagged)]
pub enum IconDto {
#[cfg(any(feature = "icon-png", feature = "icon-ico"))]
File(std::path::PathBuf),
#[cfg(any(feature = "icon-png", feature = "icon-ico"))]
Raw(Vec<u8>),
Rgba {
rgba: Vec<u8>,
width: u32,
height: u32,
},
}
impl From<IconDto> for Icon {
fn from(icon: IconDto) -> Self {
match icon {
#[cfg(any(feature = "icon-png", feature = "icon-ico"))]
IconDto::File(path) => Self::File(path),
#[cfg(any(feature = "icon-png", feature = "icon-ico"))]
IconDto::Raw(raw) => Self::Raw(raw),
IconDto::Rgba {
rgba,
width,
height,
} => Self::Rgba {
rgba,
width,
height,
},
}
}
}
#[derive(Deserialize)]
#[serde(tag = "type", content = "payload", rename_all = "camelCase")]
pub enum WindowManagerCmd {
ScaleFactor,
InnerPosition,
OuterPosition,
InnerSize,
OuterSize,
IsFullscreen,
IsMinimized,
IsMaximized,
IsFocused,
IsDecorated,
IsResizable,
IsMaximizable,
IsMinimizable,
IsClosable,
IsVisible,
Title,
CurrentMonitor,
PrimaryMonitor,
AvailableMonitors,
Theme,
#[cfg(window_center)]
Center,
#[cfg(window_request_user_attention)]
RequestUserAttention(Option<UserAttentionType>),
#[cfg(window_set_resizable)]
SetResizable(bool),
#[cfg(window_set_maximizable)]
SetMaximizable(bool),
#[cfg(window_set_minimizable)]
SetMinimizable(bool),
#[cfg(window_set_closable)]
SetClosable(bool),
#[cfg(window_set_title)]
SetTitle(String),
#[cfg(window_maximize)]
Maximize,
#[cfg(window_unmaximize)]
Unmaximize,
#[cfg(all(window_maximize, window_unmaximize))]
ToggleMaximize,
#[cfg(window_minimize)]
Minimize,
#[cfg(window_unminimize)]
Unminimize,
#[cfg(window_show)]
Show,
#[cfg(window_hide)]
Hide,
#[cfg(window_close)]
Close,
#[cfg(window_set_decorations)]
SetDecorations(bool),
#[cfg(window_set_always_on_top)]
#[serde(rename_all = "camelCase")]
SetAlwaysOnTop(bool),
#[cfg(window_set_content_protected)]
SetContentProtected(bool),
#[cfg(window_set_size)]
SetSize(Size),
#[cfg(window_set_min_size)]
SetMinSize(Option<Size>),
#[cfg(window_set_max_size)]
SetMaxSize(Option<Size>),
#[cfg(window_set_position)]
SetPosition(Position),
#[cfg(window_set_fullscreen)]
SetFullscreen(bool),
#[cfg(window_set_focus)]
SetFocus,
#[cfg(window_set_icon)]
SetIcon {
icon: IconDto,
},
#[cfg(window_set_skip_taskbar)]
SetSkipTaskbar(bool),
#[cfg(window_set_cursor_grab)]
SetCursorGrab(bool),
#[cfg(window_set_cursor_visible)]
SetCursorVisible(bool),
#[cfg(window_set_cursor_icon)]
SetCursorIcon(CursorIcon),
#[cfg(window_set_cursor_position)]
SetCursorPosition(Position),
#[cfg(window_set_ignore_cursor_events)]
SetIgnoreCursorEvents(bool),
#[cfg(window_start_dragging)]
StartDragging,
#[cfg(window_print)]
Print,
#[cfg(all(window_maximize, window_unmaximize))]
#[serde(rename = "__toggleMaximize")]
InternalToggleMaximize,
#[cfg(any(debug_assertions, feature = "devtools"))]
#[serde(rename = "__toggleDevtools")]
InternalToggleDevtools,
}
pub fn into_allowlist_error(variant: &str) -> crate::Error {
match variant {
"center" => crate::Error::ApiNotAllowlisted("window > center".to_string()),
"requestUserAttention" => {
crate::Error::ApiNotAllowlisted("window > requestUserAttention".to_string())
}
"setResizable" => crate::Error::ApiNotAllowlisted("window > setResizable".to_string()),
"setTitle" => crate::Error::ApiNotAllowlisted("window > setTitle".to_string()),
"maximize" => crate::Error::ApiNotAllowlisted("window > maximize".to_string()),
"unmaximize" => crate::Error::ApiNotAllowlisted("window > unmaximize".to_string()),
"toggleMaximize" => {
crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
}
"minimize" => crate::Error::ApiNotAllowlisted("window > minimize".to_string()),
"unminimize" => crate::Error::ApiNotAllowlisted("window > unminimize".to_string()),
"show" => crate::Error::ApiNotAllowlisted("window > show".to_string()),
"hide" => crate::Error::ApiNotAllowlisted("window > hide".to_string()),
"close" => crate::Error::ApiNotAllowlisted("window > close".to_string()),
"setDecorations" => crate::Error::ApiNotAllowlisted("window > setDecorations".to_string()),
"setAlwaysOnTop" => crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string()),
"setContentProtected" => {
crate::Error::ApiNotAllowlisted("window > setContentProtected".to_string())
}
"setSize" => crate::Error::ApiNotAllowlisted("window > setSize".to_string()),
"setMinSize" => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()),
"setMaxSize" => crate::Error::ApiNotAllowlisted("window > setMaxSize".to_string()),
"setPosition" => crate::Error::ApiNotAllowlisted("window > setPosition".to_string()),
"setFullscreen" => crate::Error::ApiNotAllowlisted("window > setFullscreen".to_string()),
"setIcon" => crate::Error::ApiNotAllowlisted("window > setIcon".to_string()),
"setSkipTaskbar" => crate::Error::ApiNotAllowlisted("window > setSkipTaskbar".to_string()),
"setCursorGrab" => crate::Error::ApiNotAllowlisted("window > setCursorGrab".to_string()),
"setCursorVisible" => crate::Error::ApiNotAllowlisted("window > setCursorVisible".to_string()),
"setCursorIcon" => crate::Error::ApiNotAllowlisted("window > setCursorIcon".to_string()),
"setCursorPosition" => {
crate::Error::ApiNotAllowlisted("window > setCursorPosition".to_string())
}
"setIgnoreCursorEvents" => {
crate::Error::ApiNotAllowlisted("window > setIgnoreCursorEvents".to_string())
}
"startDragging" => crate::Error::ApiNotAllowlisted("window > startDragging".to_string()),
"print" => crate::Error::ApiNotAllowlisted("window > print".to_string()),
"__toggleMaximize" => {
crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
}
"__toggleDevtools" => crate::Error::ApiNotAllowlisted("devtools".to_string()),
_ => crate::Error::ApiNotAllowlisted("window".to_string()),
}
}
#[command_enum]
#[derive(Deserialize, CommandModule)]
#[cmd(async)]
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
pub enum Cmd {
#[cmd(window_create, "window > create")]
CreateWebview { options: Box<WindowConfig> },
Manage {
label: Option<String>,
cmd: WindowManagerCmd,
},
}
impl Cmd {
#[module_command_handler(window_create)]
async fn create_webview<R: Runtime>(
context: InvokeContext<R>,
mut options: Box<WindowConfig>,
) -> super::Result<()> {
options.additional_browser_args = None;
crate::window::WindowBuilder::from_config(&context.window, *options)
.build()
.map_err(crate::error::into_anyhow)?;
Ok(())
}
async fn manage<R: Runtime>(
context: InvokeContext<R>,
label: Option<String>,
cmd: WindowManagerCmd,
) -> super::Result<InvokeResponse> {
Self::_manage(context, label, cmd)
.await
.map_err(crate::error::into_anyhow)
}
async fn _manage<R: Runtime>(
context: InvokeContext<R>,
label: Option<String>,
cmd: WindowManagerCmd,
) -> crate::Result<InvokeResponse> {
let window = match label {
Some(l) if !l.is_empty() => context
.window
.get_window(&l)
.ok_or(crate::Error::WebviewNotFound)?,
_ => context.window,
};
match cmd {
WindowManagerCmd::ScaleFactor => return Ok(window.scale_factor()?.into()),
WindowManagerCmd::InnerPosition => return Ok(window.inner_position()?.into()),
WindowManagerCmd::OuterPosition => return Ok(window.outer_position()?.into()),
WindowManagerCmd::InnerSize => return Ok(window.inner_size()?.into()),
WindowManagerCmd::OuterSize => return Ok(window.outer_size()?.into()),
WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
WindowManagerCmd::IsMinimized => return Ok(window.is_minimized()?.into()),
WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()),
WindowManagerCmd::IsFocused => return Ok(window.is_focused()?.into()),
WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()),
WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()),
WindowManagerCmd::IsMaximizable => return Ok(window.is_maximizable()?.into()),
WindowManagerCmd::IsMinimizable => return Ok(window.is_minimizable()?.into()),
WindowManagerCmd::IsClosable => return Ok(window.is_closable()?.into()),
WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()),
WindowManagerCmd::Title => return Ok(window.title()?.into()),
WindowManagerCmd::CurrentMonitor => return Ok(window.current_monitor()?.into()),
WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()),
WindowManagerCmd::Theme => return Ok(window.theme()?.into()),
#[cfg(window_center)]
WindowManagerCmd::Center => window.center()?,
#[cfg(window_request_user_attention)]
WindowManagerCmd::RequestUserAttention(request_type) => {
window.request_user_attention(request_type)?
}
#[cfg(window_set_resizable)]
WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?,
#[cfg(window_set_maximizable)]
WindowManagerCmd::SetMaximizable(maximizable) => window.set_maximizable(maximizable)?,
#[cfg(window_set_minimizable)]
WindowManagerCmd::SetMinimizable(minimizable) => window.set_minimizable(minimizable)?,
#[cfg(window_set_closable)]
WindowManagerCmd::SetClosable(closable) => window.set_closable(closable)?,
#[cfg(window_set_title)]
WindowManagerCmd::SetTitle(title) => window.set_title(&title)?,
#[cfg(window_maximize)]
WindowManagerCmd::Maximize => window.maximize()?,
#[cfg(window_unmaximize)]
WindowManagerCmd::Unmaximize => window.unmaximize()?,
#[cfg(all(window_maximize, window_unmaximize))]
WindowManagerCmd::ToggleMaximize => match window.is_maximized()? {
true => window.unmaximize()?,
false => window.maximize()?,
},
#[cfg(window_minimize)]
WindowManagerCmd::Minimize => window.minimize()?,
#[cfg(window_unminimize)]
WindowManagerCmd::Unminimize => window.unminimize()?,
#[cfg(window_show)]
WindowManagerCmd::Show => window.show()?,
#[cfg(window_hide)]
WindowManagerCmd::Hide => window.hide()?,
#[cfg(window_close)]
WindowManagerCmd::Close => window.close()?,
#[cfg(window_set_decorations)]
WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
#[cfg(window_set_always_on_top)]
WindowManagerCmd::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
#[cfg(window_set_content_protected)]
WindowManagerCmd::SetContentProtected(protected) => {
window.set_content_protected(protected)?
}
#[cfg(window_set_size)]
WindowManagerCmd::SetSize(size) => window.set_size(size)?,
#[cfg(window_set_min_size)]
WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?,
#[cfg(window_set_max_size)]
WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?,
#[cfg(window_set_position)]
WindowManagerCmd::SetPosition(position) => window.set_position(position)?,
#[cfg(window_set_fullscreen)]
WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
#[cfg(window_set_focus)]
WindowManagerCmd::SetFocus => window.set_focus()?,
#[cfg(window_set_icon)]
WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?,
#[cfg(window_set_skip_taskbar)]
WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
#[cfg(window_set_cursor_grab)]
WindowManagerCmd::SetCursorGrab(grab) => window.set_cursor_grab(grab)?,
#[cfg(window_set_cursor_visible)]
WindowManagerCmd::SetCursorVisible(visible) => window.set_cursor_visible(visible)?,
#[cfg(window_set_cursor_icon)]
WindowManagerCmd::SetCursorIcon(icon) => window.set_cursor_icon(icon)?,
#[cfg(window_set_cursor_position)]
WindowManagerCmd::SetCursorPosition(position) => window.set_cursor_position(position)?,
#[cfg(window_set_ignore_cursor_events)]
WindowManagerCmd::SetIgnoreCursorEvents(ignore_cursor) => {
window.set_ignore_cursor_events(ignore_cursor)?
}
#[cfg(window_start_dragging)]
WindowManagerCmd::StartDragging => window.start_dragging()?,
#[cfg(window_print)]
WindowManagerCmd::Print => window.print()?,
#[cfg(all(window_maximize, window_unmaximize))]
WindowManagerCmd::InternalToggleMaximize => {
if window.is_resizable()? {
match window.is_maximized()? {
true => window.unmaximize()?,
false => window.maximize()?,
}
}
}
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowManagerCmd::InternalToggleDevtools => {
if window.is_devtools_open() {
window.close_devtools();
} else {
window.open_devtools();
}
}
}
#[allow(unreachable_code)]
Ok(().into())
}
}