mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-19 04:08:45 +03:00
feat(core): set macOS app icon in development (#4385)
This commit is contained in:
parent
c7d13a1c60
commit
307c2ebfb6
7
.changes/dev-dock-icon.md
Normal file
7
.changes/dev-dock-icon.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"tauri-codegen": patch
|
||||
"tauri-macros": patch
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
Set the application icon in development mode on macOS.
|
@ -192,21 +192,23 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
// handle default window icons for Windows targets
|
||||
#[cfg(windows)]
|
||||
let default_window_icon = {
|
||||
let mut icon_path = find_icon(
|
||||
let icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
|i| i.ends_with(".ico"),
|
||||
"icons/icon.ico",
|
||||
);
|
||||
if !icon_path.exists() {
|
||||
icon_path = find_icon(
|
||||
if icon_path.exists() {
|
||||
ico_icon(&root, &out_dir, icon_path)?
|
||||
} else {
|
||||
let icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
png_icon(&root, &out_dir, icon_path)?
|
||||
}
|
||||
ico_icon(&root, &out_dir, icon_path)?
|
||||
};
|
||||
#[cfg(target_os = "linux")]
|
||||
let default_window_icon = {
|
||||
@ -221,6 +223,29 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
#[cfg(not(any(windows, target_os = "linux")))]
|
||||
let default_window_icon = quote!(None);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let app_icon = if dev {
|
||||
let mut icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
|i| i.ends_with(".icns"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
if !icon_path.exists() {
|
||||
icon_path = find_icon(
|
||||
&config,
|
||||
&config_parent,
|
||||
|i| i.ends_with(".png"),
|
||||
"icons/icon.png",
|
||||
);
|
||||
}
|
||||
raw_icon(&out_dir, icon_path)?
|
||||
} else {
|
||||
quote!(None)
|
||||
};
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let app_icon = quote!(None);
|
||||
|
||||
let package_name = if let Some(product_name) = &config.package.product_name {
|
||||
quote!(#product_name.to_string())
|
||||
} else {
|
||||
@ -353,6 +378,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
||||
#config,
|
||||
::std::sync::Arc::new(#assets),
|
||||
#default_window_icon,
|
||||
#app_icon,
|
||||
#system_tray_icon,
|
||||
#package_info,
|
||||
#info_plist,
|
||||
@ -403,6 +429,35 @@ fn ico_icon<P: AsRef<Path>>(
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn raw_icon<P: AsRef<Path>>(out_dir: &Path, path: P) -> Result<TokenStream, EmbeddedAssetsError> {
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
let path = path.as_ref();
|
||||
let bytes = std::fs::read(&path)
|
||||
.unwrap_or_else(|_| panic!("failed to read icon {}", path.display()))
|
||||
.to_vec();
|
||||
|
||||
let out_path = out_dir.join(path.file_name().unwrap());
|
||||
let mut out_file = File::create(&out_path).map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: out_path.clone(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
out_file
|
||||
.write_all(&bytes)
|
||||
.map_err(|error| EmbeddedAssetsError::AssetWrite {
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
})?;
|
||||
|
||||
let out_path = out_path.display().to_string();
|
||||
|
||||
let icon = quote!(Some(include_bytes!(#out_path).to_vec()));
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
fn png_icon<P: AsRef<Path>>(
|
||||
root: &TokenStream,
|
||||
out_dir: &Path,
|
||||
@ -445,7 +500,6 @@ fn png_icon<P: AsRef<Path>>(
|
||||
Ok(icon)
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
fn find_icon<F: Fn(&&String) -> bool>(
|
||||
config: &Config,
|
||||
config_parent: &Path,
|
||||
|
@ -1490,7 +1490,29 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
|
||||
label,
|
||||
event: event.into(),
|
||||
},
|
||||
RuntimeRunEvent::Ready => RunEvent::Ready,
|
||||
RuntimeRunEvent::Ready => {
|
||||
// set the app icon in development
|
||||
#[cfg(all(dev, target_os = "macos"))]
|
||||
unsafe {
|
||||
use cocoa::{
|
||||
appkit::NSImage,
|
||||
base::{id, nil},
|
||||
foundation::NSData,
|
||||
};
|
||||
use objc::*;
|
||||
if let Some(icon) = app_handle.manager.inner.app_icon.clone() {
|
||||
let ns_app: id = msg_send![class!(NSApplication), sharedApplication];
|
||||
let data = NSData::dataWithBytes_length_(
|
||||
nil,
|
||||
icon.as_ptr() as *const std::os::raw::c_void,
|
||||
icon.len() as u64,
|
||||
);
|
||||
let app_icon = NSImage::initWithData_(NSImage::alloc(nil), data);
|
||||
let _: () = msg_send![ns_app, setApplicationIconImage: app_icon];
|
||||
}
|
||||
}
|
||||
RunEvent::Ready
|
||||
}
|
||||
RuntimeRunEvent::Resumed => RunEvent::Resumed,
|
||||
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
|
||||
RuntimeRunEvent::UserEvent(t) => t.into(),
|
||||
|
@ -445,6 +445,7 @@ pub struct Context<A: Assets> {
|
||||
pub(crate) config: Config,
|
||||
pub(crate) assets: Arc<A>,
|
||||
pub(crate) default_window_icon: Option<Icon>,
|
||||
pub(crate) app_icon: Option<Vec<u8>>,
|
||||
pub(crate) system_tray_icon: Option<Icon>,
|
||||
pub(crate) package_info: PackageInfo,
|
||||
pub(crate) _info_plist: (),
|
||||
@ -458,6 +459,7 @@ impl<A: Assets> fmt::Debug for Context<A> {
|
||||
let mut d = f.debug_struct("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);
|
||||
@ -548,6 +550,7 @@ impl<A: Assets> Context<A> {
|
||||
config: Config,
|
||||
assets: Arc<A>,
|
||||
default_window_icon: Option<Icon>,
|
||||
app_icon: Option<Vec<u8>>,
|
||||
system_tray_icon: Option<Icon>,
|
||||
package_info: PackageInfo,
|
||||
info_plist: (),
|
||||
@ -558,6 +561,7 @@ impl<A: Assets> Context<A> {
|
||||
config,
|
||||
assets,
|
||||
default_window_icon,
|
||||
app_icon,
|
||||
system_tray_icon,
|
||||
package_info,
|
||||
_info_plist: info_plist,
|
||||
|
@ -206,6 +206,7 @@ pub struct InnerWindowManager<R: Runtime> {
|
||||
config: Arc<Config>,
|
||||
assets: Arc<dyn Assets>,
|
||||
default_window_icon: Option<Icon>,
|
||||
pub(crate) app_icon: Option<Vec<u8>>,
|
||||
|
||||
package_info: PackageInfo,
|
||||
/// The webview protocols protocols available to all windows.
|
||||
@ -231,6 +232,7 @@ impl<R: Runtime> fmt::Debug for InnerWindowManager<R> {
|
||||
.field("state", &self.state)
|
||||
.field("config", &self.config)
|
||||
.field("default_window_icon", &self.default_window_icon)
|
||||
.field("app_icon", &self.app_icon)
|
||||
.field("package_info", &self.package_info)
|
||||
.field("menu", &self.menu)
|
||||
.field("pattern", &self.pattern)
|
||||
@ -303,6 +305,7 @@ impl<R: Runtime> WindowManager<R> {
|
||||
config: Arc::new(context.config),
|
||||
assets: context.assets,
|
||||
default_window_icon: context.default_window_icon,
|
||||
app_icon: context.app_icon,
|
||||
package_info: context.package_info,
|
||||
pattern: context.pattern,
|
||||
uri_scheme_protocols,
|
||||
|
@ -67,6 +67,7 @@ pub fn mock_context<A: Assets>(assets: A) -> crate::Context<A> {
|
||||
},
|
||||
assets: Arc::new(assets),
|
||||
default_window_icon: None,
|
||||
app_icon: None,
|
||||
system_tray_icon: None,
|
||||
package_info: crate::PackageInfo {
|
||||
name: "test".into(),
|
||||
|
Loading…
Reference in New Issue
Block a user