mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-13 00:13:33 +08:00
🐛 fix(window): 修复 Windows 后台可见时输入卡顿
- Windows 默认关闭透明 WebView、窗口透明与 Acrylic 背景 - 保留 macOS 透明效果并补充跨平台窗口视觉配置回归测试 - 同步更新多语言性能模式提示与开发文档
This commit is contained in:
@@ -168,8 +168,7 @@ node tools/wails-fast-dev.mjs
|
||||
# Refresh Wails JS bindings after changing exported Go method signatures
|
||||
node tools/wails-fast-dev.mjs --refresh-bindings
|
||||
|
||||
# Windows PowerShell low-memory visual mode: disables transparent WebView/Acrylic backdrop
|
||||
$env:GONAVI_LOW_MEMORY_MODE="1"; node tools/wails-fast-dev.mjs
|
||||
# Windows desktop builds use an opaque WebView without an Acrylic backdrop by default.
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
@@ -162,8 +162,7 @@ node tools/wails-fast-dev.mjs
|
||||
# 修改 Go 导出方法签名后刷新 Wails JS 绑定
|
||||
node tools/wails-fast-dev.mjs --refresh-bindings
|
||||
|
||||
# Windows PowerShell 低内存视觉模式:关闭透明 WebView 和 Acrylic 背景
|
||||
$env:GONAVI_LOW_MEMORY_MODE="1"; node tools/wails-fast-dev.mjs
|
||||
# Windows 桌面端默认使用不透明 WebView,并关闭 Acrylic 背景
|
||||
```
|
||||
|
||||
### 编译构建
|
||||
|
||||
40
main.go
40
main.go
@@ -41,13 +41,9 @@ func main() {
|
||||
application := app.NewApp()
|
||||
aiService := aiservice.NewService()
|
||||
lowMemoryMode := isLowMemoryMode()
|
||||
backgroundColour, windowsOptions := resolveWindowVisualOptions(runtime.GOOS, lowMemoryMode)
|
||||
windowsOptions.WebviewUserDataPath = resolveWindowsWebviewUserDataPath()
|
||||
var runtimeCtx context.Context
|
||||
backgroundColour := &options.RGBA{R: 0, G: 0, B: 0, A: 0}
|
||||
windowsBackdrop := windows.Acrylic
|
||||
if lowMemoryMode {
|
||||
backgroundColour = &options.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||
windowsBackdrop = windows.None
|
||||
}
|
||||
var appMenu *menu.Menu
|
||||
if strings.EqualFold(strings.TrimSpace(runtime.GOOS), "darwin") {
|
||||
appMenu = buildMacApplicationMenu(func() {
|
||||
@@ -97,14 +93,7 @@ func main() {
|
||||
application,
|
||||
aiService,
|
||||
},
|
||||
Windows: &windows.Options{
|
||||
WebviewIsTransparent: !lowMemoryMode,
|
||||
WindowIsTranslucent: !lowMemoryMode,
|
||||
BackdropType: windowsBackdrop,
|
||||
DisableWindowIcon: false,
|
||||
DisableFramelessWindowDecorations: false,
|
||||
WebviewUserDataPath: resolveWindowsWebviewUserDataPath(),
|
||||
},
|
||||
Windows: windowsOptions,
|
||||
Mac: &mac.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowIsTranslucent: true,
|
||||
@@ -186,3 +175,26 @@ func isLowMemoryMode() bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func resolveWindowVisualOptions(goos string, lowMemoryMode bool) (*options.RGBA, *windows.Options) {
|
||||
// A visible Acrylic surface keeps DWM composing after GoNavi loses focus.
|
||||
// Windows therefore uses an opaque surface by default; macOS keeps its separate native effect path.
|
||||
disableTransparency := lowMemoryMode || strings.EqualFold(strings.TrimSpace(goos), "windows")
|
||||
if disableTransparency {
|
||||
return &options.RGBA{R: 255, G: 255, B: 255, A: 255}, &windows.Options{
|
||||
WebviewIsTransparent: false,
|
||||
WindowIsTranslucent: false,
|
||||
BackdropType: windows.None,
|
||||
DisableWindowIcon: false,
|
||||
DisableFramelessWindowDecorations: false,
|
||||
}
|
||||
}
|
||||
|
||||
return &options.RGBA{R: 0, G: 0, B: 0, A: 0}, &windows.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowIsTranslucent: true,
|
||||
BackdropType: windows.Acrylic,
|
||||
DisableWindowIcon: false,
|
||||
DisableFramelessWindowDecorations: false,
|
||||
}
|
||||
}
|
||||
|
||||
80
main_test.go
80
main_test.go
@@ -5,6 +5,8 @@ import (
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu/keys"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
)
|
||||
|
||||
func TestIsLowMemoryMode(t *testing.T) {
|
||||
@@ -30,24 +32,72 @@ func TestIsLowMemoryMode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldRunMCPServerMode(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
args []string
|
||||
want bool
|
||||
func TestResolveWindowVisualOptions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
goos string
|
||||
lowMemoryMode bool
|
||||
wantBackground options.RGBA
|
||||
wantWebviewOpaque bool
|
||||
wantWindowOpaque bool
|
||||
wantWindowsBackdrop windows.BackdropType
|
||||
}{
|
||||
{name: "empty", args: nil, want: false},
|
||||
{name: "mcp-server", args: []string{"mcp-server"}, want: true},
|
||||
{name: "flag style", args: []string{"--mcp-server"}, want: true},
|
||||
{name: "mcp-server http mode", args: []string{"mcp-server", "http"}, want: true},
|
||||
{name: "mcp-server remote config", args: []string{"mcp-server", "remote-config"}, want: true},
|
||||
{name: "unknown", args: []string{"serve"}, want: false},
|
||||
{
|
||||
name: "windows defaults to opaque without acrylic",
|
||||
goos: "windows",
|
||||
wantBackground: options.RGBA{R: 255, G: 255, B: 255, A: 255},
|
||||
wantWebviewOpaque: true,
|
||||
wantWindowOpaque: true,
|
||||
wantWindowsBackdrop: windows.None,
|
||||
},
|
||||
{
|
||||
name: "windows low memory remains opaque",
|
||||
goos: " Windows ",
|
||||
lowMemoryMode: true,
|
||||
wantBackground: options.RGBA{R: 255, G: 255, B: 255, A: 255},
|
||||
wantWebviewOpaque: true,
|
||||
wantWindowOpaque: true,
|
||||
wantWindowsBackdrop: windows.None,
|
||||
},
|
||||
{
|
||||
name: "mac default remains transparent",
|
||||
goos: "darwin",
|
||||
wantBackground: options.RGBA{R: 0, G: 0, B: 0, A: 0},
|
||||
wantWebviewOpaque: false,
|
||||
wantWindowOpaque: false,
|
||||
wantWindowsBackdrop: windows.Acrylic,
|
||||
},
|
||||
{
|
||||
name: "low memory remains opaque on other platforms",
|
||||
goos: "darwin",
|
||||
lowMemoryMode: true,
|
||||
wantBackground: options.RGBA{R: 255, G: 255, B: 255, A: 255},
|
||||
wantWebviewOpaque: true,
|
||||
wantWindowOpaque: true,
|
||||
wantWindowsBackdrop: windows.None,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := shouldRunMCPServerMode(tc.args); got != tc.want {
|
||||
t.Fatalf("shouldRunMCPServerMode(%v) = %v, want %v", tc.args, got, tc.want)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
background, windowsOptions := resolveWindowVisualOptions(tt.goos, tt.lowMemoryMode)
|
||||
if background == nil {
|
||||
t.Fatal("resolveWindowVisualOptions() background is nil")
|
||||
}
|
||||
if got := *background; got != tt.wantBackground {
|
||||
t.Fatalf("background = %+v, want %+v", got, tt.wantBackground)
|
||||
}
|
||||
if windowsOptions == nil {
|
||||
t.Fatal("resolveWindowVisualOptions() windows options are nil")
|
||||
}
|
||||
if got := !windowsOptions.WebviewIsTransparent; got != tt.wantWebviewOpaque {
|
||||
t.Fatalf("webview opaque = %v, want %v", got, tt.wantWebviewOpaque)
|
||||
}
|
||||
if got := !windowsOptions.WindowIsTranslucent; got != tt.wantWindowOpaque {
|
||||
t.Fatalf("window opaque = %v, want %v", got, tt.wantWindowOpaque)
|
||||
}
|
||||
if got := windowsOptions.BackdropType; got != tt.wantWindowsBackdrop {
|
||||
t.Fatalf("Windows backdrop = %v, want %v", got, tt.wantWindowsBackdrop)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "Transparenz- und Weichzeichnungseffekte",
|
||||
"app.theme.appearance.ui_scale_hint": "* Für kleine Bildschirme werden 85%-95% empfohlen",
|
||||
"app.theme.appearance.ui_scale_title": "UI-Skalierung (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows verwendet den systemeigenen Acrylic-Effekt. Die Unschärfestärke wird vom System gesteuert.",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows-Leistungsmodus: Systemhintergrundunschärfe ist deaktiviert.",
|
||||
"app.theme.appearance_settings_description": "Skalierung, Schriftgröße, Transparenz und Weichzeichnung zentral anpassen.",
|
||||
"app.theme.appearance_settings_title": "Darstellungseinstellungen",
|
||||
"app.theme.data_table.column_width_hint": "Der Standardmodus nutzt 200px, der kompakte Modus 140px als Standardspaltenbreite. Manuell angepasste Spaltenbreiten bleiben vorrangig erhalten.",
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "Transparency and Blur Effects",
|
||||
"app.theme.appearance.ui_scale_hint": "* Recommended for small screens: 85%-95%",
|
||||
"app.theme.appearance.ui_scale_title": "UI Scale (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows uses the system Acrylic effect. Blur intensity is controlled by the system.",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows performance mode: system background blur is off.",
|
||||
"app.theme.appearance_settings_description": "Adjust scale, font size, transparency, and blur effects in one place.",
|
||||
"app.theme.appearance_settings_title": "Appearance Settings",
|
||||
"app.theme.data_table.column_width_hint": "Standard mode defaults to 200px; compact mode defaults to 140px. Manually adjusted column widths are preserved first.",
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "透明度とぼかし効果",
|
||||
"app.theme.appearance.ui_scale_hint": "* 小さい画面では 85%-95% を推奨します",
|
||||
"app.theme.appearance.ui_scale_title": "UI スケール (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows ではシステムの Acrylic 効果を使用します。ぼかしの強さはシステムにより制御されます。",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows パフォーマンスモード:システム背景のぼかしは無効です。",
|
||||
"app.theme.appearance_settings_description": "スケール、フォントサイズ、透明度、ぼかし効果をまとめて調整します。",
|
||||
"app.theme.appearance_settings_title": "外観設定",
|
||||
"app.theme.data_table.column_width_hint": "標準モードの既定列幅は 200px、コンパクトモードの既定列幅は 140px です。手動で調整した列幅は優先して保持されます。",
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "Эффекты прозрачности и размытия",
|
||||
"app.theme.appearance.ui_scale_hint": "* Для небольших экранов рекомендуется 85%-95%",
|
||||
"app.theme.appearance.ui_scale_title": "Масштаб UI (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows использует системный эффект Acrylic. Сила размытия управляется системой.",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Режим производительности Windows: системное размытие фона отключено.",
|
||||
"app.theme.appearance_settings_description": "Единая настройка масштаба, размера шрифта, прозрачности и размытия.",
|
||||
"app.theme.appearance_settings_title": "Настройки внешнего вида",
|
||||
"app.theme.data_table.column_width_hint": "В стандартном режиме ширина столбца по умолчанию 200px; в компактном режиме 140px. Вручную измененные ширины столбцов сохраняются в приоритете.",
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "透明与模糊效果",
|
||||
"app.theme.appearance.ui_scale_hint": "* 建议小屏设备设置为 85%-95%",
|
||||
"app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows 性能模式:已关闭系统背景模糊",
|
||||
"app.theme.appearance_settings_description": "统一调整缩放、字体、透明度与模糊效果。",
|
||||
"app.theme.appearance_settings_title": "外观设置",
|
||||
"app.theme.data_table.column_width_hint": "标准模式默认列宽 200px;紧凑模式默认列宽 140px。已手动拖拽调整的列宽优先保留。",
|
||||
|
||||
@@ -2797,7 +2797,7 @@
|
||||
"app.theme.appearance.transparency_blur_title": "透明与模糊效果",
|
||||
"app.theme.appearance.ui_scale_hint": "* 建议小屏设备設定为 85%-95%",
|
||||
"app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制",
|
||||
"app.theme.appearance.windows_acrylic_hint": "Windows 效能模式:已停用系統背景模糊",
|
||||
"app.theme.appearance_settings_description": "集中調整縮放、字型、透明度與模糊效果。",
|
||||
"app.theme.appearance_settings_title": "外觀設定",
|
||||
"app.theme.data_table.column_width_hint": "标准模式預設列宽 200px;紧凑模式預設列宽 140px。已手动拖拽调整的列宽优先保留。",
|
||||
|
||||
Reference in New Issue
Block a user