Skip to content

Commit

Permalink
Remove vibe and implement setBackgroundMaterial
Browse files Browse the repository at this point in the history
  • Loading branch information
EastArctica committed Jan 15, 2025
1 parent 052b1cd commit 04c3c4a
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 106 deletions.
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,7 @@
"yargs": "^17.7.2",
"zod": "^3.23.8"
},
"optionalDependencies": {
"@pyke/vibe": "^0.4.0"
},
"bin": {
"replugged": "bin.mjs"
}
}
}
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions scripts/build.mts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ const contexts = await Promise.all([
target: `node${NODE_VERSION}`,
outfile: `${distDir}/main.js`,
external: ["electron", "original-fs"],
loader: {
".node": "file",
},
}),
// Preload
esbuild.context({
Expand Down
58 changes: 35 additions & 23 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ import electron from "electron";
import { CONFIG_PATHS, readSettingsSync } from "src/util.mjs";
import type { RepluggedWebContents } from "../types";
import { getSetting } from "./ipc/settings";
// @ts-expect-error Type defs are obtained through @pyke/vibe
import vibePath from "../vibe.node";

let vibe: typeof import("@pyke/vibe");
if (process.platform === "win32") {
vibe = require(vibePath) as unknown as typeof import("@pyke/vibe");
vibe.setup(electron.app);
}

const settings = readSettingsSync("dev.replugged.Settings");
const electronPath = require.resolve("electron");
Expand Down Expand Up @@ -57,7 +49,8 @@ function windowTypeFromOpts(opts: InternalBrowserWindowConstructorOptions): Disc
if (opts.webPreferences.nativeWindowOpen) {
return DiscordWindowType.DISCORD_CLIENT;
} else {
return DiscordWindowType.SPLASH_SCREEN;
// Splash Screen on macOS (Host 0.0.262+) & Windows (Host 0.0.293 / 1.0.17+)
return DiscordWindowType.DISCORD_CLIENT;
}
}

Expand All @@ -80,16 +73,13 @@ class BrowserWindow extends electron.BrowserWindow {
if (settings.get("transparentWindow")) {
switch (process.platform) {
case "win32":
// @todo: Menu bar will need to be remade
opts.autoHideMenuBar = true;
opts.show = false; // @todo: Unsure if this is needed everywhere
opts.transparent = true;
opts.backgroundColor = "#00000000";
break;
case "linux":
opts.transparent = true;
break;
}
// @todo: Determine what `frame` value is needed on each platform
// @todo: Determine what `backgroundColor` is needed on each platform
}
break;
}
Expand All @@ -105,19 +95,41 @@ class BrowserWindow extends electron.BrowserWindow {

super(opts);

if (currentWindow === DiscordWindowType.DISCORD_CLIENT && settings.get("transparentWindow")) {
this.on("ready-to-show", () => {
// if (process.platform === "win32") {
// vibe.applyEffect(this, "unified-acrylic");
// vibe.forceTheme(this, "dark");
// }
// @todo: unsure if this is needed
this.setBackgroundColor("#00000000");
});
// Center the unmaximized location
if (settings.get("transparentWindow")) {
const currentDisplay = electron.screen.getDisplayNearestPoint(electron.screen.getCursorScreenPoint())
this.repluggedPreviousBounds.x = currentDisplay.workArea.width / 2 - this.repluggedPreviousBounds.width / 2;
this.repluggedPreviousBounds.y = currentDisplay.workArea.height / 2 - this.repluggedPreviousBounds.height / 2;
this.maximize = this.repluggedToggleMaximize;
this.unmaximize = this.repluggedToggleMaximize;
}

(this.webContents as RepluggedWebContents).originalPreload = originalPreload;
}


private repluggedPreviousBounds: Electron.Rectangle = {
width: 1400,
height: 900,
x: 0,
y: 0
};

public repluggedToggleMaximize(): void {
// Determine whether the display is actually maximized already
let currentBounds = this.getBounds();
const currentDisplay = electron.screen.getDisplayNearestPoint(electron.screen.getCursorScreenPoint());
const workAreaSize = currentDisplay.workArea;
if (currentBounds.width === workAreaSize.width && currentBounds.height === workAreaSize.height) {
// Un-maximize
this.setBounds(this.repluggedPreviousBounds)
return;
}


this.repluggedPreviousBounds = this.getBounds()
this.setBounds({ x: workAreaSize.x + 1, y: workAreaSize.y + 1, width: workAreaSize.width, height: workAreaSize.height })
}
}

Object.defineProperty(BrowserWindow, "name", {
Expand Down
9 changes: 1 addition & 8 deletions src/main/ipc/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import { ipcMain } from "electron";
import { RepluggedIpcChannels, type RepluggedWebContents } from "../../types";
import "./plugins";
import "./themes";
import "./quick-css";
import "./settings";
import "./installer";
import "./i18n";
import "./react-devtools";
import "./transparency";
import "./installer";
import "./plugins";
import "./quick-css";
import "./react-devtools";
import "./settings";
import "./themes";
import './transparency';

ipcMain.on(RepluggedIpcChannels.GET_DISCORD_PRELOAD, (event) => {
event.returnValue = (event.sender as RepluggedWebContents).originalPreload;
Expand Down
80 changes: 37 additions & 43 deletions src/main/ipc/transparency.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,32 @@
import { BrowserWindow, ipcMain } from "electron";
import { RepluggedIpcChannels } from "../../types";
import os from "os";
// @ts-expect-error Type defs are obtained through @pyke/vibe
import vibePath from "../../vibe.node";

let vibe: typeof import("@pyke/vibe");
let release = os.release().split(".").map(Number);
let usesVibe =
// Windows
process.platform === "win32" &&
// Before Electron 24
Number(process.versions.electron.split(".")[0]) < 24 &&
// Before Windows 11 22H2+
release[0] <= 10 && // 11 doesn't exist yet but it could.
release[1] < 22621;

if (usesVibe) {
try {
vibe = require(vibePath) as unknown as typeof import("@pyke/vibe");
} catch (error) {
console.error("Failed to load vibe.", error);
}
}

let currentEffect: Parameters<typeof vibe.applyEffect>[1] | null = null;
let backgroundMaterial: "auto" | "none" | "mica" | "acrylic" | "tabbed" | null = null;
ipcMain.handle(
RepluggedIpcChannels.GET_TRANSPARENCY_EFFECT,
(): Parameters<typeof vibe.applyEffect>[1] | null => {
RepluggedIpcChannels.GET_BACKGROUND_MATERIAL,
(): "auto" | "none" | "mica" | "acrylic" | "tabbed" | null => {
if (process.platform !== "win32") {
console.warn("GET_TRANSPARENCY_EFFECT only works on Windows");
console.warn("GET_BACKGROUND_MATERIAL only works on Windows");
}

return currentEffect;
return backgroundMaterial;
},
);

ipcMain.handle(
RepluggedIpcChannels.APPLY_TRANSPARENCY_EFFECT,
(_, effect: Parameters<typeof vibe.applyEffect>[1] | null) => {
RepluggedIpcChannels.SET_BACKGROUND_MATERIAL,
(_, material: "auto" | "none" | "mica" | "acrylic" | "tabbed" | null) => {
if (process.platform !== "win32") {
console.warn("APPLY_TRANSPARENCY_EFFECT only works on Windows");
console.warn("SET_BACKGROUND_MATERIAL only works on Windows");
return;
}

let windows = BrowserWindow.getAllWindows();
windows.forEach((window) => {
if (!usesVibe) {
// The valid options for setBackgroundMaterial are "auto" | "none" | "mica" | "acrylic" | "tabbed".
// This goes against vibe which allows for "unified-acrylic" and "blurbehind".
// Also, vibe does not allow for "auto", "none" or "tabbed"

// @ts-expect-error Only exists in electron 24+, our types don't have this.
window.setBackgroundMaterial(effect === null ? "none" : effect); // NULL is used to disable.
} else if (effect === null) {
vibe.clearEffects(window);
} else {
vibe.applyEffect(window, effect);
}
// @ts-expect-error standalone-electron-types is not updated to have this.
window.setBackgroundMaterial(typeof material === "string" ? material : "none");
});
currentEffect = effect;
backgroundMaterial = material;
},
);

Expand All @@ -77,3 +45,29 @@ ipcMain.handle(
currentVibrancy = vibrancy;
},
);

let currentBackgroundColor = "#00000000";
ipcMain.handle(
RepluggedIpcChannels.GET_BACKGROUND_COLOR,
(): string => {
if (process.platform !== "win32") {
console.warn("SET_BACKGROUND_COLOR only works on Windows");
}

return currentBackgroundColor;
}
)

ipcMain.handle(
RepluggedIpcChannels.SET_BACKGROUND_COLOR,
(_, color: string | undefined) => {
if (process.platform !== "win32") {
console.warn("SET_BACKGROUND_COLOR only works on Windows");
return;
}

let windows = BrowserWindow.getAllWindows();
windows.forEach((window) => window.setBackgroundColor(color || "#00000000"));
currentBackgroundColor = color || "#00000000";
},
);
16 changes: 9 additions & 7 deletions src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import type {
RepluggedPlugin,
RepluggedTheme,
} from "./types";
// Note that this may ONLY be used for types.
import vibe from "@pyke/vibe";

let version = "";
void ipcRenderer.invoke(RepluggedIpcChannels.GET_REPLUGGED_VERSION).then((v) => {
Expand Down Expand Up @@ -106,10 +104,14 @@ const RepluggedNative = {
},

transparency: {
getEffect: (): Promise<Parameters<typeof vibe.applyEffect>[1]> =>
ipcRenderer.invoke(RepluggedIpcChannels.GET_TRANSPARENCY_EFFECT),
applyEffect: (effect: Parameters<typeof vibe.applyEffect>[1]): Promise<void> =>
ipcRenderer.invoke(RepluggedIpcChannels.APPLY_TRANSPARENCY_EFFECT, effect),
getBackgroundMaterial: (): Promise<"auto" | "none" | "mica" | "acrylic" | "tabbed"> =>
ipcRenderer.invoke(RepluggedIpcChannels.GET_BACKGROUND_MATERIAL),
setBackgroundMaterial: (effect: "auto" | "none" | "mica" | "acrylic" | "tabbed"): Promise<void> =>
ipcRenderer.invoke(RepluggedIpcChannels.SET_BACKGROUND_MATERIAL, effect),
getBackgroundColor: (): Promise<string> =>
ipcRenderer.invoke(RepluggedIpcChannels.GET_BACKGROUND_COLOR),
setBackgroundColor: (color: string): Promise<void> =>
ipcRenderer.invoke(RepluggedIpcChannels.SET_BACKGROUND_COLOR, color),
getVibrancy: (): Promise<Parameters<typeof BrowserWindow.prototype.setVibrancy>[0]> =>
ipcRenderer.invoke(RepluggedIpcChannels.GET_VIBRANCY),
setVibrancy: (
Expand All @@ -121,7 +123,7 @@ const RepluggedNative = {
getVersion: () => version,

// eslint-disable-next-line @typescript-eslint/no-unused-vars
openBrowserWindow: (opts: BrowserWindowConstructorOptions) => {}, // later
openBrowserWindow: (opts: BrowserWindowConstructorOptions) => { }, // later

// @todo: We probably want to move these somewhere else, but I'm putting them here for now because I'm too lazy to set anything else up
};
Expand Down
8 changes: 4 additions & 4 deletions src/renderer/coremods/settings/pages/General.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ export const General = (): React.ReactElement => {
DiscordNative.process.platform === "win32") && (
<Notice messageType={Notice.Types.WARNING} className="">
{DiscordNative.process.platform === "linux"
? Messages.REPLUGGED_SETTINGS_TRANSPARENT_ISSUES_LINUX.format()
: Messages.REPLUGGED_SETTINGS_TRANSPARENT_ISSUES_WINDOWS.format()}
? intl.format(t.REPLUGGED_SETTINGS_TRANSPARENT_ISSUES_LINUX, {})
: intl.format(t.REPLUGGED_SETTINGS_TRANSPARENT_ISSUES_WINDOWS, {})}
</Notice>
)}
</div>
Expand All @@ -131,8 +131,8 @@ export const General = (): React.ReactElement => {
transOnChange(value);
restartModal(true);
}}
note={Messages.REPLUGGED_SETTINGS_TRANSPARENT_DESC.format()}>
{Messages.REPLUGGED_SETTINGS_TRANSPARENT}
note={intl.format(t.REPLUGGED_SETTINGS_TRANSPARENT_DESC, {})}>
{intl.string(t.REPLUGGED_SETTINGS_TRANSPARENT)}
</SwitchItem>

<Category
Expand Down
31 changes: 23 additions & 8 deletions src/renderer/coremods/transparency/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { Logger } from "@replugged";

let observer: MutationObserver;

function getRootStringProperty(property: string): string {
function getRootProperty(property: string): string {
const computedStyle = getComputedStyle(document.body);
const value = computedStyle.getPropertyValue(property);

return value;
}

function getRootStringProperty(property: string): string {
const value = getRootProperty(property);
return value.split('"')[1];
}

const logger = Logger.coremod("Transparency");

export function start(): void {
let html = document.body.parentElement!;

Expand All @@ -32,28 +41,34 @@ export function start(): void {
}

if (cssModified) {
// Originally this used requestAnimationFrame but it took to long
// Originally this used requestAnimationFrame but it took too long
// so instead we setTimeout and pray. The setTimeout could be
// shorter if we wanted, but it's hard to say if it would
// work as consistently.
setTimeout(async () => {
switch (DiscordNative.process.platform) {
case "win32": {
const transparencyEffect = getRootStringProperty("--window-win-blur");
if (transparencyEffect === (await RepluggedNative.transparency.getEffect())) {
return;
const backgroundMaterial = getRootStringProperty("--window-background-material");
if (backgroundMaterial !== (await RepluggedNative.transparency.getBackgroundMaterial())) {
logger.log('Setting background material to:', backgroundMaterial);
// @ts-expect-error @todo: Check if the transparency effect is valid?
await RepluggedNative.transparency.setBackgroundMaterial(backgroundMaterial);
}

// @ts-expect-error @todo: Check if the transparency effect is valid?
await RepluggedNative.transparency.applyEffect(transparencyEffect);
const backgroundColor = getRootProperty("--window-background-color");
if (backgroundColor !== (await RepluggedNative.transparency.getBackgroundColor())) {
logger.log('Setting background color to:', backgroundColor);
await RepluggedNative.transparency.setBackgroundColor(backgroundColor);
}
break;
}
case "darwin": {
const vibrancy = getRootStringProperty("--window-vibrancy");
if (vibrancy === (await RepluggedNative.transparency.getVibrancy())) {
return;
break;
}

logger.log('Setting vibrancy effect to:', vibrancy);
// @ts-expect-error @todo: Check if the vibrancy is valid?
await RepluggedNative.transparency.setVibrancy(vibrancy);
break;
Expand Down
Loading

0 comments on commit 04c3c4a

Please sign in to comment.