fix windows window issues

This commit is contained in:
Boof2015
2026-06-07 18:34:23 -04:00
parent bf447dd8df
commit c56b86ba63
7 changed files with 189 additions and 1 deletions
+35
View File
@@ -33,6 +33,7 @@ import {
import { calculateResizedWindowBounds } from '../shared/windowResize'
import { FileBackedProfileLibrary } from './profileLibrary'
import { loadNativeWindowsMediaApi } from './nativeWindowsMedia'
import { loadNativeWindowChromeApi } from './nativeWindowChrome'
import { NowPlayingManager } from './services/nowPlayingManager'
import { AstraIntegrationService } from './services/astraIntegration'
import { MacSpotifyProvider } from './services/macSpotifyProvider'
@@ -41,6 +42,7 @@ import { checkForUpdates, resolveSafeReleaseUrl } from './services/updates'
import { FileBackedThemeLibrary } from './themeLibrary'
import { FileBackedWindowStateStore } from './windowStateStore'
import type { NativeWindowsMediaAPI } from '../types/nativeWindowsMedia'
import type { NativeWindowChromeAPI } from '../types/nativeWindowChrome'
let mainWindow: BrowserWindow | null = null
let moveInterval: ReturnType<typeof setInterval> | null = null
@@ -74,6 +76,7 @@ let nowPlayingManager: NowPlayingManager | null = null
let windowStateStore: FileBackedWindowStateStore | null = null
let secretVault: SecretVault | null = null
let nativeWindowsMediaApi: NativeWindowsMediaAPI | null | undefined
let nativeWindowChromeApi: NativeWindowChromeAPI | null | undefined
const WINDOW_DEFAULTS = {
width: 900,
@@ -350,6 +353,35 @@ function getNativeWindowsMediaApi(): NativeWindowsMediaAPI | null {
return nativeWindowsMediaApi
}
function getNativeWindowChromeApi(): NativeWindowChromeAPI | null {
if (nativeWindowChromeApi !== undefined) {
return nativeWindowChromeApi
}
nativeWindowChromeApi = loadNativeWindowChromeApi()
return nativeWindowChromeApi
}
// Strips the visible native frame/shadow from a frameless WS_THICKFRAME window so
// it looks flat again, while keeping native Aero Snap and edge resize. Windows-only;
// a no-op on macOS/Linux.
function applyFlatFramelessChrome(window: BrowserWindow): void {
if (process.platform !== 'win32') {
return
}
const api = getNativeWindowChromeApi()
if (!api) {
return
}
try {
api.applyFlatFrame(window.getNativeWindowHandle())
} catch {
// Frame styling is purely cosmetic; never block window creation on it.
}
}
function getNowPlayingManager(): NowPlayingManager {
if (!nowPlayingManager) {
nowPlayingManager = new NowPlayingManager({
@@ -1009,6 +1041,7 @@ function createMainWindow(): void {
backgroundThrottling: false,
},
})
applyFlatFramelessChrome(mainWindow)
syncMainWindowLogicalBounds(mainWindow)
mainWindow.on('close', (event) => {
@@ -1218,6 +1251,7 @@ function createScopePopoutWindow(kind: ScopeKind, rawBounds?: WindowBounds): Bro
}
const popoutWindow = new BrowserWindow(options)
applyFlatFramelessChrome(popoutWindow)
setSettingsHeightForWindow(popoutWindow, 0)
scopePopoutWindows.set(kind, popoutWindow)
@@ -1385,6 +1419,7 @@ function createNowPlayingConfigWindow(): BrowserWindow {
}
nowPlayingConfigWindow = new BrowserWindow(options)
applyFlatFramelessChrome(nowPlayingConfigWindow)
const configWindow = nowPlayingConfigWindow
+37
View File
@@ -0,0 +1,37 @@
import { createRequire } from 'node:module'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import type { VisualizerDSP } from '../renderer/audio/native/visualizer-dsp'
import type { NativeCaptureAPI } from '../types/nativeCapture'
import type { NativeWindowChromeAPI } from '../types/nativeWindowChrome'
type NativeAddonModule = VisualizerDSP & NativeCaptureAPI & {
windowChrome?: NativeWindowChromeAPI
}
const require = createRequire(import.meta.url)
const currentDir = dirname(fileURLToPath(import.meta.url))
export function loadNativeWindowChromeApi(): NativeWindowChromeAPI | null {
if (process.platform !== 'win32') {
return null
}
const candidatePaths = [
join(currentDir, '../../native/build/Release/visualizer_dsp.node'),
process.resourcesPath ? join(process.resourcesPath, 'native/visualizer_dsp.node') : null,
].filter((value): value is string => value !== null)
for (const modulePath of candidatePaths) {
try {
const nativeAddon = require(modulePath) as NativeAddonModule
if (nativeAddon.windowChrome) {
return nativeAddon.windowChrome
}
} catch {
// Try the next candidate path.
}
}
return null
}
+7
View File
@@ -0,0 +1,7 @@
export interface NativeWindowChromeAPI {
// Strips the visible native frame/shadow from a frameless WS_THICKFRAME window
// while preserving native snapping and edge resize. Returns false if the handle
// was invalid or the subclass could not be installed. Windows-only; a no-op
// elsewhere.
applyFlatFrame: (nativeWindowHandle: Buffer) => boolean
}