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
|
// handle default window icons for Windows targets
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let default_window_icon = {
|
let default_window_icon = {
|
||||||
let mut icon_path = find_icon(
|
let icon_path = find_icon(
|
||||||
&config,
|
&config,
|
||||||
&config_parent,
|
&config_parent,
|
||||||
|i| i.ends_with(".ico"),
|
|i| i.ends_with(".ico"),
|
||||||
"icons/icon.ico",
|
"icons/icon.ico",
|
||||||
);
|
);
|
||||||
if !icon_path.exists() {
|
if icon_path.exists() {
|
||||||
icon_path = find_icon(
|
ico_icon(&root, &out_dir, icon_path)?
|
||||||
|
} else {
|
||||||
|
let icon_path = find_icon(
|
||||||
&config,
|
&config,
|
||||||
&config_parent,
|
&config_parent,
|
||||||
|i| i.ends_with(".png"),
|
|i| i.ends_with(".png"),
|
||||||
"icons/icon.png",
|
"icons/icon.png",
|
||||||
);
|
);
|
||||||
|
png_icon(&root, &out_dir, icon_path)?
|
||||||
}
|
}
|
||||||
ico_icon(&root, &out_dir, icon_path)?
|
|
||||||
};
|
};
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
let default_window_icon = {
|
let default_window_icon = {
|
||||||
@ -221,6 +223,29 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
|||||||
#[cfg(not(any(windows, target_os = "linux")))]
|
#[cfg(not(any(windows, target_os = "linux")))]
|
||||||
let default_window_icon = quote!(None);
|
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 {
|
let package_name = if let Some(product_name) = &config.package.product_name {
|
||||||
quote!(#product_name.to_string())
|
quote!(#product_name.to_string())
|
||||||
} else {
|
} else {
|
||||||
@ -353,6 +378,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
|
|||||||
#config,
|
#config,
|
||||||
::std::sync::Arc::new(#assets),
|
::std::sync::Arc::new(#assets),
|
||||||
#default_window_icon,
|
#default_window_icon,
|
||||||
|
#app_icon,
|
||||||
#system_tray_icon,
|
#system_tray_icon,
|
||||||
#package_info,
|
#package_info,
|
||||||
#info_plist,
|
#info_plist,
|
||||||
@ -403,6 +429,35 @@ fn ico_icon<P: AsRef<Path>>(
|
|||||||
Ok(icon)
|
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>>(
|
fn png_icon<P: AsRef<Path>>(
|
||||||
root: &TokenStream,
|
root: &TokenStream,
|
||||||
out_dir: &Path,
|
out_dir: &Path,
|
||||||
@ -445,7 +500,6 @@ fn png_icon<P: AsRef<Path>>(
|
|||||||
Ok(icon)
|
Ok(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(windows, target_os = "linux"))]
|
|
||||||
fn find_icon<F: Fn(&&String) -> bool>(
|
fn find_icon<F: Fn(&&String) -> bool>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
config_parent: &Path,
|
config_parent: &Path,
|
||||||
|
@ -1490,7 +1490,29 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
|
|||||||
label,
|
label,
|
||||||
event: event.into(),
|
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::Resumed => RunEvent::Resumed,
|
||||||
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
|
RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,
|
||||||
RuntimeRunEvent::UserEvent(t) => t.into(),
|
RuntimeRunEvent::UserEvent(t) => t.into(),
|
||||||
|
@ -445,6 +445,7 @@ pub struct Context<A: Assets> {
|
|||||||
pub(crate) config: Config,
|
pub(crate) config: Config,
|
||||||
pub(crate) assets: Arc<A>,
|
pub(crate) assets: Arc<A>,
|
||||||
pub(crate) default_window_icon: Option<Icon>,
|
pub(crate) default_window_icon: Option<Icon>,
|
||||||
|
pub(crate) app_icon: Option<Vec<u8>>,
|
||||||
pub(crate) system_tray_icon: Option<Icon>,
|
pub(crate) system_tray_icon: Option<Icon>,
|
||||||
pub(crate) package_info: PackageInfo,
|
pub(crate) package_info: PackageInfo,
|
||||||
pub(crate) _info_plist: (),
|
pub(crate) _info_plist: (),
|
||||||
@ -458,6 +459,7 @@ impl<A: Assets> fmt::Debug for Context<A> {
|
|||||||
let mut d = f.debug_struct("Context");
|
let mut d = f.debug_struct("Context");
|
||||||
d.field("config", &self.config)
|
d.field("config", &self.config)
|
||||||
.field("default_window_icon", &self.default_window_icon)
|
.field("default_window_icon", &self.default_window_icon)
|
||||||
|
.field("app_icon", &self.app_icon)
|
||||||
.field("system_tray_icon", &self.system_tray_icon)
|
.field("system_tray_icon", &self.system_tray_icon)
|
||||||
.field("package_info", &self.package_info)
|
.field("package_info", &self.package_info)
|
||||||
.field("pattern", &self.pattern);
|
.field("pattern", &self.pattern);
|
||||||
@ -548,6 +550,7 @@ impl<A: Assets> Context<A> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
assets: Arc<A>,
|
assets: Arc<A>,
|
||||||
default_window_icon: Option<Icon>,
|
default_window_icon: Option<Icon>,
|
||||||
|
app_icon: Option<Vec<u8>>,
|
||||||
system_tray_icon: Option<Icon>,
|
system_tray_icon: Option<Icon>,
|
||||||
package_info: PackageInfo,
|
package_info: PackageInfo,
|
||||||
info_plist: (),
|
info_plist: (),
|
||||||
@ -558,6 +561,7 @@ impl<A: Assets> Context<A> {
|
|||||||
config,
|
config,
|
||||||
assets,
|
assets,
|
||||||
default_window_icon,
|
default_window_icon,
|
||||||
|
app_icon,
|
||||||
system_tray_icon,
|
system_tray_icon,
|
||||||
package_info,
|
package_info,
|
||||||
_info_plist: info_plist,
|
_info_plist: info_plist,
|
||||||
|
@ -206,6 +206,7 @@ pub struct InnerWindowManager<R: Runtime> {
|
|||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
assets: Arc<dyn Assets>,
|
assets: Arc<dyn Assets>,
|
||||||
default_window_icon: Option<Icon>,
|
default_window_icon: Option<Icon>,
|
||||||
|
pub(crate) app_icon: Option<Vec<u8>>,
|
||||||
|
|
||||||
package_info: PackageInfo,
|
package_info: PackageInfo,
|
||||||
/// The webview protocols protocols available to all windows.
|
/// 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("state", &self.state)
|
||||||
.field("config", &self.config)
|
.field("config", &self.config)
|
||||||
.field("default_window_icon", &self.default_window_icon)
|
.field("default_window_icon", &self.default_window_icon)
|
||||||
|
.field("app_icon", &self.app_icon)
|
||||||
.field("package_info", &self.package_info)
|
.field("package_info", &self.package_info)
|
||||||
.field("menu", &self.menu)
|
.field("menu", &self.menu)
|
||||||
.field("pattern", &self.pattern)
|
.field("pattern", &self.pattern)
|
||||||
@ -303,6 +305,7 @@ impl<R: Runtime> WindowManager<R> {
|
|||||||
config: Arc::new(context.config),
|
config: Arc::new(context.config),
|
||||||
assets: context.assets,
|
assets: context.assets,
|
||||||
default_window_icon: context.default_window_icon,
|
default_window_icon: context.default_window_icon,
|
||||||
|
app_icon: context.app_icon,
|
||||||
package_info: context.package_info,
|
package_info: context.package_info,
|
||||||
pattern: context.pattern,
|
pattern: context.pattern,
|
||||||
uri_scheme_protocols,
|
uri_scheme_protocols,
|
||||||
|
@ -67,6 +67,7 @@ pub fn mock_context<A: Assets>(assets: A) -> crate::Context<A> {
|
|||||||
},
|
},
|
||||||
assets: Arc::new(assets),
|
assets: Arc::new(assets),
|
||||||
default_window_icon: None,
|
default_window_icon: None,
|
||||||
|
app_icon: None,
|
||||||
system_tray_icon: None,
|
system_tray_icon: None,
|
||||||
package_info: crate::PackageInfo {
|
package_info: crate::PackageInfo {
|
||||||
name: "test".into(),
|
name: "test".into(),
|
||||||
|
Loading…
Reference in New Issue
Block a user