Files
arcrun-collector/cmd/arcrun-app/gen-icons.py
T
Leo 051c865085 Windows 版 icon 換回 CIS chevron,並根治「換了 appicon 卻沒換 Windows」
leo 08-06 封測回報:托盤與視窗 icon 是「W」,不是 CIS 的 chevron。

真兇:build/windows/icon.ico 是 wails init 生成後從沒被動過的 Wails 預設圖。
換 CIS logo 那次只換了 build/appicon.png,Windows 這顆沒人碰;
tray_windows.go 又 embed 同一顆 ⇒ 視窗與托盤兩處都是 W。
macOS 走 trayicon.png(正確)⇒ 這個病在 Mac 上 100% 驗不出來。

改法不是「這次手動換一顆」,是讓它不可能再漂移:
- 新增 gen-icons.py:兩顆 .ico 一律由 appicon.png 現場產生;
  --check 模式比對「committed == 重新產生的」,可當機械閘。
- tray_windows.go 改 embed build/trayicon.ico(小尺寸階梯,系統匣只吃 16/32)。

已驗:重新產生後把 256/32 都渲成 PNG 目視確認為 CIS chevron;--check 通過。
未驗:Windows 真機(需重打包後由封測者確認)⇒ 狀態 ◐,不是 。

同時落帳(wiki status/mistakes):
- manifest 宣告 v0.18.5 但產物是 v0.18.4 的完整證據鏈
- 五個 Windows 真兇(檔:行)
- leo 兩問的設計定案:trigger=內容指紋(不另立、不用 tag/Actions)、
  changelog 單一真相源=CHANGELOG.md 其餘全投影
- 這次穿過機械閘的那道縫:缺「宣告版本 == 產物內嵌版本」的驗證
2026-08-06 12:09:53 +08:00

72 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""gen-icons.py — 從 build/appicon.png 產生 Windows 用的 .ico2026-08-06
🔴 為什麼要有這支:
leo 08-06 封測回報「托盤及視窗 icon 是『W』,不是 CIS 的 chevron 標誌(a>>)」。
真兇=`build/windows/icon.ico` 是 `wails init` 生成後**從沒被換過的 Wails 預設圖**;
換 CIS logo 那次只換了 `build/appicon.png`Windows 這顆沒人動。
而 `tray_windows.go` 又 embed 同一顆 ⇒ 視窗與托盤兩處都是 W。
根治不是「這次手動換一顆」——是**讓它不可能再漂移**:
icon.icotrayicon.ico 一律由 appicon.png 現場產生,
build-win.sh 每次都跑這支,check-cis.sh 驗「committed == 重新產生的」。
用法:
python3 gen-icons.py # 產生(覆寫)
python3 gen-icons.py --check # 只驗證,不寫檔;不一致回傳 1
"""
import hashlib
import io
import sys
from pathlib import Path
from PIL import Image
HERE = Path(__file__).resolve().parent
SRC = HERE / "build" / "appicon.png"
APP_ICO = HERE / "build" / "windows" / "icon.ico"
TRAY_ICO = HERE / "build" / "trayicon.ico"
# 視窗/工作列/檔案總管會用到的完整尺寸階梯。
APP_SIZES = [16, 24, 32, 48, 64, 128, 256]
# 系統匣只吃小尺寸(Windows 依 DPI 取 16 或 32)。
TRAY_SIZES = [16, 24, 32, 48]
def render(sizes):
"""把 appicon.png 縮成多尺寸,包成一顆 .ico。"""
if not SRC.exists():
sys.exit("❌ 找不到來源圖:%s" % SRC)
src = Image.open(SRC).convert("RGBA")
buf = io.BytesIO()
# Pillow 的 ICO 儲存會自己依 sizes 產生各層。
src.save(buf, format="ICO", sizes=[(s, s) for s in sizes])
return buf.getvalue()
def main():
check_only = "--check" in sys.argv
fail = 0
targets = ((APP_ICO, APP_SIZES, "視窗/工作列 icon"),
(TRAY_ICO, TRAY_SIZES, "系統匣 icon"))
for path, sizes, label in targets:
want = render(sizes)
have = path.read_bytes() if path.exists() else b""
if check_only:
if hashlib.sha256(want).digest() == hashlib.sha256(have).digest():
print(" ✅ %s%s)與 appicon.png 一致" % (label, path.name))
else:
print(" ❌ %s%s)與 appicon.png 不一致 "
"⇒ 跑 `python3 gen-icons.py` 重產" % (label, path.name))
fail = 1
else:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(want)
print(" ✅ 產生 %s%d bytes%d 種尺寸)"
% (path.relative_to(HERE), len(want), len(sizes)))
return fail
if __name__ == "__main__":
sys.exit(main())