cdrop — 跨 OS 剪贴板与文件传输服务
Commilitia Drop:自托管的跨设备剪贴板同步与点对点文件传输。 - 后端 Go(chi / SQLite WAL / SSE Hub / WebRTC signaling + 状态机 / Relay ring buffer),编译进单个 distroless 镜像(前端 go:embed)。 - 前端 React + TanStack Router + Zustand,自实现 SSE + WebRTC P2P,NAT 受阻时回退服务端中继;聚珍(Juzhen)CJK 综合排版。 - 桌面端 Wails v2(macOS / Windows),瘦客户端复用 web。 - 鉴权 OIDC PKCE(自建 Casdoor 等),refresh_token 信封加密存系统密钥库;iOS Shortcut 用 HS256 scoped token。 架构文档与变更记录见 docs 分支(PROJECT_BRIEF / FRONTEND_DESIGN / CHANGELOG)。 本次为公开发布初始提交:完整开发历史(含部署细节)留存于私有归档,公开仓库自此干净起步。
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
//go:build darwin
|
||||
|
||||
package platform
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fobjc-arc
|
||||
#cgo darwin LDFLAGS: -framework Cocoa
|
||||
#include <stdlib.h>
|
||||
|
||||
void cdropStatusBarInstall(const void *iconPNG, int iconLen, const char *title,
|
||||
const char *showLabel, const char *settingsLabel,
|
||||
const char *quitLabel);
|
||||
void cdropSetActivationPolicy(int policy);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// menuBarIconPNG 是嵌入二进制的品牌吉祥物头像(avatar-head,256px)。菜单栏图标
|
||||
// 用彩色图而非 SF Symbol 模板图——彩色更有品牌辨识度(代价是不随明暗自适应)。
|
||||
// 256px 提供高清 rep,运行时按菜单栏 thickness(逻辑点)显示,retina 下采样保持清晰。
|
||||
//
|
||||
//go:embed menubar-icon.png
|
||||
var menuBarIconPNG []byte
|
||||
|
||||
// InstallStatusBar creates the menu bar (NSStatusBar) item with a Show /
|
||||
// Settings / Quit menu. Safe to call from any goroutine — the native work is
|
||||
// dispatched to the main thread. Idempotent on the native side.
|
||||
func InstallStatusBar(m StatusBarMenu, h StatusBarHandler) {
|
||||
statusBarHandler = h
|
||||
|
||||
ct := C.CString(m.Title)
|
||||
cs := C.CString(m.Show)
|
||||
cg := C.CString(m.Settings)
|
||||
cq := C.CString(m.Quit)
|
||||
defer C.free(unsafe.Pointer(ct))
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
defer C.free(unsafe.Pointer(cg))
|
||||
defer C.free(unsafe.Pointer(cq))
|
||||
|
||||
// 把 PNG 字节复制进 C 缓冲;ObjC 侧在 dispatch 前同步拷进 NSData,故调用返回后即可释放。
|
||||
cIcon := C.CBytes(menuBarIconPNG)
|
||||
defer C.free(cIcon)
|
||||
|
||||
C.cdropStatusBarInstall(cIcon, C.int(len(menuBarIconPNG)), ct, cs, cg, cq)
|
||||
}
|
||||
|
||||
// SetDockVisible toggles the Dock icon: true → regular (icon shown), false →
|
||||
// accessory (Dock hidden, only the menu bar item remains). Main-thread safe.
|
||||
func SetDockVisible(visible bool) {
|
||||
p := C.int(1) // accessory
|
||||
if visible {
|
||||
p = C.int(0) // regular
|
||||
}
|
||||
C.cdropSetActivationPolicy(p)
|
||||
}
|
||||
|
||||
//export cdropOnShowWindow
|
||||
func cdropOnShowWindow() {
|
||||
if statusBarHandler.OnShowWindow != nil {
|
||||
statusBarHandler.OnShowWindow()
|
||||
}
|
||||
}
|
||||
|
||||
//export cdropOnOpenSettings
|
||||
func cdropOnOpenSettings() {
|
||||
if statusBarHandler.OnOpenSettings != nil {
|
||||
statusBarHandler.OnOpenSettings()
|
||||
}
|
||||
}
|
||||
|
||||
//export cdropOnQuit
|
||||
func cdropOnQuit() {
|
||||
if statusBarHandler.OnQuit != nil {
|
||||
statusBarHandler.OnQuit()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user