diff --git a/src/main/appBadge.ts b/src/main/appBadge.ts index fda7eea..c462c1e 100644 --- a/src/main/appBadge.ts +++ b/src/main/appBadge.ts @@ -7,7 +7,7 @@ import { app, NativeImage, nativeImage } from "electron"; import { join } from "path"; import { BADGE_DIR, TRAY_ICON_DIR, TRAY_ICON_PATH } from "shared/paths"; -import type { VencordBrowserWindow } from "./mainWindow"; +import { globals } from "./mainWindow"; const imgCache = new Map(); @@ -31,17 +31,11 @@ function loadTrayIcon(index: number) { let lastIndex: null | number = -1; -let mainWin: null | VencordBrowserWindow; -function getMainWin() { - if (mainWin != null) return mainWin; - return (mainWin = (require("./mainWindow") as typeof import("./mainWindow")).mainWin); -} - export function setBadgeCount(count: number, tray: boolean = false) { const [index, description] = getBadgeIndexAndDescription(count); if (tray) { - getMainWin()._vencord_tray?.setImage(loadTrayIcon(index ?? 0)); + globals.tray?.setImage(loadTrayIcon(index ?? 0)); } switch (process.platform) { @@ -61,9 +55,7 @@ export function setBadgeCount(count: number, tray: boolean = false) { lastIndex = index; - // circular import shenanigans - const mainWin = getMainWin(); - mainWin.setOverlayIcon(index === null ? null : loadBadge(index), description); + globals.mainWin?.setOverlayIcon(index === null ? null : loadBadge(index), description); break; } } diff --git a/src/main/arrpc.ts b/src/main/arrpc.ts index 1899d9c..dd435bb 100644 --- a/src/main/arrpc.ts +++ b/src/main/arrpc.ts @@ -7,7 +7,7 @@ import Server from "arrpc"; import { IpcEvents } from "shared/IpcEvents"; -import { mainWin } from "./mainWindow"; +import { globals } from "./mainWindow"; import { Settings } from "./settings"; let server: any; @@ -19,12 +19,13 @@ export async function initArRPC() { try { server = await new Server(); - server.on("activity", (data: any) => mainWin.webContents.send(IpcEvents.ARRPC_ACTIVITY, JSON.stringify(data))); + const { mainWin } = globals; + server.on("activity", (data: any) => mainWin!.webContents.send(IpcEvents.ARRPC_ACTIVITY, JSON.stringify(data))); server.on("invite", (invite: string, callback: (valid: boolean) => void) => { invite = String(invite); if (!inviteCodeRegex.test(invite)) return callback(false); - mainWin.webContents + mainWin!.webContents // Safety: Result of JSON.stringify should always be safe to equal // Also, just to be super super safe, invite is regex validated above .executeJavaScript(`Vesktop.openInviteModal(${JSON.stringify(invite)})`) diff --git a/src/main/index.ts b/src/main/index.ts index 832afc8..1268361 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -9,12 +9,12 @@ import "./ipc"; import { app, BrowserWindow } from "electron"; import { checkUpdates } from "updater/main"; +import { Settings } from "./settings"; import { DATA_DIR } from "./constants"; import { createFirstLaunchTour } from "./firstLaunch"; -import { createWindows, mainWin } from "./mainWindow"; +import { createWindows, globals } from "./mainWindow"; import { registerMediaPermissionsHandler } from "./mediaPermissions"; import { registerScreenShareHandler } from "./screenShare"; -import { Settings } from "./settings"; if (IS_DEV) { require("source-map-support").install(); @@ -43,8 +43,9 @@ function init() { ); app.on("second-instance", (_event, _cmdLine, _cwd, data: any) => { + let mainWin; if (data.IS_DEV) app.quit(); - else if (mainWin) { + else if ((mainWin = globals.mainWin)) { if (mainWin.isMinimized()) mainWin.restore(); if (!mainWin.isVisible()) mainWin.show(); mainWin.focus(); diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 4003fc7..9e77c85 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -15,10 +15,11 @@ import { join } from "path"; import { debounce } from "shared/utils/debounce"; import { IpcEvents } from "../shared/IpcEvents"; -import { setBadgeCount } from "./appBadge"; import { autoStart } from "./autoStart"; import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants"; -import { mainWin } from "./mainWindow"; +import { globals } from "./mainWindow"; +// !!IMPORTANT!! ./appBadge import must occur after ./mainWindow +import { setBadgeCount } from "./appBadge"; import { Settings } from "./settings"; import { handle, handleSync } from "./utils/ipcWrappers"; import { isValidVencordInstall } from "./utils/vencordLoader"; @@ -64,6 +65,8 @@ handle(IpcEvents.SHOW_ITEM_IN_FOLDER, (_, path) => { }); handle(IpcEvents.FOCUS, () => { + const mainWin = globals.mainWin!; + if (process.platform === "win32") mainWin.minimize(); // Windows is weird mainWin.restore(); @@ -75,14 +78,14 @@ handle(IpcEvents.CLOSE, e => { }); handle(IpcEvents.MINIMIZE, e => { - mainWin.minimize(); + globals.mainWin!.minimize(); }); handle(IpcEvents.MAXIMIZE, e => { - if (mainWin.isMaximized()) { - mainWin.unmaximize(); + if (globals.mainWin!.isMaximized()) { + globals.mainWin!.unmaximize(); } else { - mainWin.maximize(); + globals.mainWin!.maximize(); } }); @@ -103,7 +106,7 @@ handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => { }); handle(IpcEvents.SELECT_VENCORD_DIR, async () => { - const res = await dialog.showOpenDialog(mainWin!, { + const res = await dialog.showOpenDialog(globals.mainWin!, { properties: ["openDirectory"] }); if (!res.filePaths.length) return "cancelled"; @@ -126,7 +129,7 @@ open(VENCORD_QUICKCSS_FILE, "a+").then(fd => { VENCORD_QUICKCSS_FILE, { persistent: false }, debounce(async () => { - mainWin?.webContents.postMessage("VencordQuickCssUpdate", await readCss()); + globals.mainWin?.webContents.postMessage("VencordQuickCssUpdate", await readCss()); }, 50) ); }); @@ -136,6 +139,6 @@ watch( VENCORD_THEMES_DIR, { persistent: false }, debounce(() => { - mainWin?.webContents.postMessage("VencordThemeUpdate", void 0); + globals.mainWin?.webContents.postMessage("VencordThemeUpdate", void 0); }) ); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 892fe93..fb44854 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -24,6 +24,7 @@ import type { SettingsStore } from "shared/utils/SettingsStore"; import { ICON_PATH, TRAY_ICON_PATH } from "../shared/paths"; import { createAboutWindow } from "./about"; import { initArRPC } from "./arrpc"; +import { Settings, VencordSettings } from "./settings"; import { DATA_DIR, DEFAULT_HEIGHT, @@ -34,7 +35,6 @@ import { UserAgent, VENCORD_FILES_DIR } from "./constants"; -import { Settings, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS"; @@ -48,12 +48,12 @@ app.on("before-quit", () => { isQuitting = true; }); -type VencordBrowserWindow = BrowserWindow & { - _vencord_tray?: Tray; +// Fixes circular dependency issues with export const +export const globals = { + tray: null, + mainWin: null }; -export let mainWin: VencordBrowserWindow; - function makeSettingsListenerHelpers(o: SettingsStore) { const listeners = new Map<(data: any) => void, PropertyKey>(); @@ -75,7 +75,7 @@ function makeSettingsListenerHelpers(o: SettingsStore) { const [addSettingsListener, removeSettingsListeners] = makeSettingsListenerHelpers(Settings); const [addVencordSettingsListener, removeVencordSettingsListeners] = makeSettingsListenerHelpers(VencordSettings); -function initTray(win: VencordBrowserWindow) { +function initTray(win: BrowserWindow) { const trayMenu = Menu.buildFromTemplate([ { label: "Open", @@ -121,7 +121,7 @@ function initTray(win: VencordBrowserWindow) { } ]); - const tray = new Tray(TRAY_ICON_PATH); + const tray = (globals.tray = new Tray(TRAY_ICON_PATH)); tray.setToolTip("Vesktop"); tray.setContextMenu(trayMenu); tray.on("click", () => win.show()); @@ -204,7 +204,7 @@ function initMenuBar(win: BrowserWindow) { label: "Settings", accelerator: "CmdOrCtrl+,", async click() { - mainWin.webContents.executeJavaScript( + globals.mainWin!.webContents.executeJavaScript( "Vencord.Webpack.Common.SettingsRouter.open('My Account')" ); } @@ -332,10 +332,14 @@ function initWindowBoundsListeners(win: BrowserWindow) { win.on("move", saveBounds); } -function initSettingsListeners(win: VencordBrowserWindow) { +function initSettingsListeners(win: BrowserWindow) { addSettingsListener("tray", enable => { - if (enable) initTray(win); - else win._vencord_tray?.destroy(); + if (enable) { + initTray(win); + } else if (globals.tray) { + globals.tray.destroy(); + globals.tray = null; + } }); addSettingsListener("disableMinSize", disable => { if (disable) { @@ -373,7 +377,7 @@ function initSpellCheck(win: BrowserWindow) { }); } -function createMainWindow(): VencordBrowserWindow { +function createMainWindow(): BrowserWindow { // Clear up previous settings listeners removeSettingsListeners(); removeVencordSettingsListeners(); @@ -384,7 +388,7 @@ function createMainWindow(): VencordBrowserWindow { const noFrame = frameless === true || (process.platform === "win32" && discordWindowsTitleBar === true); - const win = (mainWin = new BrowserWindow({ + const win = (globals.mainWin = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: false, @@ -452,7 +456,7 @@ export async function createWindows() { await ensureVencordFiles(); runVencordMain(); - mainWin = createMainWindow(); + const mainWin = (globals.mainWin = createMainWindow()); mainWin.webContents.on("did-finish-load", () => { splash.destroy();