123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- // Copyright 2019-2022 Tauri Programme within The Commons Conservancy
- // SPDX-License-Identifier: Apache-2.0
- // SPDX-License-Identifier: MIT
- #![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,
- },
- }
- }
- }
- /// Window management API descriptor.
- #[derive(Deserialize)]
- #[serde(tag = "type", content = "payload", rename_all = "camelCase")]
- pub enum WindowManagerCmd {
- // Getters
- ScaleFactor,
- InnerPosition,
- OuterPosition,
- InnerSize,
- OuterSize,
- IsFullscreen,
- IsMaximized,
- IsDecorated,
- IsResizable,
- IsVisible,
- CurrentMonitor,
- PrimaryMonitor,
- AvailableMonitors,
- Theme,
- // Setters
- #[cfg(window_center)]
- Center,
- #[cfg(window_request_user_attention)]
- RequestUserAttention(Option<UserAttentionType>),
- #[cfg(window_set_resizable)]
- SetResizable(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_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,
- // internals
- #[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()),
- "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()),
- "internalToggleMaximize" => {
- crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
- }
- _ => crate::Error::ApiNotAllowlisted("window".to_string()),
- }
- }
- /// The API descriptor.
- #[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>,
- options: Box<WindowConfig>,
- ) -> super::Result<()> {
- let label = options.label.clone();
- let url = options.url.clone();
- let file_drop_enabled = options.file_drop_enabled;
- let mut builder = crate::window::Window::builder(&context.window, label, url);
- if !file_drop_enabled {
- builder = builder.disable_file_drop_handler();
- }
- builder.window_builder =
- <<R::Dispatcher as Dispatch<crate::EventLoopMessage>>::WindowBuilder>::with_config(*options);
- builder.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 {
- // Getters
- 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::IsMaximized => return Ok(window.is_maximized()?.into()),
- WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()),
- WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()),
- WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.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()),
- // Setters
- #[cfg(all(desktop, window_center))]
- WindowManagerCmd::Center => window.center()?,
- #[cfg(all(desktop, window_request_user_attention))]
- WindowManagerCmd::RequestUserAttention(request_type) => {
- window.request_user_attention(request_type)?
- }
- #[cfg(all(desktop, window_set_resizable))]
- WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?,
- #[cfg(all(desktop, window_set_title))]
- WindowManagerCmd::SetTitle(title) => window.set_title(&title)?,
- #[cfg(all(desktop, window_maximize))]
- WindowManagerCmd::Maximize => window.maximize()?,
- #[cfg(all(desktop, window_unmaximize))]
- WindowManagerCmd::Unmaximize => window.unmaximize()?,
- #[cfg(all(desktop, window_maximize, window_unmaximize))]
- WindowManagerCmd::ToggleMaximize => match window.is_maximized()? {
- true => window.unmaximize()?,
- false => window.maximize()?,
- },
- #[cfg(all(desktop, window_minimize))]
- WindowManagerCmd::Minimize => window.minimize()?,
- #[cfg(all(desktop, window_unminimize))]
- WindowManagerCmd::Unminimize => window.unminimize()?,
- #[cfg(all(desktop, window_show))]
- WindowManagerCmd::Show => window.show()?,
- #[cfg(all(desktop, window_hide))]
- WindowManagerCmd::Hide => window.hide()?,
- #[cfg(all(desktop, window_close))]
- WindowManagerCmd::Close => window.close()?,
- #[cfg(all(desktop, window_set_decorations))]
- WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
- #[cfg(all(desktop, window_set_always_on_top))]
- WindowManagerCmd::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
- #[cfg(all(desktop, window_set_size))]
- WindowManagerCmd::SetSize(size) => window.set_size(size)?,
- #[cfg(all(desktop, window_set_min_size))]
- WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?,
- #[cfg(all(desktop, window_set_max_size))]
- WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?,
- #[cfg(all(desktop, window_set_position))]
- WindowManagerCmd::SetPosition(position) => window.set_position(position)?,
- #[cfg(all(desktop, window_set_fullscreen))]
- WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
- #[cfg(all(desktop, window_set_focus))]
- WindowManagerCmd::SetFocus => window.set_focus()?,
- #[cfg(all(desktop, window_set_icon))]
- WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?,
- #[cfg(all(desktop, window_set_skip_taskbar))]
- WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
- #[cfg(all(desktop, window_set_cursor_grab))]
- WindowManagerCmd::SetCursorGrab(grab) => window.set_cursor_grab(grab)?,
- #[cfg(all(desktop, window_set_cursor_visible))]
- WindowManagerCmd::SetCursorVisible(visible) => window.set_cursor_visible(visible)?,
- #[cfg(all(desktop, window_set_cursor_icon))]
- WindowManagerCmd::SetCursorIcon(icon) => window.set_cursor_icon(icon)?,
- #[cfg(all(desktop, window_set_cursor_position))]
- WindowManagerCmd::SetCursorPosition(position) => window.set_cursor_position(position)?,
- #[cfg(all(desktop, window_set_ignore_cursor_events))]
- WindowManagerCmd::SetIgnoreCursorEvents(ignore_cursor) => {
- window.set_ignore_cursor_events(ignore_cursor)?
- }
- #[cfg(all(desktop, window_start_dragging))]
- WindowManagerCmd::StartDragging => window.start_dragging()?,
- #[cfg(all(desktop, window_print))]
- WindowManagerCmd::Print => window.print()?,
- // internals
- #[cfg(all(desktop, window_maximize, window_unmaximize))]
- WindowManagerCmd::InternalToggleMaximize => {
- if window.is_resizable()? {
- match window.is_maximized()? {
- true => window.unmaximize()?,
- false => window.maximize()?,
- }
- }
- }
- #[cfg(all(desktop, any(debug_assertions, feature = "devtools")))]
- WindowManagerCmd::InternalToggleDevtools => {
- if window.is_devtools_open() {
- window.close_devtools();
- } else {
- window.open_devtools();
- }
- }
- _ => (),
- }
- #[allow(unreachable_code)]
- Ok(().into())
- }
- }
|