fix(windows): 托盘图标不显示——tray_manager 原生 LoadImage 只认 .ico
用户 Windows 实测:日志"托盘已就绪"无报错、不在折叠区,但任务栏无图标。 源码级定位:tray_manager 0.5.3 Windows 原生端用 LoadImage(IMAGE_ICON, LR_LOADFROMFILE) 加载图标文件——该 Win32 API 只认 .ico,传入 png 返回 NULL → Shell_NotifyIcon 添加成功但图标为空 → 任务栏 不显示且全程无任何报错(mac 走 base64+NSImage 另一条路径所以正常)。 修复:Windows 托盘改用 assets/tray_icon_win.ico(16/24/32 三尺寸 PNG-in-ICO, gen_app_icons.dart 生成,python struct 校验目录项 offset 严格对齐;ico 随 flutter_assets 打包,Debug/Release/Inno 全形态生效);删除无效的 tray_icon_win.png;AppTray 按平台选路径。
This commit is contained in:
1 parent
1deb3125be
commit
527baf7ec5
5 files changed
+37
-4
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 719 B |
@@ -25,7 +25,7 @@ class AppTray with TrayListener, WindowListener {
|
||||
await windowManager.setPreventClose(true);
|
||||
|
||||
await trayManager.setIcon(
|
||||
Platform.isMacOS ? 'assets/tray_icon_mac.png' : 'assets/tray_icon_win.png',
|
||||
Platform.isMacOS ? 'assets/tray_icon_mac.png' : 'assets/tray_icon_win.ico',
|
||||
);
|
||||
await trayManager.setToolTip('资安信插件助手 · 饭卡打印(后台运行中)');
|
||||
await trayManager.setContextMenu(_menu);
|
||||
|
||||
+2
-1
@@ -71,9 +71,10 @@ flutter:
|
||||
uses-material-design: true
|
||||
|
||||
# 托盘图标(白底圆盘+logo,深浅菜单栏/任务栏均可见)与侧栏 logo
|
||||
# Windows 托盘必须用 .ico(tray_manager 原生 LoadImage 只认 ico,png 静默失败)
|
||||
assets:
|
||||
- assets/tray_icon_mac.png
|
||||
- assets/tray_icon_win.png
|
||||
- assets/tray_icon_win.ico
|
||||
- assets/logo.png
|
||||
# HiTi Mac 驱动安装包(不进 git:放 assets/drivers/*.dmg 后重新打包;缺失时向导降级为官网链接)
|
||||
- assets/drivers/
|
||||
|
||||
+34
-2
@@ -134,8 +134,40 @@ void main(List<String> args) {
|
||||
|
||||
Directory('assets').createSync(recursive: true);
|
||||
File('assets/tray_icon_mac.png').writeAsBytesSync(encodePng(trayIcon(64)));
|
||||
File('assets/tray_icon_win.png').writeAsBytesSync(encodePng(trayIcon(32)));
|
||||
print('written assets/tray_icon_mac.png / tray_icon_win.png');
|
||||
print('written assets/tray_icon_mac.png');
|
||||
// Windows 托盘必须用 .ico:tray_manager 的原生端 LoadImage(IMAGE_ICON) 只认
|
||||
// ico 文件(传 png 返回 NULL → 图标空占位、任务栏不显示且无任何报错)
|
||||
Uint8List buildIcoFrom(Image Function(int) generator, List<int> sizes) {
|
||||
final pngs = <int, Uint8List>{
|
||||
for (final s in sizes) s: Uint8List.fromList(encodePng(generator(s))),
|
||||
};
|
||||
final b = BytesBuilder();
|
||||
// ICONDIR:reserved=0, type=icon, count
|
||||
b.addByte(0); b.addByte(0); b.addByte(1); b.addByte(0);
|
||||
b.addByte(sizes.length); b.addByte(0);
|
||||
var offset = 6 + 16 * sizes.length;
|
||||
// 目录项全部在前
|
||||
for (final s in sizes) {
|
||||
final png = pngs[s]!;
|
||||
b.addByte(s); b.addByte(s); b.addByte(0); b.addByte(0);
|
||||
b.addByte(1); b.addByte(0); b.addByte(32); b.addByte(0);
|
||||
for (var i = 0; i < 4; i++) {
|
||||
b.addByte((png.length >> (8 * i)) & 0xff);
|
||||
}
|
||||
for (var i = 0; i < 4; i++) {
|
||||
b.addByte((offset >> (8 * i)) & 0xff);
|
||||
}
|
||||
offset += png.length;
|
||||
}
|
||||
// PNG 数据全部在后
|
||||
for (final s in sizes) {
|
||||
b.add(pngs[s]!);
|
||||
}
|
||||
return b.toBytes();
|
||||
}
|
||||
final trayIco = buildIcoFrom(trayIcon, [16, 24, 32]);
|
||||
File('assets/tray_icon_win.ico').writeAsBytesSync(trayIco);
|
||||
print('written assets/tray_icon_win.ico (${trayIco.length} bytes)');
|
||||
|
||||
// ---------- 原样 logo ----------
|
||||
File('assets/logo.png').writeAsBytesSync(encodePng(logo));
|
||||
|
||||
Reference in new issue
Block a user