Skip to content

Commit 7207cb7

Browse files
committed
feat: auto exit evs when idle
1 parent a5a330d commit 7207cb7

2 files changed

Lines changed: 48 additions & 46 deletions

File tree

core/main.go

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,39 @@ import (
3030

3131
var configPath = "config.yaml" // 全局可用
3232
var appStatus = "未启动"
33-
var currentAppPid int
3433
var extraArgs []string
3534
var lastFoundArgs []string // 仅记录 FindProcessByPath 找到的参数(不含exe路径)
35+
var currentAppPid int
36+
37+
var (
38+
idleTimer *time.Timer
39+
idleTimerC <-chan time.Time
40+
)
41+
42+
func setCurrentAppPid(pid int) {
43+
currentAppPid = pid
44+
if pid == 0 {
45+
if idleTimer == nil {
46+
idleTimer = time.NewTimer(2 * time.Minute)
47+
idleTimerC = idleTimer.C
48+
go func() {
49+
<-idleTimerC
50+
if currentAppPid == 0 {
51+
fmt.Println("[evs] 2分钟无应用运行,自动退出")
52+
os.Exit(0)
53+
}
54+
}()
55+
}
56+
} else {
57+
if idleTimer != nil {
58+
if !idleTimer.Stop() {
59+
<-idleTimer.C // drain
60+
}
61+
idleTimer = nil
62+
idleTimerC = nil
63+
}
64+
}
65+
}
3666

3767
func internalGetConfig() (*internal.Config, error) {
3868
cfg := internal.GetConfig()
@@ -119,10 +149,10 @@ func internalKillCurrentApp() error {
119149
err := internal.KillProcessTreeAndWait(currentAppPid)
120150
if err == nil {
121151
appStatus = "已终止 (PID=" + fmt.Sprint(currentAppPid) + ")"
152+
setCurrentAppPid(0)
122153
} else {
123154
appStatus = "终止失败 (PID=" + fmt.Sprint(currentAppPid) + ")"
124155
}
125-
currentAppPid = 0
126156
return err
127157
}
128158

@@ -160,24 +190,24 @@ func runAppProxy(args []string) {
160190
switch status {
161191
case "running":
162192
appStatus = fmt.Sprintf("运行中 (PID=%d)", pid)
163-
currentAppPid = pid
193+
setCurrentAppPid(pid)
164194
fmt.Printf("已启动应用: %s (PID=%d)\n", app.Path, pid)
165195
case "exited":
166196
appStatus = fmt.Sprintf("已退出 (PID=%d)", pid)
167197
fmt.Println("应用已正常退出")
168-
currentAppPid = 0
198+
setCurrentAppPid(0)
169199
case "exit_failed":
170200
appStatus = fmt.Sprintf("异常退出 (PID=%d)", pid)
171201
fmt.Printf("应用异常退出,返回码非0: %v\n", exitErr)
172-
currentAppPid = 0
202+
setCurrentAppPid(0)
173203
case "killed":
174204
appStatus = fmt.Sprintf("被终止 (PID=%d)", pid)
175205
fmt.Printf("应用被信号终止: %v\n", exitErr)
176-
currentAppPid = 0
206+
setCurrentAppPid(0)
177207
case "crashed":
178208
appStatus = fmt.Sprintf("已崩溃 (PID=%d)", pid)
179209
fmt.Printf("应用崩溃: %v\n", exitErr)
180-
currentAppPid = 0
210+
setCurrentAppPid(0)
181211
case "start_failed":
182212
appStatus = "启动失败"
183213
fmt.Printf("启动应用失败: %v\n", exitErr)
@@ -299,7 +329,7 @@ func handleConsoleConn(conn net.Conn, configPath string) {
299329
case "exit":
300330
if currentAppPid != 0 {
301331
_ = internalKillCurrentApp()
302-
currentAppPid = 0
332+
setCurrentAppPid(0)
303333
}
304334
conn.Write([]byte("OK\n"))
305335
time.Sleep(50 * time.Millisecond)
@@ -358,14 +388,14 @@ func main() {
358388
lastFoundArgs = nil
359389
}
360390
fmt.Printf("[DEBUG] lastFoundArgs 赋值后: %v\n", lastFoundArgs)
361-
currentAppPid = pid
391+
setCurrentAppPid(pid)
362392
}
363393

364394
if shouldStart {
365395
go runAppProxy(nil)
366396
}
367397

368-
// 启动 socket 服务
398+
// 启动 soc
369399
startConsoleServer(configPath)
370400
}
371401
}

internal/ui.go

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package internal
22

33
import (
4-
"fmt"
5-
"os"
64
"time"
75

86
"github.com/getlantern/systray"
@@ -68,39 +66,18 @@ func CreateMenuFromConfig(cfg MenuItemData) *MenuEntry {
6866
}
6967

7068
// 递归刷新所有菜单项的 OnRefresh
71-
func RefreshAllMenuItems() {
72-
for _, entry := range RootMenuEntries {
73-
refreshEntry(entry)
74-
}
75-
}
76-
77-
func refreshEntry(entry *MenuEntry) {
69+
func internalRefreshEntry(entry *MenuEntry) {
7870
if entry.Config.OnRefresh != nil {
7971
entry.Config.OnRefresh(entry.Item)
8072
}
8173
for _, sub := range entry.Subs {
82-
refreshEntry(sub)
74+
internalRefreshEntry(sub)
8375
}
8476
}
8577

86-
// 子菜单递归辅助
87-
func CreateMenuFromConfigRecursive(parent *systray.MenuItem, data MenuItemData) {
88-
for _, sub := range data.SubMenus {
89-
subItem := parent.AddSubMenuItem(sub.Title, sub.Tooltip)
90-
if sub.OnClick != nil {
91-
go func(s *systray.MenuItem, handler func(*systray.MenuItem)) {
92-
for {
93-
<-s.ClickedCh
94-
handler(s)
95-
}
96-
}(subItem, sub.OnClick)
97-
}
98-
if len(sub.SubMenus) > 0 {
99-
CreateMenuFromConfigRecursive(subItem, sub)
100-
}
101-
if sub.Separator {
102-
systray.AddSeparator()
103-
}
78+
func RefreshAllMenuItems() {
79+
for _, entry := range RootMenuEntries {
80+
internalRefreshEntry(entry)
10481
}
10582
}
10683

@@ -114,9 +91,9 @@ func StartMenuRefresher() {
11491
for _, f := range menuRefreshers {
11592
f()
11693
}
117-
// 新增:每秒统一刷新所有菜单项
118-
RefreshAllMenuItems()
119-
time.Sleep(time.Second)
94+
95+
RefreshAllMenuItems() // 统一刷新所有菜单项
96+
time.Sleep(time.Second * 2)
12097
}
12198
}()
12299
}
@@ -128,8 +105,3 @@ func UpdateTrayTitle(current string) {
128105
defer func() { _ = recover() }()
129106
// systray.SetTooltip("当前应用: " + current) // 避免 Windows 报错
130107
}
131-
132-
// 显示错误信息
133-
func ShowError(msg string) {
134-
fmt.Fprintf(os.Stderr, "[错误] %s\n", msg)
135-
}

0 commit comments

Comments
 (0)