Przeglądaj źródła

refactor(core): Context fields now private, Icon used on all platforms (#1774)

chip 4 lat temu
rodzic
commit
55423590dd

+ 8 - 0
.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.

+ 16 - 14
core/tauri-codegen/src/context.rs

@@ -88,16 +88,18 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
         .join(system_tray_icon_path)
         .display()
         .to_string();
-      quote!(Some(::std::path::PathBuf::from(#system_tray_icon_path)))
+      quote!(Some(#root::Icon::File(::std::path::PathBuf::from(#system_tray_icon_path))))
     } else {
       let system_tray_icon_file_path = system_tray_icon_path.to_string_lossy().to_string();
       quote!(
         Some(
-          #root::api::path::resolve_path(
-            &#config, &#package_info,
-            #system_tray_icon_file_path,
-            Some(#root::api::path::BaseDirectory::Resource)
-          ).expect("failed to resolve resource dir")
+          #root::Icon::File(
+            #root::api::path::resolve_path(
+              &#config, &#package_info,
+             #system_tray_icon_file_path,
+             Some(#root::api::path::BaseDirectory::Resource)
+            ).expect("failed to resolve resource dir")
+          )
         )
       )
     }
@@ -113,17 +115,17 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
       .join(system_tray_icon_path)
       .display()
       .to_string();
-    quote!(Some(include_bytes!(#system_tray_icon_path).to_vec()))
+    quote!(Some(#root::Icon::Raw(include_bytes!(#system_tray_icon_path).to_vec())))
   } else {
     quote!(None)
   };
 
   // double braces are purposeful to force the code into a block expression
-  Ok(quote!(#root::Context {
-    system_tray_icon: #system_tray_icon,
-    config: #config,
-    assets: ::std::sync::Arc::new(#assets),
-    default_window_icon: #default_window_icon,
-    package_info: #package_info,
-  }))
+  Ok(quote!(#root::Context::new(
+    #config,
+    ::std::sync::Arc::new(#assets),
+    #default_window_icon,
+    #system_tray_icon,
+    #package_info,
+  )))
 }

+ 23 - 19
core/tauri-runtime-wry/src/lib.rs

@@ -820,30 +820,34 @@ impl Runtime for Wry {
     Ok(DetachedWindow { label, dispatcher })
   }
 
-  #[cfg(all(feature = "system-tray", target_os = "linux"))]
+  #[cfg(feature = "system-tray")]
   fn system_tray<I: MenuId>(
     &self,
-    icon: std::path::PathBuf,
+    icon: Icon,
     menu_items: Vec<SystemTrayMenuItem<I>>,
   ) -> 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<I: MenuId>(
-    &self,
-    icon: Vec<u8>,
-    menu_items: Vec<SystemTrayMenuItem<I>>,
-  ) -> Result<()> {
     SystemTrayBuilder::new(
       icon,
       menu_items

+ 3 - 15
core/tauri-runtime/src/lib.rs

@@ -119,23 +119,11 @@ pub trait Runtime: Sized + 'static {
   ) -> crate::Result<DetachedWindow<P>>;
 
   /// 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<I: MenuId>(
-    &self,
-    icon: std::path::PathBuf,
-    menu: Vec<menu::SystemTrayMenuItem<I>>,
-  ) -> 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<I: MenuId>(
     &self,
-    icon: Vec<u8>,
+    icon: Icon,
     menu: Vec<menu::SystemTrayMenuItem<I>>,
   ) -> crate::Result<()>;
 

+ 27 - 2
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<A>) -> 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,

+ 47 - 11
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<A: Assets> {
+  pub(crate) config: Config,
+  pub(crate) assets: Arc<A>,
+  pub(crate) default_window_icon: Option<Vec<u8>>,
+  pub(crate) system_tray_icon: Option<Icon>,
+  pub(crate) package_info: crate::api::PackageInfo,
+}
+
+impl<A: Assets> Context<A> {
   /// 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<A>,
+  #[inline(always)]
+  pub fn assets(&self) -> Arc<A> {
+    self.assets.clone()
+  }
 
   /// The default window icon Tauri should use when creating windows.
-  pub default_window_icon: Option<Vec<u8>>,
-
-  /// The icon to use use on the system tray UI.
-  #[cfg(target_os = "linux")]
-  pub system_tray_icon: Option<std::path::PathBuf>,
+  #[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<Vec<u8>>,
+  #[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<A>,
+    default_window_icon: Option<Vec<u8>>,
+    system_tray_icon: Option<Icon>,
+    package_info: crate::api::PackageInfo,
+  ) -> Self {
+    Self {
+      config,
+      assets,
+      default_window_icon,
+      system_tray_icon,
+      package_info,
+    }
+  }
 }
 
 // TODO: expand these docs