Files
lmvpn_client/internal/ui/dock_darwin.go
T
kevin 15af9ef72c
Release / build-macos (push) Canceled after 0s
Release / build-windows (push) Canceled after 0s
Release / release (push) Canceled after 0s
fix: 移除showAndActivate避免误显示SystrayMonitor窗口
回退绕过GLFW遍历所有NSWindow的失败方案,恢复使用activateApp()+
showDockIcon()+window.Show()。保留真正生效的修复:正确selector
applicationShouldHandleReopen:hasVisibleWindows: + SetOnStarted延迟注册
2026-07-09 00:49:53 +08:00

62 lines
2.3 KiB
Go

//go:build darwin
package ui
/*
#cgo LDFLAGS: -framework Cocoa
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
// Forward declaration: Go callback (defined via //export in
// dock_callback_darwin.go). Called when the user re-opens the .app
// bundle while the process is still running (e.g. after closing the
// window to tray).
extern void cmAppBecameActive(void);
// appShouldHandleReopen is the IMP added to GLFWApplicationDelegate
// for the applicationShouldHandleReopen:hasVisibleWindows: selector.
// This is the delegate method macOS calls when the user re-opens an
// already-running .app bundle. We return YES so macOS proceeds with
// its default activation, and invoke the Go callback to show the
// hidden window.
static BOOL appShouldHandleReopen(id self, SEL cmd, id sender, BOOL flag) {
cmAppBecameActive();
return YES;
}
static void setDockIconVisible(int visible) {
Class cls = objc_getClass("NSApplication");
id app = ((id (*)(Class, SEL))objc_msgSend)(cls, sel_getUid("sharedApplication"));
((void (*)(id, SEL, long))objc_msgSend)(app, sel_getUid("setActivationPolicy:"), visible ? 0 : 1);
}
static void cmActivateApp(void) {
Class cls = objc_getClass("NSApplication");
id app = ((id (*)(Class, SEL))objc_msgSend)(cls, sel_getUid("sharedApplication"));
((void (*)(id, SEL, BOOL))objc_msgSend)(app, sel_getUid("activateIgnoringOtherApps:"), YES);
}
// cmRegisterReopenHandler adds applicationShouldHandleReopen:
// hasVisibleWindows: to the GLFWApplicationDelegate class at runtime
// (class_addMethod). This lets us detect when macOS re-opens the
// .app bundle without starting a new process (which bypasses our IPC
// single-instance mechanism). If the class already implements the
// method, this is a no-op.
static void cmRegisterReopenHandler(void) {
Class cls = objc_getClass("GLFWApplicationDelegate");
if (!cls) return;
SEL sel = sel_getUid("applicationShouldHandleReopen:hasVisibleWindows:");
if (class_getInstanceMethod(cls, sel)) return;
class_addMethod(cls, sel, (IMP)appShouldHandleReopen, "B@:@B");
}
*/
import "C"
func showDockIcon() { C.setDockIconVisible(1) }
func hideDockIcon() { C.setDockIconVisible(0) }
func activateApp() { C.cmActivateApp() }
func registerReopenHandler() { C.cmRegisterReopenHandler() }