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,74 @@
|
||||
//go:build windows
|
||||
|
||||
package platform
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"runtime"
|
||||
|
||||
"fyne.io/systray"
|
||||
)
|
||||
|
||||
// trayIconICO is the brand mascot as a Windows .ico, embedded in the binary and
|
||||
// shown in the notification area.
|
||||
//
|
||||
//go:embed tray-icon.ico
|
||||
var trayIconICO []byte
|
||||
|
||||
// InstallStatusBar installs the Windows system-tray icon, mirroring the macOS
|
||||
// menu bar: left-click (primary tap) opens the main window, right-click shows
|
||||
// the Show / Settings / Quit menu. systray owns a Win32 message loop, so it runs
|
||||
// on its own OS-locked goroutine; the menu-item click channels are drained in a
|
||||
// second goroutine. The handler closures already hand work to a goroutine before
|
||||
// touching the Wails runtime, so invoking them from here is safe.
|
||||
func InstallStatusBar(m StatusBarMenu, h StatusBarHandler) {
|
||||
statusBarHandler = h
|
||||
go func() {
|
||||
// systray creates a window + GetMessage loop on this thread; the window
|
||||
// is thread-affine, so the goroutine must not migrate.
|
||||
runtime.LockOSThread()
|
||||
systray.Run(func() { trayOnReady(m) }, nil)
|
||||
}()
|
||||
}
|
||||
|
||||
func trayOnReady(m StatusBarMenu) {
|
||||
systray.SetIcon(trayIconICO)
|
||||
systray.SetTitle(m.Title)
|
||||
systray.SetTooltip(m.Title)
|
||||
|
||||
// Left-click → open the main window (matches the macOS convention). Right-
|
||||
// click falls through to the menu below (Windows default).
|
||||
systray.SetOnTapped(func() {
|
||||
if statusBarHandler.OnShowWindow != nil {
|
||||
statusBarHandler.OnShowWindow()
|
||||
}
|
||||
})
|
||||
|
||||
show := systray.AddMenuItem(m.Show, "")
|
||||
settings := systray.AddMenuItem(m.Settings, "")
|
||||
quit := systray.AddMenuItem(m.Quit, "")
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-show.ClickedCh:
|
||||
if statusBarHandler.OnShowWindow != nil {
|
||||
statusBarHandler.OnShowWindow()
|
||||
}
|
||||
case <-settings.ClickedCh:
|
||||
if statusBarHandler.OnOpenSettings != nil {
|
||||
statusBarHandler.OnOpenSettings()
|
||||
}
|
||||
case <-quit.ClickedCh:
|
||||
if statusBarHandler.OnQuit != nil {
|
||||
statusBarHandler.OnQuit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// SetDockVisible is a no-op on Windows: the app lifecycle already hides/shows the
|
||||
// window (Wails WindowHide/WindowShow), which removes/adds the taskbar button, so
|
||||
// there is no separate Dock-style activation policy to toggle.
|
||||
func SetDockVisible(_ bool) {}
|
||||
Reference in New Issue
Block a user