t194:托盤收成 Google Drive 式(點 icon 開視窗/右鍵只有結束)+同綑 collector

leo 2026-08-05:「依照 google drive,托盤裡只剩下按右鍵會結束,
其他設定都在這個頁面,點擊托盤的 icon 就立刻展開界面」

## 托盤
Wails v2 沒有內建托盤 ⇒ 用 energye/systray(Wails 相容分支,支援左鍵事件)。
- 左鍵:直接展開主視窗,**不彈選單**
- 右鍵:只有一項「結束 Arcrun」
- 設定全部留在視窗裡,托盤不再是第二套 UI
  (fyne 版把設定塞下拉選單,leo 早說過「不可能統統塞在下拉選單」)
- 關窗=隱藏不結束(daemon 常駐;按 × 就停止同步不符預期)
- Dock 不出現 icon:Wails v2.13 的 mac.ActivationPolicy 還沒開放(原始碼是註解掉的)
  ⇒ 改走 Info.plist 的 LSUIElement,與 fyne 版同一個做法

## 🔴 順手抓到自己的大漏:這個 App 根本沒有啟動 collector
daemon 的**本體**是 `collector direct`(監看/萃卡/上傳),Wails 版我一路沒接
⇒ 照這樣出貨會是「裝了也不會同步」的空殼。
修:新增 supervise.go,**複用既有 supervisor 套件**(重起退避/狀態機/
    t191 的 phase:start/done ⇒「同步中…」),不複製一份(複製=會漂移)。
    go.mod 用 replace 指回 collector 主模組。
    加/刪資料夾、改 AI 設定後都會 restartWatch(),設定立刻生效。

## 打包
新增 build-mac.sh:編 collector → wails build → **同綑進 .app** → ad-hoc 重簽。
沒同綑就等於沒有 daemon。

實測(v0.18.0):collector 同綑 15M /LSUIElement=true /版本注入 /已簽 
兩支機械閘全過。
⚠️ 未驗:托盤左右鍵的實際行為要真機點(我開不了視窗)。
This commit is contained in:
2026-08-05 00:31:52 +08:00
parent 5a48abb784
commit 549834f343
9 changed files with 191 additions and 28 deletions
+48 -12
View File
@@ -1,39 +1,75 @@
package main
import (
"context"
"embed"
"github.com/energye/systray"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
)
//go:embed all:frontend/dist
var assets embed.FS
//go:embed build/trayicon.png
var trayIcon []byte
type wailsCtx = context.Context
// 版本號由 build 時 -ldflags 注入(同 arcrun-tray 的規矩)。
var version = "dev"
func main() {
// Create an instance of the app structure
app := NewApp()
// Create application with options
err := wails.Run(&options.App{
Title: "arcrun-app",
Width: 1024,
Height: 768,
AssetServer: &assetserver.Options{
Assets: assets,
Title: "Arcrun",
Width: 1000, Height: 700,
MinWidth: 820, MinHeight: 560,
AssetServer: &assetserver.Options{Assets: assets},
OnStartup: func(ctx wailsCtx) {
app.startup(ctx)
startSupervisor() // 🔴 daemon 本體:不啟動就不會同步
setupTray(app)
},
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
OnStartup: app.startup,
Bind: []interface{}{
app,
// 🔴 daemon 是常駐程式:關窗只是收起來,**不能真的結束**
// (結束=停止看守資料夾,使用者不會預期按 × 就不再同步)。
OnBeforeClose: func(ctx wailsCtx) bool {
wruntime.WindowHide(ctx)
return true // true=攔下關閉
},
HideWindowOnClose: true,
// Dock 不出現 iconWails v2.13 的 mac.ActivationPolicy 還沒開放(原始碼裡是註解掉的),
// 改走 Info.plist 的 LSUIElement(與 fyne 版同一個做法,見 build/darwin/Info.plist)。
Bind: []interface{}{app},
})
if err != nil {
println("Error:", err.Error())
}
}
// setupTray 建立選單列 icon。
//
// 🔴 leo 2026-08-05:「依照 google drive,托盤裡**只剩下按右鍵會結束**,
// 其他設定都在這個頁面,**點擊托盤的 icon 就立刻展開界面**」
//
// ⇒ 左鍵=直接開視窗(不彈選單);右鍵=只有一項「結束 Arcrun」。
// 所有設定都在視窗裡,托盤不再是第二套 UI(fyne 版把設定塞在下拉選單,
// leo:「daemon 設定項越來越多,不可能統統塞在下拉選單」)。
func setupTray(app *App) {
go systray.Run(func() {
systray.SetTemplateIcon(trayIcon, trayIcon)
systray.SetTooltip("Arcrun — 你的知識庫同步小幫手")
// 左鍵:立刻展開主視窗
systray.SetOnClick(func(menu systray.IMenu) { app.ShowWindow() })
// 右鍵:只有「結束」一項
quit := systray.AddMenuItem("結束 Arcrun", "停止同步並關閉")
quit.Click(func() { app.Quit() })
systray.SetOnRClick(func(menu systray.IMenu) { _ = menu.ShowMenu() })
}, nil)
}