8
8
"path/filepath"
9
9
"runtime"
10
10
"sync"
11
+ "time"
11
12
12
13
"github.com/getlantern/systray"
13
14
"github.com/skratchdot/open-golang/open"
@@ -159,7 +160,7 @@ func (s *TrayService) onReady() {
159
160
// 设置托盘图标
160
161
systray .SetIcon (iconData )
161
162
systray .SetTitle ("host 管理工具" )
162
- systray .SetTooltip ("host 管理工具 - 双击显示主窗口 " )
163
+ systray .SetTooltip ("host 管理工具" )
163
164
164
165
// 创建托盘菜单
165
166
mShow := systray .AddMenuItem ("显示主界面" , "显示主应用界面" )
@@ -174,63 +175,73 @@ func (s *TrayService) onReady() {
174
175
go s .handleMenuEvents (mShow , mRefreshRemote , mExit )
175
176
}
176
177
177
- // handleMenuEvents 处理菜单事件
178
+ // handleMenuEvents 处理菜单事件 - 优雅的统一事件处理器
178
179
func (s * TrayService ) handleMenuEvents (mShow , mRefreshRemote , mExit * systray.MenuItem ) {
179
180
defer func () {
180
181
if r := recover (); r != nil {
181
182
if s .ctx != nil {
182
183
wailsRuntime .LogError (s .ctx , fmt .Sprintf ("托盘菜单处理发生错误: %v" , r ))
183
184
}
185
+ // 出错后重新启动事件处理
186
+ time .Sleep (1 * time .Second )
187
+ if ! s .isRunning {
188
+ return
189
+ }
190
+ go s .handleMenuEvents (mShow , mRefreshRemote , mExit )
184
191
}
185
192
}()
186
193
187
- // 启动独立的goroutine处理每个菜单项
188
- go func () {
189
- for {
190
- select {
191
- case <- s .stopChan :
192
- return
193
- case <- mShow .ClickedCh :
194
- // 显示主窗口
194
+ // 简单防抖:记录上次处理时间
195
+ var lastProcessTime time.Time
196
+ debounceInterval := 500 * time .Millisecond
197
+
198
+ // 统一事件循环 - 只用一个goroutine处理所有事件
199
+ for {
200
+ select {
201
+ case <- s .stopChan :
202
+ return
203
+
204
+ case <- mShow .ClickedCh :
205
+ // 防抖检查
206
+ if time .Since (lastProcessTime ) < debounceInterval {
207
+ continue
208
+ }
209
+ lastProcessTime = time .Now ()
210
+
211
+ // 异步处理,避免阻塞事件循环
212
+ go func () {
195
213
if s .ctx != nil {
196
214
wailsRuntime .WindowShow (s .ctx )
197
215
wailsRuntime .WindowUnminimise (s .ctx )
198
216
wailsRuntime .WindowSetAlwaysOnTop (s .ctx , false )
199
217
wailsRuntime .WindowCenter (s .ctx )
200
218
}
219
+ }()
220
+
221
+ case <- mRefreshRemote .ClickedCh :
222
+ if time .Since (lastProcessTime ) < debounceInterval {
223
+ continue
201
224
}
202
- }
203
- }()
204
-
205
- go func () {
206
- for {
207
- select {
208
- case <- s .stopChan :
209
- return
210
- case <- mRefreshRemote .ClickedCh :
211
- // 更新远程源
225
+ lastProcessTime = time .Now ()
226
+
227
+ go func () {
212
228
if s .ctx != nil {
213
229
wailsRuntime .EventsEmit (s .ctx , "tray-refresh-remote" )
214
230
}
215
- }
216
- }
217
- }()
218
-
219
- go func () {
220
- for {
221
- select {
222
- case <- s .stopChan :
223
- return
224
- case <- mExit .ClickedCh :
225
- // 退出应用
231
+ }()
232
+
233
+ case <- mExit .ClickedCh :
234
+ // 退出无需防抖,立即处理
235
+ go func () {
226
236
if s .ctx != nil {
227
237
wailsRuntime .LogInfo (s .ctx , "用户从托盘退出应用" )
228
238
wailsRuntime .Quit (s .ctx )
229
239
}
230
240
systray .Quit ()
231
- }
241
+ }()
242
+ return
232
243
}
233
- }()
244
+ }
234
245
}
235
246
236
247
// OpenSystemHostsFile 打开系统 hosts 文件
0 commit comments