feat: 单实例锁与窗口恢复机制
- GUI 单实例锁: 新增 internal/instance 包,首实例监听专用端点, 第二实例发送 focus 信号后静默退出 (Unix: gui.sock, Win: 18924) - 守护进程弱锁修复: NewServer() 在 os.Remove 前先 net.Dial 探测, 有活进程时拒绝启动,避免静默抢占 socket 导致孤儿进程 - macOS .app 重开恢复: 通过 class_addMethod 给 GLFWApplicationDelegate 注册 applicationShouldHandleReopen:hasVisibleWindows: 回调, 绕过 GLFW 直接用 Cocoa makeKeyAndOrderFront: 显示窗口 - 三平台覆盖: macOS/Linux 用 unix socket, Windows 用 TCP 端口
This commit is contained in:
+9
-1
@@ -109,8 +109,16 @@ func NewServer() (*Server, error) {
|
||||
netType := paths.IPCNetwork()
|
||||
addr := paths.IPCAddress()
|
||||
|
||||
// Clean up stale unix socket file (not needed for TCP).
|
||||
// Guard against a second daemon instance on unix: probe the
|
||||
// socket before removing it. If the dial succeeds, another
|
||||
// daemon is alive and owns the socket - refuse to start so we
|
||||
// don't silently orphan it. Only remove the file when the dial
|
||||
// fails (stale socket from a crashed process).
|
||||
if netType == "unix" {
|
||||
if c, derr := net.Dial(netType, addr); derr == nil {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("daemon already running on %s", addr)
|
||||
}
|
||||
_ = os.Remove(addr)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user