From cf7fd2e3103c6b62cf7b7c757432d1299beb7842 Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Sun, 16 Apr 2023 12:00:25 -0300 Subject: [PATCH 1/5] refactor(core): read tray icon only on desktop, refactor Context --- .changes/remove-tray-icon-mobile.md | 6 ++ core/tauri-codegen/src/context.rs | 90 ++++++++++++++++++----------- core/tauri/src/lib.rs | 29 ++++++++-- core/tauri/src/manager.rs | 16 +++-- core/tauri/src/scope/shell.rs | 4 +- core/tauri/src/test/mod.rs | 1 + 6 files changed, 99 insertions(+), 47 deletions(-) create mode 100644 .changes/remove-tray-icon-mobile.md diff --git a/.changes/remove-tray-icon-mobile.md b/.changes/remove-tray-icon-mobile.md new file mode 100644 index 000000000000..f18cd3779694 --- /dev/null +++ b/.changes/remove-tray-icon-mobile.md @@ -0,0 +1,6 @@ +--- +"tauri-codegen": patch +"tauri": patch +--- + +Refactor the `Context` conditional fields and only parse the tray icon on desktop. diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index 619be21b8aa1..6978c56d9d4a 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -125,6 +125,16 @@ enum Target { Ios, } +impl Target { + fn mobile(&self) -> bool { + matches!(self, Target::Android | Target::Ios) + } + + fn desktop(&self) -> bool { + !self.mobile() + } +} + /// Build a `tauri::Context` for including in application code. pub fn context_codegen(data: ContextData) -> Result { let ContextData { @@ -247,7 +257,7 @@ pub fn context_codegen(data: ContextData) -> Result Result Result Result Result Result Result panic!("unknown shell open format, unable to prepare"), }; - quote!(#root::ShellScopeConfig { + quote!(context.with_shell_scope(#root::ShellScopeConfig { open: #shell_scope_open, scopes: #shell_scopes - }) + });) }; #[cfg(not(feature = "shell-scope"))] - let shell_scope_config = quote!(); - - Ok(quote!(#root::Context::new( - #config, - ::std::sync::Arc::new(#assets), - #default_window_icon, - #app_icon, - #system_tray_icon, - #package_info, - #info_plist, - #pattern, - #shell_scope_config - ))) + let with_shell_scope_code = quote!(); + + Ok(quote!({ + #[allow(unused_mut, clippy::let_and_return)] + let mut context = #root::Context::new( + #config, + ::std::sync::Arc::new(#assets), + #default_window_icon, + #app_icon, + #package_info, + #info_plist, + #pattern, + ); + #with_system_tray_icon_code + #with_shell_scope_code + context + })) } fn ico_icon>( @@ -483,7 +503,7 @@ fn ico_icon>( let out_path = out_path.display().to_string(); - let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height })); + let icon = quote!(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }); Ok(icon) } @@ -501,7 +521,7 @@ fn raw_icon>(out_dir: &Path, path: P) -> Result>( let out_path = out_path.display().to_string(); - let icon = quote!(Some(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height })); + let icon = quote!(#root::Icon::Rgba { rgba: include_bytes!(#out_path).to_vec(), width: #width, height: #height }); Ok(icon) } diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index e31e4cc1edd9..79f95cc44145 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -552,6 +552,7 @@ pub struct Context { pub(crate) assets: Arc, pub(crate) default_window_icon: Option, pub(crate) app_icon: Option>, + #[cfg(desktop)] pub(crate) system_tray_icon: Option, pub(crate) package_info: PackageInfo, pub(crate) _info_plist: (), @@ -566,9 +567,12 @@ impl fmt::Debug for Context { d.field("config", &self.config) .field("default_window_icon", &self.default_window_icon) .field("app_icon", &self.app_icon) - .field("system_tray_icon", &self.system_tray_icon) .field("package_info", &self.package_info) .field("pattern", &self.pattern); + + #[cfg(desktop)] + d.field("system_tray_icon", &self.system_tray_icon); + #[cfg(shell_scope)] d.field("shell_scope", &self.shell_scope); d.finish() @@ -613,12 +617,14 @@ impl Context { } /// The icon to use on the system tray UI. + #[cfg(desktop)] #[inline(always)] pub fn system_tray_icon(&self) -> Option<&Icon> { self.system_tray_icon.as_ref() } /// A mutable reference to the icon to use on the system tray UI. + #[cfg(desktop)] #[inline(always)] pub fn system_tray_icon_mut(&mut self) -> &mut Option { &mut self.system_tray_icon @@ -657,25 +663,38 @@ impl Context { assets: Arc, default_window_icon: Option, app_icon: Option>, - system_tray_icon: Option, package_info: PackageInfo, info_plist: (), pattern: Pattern, - #[cfg(shell_scope)] shell_scope: scope::ShellScopeConfig, ) -> Self { Self { config, assets, default_window_icon, app_icon, - system_tray_icon, + #[cfg(desktop)] + system_tray_icon: None, package_info, _info_plist: info_plist, pattern, #[cfg(shell_scope)] - shell_scope, + shell_scope: Default::default(), } } + + /// Sets the app tray icon. + #[cfg(desktop)] + #[inline(always)] + pub fn with_system_tray_icon(&mut self, icon: Icon) { + self.system_tray_icon.replace(icon); + } + + /// Sets the app shell scope. + #[cfg(shell_scope)] + #[inline(always)] + pub fn with_shell_scope(&mut self, scope: scope::ShellScopeConfig) { + self.shell_scope = scope; + } } // TODO: expand these docs diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index 37e08aaa95cb..3a4c4bd9fb79 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -219,6 +219,7 @@ pub struct InnerWindowManager { assets: Arc, pub(crate) default_window_icon: Option, pub(crate) app_icon: Option>, + #[cfg(desktop)] pub(crate) tray_icon: Option, package_info: PackageInfo, @@ -240,17 +241,21 @@ pub struct InnerWindowManager { impl fmt::Debug for InnerWindowManager { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("InnerWindowManager") - .field("plugins", &self.plugins) + let mut d = f.debug_struct("InnerWindowManager"); + + d.field("plugins", &self.plugins) .field("state", &self.state) .field("config", &self.config) .field("default_window_icon", &self.default_window_icon) .field("app_icon", &self.app_icon) - .field("tray_icon", &self.tray_icon) .field("package_info", &self.package_info) .field("menu", &self.menu) - .field("pattern", &self.pattern) - .finish() + .field("pattern", &self.pattern); + + #[cfg(desktop)] + d.field("tray_icon", &self.tray_icon); + + d.finish() } } @@ -322,6 +327,7 @@ impl WindowManager { assets: context.assets, default_window_icon: context.default_window_icon, app_icon: context.app_icon, + #[cfg(desktop)] tray_icon: context.system_tray_icon, package_info: context.package_info, pattern: context.pattern, diff --git a/core/tauri/src/scope/shell.rs b/core/tauri/src/scope/shell.rs index a03644a090a3..c773cca4d96d 100644 --- a/core/tauri/src/scope/shell.rs +++ b/core/tauri/src/scope/shell.rs @@ -58,7 +58,7 @@ impl From> for ExecuteArgs { } /// Shell scope configuration. -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] pub struct ScopeConfig { /// The validation regex that `shell > open` paths must match against. pub open: Option, @@ -106,7 +106,7 @@ impl ScopeAllowedArg { } /// Scope for filesystem access. -#[derive(Clone)] +#[derive(Default, Clone)] pub struct Scope(ScopeConfig); /// All errors that can happen while validating a scoped command. diff --git a/core/tauri/src/test/mod.rs b/core/tauri/src/test/mod.rs index f7972ac5bdc5..509b2ae97f32 100644 --- a/core/tauri/src/test/mod.rs +++ b/core/tauri/src/test/mod.rs @@ -60,6 +60,7 @@ pub fn mock_context(assets: A) -> crate::Context { assets: Arc::new(assets), default_window_icon: None, app_icon: None, + #[cfg(desktop)] system_tray_icon: None, package_info: crate::PackageInfo { name: "test".into(), From 96a1b2a50f6756d13a2c00bef0ad0df0581ff97f Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Mon, 17 Apr 2023 13:48:31 -0300 Subject: [PATCH 2/5] fix macos app_icon regression --- core/tauri-codegen/src/context.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index 6978c56d9d4a..5bdbef595567 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -521,7 +521,9 @@ fn raw_icon>(out_dir: &Path, path: P) -> Result Date: Tue, 18 Apr 2023 08:04:14 -0300 Subject: [PATCH 3/5] use is_ prefix --- core/tauri-codegen/src/context.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index 5bdbef595567..05845f3b243a 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -126,12 +126,12 @@ enum Target { } impl Target { - fn mobile(&self) -> bool { + fn is_mobile(&self) -> bool { matches!(self, Target::Android | Target::Ios) } - fn desktop(&self) -> bool { - !self.mobile() + fn is_desktop(&self) -> bool { + !self.is_mobile() } } @@ -322,7 +322,7 @@ pub fn context_codegen(data: ContextData) -> Result Date: Tue, 18 Apr 2023 08:04:48 -0300 Subject: [PATCH 4/5] change with_ to set_ --- core/tauri-codegen/src/context.rs | 6 +++--- core/tauri/src/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index 05845f3b243a..f7edf0b07d0f 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -328,10 +328,10 @@ pub fn context_codegen(data: ContextData) -> Result Result panic!("unknown shell open format, unable to prepare"), }; - quote!(context.with_shell_scope(#root::ShellScopeConfig { + quote!(context.set_shell_scope(#root::ShellScopeConfig { open: #shell_scope_open, scopes: #shell_scopes });) diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 79f95cc44145..c640b5878f9a 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -685,14 +685,14 @@ impl Context { /// Sets the app tray icon. #[cfg(desktop)] #[inline(always)] - pub fn with_system_tray_icon(&mut self, icon: Icon) { + pub fn set_system_tray_icon(&mut self, icon: Icon) { self.system_tray_icon.replace(icon); } /// Sets the app shell scope. #[cfg(shell_scope)] #[inline(always)] - pub fn with_shell_scope(&mut self, scope: scope::ShellScopeConfig) { + pub fn set_shell_scope(&mut self, scope: scope::ShellScopeConfig) { self.shell_scope = scope; } } From 24934fe05251b21666f3229219e948d53fa14124 Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Tue, 18 Apr 2023 08:23:17 -0300 Subject: [PATCH 5/5] fix ScopeConfig default impl, add constructors --- core/tauri-codegen/src/context.rs | 20 +++++++------- core/tauri/src/scope/shell.rs | 45 +++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index f7edf0b07d0f..643ada6a8fef 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -431,28 +431,26 @@ pub fn context_codegen(data: ContextData) -> Result quote!(::std::option::Option::None), - ShellAllowlistOpen::Flag(true) => { - quote!(::std::option::Option::Some(#root::regex::Regex::new(r#"^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+"#).unwrap())) - } + let shell_scope_constructor = match &config.tauri.allowlist.shell.open { + ShellAllowlistOpen::Flag(false) => quote!(#root::ShellScopeConfig::new().skip_validation()), + ShellAllowlistOpen::Flag(true) => quote!(#root::ShellScopeConfig::new()), ShellAllowlistOpen::Validate(regex) => match Regex::new(regex) { - Ok(_) => quote!(::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap())), + Ok(_) => { + quote!(#root::ShellScopeConfig::with_validator(#root::regex::Regex::new(#regex).unwrap())) + } Err(error) => { let error = error.to_string(); quote!({ compile_error!(#error); - ::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap()) + #root::ShellScopeConfig::with_validator(#root::regex::Regex::new(#regex).unwrap()) }) } }, _ => panic!("unknown shell open format, unable to prepare"), }; + let shell_scope = quote!(#shell_scope_constructor.set_allowed_commands(#shell_scopes)); - quote!(context.set_shell_scope(#root::ShellScopeConfig { - open: #shell_scope_open, - scopes: #shell_scopes - });) + quote!(context.set_shell_scope(#shell_scope);) }; #[cfg(not(feature = "shell-scope"))] diff --git a/core/tauri/src/scope/shell.rs b/core/tauri/src/scope/shell.rs index c773cca4d96d..4d1aba537ba8 100644 --- a/core/tauri/src/scope/shell.rs +++ b/core/tauri/src/scope/shell.rs @@ -12,6 +12,8 @@ use regex::Regex; use std::collections::HashMap; +const DEFAULT_OPEN_REGEX: &str = r#"^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+"#; + /// Allowed representation of `Execute` command arguments. #[derive(Debug, Clone, serde::Deserialize)] #[serde(untagged, deny_unknown_fields)] @@ -58,7 +60,7 @@ impl From> for ExecuteArgs { } /// Shell scope configuration. -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct ScopeConfig { /// The validation regex that `shell > open` paths must match against. pub open: Option, @@ -67,6 +69,45 @@ pub struct ScopeConfig { pub scopes: HashMap, } +impl Default for ScopeConfig { + fn default() -> Self { + Self { + open: Some(Regex::new(DEFAULT_OPEN_REGEX).unwrap()), + scopes: Default::default(), + } + } +} + +impl ScopeConfig { + /// Creates a new scope configuration with the default validation regex ^((mailto:\w+)|(tel:\w+)|(https?://\w+)).+. + pub fn new() -> Self { + Self::default() + } + + /// Creates a new scope configuration with the specified validation regex. + pub fn with_validator(regex: Regex) -> Self { + Self { + open: Some(regex), + scopes: Default::default(), + } + } + + /// Unsets the validator regex, allowing any path to be opened. + pub fn skip_validation(mut self) -> Self { + self.open = None; + self + } + + /// Sets the commands that are allowed to be executed. + pub fn set_allowed_commands>( + mut self, + scopes: I, + ) -> Self { + self.scopes = scopes.into_iter().collect(); + self + } +} + /// A configured scoped shell command. #[derive(Debug, Clone)] pub struct ScopeAllowedCommand { @@ -106,7 +147,7 @@ impl ScopeAllowedArg { } /// Scope for filesystem access. -#[derive(Default, Clone)] +#[derive(Clone)] pub struct Scope(ScopeConfig); /// All errors that can happen while validating a scoped command.