import { getVersion } from '@tauri-apps/api/app'; import { getCurrentWindow } from '@tauri-apps/api/window'; import { formatDesktopWindowTitle } from '@frontend/utils/desktopAppVersion'; export { formatDesktopWindowTitle } from '@frontend/utils/desktopAppVersion'; /** macOS/Windows 네이티브 창 타이틀 — GoldenChart (vX.Y.Z) */ export async function syncMainWindowTitle(): Promise { const version = (await getVersion()).trim(); const title = formatDesktopWindowTitle(version); await getCurrentWindow().setTitle(title); if (typeof document !== 'undefined' && document.title !== title) { document.title = title; } return title; } let titleGuardInstalled = false; /** macOS WebKit — document.title 변경 시 네이티브 타이틀을 다시 맞춤 */ export function installDocumentTitleGuard(): void { if (titleGuardInstalled || typeof document === 'undefined') return; titleGuardInstalled = true; const rebalance = () => { void syncMainWindowTitle().catch(() => {}); }; const titleEl = document.querySelector('title'); if (titleEl) { const observer = new MutationObserver(() => { if (!document.title.includes('(v')) rebalance(); }); observer.observe(titleEl, { childList: true, characterData: true, subtree: true }); } window.setInterval(() => { if (!document.title.includes('(v')) rebalance(); }, 3000); } /** WebView 로드 후 macOS가 document.title로 타이틀을 덮어쓸 수 있어 재시도 */ export function scheduleMainWindowTitleSync(): void { installDocumentTitleGuard(); const delays = [0, 50, 150, 400, 1000, 2500, 5000]; for (const ms of delays) { window.setTimeout(() => { void syncMainWindowTitle().catch(() => {}); }, ms); } void getCurrentWindow() .listen('tauri://focus', () => { void syncMainWindowTitle().catch(() => {}); }) .catch(() => {}); }