新增: 自动升级体系 + WorkerW重建检测 + 知识卡片优化
自动升级: - 版本变量注入 (-ldflags -X main.version) - 远程 version.json 检查 + 弹窗提示(非强制右下角/强制居中) - updater.exe 嵌入主程序, 运行时释放到临时目录 - 下载+SHA256校验+备份+替换+回滚 全流程 - 托盘菜单"检查更新" 稳定性: - WorkerW 重建自动检测(每10s)并重新嵌入 - 左键托盘点击防抖 - 设置窗口已打开时正确前置 优化: - 知识卡片prompt改为面向开发者的硬核内容 - 配置目录统一到 ~/.u-desktop/ - 设置窗口WebView2数据目录改为configDir下
This commit is contained in:
54
systray.go
54
systray.go
@@ -18,10 +18,35 @@ func onSystrayReady() {
|
||||
systray.SetIcon(trayIcon)
|
||||
systray.SetTooltip("动态壁纸引擎")
|
||||
|
||||
// 左键点击托盘图标 → 打开设置(防抖: 连续点击只响应一次)
|
||||
go func() {
|
||||
for range systray.TrayClickCh {
|
||||
openSettingsWindow()
|
||||
// 消费后续积压的点击
|
||||
for {
|
||||
select {
|
||||
case <-systray.TrayClickCh:
|
||||
default:
|
||||
goto done
|
||||
}
|
||||
}
|
||||
done:
|
||||
}
|
||||
}()
|
||||
|
||||
mSettings := systray.AddMenuItem("桌面设置", "打开设置窗口")
|
||||
mCheckUpdate := systray.AddMenuItem("检查更新", "检查是否有新版本")
|
||||
mRestart := systray.AddMenuItem("重启", "重启程序")
|
||||
mQuit := systray.AddMenuItem("退出", "退出程序")
|
||||
|
||||
// 检查更新
|
||||
go func() {
|
||||
for {
|
||||
<-mCheckUpdate.ClickedCh
|
||||
manualCheckUpdate()
|
||||
}
|
||||
}()
|
||||
|
||||
// 设置窗口
|
||||
go func() {
|
||||
for {
|
||||
@@ -53,6 +78,7 @@ func onSystrayReady() {
|
||||
go bingWallpaperLoop()
|
||||
go knowledgeLoop()
|
||||
go startPhotoLoop()
|
||||
go runAutoUpdateCheck()
|
||||
}
|
||||
|
||||
func startWebView() {
|
||||
@@ -89,10 +115,10 @@ func startWebView() {
|
||||
wvHwnd = uintptr(wv.Window())
|
||||
procShowWindow.Call(wvHwnd, 0) // SW_HIDE
|
||||
procSetWindowLongPtrW.Call(wvHwnd, gwlStyle, wsPopup|wsVisible|wsChild)
|
||||
procSetWindowLongPtrW.Call(wvHwnd, gwlExStyle, wsExTransparent|wsExLayered)
|
||||
|
||||
// 立即嵌入 WorkerW
|
||||
procSetParent.Call(wvHwnd, workerw)
|
||||
procMoveWindow.Call(wvHwnd, uintptr(^uint(0)), uintptr(^uint(0)), uintptr(screenW+2), uintptr(screenH+2), 1)
|
||||
embedWorkerW(workerw, screenW, screenH)
|
||||
log.Printf("已嵌入 WorkerW: HWND=0x%x, %dx%d", wvHwnd, screenW, screenH)
|
||||
|
||||
wv.Bind("setZodiacFromGo", func(zodiac string) error {
|
||||
@@ -158,11 +184,35 @@ func startWebView() {
|
||||
}
|
||||
}
|
||||
|
||||
func embedWorkerW(workerw uintptr, screenW, screenH int32) {
|
||||
procSetParent.Call(wvHwnd, workerw)
|
||||
procMoveWindow.Call(wvHwnd, uintptr(^uint(0)), uintptr(^uint(0)), uintptr(screenW+2), uintptr(screenH+2), 1)
|
||||
}
|
||||
|
||||
func fullscreenMonitor() {
|
||||
type rect struct{ Left, Top, Right, Bottom int32 }
|
||||
var lastState string
|
||||
var lastParent uintptr
|
||||
var parentTick int
|
||||
for {
|
||||
if atomic.LoadInt32(&paused) == 0 && wv != nil {
|
||||
// 每 5 轮(10s)检测一次父窗口,极轻量系统调用
|
||||
parentTick++
|
||||
if parentTick >= 5 {
|
||||
parentTick = 0
|
||||
parent, _, _ := procGetParent.Call(wvHwnd)
|
||||
if parent != lastParent {
|
||||
lastParent = parent
|
||||
ww := findWorkerW()
|
||||
if ww != 0 && ww != parent {
|
||||
screenW, screenH := getScreenSize()
|
||||
embedWorkerW(ww, screenW, screenH)
|
||||
procShowWindow.Call(wvHwnd, 5)
|
||||
log.Printf("WorkerW 变更,已重新嵌入: 0x%x → 0x%x", parent, ww)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fg, _, _ := procGetForegroundWindow.Call()
|
||||
if fg != 0 {
|
||||
var r rect
|
||||
|
||||
Reference in New Issue
Block a user