diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 502beca..9deb4e7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,6 +16,7 @@ import { SavedConnection } from './types'; import { blurToFilter, normalizeBlurForPlatform, normalizeOpacityForPlatform, isWindowsPlatform, resolveAppearanceValues } from './utils/appearance'; import { DATA_GRID_COLUMN_WIDTH_MODE_OPTIONS, sanitizeDataTableColumnWidthMode } from './utils/dataGridDisplay'; import { getMacNativeTitlebarPaddingLeft, getMacNativeTitlebarPaddingRight, shouldHandleMacNativeFullscreenShortcut, shouldSuppressMacNativeEscapeExit } from './utils/macWindow'; +import { shouldEnableMacWindowDiagnostics } from './utils/macWindowDiagnostics'; import { buildOverlayWorkbenchTheme } from './utils/overlayWorkbenchTheme'; import { getConnectionWorkbenchState } from './utils/startupReadiness'; import { createGlobalProxyDraft, toSaveGlobalProxyInput } from './utils/globalProxyDraft'; @@ -897,9 +898,10 @@ function App() { const isWindowsRuntime = runtimePlatform === 'windows' || (runtimePlatform === '' && isWindowsPlatform()); const useNativeMacWindowControls = isMacRuntime && appearance.useNativeMacWindowControls === true; + const macWindowDiagnosticsEnabled = shouldEnableMacWindowDiagnostics(isMacRuntime, import.meta.env.DEV); const emitWindowDiagnostic = useCallback(async (stage: string, extra: Record = {}) => { - if (!isMacRuntime) { + if (!macWindowDiagnosticsEnabled) { return; } const backendApp = (window as any).go?.app?.App; @@ -953,7 +955,7 @@ function App() { } catch (error) { console.warn('Failed to emit window diagnostic', error); } - }, [isMacRuntime, useNativeMacWindowControls]); + }, [macWindowDiagnosticsEnabled, useNativeMacWindowControls]); useEffect(() => { if (!isStoreHydrated || !isMacRuntime) { @@ -968,7 +970,7 @@ function App() { }, [isMacRuntime, isStoreHydrated, useNativeMacWindowControls]); useEffect(() => { - if (!isMacRuntime) { + if (!macWindowDiagnosticsEnabled) { return; } @@ -1063,7 +1065,7 @@ function App() { window.removeEventListener('compositionend', handleCompositionEnd, true); document.removeEventListener('visibilitychange', handleVisibilityChange); }; - }, [emitWindowDiagnostic, isMacRuntime]); + }, [emitWindowDiagnostic, macWindowDiagnosticsEnabled]); const formatBytes = (bytes?: number) => { if (!bytes || bytes <= 0) return '0 B'; diff --git a/frontend/src/utils/macWindowDiagnostics.test.ts b/frontend/src/utils/macWindowDiagnostics.test.ts new file mode 100644 index 0000000..8c17c75 --- /dev/null +++ b/frontend/src/utils/macWindowDiagnostics.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; + +import { shouldEnableMacWindowDiagnostics } from './macWindowDiagnostics'; + +describe('macWindowDiagnostics', () => { + it('stays disabled outside macOS runtime', () => { + expect(shouldEnableMacWindowDiagnostics(false, true)).toBe(false); + }); + + it('stays disabled for production builds on macOS', () => { + expect(shouldEnableMacWindowDiagnostics(true, false)).toBe(false); + }); + + it('enables diagnostics only for macOS development builds', () => { + expect(shouldEnableMacWindowDiagnostics(true, true)).toBe(true); + }); +}); diff --git a/frontend/src/utils/macWindowDiagnostics.ts b/frontend/src/utils/macWindowDiagnostics.ts new file mode 100644 index 0000000..90be3ab --- /dev/null +++ b/frontend/src/utils/macWindowDiagnostics.ts @@ -0,0 +1,6 @@ +export const shouldEnableMacWindowDiagnostics = ( + isMacRuntime: boolean, + isDevBuild: boolean, +): boolean => { + return isMacRuntime && isDevBuild; +}; diff --git a/internal/app/app.go b/internal/app/app.go index b91400b..491d103 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -94,7 +94,9 @@ func (a *App) startup(ctx context.Context) { db.SetExternalDriverDownloadDirectory(appdata.DriverRoot(a.configDir)) logger.Init() a.loadPersistedGlobalProxy() - installMacNativeWindowDiagnostics(logger.Path()) + if shouldInstallMacNativeWindowDiagnostics() { + installMacNativeWindowDiagnostics(logger.Path()) + } applyMacWindowTranslucencyFix() logger.Infof("应用启动完成(首次连接保护窗口=%s,最多重试=%d 次)", startupConnectRetryWindow, startupConnectRetryAttempts) } diff --git a/internal/app/env.go b/internal/app/env.go new file mode 100644 index 0000000..b21abbd --- /dev/null +++ b/internal/app/env.go @@ -0,0 +1,5 @@ +package app + +import "os" + +var getenv = os.Getenv diff --git a/internal/app/window_diagnostics.go b/internal/app/window_diagnostics.go new file mode 100644 index 0000000..107ca74 --- /dev/null +++ b/internal/app/window_diagnostics.go @@ -0,0 +1,14 @@ +package app + +import "strings" + +const macWindowDiagnosticsEnv = "GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS" + +func shouldInstallMacNativeWindowDiagnostics() bool { + switch strings.ToLower(strings.TrimSpace(getenv(macWindowDiagnosticsEnv))) { + case "1", "true", "yes", "on": + return true + default: + return false + } +} diff --git a/internal/app/window_diagnostics_test.go b/internal/app/window_diagnostics_test.go new file mode 100644 index 0000000..23b3d83 --- /dev/null +++ b/internal/app/window_diagnostics_test.go @@ -0,0 +1,37 @@ +package app + +import "testing" + +func TestShouldInstallMacNativeWindowDiagnosticsDefaultsDisabled(t *testing.T) { + t.Setenv("GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS", "") + + if shouldInstallMacNativeWindowDiagnostics() { + t.Fatal("expected mac native window diagnostics to stay disabled by default") + } +} + +func TestShouldInstallMacNativeWindowDiagnosticsHonorsEnvOptIn(t *testing.T) { + t.Setenv("GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS", "1") + + if !shouldInstallMacNativeWindowDiagnostics() { + t.Fatal("expected mac native window diagnostics to enable when explicitly opted in") + } + + t.Setenv("GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS", "true") + if !shouldInstallMacNativeWindowDiagnostics() { + t.Fatal("expected mac native window diagnostics to accept true as opt-in value") + } + + t.Setenv("GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS", "0") + if shouldInstallMacNativeWindowDiagnostics() { + t.Fatal("expected mac native window diagnostics to stay disabled for non-opt-in values") + } +} + +func TestShouldInstallMacNativeWindowDiagnosticsIgnoresCaseAndWhitespace(t *testing.T) { + t.Setenv("GONAVI_ENABLE_MAC_WINDOW_DIAGNOSTICS", " TRUE ") + + if !shouldInstallMacNativeWindowDiagnostics() { + t.Fatal("expected helper to trim and lowercase opt-in values") + } +}