feat: support ico format for tray icon (#911)

This commit is contained in:
MystiPanda 2024-04-22 20:43:15 +08:00 committed by GitHub
parent 2074da05c8
commit e014fdf3da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 79 additions and 25 deletions

13
src-tauri/Cargo.lock generated
View File

@ -2411,6 +2411,16 @@ dependencies = [
"cc",
]
[[package]]
name = "ico"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd"
dependencies = [
"byteorder",
"png",
]
[[package]]
name = "ico"
version = "0.3.0"
@ -5248,6 +5258,7 @@ dependencies = [
"gtk",
"heck 0.4.1",
"http 0.2.11",
"ico 0.2.0",
"ignore",
"indexmap 1.9.3",
"infer 0.9.0",
@ -5316,7 +5327,7 @@ checksum = "a1554c5857f65dbc377cefb6b97c8ac77b1cb2a90d30d3448114d5d6b48a77fc"
dependencies = [
"base64 0.21.7",
"brotli",
"ico",
"ico 0.3.0",
"json-patch",
"plist",
"png",

View File

@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
auto-launch = { git="https://github.com/zzzgydi/auto-launch", branch = "main" }
tauri = { version = "1.6", features = [ "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
tauri = { version = "1.6", features = [ "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
[target.'cfg(windows)'.dependencies]
runas = "=1.2.0"

View File

@ -299,9 +299,17 @@ pub fn copy_icon_file(path: String, name: String) -> CmdResult<String> {
if !icon_dir.exists() {
let _ = std::fs::create_dir_all(&icon_dir);
}
let dest_path = icon_dir.join(name);
let ext = match file_path.extension() {
Some(e) => e.to_string_lossy().to_string(),
None => "ico".to_string(),
};
let png_dest_path = icon_dir.join(format!("{name}.png"));
let ico_dest_path = icon_dir.join(format!("{name}.ico"));
let dest_path = icon_dir.join(format!("{name}.{ext}"));
if file_path.exists() {
std::fs::remove_file(png_dest_path).unwrap_or_default();
std::fs::remove_file(ico_dest_path).unwrap_or_default();
match std::fs::copy(file_path, &dest_path) {
Ok(_) => Ok(dest_path.to_string_lossy().to_string()),
Err(err) => Err(err.to_string()),

View File

@ -182,9 +182,13 @@ impl Tray {
#[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon-sys.png").to_vec();
if *sysproxy_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("sysproxy.png");
if path.exists() {
icon = std::fs::read(path).unwrap();
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("sysproxy.png");
let ico_path = icon_dir_path.join("sysproxy.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
@ -194,9 +198,13 @@ impl Tray {
#[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon.png").to_vec();
if *common_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("common.png");
if path.exists() {
icon = std::fs::read(path).unwrap();
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("common.png");
let ico_path = icon_dir_path.join("common.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
@ -208,9 +216,13 @@ impl Tray {
#[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon-tun.png").to_vec();
if *tun_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("tun.png");
if path.exists() {
icon = std::fs::read(path).unwrap();
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("tun.png");
let ico_path = icon_dir_path.join("tun.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
indication_icon = icon

View File

@ -66,6 +66,10 @@
},
"path": {
"all": true
},
"fs": {
"exists": true,
"scope": ["$APPDATA/**", "$RESOURCE/../**"]
}
},
"windows": [],

View File

@ -9,6 +9,7 @@ import { open as openDialog } from "@tauri-apps/api/dialog";
import { convertFileSrc } from "@tauri-apps/api/tauri";
import { copyIconFile, getAppDir } from "@/services/cmds";
import { join } from "@tauri-apps/api/path";
import { exists } from "@tauri-apps/api/fs";
export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation();
@ -26,12 +27,27 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
async function initIconPath() {
const appDir = await getAppDir();
const icon_dir = await join(appDir, "icons");
const common_icon = await join(icon_dir, "common.png");
const sysproxy_icon = await join(icon_dir, "sysproxy.png");
const tun_icon = await join(icon_dir, "tun.png");
setCommonIcon(common_icon);
setSysproxyIcon(sysproxy_icon);
setTunIcon(tun_icon);
const common_icon_png = await join(icon_dir, "common.png");
const common_icon_ico = await join(icon_dir, "common.ico");
const sysproxy_icon_png = await join(icon_dir, "sysproxy.png");
const sysproxy_icon_ico = await join(icon_dir, "sysproxy.ico");
const tun_icon_png = await join(icon_dir, "tun.png");
const tun_icon_ico = await join(icon_dir, "tun.ico");
if (await exists(common_icon_ico)) {
setCommonIcon(common_icon_ico);
} else {
setCommonIcon(common_icon_png);
}
if (await exists(sysproxy_icon_ico)) {
setSysproxyIcon(sysproxy_icon_ico);
} else {
setSysproxyIcon(sysproxy_icon_png);
}
if (await exists(tun_icon_ico)) {
setTunIcon(tun_icon_ico);
} else {
setTunIcon(tun_icon_png);
}
}
useImperativeHandle(ref, () => ({
@ -140,12 +156,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [
{
name: "Tray Icon Image",
extensions: ["png"],
extensions: ["png", "ico"],
},
],
});
if (path?.length) {
await copyIconFile(`${path}`, "common.png");
await copyIconFile(`${path}`, "common");
await initIconPath();
onChangeData({ common_tray_icon: true });
patchVerge({ common_tray_icon: true });
}
@ -184,12 +201,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [
{
name: "Tray Icon Image",
extensions: ["png"],
extensions: ["png", "ico"],
},
],
});
if (path?.length) {
await copyIconFile(`${path}`, "sysproxy.png");
await copyIconFile(`${path}`, "sysproxy");
await initIconPath();
onChangeData({ sysproxy_tray_icon: true });
patchVerge({ sysproxy_tray_icon: true });
}
@ -226,12 +244,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [
{
name: "Tray Icon Image",
extensions: ["png"],
extensions: ["png", "ico"],
},
],
});
if (path?.length) {
await copyIconFile(`${path}`, "tun.png");
await copyIconFile(`${path}`, "tun");
await initIconPath();
onChangeData({ tun_tray_icon: true });
patchVerge({ tun_tray_icon: true });
}

View File

@ -223,7 +223,7 @@ export async function exitApp() {
export async function copyIconFile(
path: string,
name: "common.png" | "sysproxy.png" | "tun.png"
name: "common" | "sysproxy" | "tun"
) {
return invoke<void>("copy_icon_file", { path, name });
}