优化: 知识卡片交互+deepseek模型+鼠标钩子

This commit is contained in:
2026-06-05 21:45:45 +08:00
parent 004dba7db6
commit 0302546267
10 changed files with 667 additions and 77 deletions

View File

@@ -12,6 +12,7 @@ import (
"unsafe"
"github.com/jchv/go-webview2"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
@@ -19,9 +20,12 @@ import (
var settingsHTML string
var (
settingsMu sync.Mutex
settingsOpen bool
settingsHwnd uintptr
settingsMu sync.Mutex
settingsWv webview2.WebView // 持久实例nil 直到首次打开
settingsHwnd uintptr
settingsOldWndProc uintptr // 子类化前的原始 wndproc
settingsWndProcCb uintptr // NewCallback 指针,防止 GC
settingsCreated bool // 首次创建完成后 true
)
const runKeyPath = `Software\Microsoft\Windows\CurrentVersion\Run`
@@ -71,6 +75,16 @@ func isSystemLightTheme() bool {
return v == 1
}
// settingsWndProc 拦截 WM_CLOSE隐藏窗口而非销毁
func settingsWndProc(hwnd, msg, wp, lp uintptr) uintptr {
if msg == 0x0010 { // WM_CLOSE
procShowWindow.Call(hwnd, 0) // SW_HIDE
return 0
}
r, _, _ := procCallWindowProcW.Call(settingsOldWndProc, hwnd, msg, wp, lp)
return r
}
var themeNames = []struct {
Name ThemeName
Label string
@@ -105,26 +119,20 @@ func refreshVisibleCards(cfg, oldCfg *Config) {
func openSettingsWindow() {
settingsMu.Lock()
if settingsOpen {
if settingsCreated {
settingsMu.Unlock()
if settingsHwnd != 0 {
procShowWindow.Call(settingsHwnd, 9)
procGetForegroundWindow.Call(settingsHwnd)
}
procShowWindow.Call(settingsHwnd, 9) // SW_RESTORE
procSetForegroundWindow.Call(settingsHwnd)
settingsWv.Dispatch(func() {
settingsWv.Eval("if(window.__refreshSettings) window.__refreshSettings()")
})
return
}
settingsOpen = true
settingsMu.Unlock()
go func() {
runtime.LockOSThread()
defer func() {
settingsMu.Lock()
settingsOpen = false
settingsHwnd = 0
settingsMu.Unlock()
runtime.UnlockOSThread()
}()
defer runtime.UnlockOSThread()
dataDir := filepath.Join(configDir(), "settings-data")
os.MkdirAll(dataDir, 0755)
@@ -135,7 +143,7 @@ func openSettingsWindow() {
WindowOptions: webview2.WindowOptions{
Title: "桌面设置",
Width: 760,
Height: 1350,
Height: 800,
},
})
if w == nil {
@@ -143,6 +151,17 @@ func openSettingsWindow() {
return
}
settingsWv = w
hwnd := uintptr(w.Window())
// 子类化:拦截 WM_CLOSE → 隐藏而非销毁
settingsWndProcCb = windows.NewCallback(settingsWndProc)
oldProc, _, _ := procSetWindowLongPtrW.Call(hwnd, gwlpWndProc, settingsWndProcCb)
settingsOldWndProc = oldProc
// 初始隐藏resizeToFit 完成后再显示
procShowWindow.Call(hwnd, 0) // SW_HIDE
w.Bind("loadAllSettings", func() string {
cfg := loadConfig()
@@ -536,13 +555,12 @@ func openSettingsWindow() {
w.SetHtml(settingsHTML)
hwnd := uintptr(w.Window())
// disable resize + hide from taskbar
style, _, _ := procGetWindowLongPtrW.Call(hwnd, gwlStyle)
procSetWindowLongPtrW.Call(hwnd, gwlStyle, style & ^uintptr(wsSizebox|wsMaxbox))
procSetWindowLongPtrW.Call(hwnd, gwlExStyle, wsExToolwindow)
style, _, _ := procGetWindowLongPtrW.Call(hwnd, gwlStyle)
procSetWindowLongPtrW.Call(hwnd, gwlStyle, style & ^uintptr(wsSizebox|wsMaxbox))
procSetWindowLongPtrW.Call(hwnd, gwlExStyle, wsExToolwindow)
// resizeToFit: JS measures content, Go adjusts window frame
// resizeToFit: JS measures content, Go adjusts window frame, then shows window
w.Bind("resizeToFit", func(contentW, contentH int) string {
type rect struct{ Left, Top, Right, Bottom int32 }
var wr, cr rect
@@ -562,15 +580,19 @@ func openSettingsWindow() {
x := (int(screenW) - winW) / 2
y := (int(screenH) - winH) / 2
procMoveWindow.Call(hwnd, uintptr(x), uintptr(y), uintptr(winW), uintptr(winH), 1)
// 首次 resize 完成后显示窗口
procShowWindow.Call(hwnd, 9) // SW_RESTORE
procSetForegroundWindow.Call(hwnd)
return ""
})
settingsMu.Lock()
settingsHwnd = hwnd
settingsCreated = true
settingsMu.Unlock()
log.Println("设置窗口已打开")
w.Run()
log.Println("设置窗口已关闭")
log.Println("设置窗口消息循环退出")
}()
}