123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
- // SPDX-License-Identifier: Apache-2.0
- // SPDX-License-Identifier: MIT
- 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::{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
- Center,
- RequestUserAttention(Option<UserAttentionType>),
- SetResizable(bool),
- SetTitle(String),
- Maximize,
- Unmaximize,
- ToggleMaximize,
- Minimize,
- Unminimize,
- Show,
- Hide,
- Close,
- SetDecorations(bool),
- #[serde(rename_all = "camelCase")]
- SetAlwaysOnTop(bool),
- SetSize(Size),
- SetMinSize(Option<Size>),
- SetMaxSize(Option<Size>),
- SetPosition(Position),
- SetFullscreen(bool),
- SetFocus,
- SetIcon {
- icon: IconDto,
- },
- SetSkipTaskbar(bool),
- SetCursorGrab(bool),
- SetCursorVisible(bool),
- SetCursorIcon(CursorIcon),
- SetCursorPosition(Position),
- StartDragging,
- Print,
- // internals
- #[serde(rename = "__toggleMaximize")]
- InternalToggleMaximize,
- #[cfg(any(debug_assertions, feature = "devtools"))]
- #[serde(rename = "__toggleDevtools")]
- InternalToggleDevtools,
- }
- impl WindowManagerCmd {
- fn into_allowlist_error(self) -> crate::Error {
- match self {
- Self::Center => crate::Error::ApiNotAllowlisted("window > center".to_string()),
- Self::RequestUserAttention(_) => {
- crate::Error::ApiNotAllowlisted("window > requestUserAttention".to_string())
- }
- Self::SetResizable(_) => crate::Error::ApiNotAllowlisted("window > setResizable".to_string()),
- Self::SetTitle(_) => crate::Error::ApiNotAllowlisted("window > setTitle".to_string()),
- Self::Maximize => crate::Error::ApiNotAllowlisted("window > maximize".to_string()),
- Self::Unmaximize => crate::Error::ApiNotAllowlisted("window > unmaximize".to_string()),
- Self::ToggleMaximize => {
- crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
- }
- Self::Minimize => crate::Error::ApiNotAllowlisted("window > minimize".to_string()),
- Self::Unminimize => crate::Error::ApiNotAllowlisted("window > unminimize".to_string()),
- Self::Show => crate::Error::ApiNotAllowlisted("window > show".to_string()),
- Self::Hide => crate::Error::ApiNotAllowlisted("window > hide".to_string()),
- Self::Close => crate::Error::ApiNotAllowlisted("window > close".to_string()),
- Self::SetDecorations(_) => {
- crate::Error::ApiNotAllowlisted("window > setDecorations".to_string())
- }
- Self::SetAlwaysOnTop(_) => {
- crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string())
- }
- Self::SetSize(_) => crate::Error::ApiNotAllowlisted("window > setSize".to_string()),
- Self::SetMinSize(_) => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()),
- Self::SetMaxSize(_) => crate::Error::ApiNotAllowlisted("window > setMaxSize".to_string()),
- Self::SetPosition(_) => crate::Error::ApiNotAllowlisted("window > setPosition".to_string()),
- Self::SetFullscreen(_) => {
- crate::Error::ApiNotAllowlisted("window > setFullscreen".to_string())
- }
- Self::SetIcon { .. } => crate::Error::ApiNotAllowlisted("window > setIcon".to_string()),
- Self::SetSkipTaskbar(_) => {
- crate::Error::ApiNotAllowlisted("window > setSkipTaskbar".to_string())
- }
- Self::SetCursorGrab(_) => {
- crate::Error::ApiNotAllowlisted("window > setCursorGrab".to_string())
- }
- Self::SetCursorVisible(_) => {
- crate::Error::ApiNotAllowlisted("window > setCursorVisible".to_string())
- }
- Self::SetCursorIcon(_) => {
- crate::Error::ApiNotAllowlisted("window > setCursorIcon".to_string())
- }
- Self::SetCursorPosition(_) => {
- crate::Error::ApiNotAllowlisted("window > setCursorPosition".to_string())
- }
- Self::StartDragging => crate::Error::ApiNotAllowlisted("window > startDragging".to_string()),
- Self::Print => crate::Error::ApiNotAllowlisted("window > print".to_string()),
- Self::InternalToggleMaximize => {
- crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
- }
- _ => crate::Error::ApiNotAllowlisted("window > all".to_string()),
- }
- }
- }
- /// The API descriptor.
- #[derive(Deserialize, CommandModule)]
- #[cmd(async)]
- #[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
- pub enum Cmd {
- CreateWebview {
- options: Box<WindowConfig>,
- },
- Manage {
- label: Option<String>,
- cmd: WindowManagerCmd,
- },
- }
- impl Cmd {
- #[module_command_handler(window_create, "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 mut builder = crate::window::Window::builder(&context.window, label, url);
- 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(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_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_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_start_dragging)]
- WindowManagerCmd::StartDragging => window.start_dragging()?,
- #[cfg(window_print)]
- WindowManagerCmd::Print => window.print()?,
- // internals
- #[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_patterns)]
- _ => return Err(cmd.into_allowlist_error()),
- }
- #[allow(unreachable_code)]
- Ok(().into())
- }
- }
|