优化: 知识卡片交互+deepseek模型+鼠标钩子
This commit is contained in:
68
settings.go
68
settings.go
@@ -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("设置窗口消息循环退出")
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user