From 779c8fa5165f15faf469ea1489073c781a3fbc03 Mon Sep 17 00:00:00 2001 From: Marocco2 Date: Sun, 7 Jan 2024 01:59:29 +0100 Subject: [PATCH 01/19] Remove `transparent: true` for transparencyOption (#266) Co-authored-by: V --- src/main/mainWindow.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 8fdb6ee..9c929db 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -396,7 +396,12 @@ function createMainWindow() { ...(transparencyOption && transparencyOption !== "none" && { backgroundColor: "#00000000", - backgroundMaterial: transparencyOption, + backgroundMaterial: transparencyOption + }), + // Fix transparencyOption for custom discord titlebar + ...(discordWindowsTitleBar && + transparencyOption && + transparencyOption !== "none" && { transparent: true }), ...(staticTitle && { title: "Vesktop" }), From 4074e8d6ac9c322d81b93e16fabde521e1a4c0c1 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sun, 7 Jan 2024 02:26:18 +0100 Subject: [PATCH 02/19] move internal state from settings.json to state.json --- src/main/firstLaunch.ts | 4 ++-- src/main/index.ts | 4 ++-- src/main/mainWindow.ts | 12 ++++++------ src/main/settings.ts | 31 ++++++++++++++++++++++++++----- src/main/utils/steamOS.ts | 10 +++++----- src/shared/settings.d.ts | 15 +++++++++------ src/shared/utils/SettingsStore.ts | 7 +++++++ src/updater/main.ts | 6 +++--- 8 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/main/firstLaunch.ts b/src/main/firstLaunch.ts index 0ce585d..d1bbceb 100644 --- a/src/main/firstLaunch.ts +++ b/src/main/firstLaunch.ts @@ -14,7 +14,7 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths"; import { autoStart } from "./autoStart"; import { DATA_DIR } from "./constants"; import { createWindows } from "./mainWindow"; -import { Settings } from "./settings"; +import { Settings, State } from "./settings"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; interface Data { @@ -44,9 +44,9 @@ export function createFirstLaunchTour() { if (!msg.startsWith("form:")) return; const data = JSON.parse(msg.slice(5)) as Data; + State.store.firstLaunch = false; Settings.store.minimizeToTray = data.minimizeToTray; Settings.store.discordBranch = data.discordBranch; - Settings.store.firstLaunch = false; Settings.store.arRPC = data.richPresence; if (data.autoStart) autoStart.enable(); diff --git a/src/main/index.ts b/src/main/index.ts index f73a543..6c43dfe 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -14,7 +14,7 @@ import { createFirstLaunchTour } from "./firstLaunch"; import { createWindows, mainWin } from "./mainWindow"; import { registerMediaPermissionsHandler } from "./mediaPermissions"; import { registerScreenShareHandler } from "./screenShare"; -import { Settings } from "./settings"; +import { Settings, State } from "./settings"; import { isDeckGameMode } from "./utils/steamOS"; if (IS_DEV) { @@ -84,7 +84,7 @@ if (!app.requestSingleInstanceLock({ IS_DEV })) { } async function bootstrap() { - if (!Object.hasOwn(Settings.store, "firstLaunch")) { + if (!Object.hasOwn(State.store, "firstLaunch")) { createFirstLaunchTour(); } else { createWindows(); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 9c929db..cff400b 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -34,7 +34,7 @@ import { UserAgent, VENCORD_FILES_DIR } from "./constants"; -import { Settings, VencordSettings } from "./settings"; +import { Settings, State, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS"; @@ -268,7 +268,7 @@ function getWindowBoundsOptions(): BrowserWindowConstructorOptions { // We want the default window behaivour to apply in game mode since it expects everything to be fullscreen and maximized. if (isDeckGameMode) return {}; - const { x, y, width, height } = Settings.store.windowBounds ?? {}; + const { x, y, width, height } = State.store.windowBounds ?? {}; const options = { width: width ?? DEFAULT_WIDTH, @@ -313,8 +313,8 @@ function getDarwinOptions(): BrowserWindowConstructorOptions { function initWindowBoundsListeners(win: BrowserWindow) { const saveState = () => { - Settings.store.maximized = win.isMaximized(); - Settings.store.minimized = win.isMinimized(); + State.store.maximized = win.isMaximized(); + State.store.minimized = win.isMinimized(); }; win.on("maximize", saveState); @@ -322,7 +322,7 @@ function initWindowBoundsListeners(win: BrowserWindow) { win.on("unmaximize", saveState); const saveBounds = () => { - Settings.store.windowBounds = win.getBounds(); + State.store.windowBounds = win.getBounds(); }; win.on("resize", saveBounds); @@ -459,7 +459,7 @@ export async function createWindows() { splash.destroy(); mainWin!.show(); - if (Settings.store.maximized && !isDeckGameMode) { + if (State.store.maximized && !isDeckGameMode) { mainWin!.maximize(); } diff --git a/src/main/settings.ts b/src/main/settings.ts index 6fad97f..c4df364 100644 --- a/src/main/settings.ts +++ b/src/main/settings.ts @@ -4,14 +4,15 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import { mkdirSync, readFileSync, writeFileSync } from "fs"; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; import { dirname, join } from "path"; -import type { Settings as TSettings } from "shared/settings"; +import type { Settings as TSettings, State as TState } from "shared/settings"; import { SettingsStore } from "shared/utils/SettingsStore"; import { DATA_DIR, VENCORD_SETTINGS_FILE } from "./constants"; const SETTINGS_FILE = join(DATA_DIR, "settings.json"); +const STATE_FILE = join(DATA_DIR, "state.json"); function loadSettings(file: string, name: string) { let settings = {} as T; @@ -20,7 +21,7 @@ function loadSettings(file: string, name: string) { try { settings = JSON.parse(content); } catch (err) { - console.error(`Failed to parse ${name} settings.json:`, err); + console.error(`Failed to parse ${name}.json:`, err); } } catch {} @@ -33,5 +34,25 @@ function loadSettings(file: string, name: string) { return store; } -export const Settings = loadSettings(SETTINGS_FILE, "Vesktop"); -export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord"); +export const Settings = loadSettings(SETTINGS_FILE, "Vesktop settings"); +export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord settings"); + +if (Object.hasOwn(Settings.store, "firstLaunch") && !existsSync(STATE_FILE)) { + console.warn("legacy state in settings.json detected. migrating to state.json"); + const state = {} as TState; + for (const prop of [ + "firstLaunch", + "maximized", + "minimized", + "skippedUpdate", + "steamOSLayoutVersion", + "windowBounds" + ]) { + state[prop] = Settings.plain[prop]; + delete Settings.plain[prop]; + } + Settings.markAsChanged(); + writeFileSync(STATE_FILE, JSON.stringify(state, null, 4)); +} + +export const State = loadSettings(STATE_FILE, "Vesktop state"); diff --git a/src/main/utils/steamOS.ts b/src/main/utils/steamOS.ts index 8145e5a..e61166c 100644 --- a/src/main/utils/steamOS.ts +++ b/src/main/utils/steamOS.ts @@ -9,7 +9,7 @@ import { writeFile } from "fs/promises"; import { join } from "path"; import { MessageBoxChoice } from "../constants"; -import { Settings } from "../settings"; +import { State } from "../settings"; // Bump this to re-show the prompt const layoutVersion = 2; @@ -70,8 +70,8 @@ async function showLayout(appId: string) { export async function askToApplySteamLayout(win: BrowserWindow) { const appId = getAppId(); if (!appId) return; - if (Settings.store.steamOSLayoutVersion === layoutVersion) return; - const update = Boolean(Settings.store.steamOSLayoutVersion); + if (State.store.steamOSLayoutVersion === layoutVersion) return; + const update = Boolean(State.store.steamOSLayoutVersion); // Touch screen breaks in some menus when native touch mode is enabled on latest SteamOS beta, remove most of the update specific text once that's fixed. const { response } = await dialog.showMessageBox(win, { @@ -87,8 +87,8 @@ ${update ? "Click" : "Tap"} no to keep your current layout.`, type: "question" }); - if (Settings.store.steamOSLayoutVersion !== layoutVersion) { - Settings.store.steamOSLayoutVersion = layoutVersion; + if (State.store.steamOSLayoutVersion !== layoutVersion) { + State.store.steamOSLayoutVersion = layoutVersion; } if (response === MessageBoxChoice.Cancel) return; diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index 6e5ccfc..8c63373 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -20,19 +20,22 @@ export interface Settings { arRPC?: boolean; appBadge?: boolean; discordWindowsTitleBar?: boolean; - - maximized?: boolean; - minimized?: boolean; - windowBounds?: Rectangle; disableMinSize?: boolean; checkUpdates?: boolean; - skippedUpdate?: string; - firstLaunch?: boolean; splashTheming?: boolean; splashColor?: string; splashBackground?: string; +} + +export interface State { + maximized?: boolean; + minimized?: boolean; + windowBounds?: Rectangle; + + skippedUpdate?: string; + firstLaunch?: boolean; steamOSLayoutVersion?: number; } diff --git a/src/shared/utils/SettingsStore.ts b/src/shared/utils/SettingsStore.ts index 89c57dd..22dd145 100644 --- a/src/shared/utils/SettingsStore.ts +++ b/src/shared/utils/SettingsStore.ts @@ -144,4 +144,11 @@ export class SettingsStore { listeners.delete(cb); if (!listeners.size) this.pathListeners.delete(path as string); } + + /** + * Call all global change listeners + */ + public markAsChanged() { + this.globalListeners.forEach(cb => cb(this.plain, "")); + } } diff --git a/src/updater/main.ts b/src/updater/main.ts index b84081c..059afb9 100644 --- a/src/updater/main.ts +++ b/src/updater/main.ts @@ -5,7 +5,7 @@ */ import { app, BrowserWindow, shell } from "electron"; -import { Settings } from "main/settings"; +import { Settings, State } from "main/settings"; import { handle } from "main/utils/ipcWrappers"; import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally"; import { githubGet, ReleaseData } from "main/utils/vencordLoader"; @@ -52,7 +52,7 @@ handle(IpcEvents.UPDATER_DOWNLOAD, () => { }); handle(IpcEvents.UPDATE_IGNORE, () => { - Settings.store.skippedUpdate = updateData.latestVersion; + State.store.skippedUpdate = updateData.latestVersion; }); function isOutdated(oldVersion: string, newVersion: string) { @@ -91,7 +91,7 @@ export async function checkUpdates() { release: data }; - if (Settings.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) { + if (State.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) { openNewUpdateWindow(); } } catch (e) { From effd950b2d35c9c0311b4d3be50e9d24ffccc087 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sun, 7 Jan 2024 02:44:14 +0100 Subject: [PATCH 03/19] fully rename app to Vesktop --- README.md | 6 +++--- build/installer.nsh | 8 ++++---- package.json | 4 ++-- src/main/constants.ts | 18 +++++++++++++++++- src/main/mainWindow.ts | 1 - 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index c63c163..0e55685 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ Vesktop is a cross platform desktop app aiming to give you a snappier Discord experience with [Vencord](https://github.com/Vendicated/Vencord) pre-installed **Not yet supported**: -- Global Keybinds + +- Global Keybinds Bug reports, feature requests & contributions are highly appreciated!! ![](https://github.com/Vencord/Vesktop/assets/45497981/8608a899-96a9-4027-9725-2cb02ba189fd) ![grafik](https://github.com/Vencord/Vesktop/assets/45497981/8701e5de-52c4-4346-a990-719cb971642e) - ## Installing ### Windows @@ -39,7 +39,7 @@ Download Vesktop-VERSION.rpm from [releases](https://github.com/Vencord/Vesktop/ #### Other -Either download Vesktop-VERSION.AppImage and just run it directly or grab Vesktop-VERSION.tar.gz, extract it somewhere and run `vencorddesktop`. +Either download Vesktop-VERSION.AppImage and just run it directly or grab Vesktop-VERSION.tar.gz, extract it somewhere and run `vesktop`. If other packages are created, feel free to open an issue and we'll link them here. diff --git a/build/installer.nsh b/build/installer.nsh index 2877dba..2bce914 100644 --- a/build/installer.nsh +++ b/build/installer.nsh @@ -1,8 +1,8 @@ !macro preInit SetRegView 64 - WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" - WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" + WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" + WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" SetRegView 32 - WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" - WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" + WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" + WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" !macroend diff --git a/package.json b/package.json index fae146f..43303e5 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "VencordDesktop", + "name": "vesktop", "version": "0.4.4", "private": true, "description": "", @@ -111,7 +111,7 @@ "Type": "Application", "Categories": "Network;InstantMessaging;Chat;", "Keywords": "discord;vencord;electron;chat;", - "StartupWMClass": "VencordDesktop" + "StartupWMClass": "vesktop" } }, "mac": { diff --git a/src/main/constants.ts b/src/main/constants.ts index 068521b..fb873ee 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -5,9 +5,25 @@ */ import { app } from "electron"; +import { existsSync, readdirSync, renameSync, rmdirSync } from "fs"; import { join } from "path"; -export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR || join(app.getPath("userData"), "VencordDesktop"); +const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop"); +export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR || join(app.getPath("userData")); +// TODO: remove eventually +if (existsSync(LEGACY_DATA_DIR)) { + try { + console.warn("Detected legacy settings dir", LEGACY_DATA_DIR + ".", "migrating to", DATA_DIR); + for (const file of readdirSync(LEGACY_DATA_DIR)) { + renameSync(join(LEGACY_DATA_DIR, file), join(DATA_DIR, file)); + } + rmdirSync(LEGACY_DATA_DIR); + } catch (e) { + console.error("Migration failed", e); + } +} +app.setPath("sessionData", join(DATA_DIR, "sessionData")); + export const VENCORD_SETTINGS_DIR = join(DATA_DIR, "settings"); export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css"); export const VENCORD_SETTINGS_FILE = join(VENCORD_SETTINGS_DIR, "settings.json"); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index cff400b..68cc0cb 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -210,7 +210,6 @@ function initMenuBar(win: BrowserWindow) { type: "separator" }, { - label: "Hide Vesktop", // Should probably remove the label, but it says "Hide VencordDesktop" instead of "Hide Vesktop" role: "hide" }, { From 0881143d57235ae1d64674c136fc03b9b09a5594 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sun, 7 Jan 2024 02:52:39 +0100 Subject: [PATCH 04/19] update appId --- package.json | 5 ++--- src/main/index.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 43303e5..274c375 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "pnpm": ">=8" }, "build": { - "appId": "dev.vencord.desktop", + "appId": "dev.vencord.vesktop", "productName": "Vesktop", "files": [ "!*", @@ -110,8 +110,7 @@ "GenericName": "Internet Messenger", "Type": "Application", "Categories": "Network;InstantMessaging;Chat;", - "Keywords": "discord;vencord;electron;chat;", - "StartupWMClass": "vesktop" + "Keywords": "discord;vencord;electron;chat;" } }, "mac": { diff --git a/src/main/index.ts b/src/main/index.ts index 6c43dfe..9d6a52c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -58,7 +58,7 @@ function init() { app.whenReady().then(async () => { checkUpdates(); - if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop"); + if (process.platform === "win32") app.setAppUserModelId("dev.vencord.vesktop"); registerScreenShareHandler(); registerMediaPermissionsHandler(); From 0f0bddbef916286f5a2e6391660120c8ce9bfda5 Mon Sep 17 00:00:00 2001 From: Redeven <18680184+redeven@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:11:00 -0300 Subject: [PATCH 05/19] feat: Add start minimized as a launch argument (#316) Co-authored-by: V --- src/main/mainWindow.ts | 15 +++++++++++---- src/main/splash.ts | 5 +++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 68cc0cb..2561c43 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -446,7 +446,8 @@ function createMainWindow() { const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"))); export async function createWindows() { - const splash = createSplashWindow(); + const startMinimized = process.argv.includes("--start-minimized"); + const splash = createSplashWindow(startMinimized); // SteamOS letterboxes and scales it terribly, so just full screen it if (isDeckGameMode) splash.setFullScreen(true); await ensureVencordFiles(); @@ -456,10 +457,10 @@ export async function createWindows() { mainWin.webContents.on("did-finish-load", () => { splash.destroy(); - mainWin!.show(); - if (State.store.maximized && !isDeckGameMode) { - mainWin!.maximize(); + if (!startMinimized) { + mainWin!.show(); + if (State.store.maximized && !isDeckGameMode) mainWin!.maximize(); } if (isDeckGameMode) { @@ -468,6 +469,12 @@ export async function createWindows() { askToApplySteamLayout(mainWin); } + + mainWin.once("show", () => { + if (State.store.maximized && !mainWin!.isMaximized() && !isDeckGameMode) { + mainWin!.maximize(); + } + }); }); initArRPC(); diff --git a/src/main/splash.ts b/src/main/splash.ts index f21799d..7c05de9 100644 --- a/src/main/splash.ts +++ b/src/main/splash.ts @@ -11,10 +11,11 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths"; import { Settings } from "./settings"; -export function createSplashWindow() { +export function createSplashWindow(startMinimized = false) { const splash = new BrowserWindow({ ...SplashProps, - icon: ICON_PATH + icon: ICON_PATH, + show: !startMinimized }); splash.loadFile(join(VIEW_DIR, "splash.html")); From 62cf02e7b10b8c755d6f9ad26ecd2b407ae1169f Mon Sep 17 00:00:00 2001 From: Vendicated Date: Mon, 8 Jan 2024 02:38:38 +0100 Subject: [PATCH 06/19] make splash window draggable --- static/views/splash.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/views/splash.html b/static/views/splash.html index 94ef13e..bac2ad2 100644 --- a/static/views/splash.html +++ b/static/views/splash.html @@ -2,8 +2,9 @@