diff --git a/assets/lang/en-US.json b/assets/lang/en-US.json index cfede343..9987c862 100644 --- a/assets/lang/en-US.json +++ b/assets/lang/en-US.json @@ -15,8 +15,12 @@ "settings-theme-desc": "Window style manages what titlebar Legcord uses.", "settings-theme-default": "Default (Custom)", "settings-theme-native": "Native", - "settings-theme-transparent": "Transparent", "settings-theme-overlay": "Overlay", + "settings-transparency": "Transparency", + "settings-transparency-desc": "Set the transparency mode Legcord uses.", + "settings-transparency-universal": "Universal", + "settings-transparency-modern": "Modern (Windows 11 only)", + "settings-theme-transparent": "Transparent", "settings-audio": "Audio", "settings-audio-desc": "Select which method Legcord uses to grab audio from your system during screenshare.", "settings-csp-desc": "Legcord CSP is our system that manages loading custom content loading into the Discord app. Stuff like client mods and themes depend on it. Disable if you want to get rid of mods and custom styles.", diff --git a/build/icon.icns b/build/icon.icns index 005e190a..262fd947 100644 Binary files a/build/icon.icns and b/build/icon.icns differ diff --git a/src/@types/settings.d.ts b/src/@types/settings.d.ts index 2c1622e4..3190ad4a 100644 --- a/src/@types/settings.d.ts +++ b/src/@types/settings.d.ts @@ -8,9 +8,10 @@ export interface Settings { // Only used for external url warning dialog. ignoreProtocolWarning?: boolean; customIcon: string; - windowStyle: "default" | "native" | "transparent" | "overlay"; + windowStyle: "default" | "native" | "overlay"; channel: "stable" | "ptb" | "canary"; audio: "loopback" | "loopbackWithMute"; + transparency: "universal" | "modern" | "none"; legcordCSP: boolean; minimizeToTray: boolean; multiInstance: boolean; diff --git a/src/common/config.ts b/src/common/config.ts index 40549c70..bae7c23e 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -13,6 +13,7 @@ const defaults: Settings = { audio: "loopbackWithMute", multiInstance: false, mods: ["vencord"], + transparency: "none", spellcheck: true, hardwareAcceleration: true, performanceMode: "none", diff --git a/src/discord/window.ts b/src/discord/window.ts index f8986174..e253059f 100644 --- a/src/discord/window.ts +++ b/src/discord/window.ts @@ -59,7 +59,7 @@ function doAfterDefiningTheWindow(passedWindow: BrowserWindow): void { void passedWindow.webContents.executeJavaScript(`document.body.setAttribute("isMaximized", "");`); passedWindow.hide(); // please don't flashbang the user } - if (getConfig("windowStyle") === "transparent" && process.platform === "win32") { + if (getConfig("transparency") === "modern" && process.platform === "win32") { passedWindow.setBackgroundMaterial("mica"); if (getConfig("startMinimized") === false) { passedWindow.show(); @@ -339,15 +339,18 @@ export function createWindow() { height: 30, }; break; - case "transparent": + } + switch (getConfig("transparency")) { + case "universal": browserWindowOptions.backgroundColor = "#00000000"; - - if (os.platform() === "win32" && os.release().startsWith("10")) { - browserWindowOptions.transparent = true; - } else { - browserWindowOptions.transparent = false; - browserWindowOptions.frame = true; - } + browserWindowOptions.transparent = true; + break; + case "modern": + browserWindowOptions.backgroundColor = "#00000000"; + browserWindowOptions.transparent = false; + browserWindowOptions.frame = true; + break; + case "none": break; } const mainWindow = new BrowserWindow(browserWindowOptions); diff --git a/src/main.ts b/src/main.ts index 272d55db..71319ffc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -65,6 +65,7 @@ if (!app.requestSingleInstanceLock() && getConfig("multiInstance") === false) { // kill if 2nd instance app.quit(); } else { + app.setAppUserModelId("app.legcord.Legcord"); app.commandLine.appendSwitch("disable-features", "WidgetLayering"); // fix dev tools layers // Your data now belongs to CCP crashReporter.start({ uploadToServer: false }); @@ -105,6 +106,9 @@ if (!app.requestSingleInstanceLock() && getConfig("multiInstance") === false) { if (getConfig("audio") === undefined) setConfig("audio", "loopbackWithMute"); if (getConfig("keybinds") === undefined) setConfig("keybinds", []); if (getConfig("trayIcon") === "default") setConfig("trayIcon", "dynamic"); + if (getConfig("transparency") === undefined) setConfig("transparency", "none"); + // @ts-ignore + if (getConfig("windowStyle") === "transparent") setConfig("windowStyle", "default"); if (getConfig("smoothScroll") === false) app.commandLine.appendSwitch("disable-smooth-scrolling"); if (getConfig("autoScroll")) app.commandLine.appendSwitch("enable-blink-features", "MiddleClickAutoscroll"); if (getConfig("disableHttpCache")) app.commandLine.appendSwitch("disable-http-cache"); @@ -128,6 +132,10 @@ if (!app.requestSingleInstanceLock() && getConfig("multiInstance") === false) { // Approves the permissions request callback(true); } + if (permission === "fullscreen") { + // Approves the permissions request + callback(true); + } }); app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) { diff --git a/src/screenshare/main.ts b/src/screenshare/main.ts index 969731a1..60617ac2 100644 --- a/src/screenshare/main.ts +++ b/src/screenshare/main.ts @@ -33,61 +33,65 @@ function showAudioDialog(): boolean { } function registerCustomHandler(): void { - session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { - console.log(request); - void desktopCapturer - .getSources({ - types: ["screen", "window"], - }) - .then((sources) => { - if (!sources) return callback({}); - isDone = false; - console.log(sources); - if (process.platform === "linux" && process.env.XDG_SESSION_TYPE?.toLowerCase() === "wayland") { - console.log("WebRTC Capturer detected, skipping window creation."); //assume webrtc capturer is used - let options: Streams = { video: sources[0] }; - if (sources[0] === undefined) return callback({}); - if (showAudioDialog() === true) options = { video: sources[0], audio: getConfig("audio") }; - callback(options); - } else { - capturerWindow = new BrowserWindow({ - width: 800, - height: 600, - title: "Legcord Screenshare", - darkTheme: true, - icon: getConfig("customIcon") ?? path.join(import.meta.dirname, "../", "/assets/desktop.png"), - frame: true, - autoHideMenuBar: true, - webPreferences: { - sandbox: false, - spellcheck: false, - preload: path.join(import.meta.dirname, "screenshare", "preload.mjs"), - }, - }); - ipcMain.once("selectScreenshareSource", (_event, id: string, name: string, audio: boolean) => { - isDone = true; - console.log(`Audio status: ${audio}`); - capturerWindow.close(); - const result = { id, name }; + session.defaultSession.setDisplayMediaRequestHandler( + (request, callback) => { + console.log(request); + void desktopCapturer + .getSources({ + types: ["screen", "window"], + }) + .then((sources) => { + if (!sources) return callback({}); + isDone = false; + console.log(sources); + if (process.platform === "linux" && process.env.XDG_SESSION_TYPE?.toLowerCase() === "wayland") { + console.log("WebRTC Capturer detected, skipping window creation."); //assume webrtc capturer is used let options: Streams = { video: sources[0] }; - switch (process.platform) { - case "win32": - case "linux": - options = { video: result }; - if (audio) options = { video: result, audio: getConfig("audio") }; - callback(options); - break; - default: - callback({ video: result }); - } - }); - capturerWindow.on("closed", () => { - if (!isDone) callback({}); - }); - void capturerWindow.loadFile(path.join(import.meta.dirname, "html", "picker.html")); - capturerWindow.webContents.send("getSources", sources); - } - }); - }); + if (sources[0] === undefined) return callback({}); + if (showAudioDialog() === true) options = { video: sources[0], audio: getConfig("audio") }; + callback(options); + } else { + capturerWindow = new BrowserWindow({ + width: 800, + height: 600, + title: "Legcord Screenshare", + darkTheme: true, + icon: + getConfig("customIcon") ?? path.join(import.meta.dirname, "../", "/assets/desktop.png"), + frame: true, + autoHideMenuBar: true, + webPreferences: { + sandbox: false, + spellcheck: false, + preload: path.join(import.meta.dirname, "screenshare", "preload.mjs"), + }, + }); + ipcMain.once("selectScreenshareSource", (_event, id: string, name: string, audio: boolean) => { + isDone = true; + console.log(`Audio status: ${audio}`); + capturerWindow.close(); + const result = { id, name }; + let options: Streams = { video: sources[0] }; + switch (process.platform) { + case "win32": + case "linux": + options = { video: result }; + if (audio) options = { video: result, audio: getConfig("audio") }; + callback(options); + break; + default: + callback({ video: result }); + } + }); + capturerWindow.on("closed", () => { + if (!isDone) callback({}); + }); + void capturerWindow.loadFile(path.join(import.meta.dirname, "html", "picker.html")); + capturerWindow.webContents.send("getSources", sources); + } + }); + }, + { useSystemPicker: true }, + ); } registerCustomHandler(); diff --git a/src/shelter/settings/pages/SettingsPage.tsx b/src/shelter/settings/pages/SettingsPage.tsx index 3f438bf0..6da358ac 100644 --- a/src/shelter/settings/pages/SettingsPage.tsx +++ b/src/shelter/settings/pages/SettingsPage.tsx @@ -61,11 +61,25 @@ export function SettingsPage() { > - + + setConfig("transparency", (e.target as HTMLInputElement).value as Settings["transparency"], true) + } + title={store.i18n["settings-transparency"]} + note={store.i18n["settings-transparency-desc"]} + link="https://github.com/Legcord/Legcord/wiki/Transparency-options" + > + + + + + +