Files
arcrun-collector/cmd/arcrun-app/tray_windows.go
T
Leo d80e9e1357 t196:Windows 版重編(Wails)+MSIX 打包——在 Mac 上交叉編譯,不需 Windows 機器
leo 08-05:「Windows 版一定要重編,因為我只有 Mac,我需要人家測試,
要做到最完善不要給人家找麻煩,然後當測試者給我截圖安裝成功就要提交 ms store」

## 缺口
Windows 打包腳本全在**舊的 arcrun-tray(fyne 版)**,
新的 arcrun-app(Wails,t193/t194 整批 UI 重做)**完全沒有 Windows 產線**
⇒ Windows 封測者只能拿到 v0.15.7 的舊 fyne 版。

## 新增
· tray_windows.go — Windows 系統匣(energye/systray)
  行為與 macOS 版逐項對齊:左鍵開視窗/右鍵只有「結束 Arcrun」/關窗不結束。
  ⚠️ 為什麼 Windows 能用 systray 而 macOS 不能(wiki 有全文):
     macOS 上它在 Wails 之下根本不建托盤(setInternalLoop 只在 systray.Run() 呼叫),
     改用 systray.Run() 又搶 macOS 主 loop ⇒ macOS 最後走原生 NSStatusItem。
     **Windows 走 Win32 訊息迴圈,沒有主執行緒限制**,所以這裡用 systray 是對的,
     不是抄 macOS 失敗的做法。
  trayApp 與 ICO 都在本檔自帶(tray_darwin.go 有 //go:build darwin,Windows 看不到)。
· build-win.sh  — 交叉編譯 zip(CGO_ENABLED=1 + mingw-w64,Wails Windows 要 WebView2 綁定)
  **同綑 collector.exe**:daemon 本體是 collector direct,沒同綑=裝了不會同步
  (t194 在 Mac 版就漏過一次)。supervise.go 的 collectorBinPath() 已處理 .exe 副檔名。
· build-msix.sh — MS Store 用的 msix(沿用 makemsix,Mac 上就打得出來)
  與舊 fyne 版差別:**Wails 是兩個 exe**,兩個都要進 msix root。
  Identity 三值走環境變數(要與 Partner Center 完全一致),預設佔位並印警告。

## 驗
· Windows zip:兩個檔都是正牌 PE(MZ 標頭)/Arcrun.exe 11.4MB+collector.exe 16.1MB
· 退避修復確實編進 Windows 版(不剝符號重編一份,grep 到 MarkFailed/ShouldRetry/
  retrySkipReason 各 2 處;出貨版用 -s -w 剝符號故查不到,屬預期)
· MSIX:16 檔、含 AppxBlockMap;zip 回讀兩個 exe 的 sha256 與原檔**逐一相符**;
  manifest Executable="Arcrun.exe"、Version=0.18.4.0
· **macOS 版不受影響**:編譯通過、三支機械閘全過

## 兩個踩到的坑(已修)
· zip 用相對路徑在 cd 後失效(zip I/O error,fallback 湊巧成功但不可靠)⇒ 改絕對路徑
· 全形括號緊接變數會被當成變數名(腳本自己的註解就警告過)⇒ 改 ${VAR}

## 殘項
· Identity 仍是 PLACEHOLDER ⇒ **這顆 msix 還不能送 Store**,等 leo 給 Partner Center 三值
· 未在真 Windows 上跑過(誠實界定:只證明編得出來,不證明跑起來對)
2026-08-05 15:50:57 +08:00

73 lines
2.7 KiB
Go
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.
//go:build windows
package main
// tray_windows.go — Windows 系統匣(t1962026-08-05
//
// 為什麼 Windows 用 energye/systray 而 macOS 不用(wiki mistakes 有全文):
// macOS 上 systray 在 Wails 之下**根本不會建立托盤**——`setInternalLoop(true)` 只在
// `systray.Run()` 裡呼叫,走 `RunWithExternalLoop` 時 `registerSystray()` 第一行就 return
// 而改用 `systray.Run()` 又會與 Wails 搶 macOS 主 loopSIGTRAP)。
// ⇒ 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 darwinWindows 編譯時不存在,故這裡自帶一份)。
var trayApp *App
// Windows 系統匣要 .ico(PNG 會顯示成空白/方塊)。
// build/windows/icon.ico 是 Wails 產生 exe 圖示用的同一顆,一併拿來當托盤圖。
//
//go:embed build/windows/icon.ico
var trayIconICO []byte
// setupTray 建立系統匣圖示。
//
// 與 macOS 版的介面契約相同(main.go 只呼叫 setupTray(app)),
// 但這裡**不阻塞**systray 自己開 goroutine 跑訊息迴圈,Wails 主迴圈不受影響。
func setupTray(app *App) {
trayApp = app
// RunWithExternalLoop 回傳 start/endWindows 下 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() {})
}