add Windows background material customisation (#4230)
This commit is contained in:
parent
9b94e49622
commit
b8a515dff5
9 changed files with 183 additions and 112 deletions
|
|
@ -55,6 +55,7 @@ window.VencordNative = {
|
|||
|
||||
native: {
|
||||
getVersions: () => ({}),
|
||||
supportsWindowsMaterial: () => false,
|
||||
openExternal: async (url) => void open(url, "_blank"),
|
||||
getRendererCss: async () => {
|
||||
if (IS_USERSCRIPT)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ export default {
|
|||
|
||||
native: {
|
||||
getVersions: () => process.versions as Partial<NodeJS.ProcessVersions>,
|
||||
supportsWindowsMaterial: () => sendSync<boolean>(IpcEvents.SUPPORTS_WINDOWS_MATERIAL),
|
||||
openExternal: (url: string) => invoke<void>(IpcEvents.OPEN_EXTERNAL, url),
|
||||
getRendererCss: () => invoke<string>(IpcEvents.GET_RENDERER_CSS),
|
||||
onRendererCssUpdate: (cb: (newCss: string) => void) => {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ export interface Settings {
|
|||
| "under-page"
|
||||
| "window"
|
||||
| undefined;
|
||||
windowsMaterial: "none" | "mica" | "tabbed" | "acrylic";
|
||||
disableMinSize: boolean;
|
||||
winNativeTitleBar: boolean;
|
||||
plugins: {
|
||||
|
|
@ -103,6 +104,7 @@ const DefaultSettings: Settings = {
|
|||
transparent: false,
|
||||
winCtrlQ: false,
|
||||
macosVibrancyStyle: undefined,
|
||||
windowsMaterial: "none",
|
||||
disableMinSize: false,
|
||||
winNativeTitleBar: false,
|
||||
plugins: {},
|
||||
|
|
|
|||
|
|
@ -6,79 +6,80 @@
|
|||
|
||||
import { useSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { IS_MAC } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { identity } from "@utils/misc";
|
||||
import { Forms, Select } from "@webpack/common";
|
||||
|
||||
export function VibrancySettings() {
|
||||
export function MacOSVibrancySettings() {
|
||||
const settings = useSettings(["macosVibrancyStyle"]);
|
||||
|
||||
if (!IS_MAC || IS_WEB) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Forms.FormTitle tag="h5">Window vibrancy style (requires restart)</Forms.FormTitle>
|
||||
<ErrorBoundary noop>
|
||||
<Select
|
||||
className={Margins.bottom20}
|
||||
placeholder="Window vibrancy style"
|
||||
options={[
|
||||
// Sorted from most opaque to most transparent
|
||||
{
|
||||
label: "No vibrancy", value: undefined
|
||||
},
|
||||
{
|
||||
label: "Under Page (window tinting)",
|
||||
value: "under-page"
|
||||
},
|
||||
{
|
||||
label: "Content",
|
||||
value: "content"
|
||||
},
|
||||
{
|
||||
label: "Window",
|
||||
value: "window"
|
||||
},
|
||||
{
|
||||
label: "Selection",
|
||||
value: "selection"
|
||||
},
|
||||
{
|
||||
label: "Titlebar",
|
||||
value: "titlebar"
|
||||
},
|
||||
{
|
||||
label: "Header",
|
||||
value: "header"
|
||||
},
|
||||
{
|
||||
label: "Sidebar",
|
||||
value: "sidebar"
|
||||
},
|
||||
{
|
||||
label: "Tooltip",
|
||||
value: "tooltip"
|
||||
},
|
||||
{
|
||||
label: "Menu",
|
||||
value: "menu"
|
||||
},
|
||||
{
|
||||
label: "Popover",
|
||||
value: "popover"
|
||||
},
|
||||
{
|
||||
label: "Fullscreen UI (transparent but slightly muted)",
|
||||
value: "fullscreen-ui"
|
||||
},
|
||||
{
|
||||
label: "HUD (Most transparent)",
|
||||
value: "hud"
|
||||
},
|
||||
]}
|
||||
select={v => settings.macosVibrancyStyle = v}
|
||||
isSelected={v => settings.macosVibrancyStyle === v}
|
||||
serialize={identity}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</>
|
||||
<ErrorBoundary noop>
|
||||
<Forms.FormTitle tag="h5">MacOS Window vibrancy style (requires restart)</Forms.FormTitle>
|
||||
<Select
|
||||
className={Margins.bottom20}
|
||||
placeholder="Window vibrancy style"
|
||||
options={[
|
||||
// Sorted from most opaque to most transparent
|
||||
{
|
||||
label: "No vibrancy", value: undefined
|
||||
},
|
||||
{
|
||||
label: "Under Page (window tinting)",
|
||||
value: "under-page"
|
||||
},
|
||||
{
|
||||
label: "Content",
|
||||
value: "content"
|
||||
},
|
||||
{
|
||||
label: "Window",
|
||||
value: "window"
|
||||
},
|
||||
{
|
||||
label: "Selection",
|
||||
value: "selection"
|
||||
},
|
||||
{
|
||||
label: "Titlebar",
|
||||
value: "titlebar"
|
||||
},
|
||||
{
|
||||
label: "Header",
|
||||
value: "header"
|
||||
},
|
||||
{
|
||||
label: "Sidebar",
|
||||
value: "sidebar"
|
||||
},
|
||||
{
|
||||
label: "Tooltip",
|
||||
value: "tooltip"
|
||||
},
|
||||
{
|
||||
label: "Menu",
|
||||
value: "menu"
|
||||
},
|
||||
{
|
||||
label: "Popover",
|
||||
value: "popover"
|
||||
},
|
||||
{
|
||||
label: "Fullscreen UI (transparent but slightly muted)",
|
||||
value: "fullscreen-ui"
|
||||
},
|
||||
{
|
||||
label: "HUD (Most transparent)",
|
||||
value: "hud"
|
||||
},
|
||||
]}
|
||||
select={v => settings.macosVibrancyStyle = v}
|
||||
isSelected={v => settings.macosVibrancyStyle === v}
|
||||
serialize={identity}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2026 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { useSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Heading } from "@components/Heading";
|
||||
import { Margins } from "@components/margins";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { IS_WINDOWS } from "@utils/constants";
|
||||
import { Select } from "@webpack/common";
|
||||
|
||||
export function WindowsMaterialSettings() {
|
||||
const settings = useSettings(["windowsMaterial"]);
|
||||
|
||||
if (!IS_WINDOWS || IS_WEB || !VencordNative.native.supportsWindowsMaterial()) return null;
|
||||
|
||||
return (
|
||||
<ErrorBoundary noop>
|
||||
<Heading tag="h5">Background Material</Heading>
|
||||
<Paragraph className={Margins.bottom8}>
|
||||
Windows transparent background effects. You need a theme that supports transparency or this will do nothing. A restart is required after changing this setting.
|
||||
</Paragraph>
|
||||
|
||||
<Select
|
||||
placeholder="None"
|
||||
options={[
|
||||
{
|
||||
label: "None",
|
||||
value: "none",
|
||||
default: true
|
||||
},
|
||||
{
|
||||
label: "Mica (incorporates system theme + desktop wallpaper to paint the background)",
|
||||
value: "mica"
|
||||
},
|
||||
{
|
||||
label: "Tabbed (variant of Mica with stronger background tinting)",
|
||||
value: "tabbed"
|
||||
},
|
||||
{
|
||||
label: "Acrylic (blurs the window behind Vesktop for a translucent background)",
|
||||
value: "acrylic"
|
||||
}
|
||||
]}
|
||||
closeOnSelect={true}
|
||||
select={v => (settings.windowsMaterial = v)}
|
||||
isSelected={v => v === settings.windowsMaterial}
|
||||
serialize={s => s}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
|
@ -28,15 +28,16 @@ import { openContributorModal } from "@components/settings/tabs/plugins/Contribu
|
|||
import { openPluginModal } from "@components/settings/tabs/plugins/PluginModal";
|
||||
import SettingsPlugin from "@plugins/_core/settings";
|
||||
import { gitRemote } from "@shared/vencordUserAgent";
|
||||
import { IS_MAC, IS_WINDOWS } from "@utils/constants";
|
||||
import { IS_WINDOWS } from "@utils/constants";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { isPluginDev } from "@utils/misc";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { ConfirmModal,Forms, openModal, React, useMemo, UserStore } from "@webpack/common";
|
||||
import { ConfirmModal, Forms, openModal, React, useMemo, UserStore } from "@webpack/common";
|
||||
|
||||
import { DonateButtonComponent, isDonor } from "./DonateButton";
|
||||
import { VibrancySettings } from "./MacVibrancySettings";
|
||||
import { MacOSVibrancySettings } from "./MacVibrancySettings";
|
||||
import { NotificationSection } from "./NotificationSettings";
|
||||
import { WindowsMaterialSettings } from "./WindowsMaterialSettings";
|
||||
|
||||
const DEFAULT_DONATE_IMAGE = "https://cdn.discordapp.com/emojis/1026533090627174460.png";
|
||||
const SHIGGY_DONATE_IMAGE = "https://media.discordapp.net/stickers/1039992459209490513.png";
|
||||
|
|
@ -135,8 +136,6 @@ function VencordSettings() {
|
|||
[]
|
||||
);
|
||||
|
||||
const needsVibrancySettings = IS_DISCORD_DESKTOP && IS_MAC;
|
||||
|
||||
const user = UserStore?.getCurrentUser();
|
||||
|
||||
return (
|
||||
|
|
@ -231,7 +230,8 @@ function VencordSettings() {
|
|||
</section>
|
||||
|
||||
|
||||
{needsVibrancySettings && <VibrancySettings />}
|
||||
<MacOSVibrancySettings />
|
||||
<WindowsMaterialSettings />
|
||||
|
||||
<NotificationSection />
|
||||
</SettingsTab>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import { BrowserWindow, ipcMain, nativeTheme, shell, systemPreferences } from "e
|
|||
import monacoHtml from "file://monacoWin.html?minify&base64";
|
||||
import { FSWatcher, mkdirSync, readFileSync, watch, writeFileSync } from "fs";
|
||||
import { open, readdir, readFile } from "fs/promises";
|
||||
import { release } from "os";
|
||||
import { join, normalize } from "path";
|
||||
|
||||
import { registerCspIpcHandlers } from "./csp/manager";
|
||||
|
|
@ -176,3 +177,7 @@ if (IS_DISCORD_DESKTOP) {
|
|||
e.returnValue = readFileSync(join(__dirname, "renderer.js"), "utf-8");
|
||||
});
|
||||
}
|
||||
|
||||
ipcMain.on(IpcEvents.SUPPORTS_WINDOWS_MATERIAL, e => {
|
||||
e.returnValue = process.platform === "win32" && Number(release().split(".")[2]) >= 22621;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -68,47 +68,51 @@ if (!IS_VANILLA) {
|
|||
|
||||
class BrowserWindow extends electron.BrowserWindow {
|
||||
constructor(options: BrowserWindowConstructorOptions) {
|
||||
if (options?.webPreferences?.preload && options.title) {
|
||||
const original = options.webPreferences.preload;
|
||||
options.webPreferences.preload = join(__dirname, "preload.js");
|
||||
options.webPreferences.sandbox = false;
|
||||
// work around discord unloading when in background
|
||||
options.webPreferences.backgroundThrottling = false;
|
||||
|
||||
if (settings.frameless) {
|
||||
options.frame = false;
|
||||
} else if (process.platform === "win32" && settings.winNativeTitleBar) {
|
||||
delete options.frame;
|
||||
}
|
||||
|
||||
if (settings.transparent) {
|
||||
options.transparent = true;
|
||||
options.backgroundColor = "#00000000";
|
||||
}
|
||||
|
||||
if (settings.disableMinSize) {
|
||||
options.minWidth = 0;
|
||||
options.minHeight = 0;
|
||||
}
|
||||
|
||||
const needsVibrancy = process.platform === "darwin" && settings.macosVibrancyStyle;
|
||||
|
||||
if (needsVibrancy) {
|
||||
options.backgroundColor = "#00000000";
|
||||
if (settings.macosVibrancyStyle) {
|
||||
options.vibrancy = settings.macosVibrancyStyle;
|
||||
}
|
||||
}
|
||||
|
||||
process.env.DISCORD_PRELOAD = original;
|
||||
|
||||
if (!options?.webPreferences?.preload || !options.title) {
|
||||
super(options);
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.disableMinSize) {
|
||||
// Disable the Electron call entirely so that Discord can't dynamically change the size
|
||||
this.setMinimumSize = (width: number, height: number) => { };
|
||||
}
|
||||
} else super(options);
|
||||
const { frameless, winNativeTitleBar, disableMinSize, transparent, macosVibrancyStyle, windowsMaterial } = settings;
|
||||
|
||||
const original = options.webPreferences.preload;
|
||||
options.webPreferences.preload = join(__dirname, "preload.js");
|
||||
options.webPreferences.sandbox = false;
|
||||
// work around discord unloading when in background
|
||||
options.webPreferences.backgroundThrottling = false;
|
||||
|
||||
if (frameless) {
|
||||
options.frame = false;
|
||||
} else if (process.platform === "win32" && winNativeTitleBar) {
|
||||
delete options.frame;
|
||||
}
|
||||
|
||||
if (disableMinSize) {
|
||||
options.minWidth = 0;
|
||||
options.minHeight = 0;
|
||||
}
|
||||
|
||||
if (transparent) {
|
||||
options.transparent = true;
|
||||
options.backgroundColor = "#00000000";
|
||||
}
|
||||
if (process.platform === "darwin" && macosVibrancyStyle) {
|
||||
options.vibrancy = macosVibrancyStyle;
|
||||
options.backgroundColor = "#00000000";
|
||||
}
|
||||
if (process.platform === "win32" && windowsMaterial && windowsMaterial !== "none") {
|
||||
options.backgroundMaterial = windowsMaterial;
|
||||
options.backgroundColor = "#00000000";
|
||||
}
|
||||
|
||||
process.env.DISCORD_PRELOAD = original;
|
||||
|
||||
super(options);
|
||||
|
||||
if (disableMinSize) {
|
||||
// Disable the Electron call entirely so that Discord can't dynamically change the size
|
||||
this.setMinimumSize = (_width: number, _height: number) => { };
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.assign(BrowserWindow, electron.BrowserWindow);
|
||||
|
|
|
|||
|
|
@ -53,4 +53,6 @@ export const enum IpcEvents {
|
|||
GET_RENDERER_CSS = "VencordGetRendererCss",
|
||||
RENDERER_CSS_UPDATE = "VencordRendererCssUpdate",
|
||||
PRELOAD_GET_RENDERER_JS = "VencordPreloadGetRendererJs",
|
||||
|
||||
SUPPORTS_WINDOWS_MATERIAL = "VencordSupportsWindowsMaterial",
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue