t194 三修:右鍵選單——正解是「**少寫**一段」,不是再補一段
leo 實測:右鍵仍然沒有 quit 選單。
## 真兇:我把函式庫本來就會做對的事,換成一個更脆弱的版本
讀 systray_darwin.go 的 systray_on_rclick():
func systray_on_rclick() {
if onRClick != nil { onRClick(st) } else { C.show_menu() }
}
⇒ **沒註冊 SetOnRClick 時,函式庫自己就會把選單叫出來**;
而且 C 層的 show_menu 內部已經處理好整套:
create_menu() → [statusItem.button performClick:nil] → set_menu_nil()
我卻註冊了自己的 handler、還加 `if menu != nil` 防呆
⇒ 等於用一個判斷把「本來會動的預設行為」擋掉。
修:**刪掉 SetOnRClick 註冊**。左鍵仍自訂(要開視窗),右鍵交還函式庫。
## 判準(已寫進 mistakes)
用第三方函式庫時,**先讀它的預設行為再決定要不要覆寫**。
「多註冊一個 handler」看起來是加功能,實際上常是**關掉**原本正確的行為。
## 閘也跟著改
check-tray.sh 原本驗「SetOnRClick 有註冊且順序對」——**那是在守一個錯的寫法**。
改成反向:**出現 systray.SetOnRClick 就擋下**,並說明原因。
實跑 7 項全過;App 活著 pid 14081、crash 0。
This commit is contained in:
@@ -52,12 +52,17 @@ import sys
|
||||
s=open('main.go',encoding='utf-8').read()
|
||||
try:
|
||||
a=s.index('systray.AddMenuItem'); n=s.index('systray.SetMenuNil')
|
||||
c=s.index('systray.SetOnClick'); r=s.index('systray.SetOnRClick')
|
||||
c=s.index('systray.SetOnClick')
|
||||
except ValueError as e:
|
||||
print(f" ❌ 找不到必要呼叫:{e}"); sys.exit(1)
|
||||
if not (a < n < c and n < r):
|
||||
print(" ❌ 順序錯:必須 AddMenuItem → SetMenuNil → SetOnClick/SetOnRClick"); sys.exit(1)
|
||||
print(" ✅ 順序正確(建選單→清掉→註冊滑鼠事件)")
|
||||
if not (a < n < c):
|
||||
print(" ❌ 順序錯:必須 AddMenuItem → SetMenuNil → SetOnClick"); sys.exit(1)
|
||||
print(" ✅ 順序正確(建選單→清掉→註冊左鍵)")
|
||||
# 🔴 右鍵**不可以**註冊 handler:systray_on_rclick() 在沒註冊時會自己 show_menu(),
|
||||
# 註冊了反而要自己重做一遍(leo 實測「右鍵沒跳出 quit」就是這樣來的)。
|
||||
if 'systray.SetOnRClick' in s:
|
||||
print(" ❌ 註冊了 SetOnRClick ⇒ 蓋掉函式庫預設的『右鍵開選單』,右鍵會沒反應"); sys.exit(1)
|
||||
print(" ✅ 右鍵交給函式庫預設行為(不自己註冊)")
|
||||
PY
|
||||
|
||||
# ③ ShowWindow 要能叫回「已開但被蓋住」的視窗
|
||||
|
||||
+11
-8
@@ -98,18 +98,21 @@ func setupTray(app *App) {
|
||||
// 「該方法主動調用後 如果托盤菜單已創建則添加進去, **之後鼠標事件失效**」
|
||||
// ⇒ 只要用 AddMenuItem 建了選單,左右鍵 handler **全部失效**
|
||||
// ⇒ leo 實測「右鍵沒跳出 quit」「第一次能開之後就不再跳」。
|
||||
// 正解:SetMenuNil() 移除選單讓滑鼠事件生效,右鍵時**自己叫出選單**。
|
||||
// 正解:SetMenuNil() 移除選單讓滑鼠事件生效;右鍵則交給函式庫預設行為(見下)。
|
||||
quit := systray.AddMenuItem("結束 Arcrun", "停止同步並關閉")
|
||||
quit.Click(func() { app.Quit() })
|
||||
systray.SetMenuNil() // ← 沒有這行,下面兩個 handler 都不會被呼叫
|
||||
systray.SetMenuNil() // ← 沒有這行,SetOnClick 不會被呼叫
|
||||
|
||||
// 左鍵:立刻展開主視窗(leo:「點擊托盤的 icon 就立刻展開界面」)
|
||||
systray.SetOnClick(func(menu systray.IMenu) { app.ShowWindow() })
|
||||
// 右鍵:把選單叫出來(只有「結束 Arcrun」一項)
|
||||
systray.SetOnRClick(func(menu systray.IMenu) {
|
||||
if menu != nil {
|
||||
_ = menu.ShowMenu()
|
||||
}
|
||||
})
|
||||
|
||||
// 🔴 右鍵:**故意不註冊 handler**。
|
||||
// 看 systray_darwin.go 的 systray_on_rclick():
|
||||
// if onRClick != nil { onRClick(st) } else { C.show_menu() }
|
||||
// ⇒ **沒註冊時,函式庫自己就會把選單叫出來**(而且 show_menu 內部
|
||||
// 已經處理好 create_menu → performClick → set_menu_nil 整套)。
|
||||
// 我先前註冊了自己的 handler 並加 `if menu != nil` 防呆,
|
||||
// 反而把「函式庫本來就會做對的事」換成一個更脆弱的版本
|
||||
// ⇒ leo 實測「右鍵沒跳出 quit」。少寫這段才是正解。
|
||||
}, nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user