051c865085
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 其餘全投影
- 這次穿過機械閘的那道縫:缺「宣告版本 == 產物內嵌版本」的驗證
78 lines
3.0 KiB
Go
78 lines
3.0 KiB
Go
//go:build windows
|
||
|
||
package main
|
||
|
||
// tray_windows.go — Windows 系統匣(t196,2026-08-05)
|
||
//
|
||
// 為什麼 Windows 用 energye/systray 而 macOS 不用(wiki mistakes 有全文):
|
||
// macOS 上 systray 在 Wails 之下**根本不會建立托盤**——`setInternalLoop(true)` 只在
|
||
// `systray.Run()` 裡呼叫,走 `RunWithExternalLoop` 時 `registerSystray()` 第一行就 return;
|
||
// 而改用 `systray.Run()` 又會與 Wails 搶 macOS 主 loop(SIGTRAP)。
|
||
// ⇒ macOS 最後改走原生 `NSStatusItem`(tray_darwin.m)。
|
||
//
|
||
// **Windows 沒有這個限制**:托盤走 Win32 訊息迴圈(自己的 goroutine 就能跑),
|
||
// 不像 macOS 的 NSStatusItem 硬性要求主執行緒。所以這裡用 systray 是合適的,
|
||
// 不是「抄 macOS 失敗的做法」。
|
||
//
|
||
// 行為與 macOS 版**逐項對齊**(tray_darwin.go/.m):
|
||
// · 左鍵點 icon → 直接開視窗(不彈選單)
|
||
// · 右鍵 → 只有「結束 Arcrun」一項
|
||
// · 關視窗 → 隱藏不結束(daemon 常駐;在 app.go 的 OnBeforeClose 處理)
|
||
|
||
import (
|
||
_ "embed"
|
||
|
||
"github.com/energye/systray"
|
||
)
|
||
|
||
// trayApp 讓回呼找得到 App(與 tray_darwin.go 同名同用途;
|
||
// 該檔有 //go:build darwin,Windows 編譯時不存在,故這裡自帶一份)。
|
||
var trayApp *App
|
||
|
||
// Windows 系統匣要 .ico(PNG 會顯示成空白/方塊)。
|
||
//
|
||
// 🔴 2026-08-06:這裡以前 embed `build/windows/icon.ico`,而那顆是 `wails init` 留下的
|
||
// **Wails 預設「W」圖**(換 CIS logo 時只換了 appicon.png,沒人動它)
|
||
// ⇒ leo 封測看到視窗與托盤兩處都是「W」。
|
||
// 現在兩顆 .ico 都由 `gen-icons.py` 從 `build/appicon.png` 現場產生(build-win.sh 會跑),
|
||
// 這裡改用小尺寸階梯的 trayicon.ico——系統匣只吃 16/32,塞 256 的那顆是浪費。
|
||
//
|
||
//go:embed build/trayicon.ico
|
||
var trayIconICO []byte
|
||
|
||
// setupTray 建立系統匣圖示。
|
||
//
|
||
// 與 macOS 版的介面契約相同(main.go 只呼叫 setupTray(app)),
|
||
// 但這裡**不阻塞**:systray 自己開 goroutine 跑訊息迴圈,Wails 主迴圈不受影響。
|
||
func setupTray(app *App) {
|
||
trayApp = app
|
||
// RunWithExternalLoop 回傳 start/end;Windows 下 start 不阻塞。
|
||
trayStart, trayEnd = systray.RunWithExternalLoop(func() {
|
||
systray.SetIcon(trayIconICO)
|
||
systray.SetTitle("Arcrun")
|
||
systray.SetTooltip("Arcrun — 你的知識庫同步小幫手")
|
||
|
||
// 🔴 右鍵選單:**只有結束**(leo 08-05:「依照 google drive,托盤裡只剩下
|
||
// 按右鍵會結束,其他設定都在這個頁面」)。
|
||
quit := systray.AddMenuItem("結束 Arcrun", "結束 Arcrun(同步會停止)")
|
||
quit.Click(func() {
|
||
if trayApp != nil {
|
||
trayApp.Quit()
|
||
}
|
||
})
|
||
|
||
// 左鍵=直接開視窗,不彈選單(Google Drive 式)。
|
||
systray.SetOnClick(func(menu systray.IMenu) {
|
||
if trayApp != nil {
|
||
trayApp.ShowWindow()
|
||
}
|
||
})
|
||
// 右鍵才顯示選單。
|
||
systray.SetOnRClick(func(menu systray.IMenu) {
|
||
if menu != nil {
|
||
_ = menu.ShowMenu()
|
||
}
|
||
})
|
||
}, func() {})
|
||
}
|