diff --git a/.changes/private-context.md b/.changes/private-context.md new file mode 100644 index 00000000000..dbad3b8ccd3 --- /dev/null +++ b/.changes/private-context.md @@ -0,0 +1,8 @@ +--- +"tauri": patch +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +**Breaking:** `Context` fields are now private, and is expected to be created through `Context::new(...)`. +All fields previously available through `Context` are now public methods. diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index 5ed2321fa05..2fbbfc54e21 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -88,16 +88,18 @@ pub fn context_codegen(data: ContextData) -> Result Result( &self, - icon: std::path::PathBuf, + icon: Icon, menu_items: Vec>, ) -> Result<()> { - SystemTrayBuilder::new( - icon, - menu_items - .into_iter() - .map(|m| MenuItemWrapper::from(m).0) - .collect(), - ) - .build(&self.event_loop) - .map_err(|e| Error::SystemTray(Box::new(e)))?; - Ok(()) - } + // todo: fix this interface in Tao to an enum similar to Icon + + // we expect the code that passes the Icon enum to have already checked the platform. + let icon = match icon { + #[cfg(target_os = "linux")] + Icon::File(path) => path, + + #[cfg(not(target_os = "linux"))] + Icon::Raw(bytes) => bytes, + + #[cfg(target_os = "linux")] + Icon::Raw(_) => { + panic!("linux requires the system menu icon to be a file path, not bytes.") + } + + #[cfg(not(target_os = "linux"))] + Icon::File(_) => { + panic!("non-linux system menu icons must be bytes, not a file path",) + } + _ => unreachable!(), + }; - #[cfg(all(feature = "system-tray", not(target_os = "linux")))] - fn system_tray( - &self, - icon: Vec, - menu_items: Vec>, - ) -> Result<()> { SystemTrayBuilder::new( icon, menu_items diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index db9b3b767ae..adb385780bf 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -119,23 +119,11 @@ pub trait Runtime: Sized + 'static { ) -> crate::Result>; /// Adds the icon to the system tray with the specified menu items. - #[cfg(all(feature = "system-tray", target_os = "linux"))] - #[cfg_attr(doc_cfg, doc(cfg(all(feature = "system-tray", target_os = "linux"))))] - fn system_tray( - &self, - icon: std::path::PathBuf, - menu: Vec>, - ) -> crate::Result<()>; - - /// Adds the icon to the system tray with the specified menu items. - #[cfg(all(feature = "system-tray", not(target_os = "linux")))] - #[cfg_attr( - doc_cfg, - doc(cfg(all(feature = "system-tray", not(target_os = "linux")))) - )] + #[cfg(feature = "system-tray")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))] fn system_tray( &self, - icon: Vec, + icon: Icon, menu: Vec>, ) -> crate::Result<()>; diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index d90dfd82740..9fa4b2cd0be 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -23,7 +23,7 @@ use std::{collections::HashMap, sync::Arc}; #[cfg(feature = "menu")] use crate::runtime::menu::Menu; #[cfg(feature = "system-tray")] -use crate::runtime::menu::SystemTrayMenuItem; +use crate::runtime::{menu::SystemTrayMenuItem, Icon}; #[cfg(feature = "updater")] use crate::updater; @@ -474,7 +474,32 @@ where /// Runs the configured Tauri application. pub fn run(mut self, context: Context) -> crate::Result<()> { #[cfg(feature = "system-tray")] - let system_tray_icon = context.system_tray_icon.clone(); + let system_tray_icon = { + let icon = context.system_tray_icon.clone(); + + // check the icon format if the system tray is supposed to be ran + if !self.system_tray.is_empty() { + use std::io::{Error, ErrorKind}; + #[cfg(target_os = "linux")] + if let Some(Icon::Raw(_)) = icon { + return Err(crate::Error::InvalidIcon(Box::new(Error::new( + ErrorKind::InvalidInput, + "system tray icons on linux must be a file path", + )))); + } + + #[cfg(not(target_os = "linux"))] + if let Some(Icon::File(bytes)) = icon { + return Err(crate::Error::InvalidIcon(Box::new(Error::new( + ErrorKind::InvalidInput, + "system tray icons on non-linux platforms must be the raw bytes", + )))); + } + } + + icon + }; + let manager = WindowManager::with_handlers( context, self.plugins, diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index e2ca22eedd3..3a13ffff21c 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -72,7 +72,7 @@ pub use { dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size}, WindowEvent, }, - MenuId, Params, + Icon, MenuId, Params, }, self::state::{State, StateManager}, self::window::{Monitor, Window}, @@ -128,25 +128,61 @@ macro_rules! tauri_build_context { /// This is the output of the `tauri::generate_context!` macro, and is not considered part of the stable API. /// Unless you know what you are doing and are prepared for this type to have breaking changes, do not create it yourself. pub struct Context { + pub(crate) config: Config, + pub(crate) assets: Arc, + pub(crate) default_window_icon: Option>, + pub(crate) system_tray_icon: Option, + pub(crate) package_info: crate::api::PackageInfo, +} + +impl Context { /// The config the application was prepared with. - pub config: Config, + #[inline(always)] + pub fn config(&self) -> &Config { + &self.config + } /// The assets to be served directly by Tauri. - pub assets: Arc, + #[inline(always)] + pub fn assets(&self) -> Arc { + self.assets.clone() + } /// The default window icon Tauri should use when creating windows. - pub default_window_icon: Option>, - - /// The icon to use use on the system tray UI. - #[cfg(target_os = "linux")] - pub system_tray_icon: Option, + #[inline(always)] + pub fn default_window_icon(&self) -> Option<&[u8]> { + self.default_window_icon.as_deref() + } /// The icon to use use on the system tray UI. - #[cfg(not(target_os = "linux"))] - pub system_tray_icon: Option>, + #[inline(always)] + pub fn system_tray_icon(&self) -> Option<&Icon> { + self.system_tray_icon.as_ref() + } /// Package information. - pub package_info: crate::api::PackageInfo, + #[inline(always)] + pub fn package_info(&self) -> &crate::api::PackageInfo { + &self.package_info + } + + /// Create a new [`Context`] from the minimal required items. + #[inline(always)] + pub fn new( + config: Config, + assets: Arc, + default_window_icon: Option>, + system_tray_icon: Option, + package_info: crate::api::PackageInfo, + ) -> Self { + Self { + config, + assets, + default_window_icon, + system_tray_icon, + package_info, + } + } } // TODO: expand these docs