Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions src/plugins/disableRestartShortcut.discordDesktop/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { definePluginSettings, migratePluginSetting, migratePluginSettings } from "@api/Settings";
import { Button } from "@components/Button";
import { SettingsSection } from "@components/settings/tabs/plugins/components/Common";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType, PluginNative } from "@utils/types";
import { useEffect, useState } from "@webpack/common";

import { parseRestartShortcut } from "./restartShortcut";
migratePluginSettings("DisableRestartShortcut", "ReloadShortcut");
migratePluginSetting("DisableRestartShortcut", "reloadShortcut", "restartShortcut");
const RestartShortcutNative = VencordNative.pluginHelpers.DisableRestartShortcut as PluginNative<typeof import("./native")>;
const settings = definePluginSettings({
blockCtrlR: {
type: OptionType.BOOLEAN,
displayName: "Disable Ctrl + R",
description: "Disable Ctrl + R shortcut.",
default: true
},
restartShortcut: {
type: OptionType.COMPONENT,
default: "Ctrl+Shift+R",
component: () => <RestartShortcutControls />
}
}, {
restartShortcut: {
hidden() {
return this.store.blockCtrlR;
}
}
});
function RestartShortcutControls() {
const { restartShortcut } = settings.use(["restartShortcut"]);
const [capturing, setCapturing] = useState(false);
useEffect(() => {
if (!capturing) return;
void RestartShortcutNative.setCapturing(true);
const onKeyDown = (event: KeyboardEvent) => {
event.preventDefault();
event.stopImmediatePropagation();
if (event.key === "Escape") {
setCapturing(false);
return;
}
const key = event.code.startsWith("Key") ? event.code.slice(3)
: event.code.startsWith("Digit") ? event.code.slice(5)
: event.code;
const restartShortcut = [event.ctrlKey && "Ctrl", event.altKey && "Alt", event.shiftKey && "Shift", key].filter(Boolean).join("+");
if (event.metaKey || !parseRestartShortcut(restartShortcut)) return;
settings.store.restartShortcut = restartShortcut;
setCapturing(false);
};
window.addEventListener("keydown", onKeyDown, true);
return () => {
window.removeEventListener("keydown", onKeyDown, true);
void RestartShortcutNative.setCapturing(false);
};
}, [capturing]);
return (
<SettingsSection id="restartShortcut" name="Config Shortcut" description="" inlineSetting>
<Button onClick={() => setCapturing(value => !value)}>
{capturing ? "Press shortcut..." : `Config: ${restartShortcut}`}
</Button>
</SettingsSection>
);
}
export default definePlugin({
name: "DisableRestartShortcut",
description: "Disables Ctrl+R or config with a custom shortcut.",
authors: [Devs.Mashiro],
tags: ["Shortcuts"],
settings
});
34 changes: 34 additions & 0 deletions src/plugins/disableRestartShortcut.discordDesktop/native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { RendererSettings } from "@main/settings";
import { app, IpcMainInvokeEvent, WebContents } from "electron";

import { parseRestartShortcut } from "./restartShortcut";
const capturing = new WeakSet<WebContents>();
export function setCapturing(event: IpcMainInvokeEvent, active: boolean) {
if (typeof active !== "boolean") throw new TypeError("active must be a boolean");
event.sender.setIgnoreMenuShortcuts(active);
if (active) capturing.add(event.sender);
else capturing.delete(event.sender);
}
app.on("browser-window-created", (_, win) => {
win.webContents.on("before-input-event", (event, input) => {
const settings = RendererSettings.store.plugins?.DisableRestartShortcut;
if (capturing.has(win.webContents) || !settings?.enabled
|| input.meta || input.isComposing) return;
if (input.code === "KeyR" && input.control && !input.alt && !input.shift) {
if (settings.blockCtrlR !== false) event.preventDefault();
return;
}
if (settings.blockCtrlR !== false) return;
const restartShortcut = parseRestartShortcut(settings.restartShortcut ?? "Ctrl+Shift+R");
if (!restartShortcut || input.code !== restartShortcut.code || input.control !== restartShortcut.ctrl
|| input.alt !== restartShortcut.alt || input.shift !== restartShortcut.shift) return;
event.preventDefault();
if (input.type === "keyDown" && !input.isAutoRepeat) win.webContents.reload();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

export function parseRestartShortcut(value: unknown) {
if (typeof value !== "string") return null;
const parts = value.trim().toUpperCase().split("+").map(part => part.trim());
const key = parts.pop();
const modifiers = new Set(parts);
if (!key || !/^(?:[A-Z0-9]|F(?:[1-9]|1[0-2]))$/.test(key)
|| (!modifiers.has("CTRL") && !modifiers.has("ALT")) || modifiers.size !== parts.length
|| parts.some(part => part !== "CTRL" && part !== "ALT" && part !== "SHIFT")
|| (key === "R" && modifiers.has("CTRL") && modifiers.size === 1)) return null;
const code = /^[A-Z]$/.test(key) ? `Key${key}` : /^[0-9]$/.test(key) ? `Digit${key}` : key;
return { code, ctrl: modifiers.has("CTRL"), alt: modifiers.has("ALT"), shift: modifiers.has("SHIFT") };
}
4 changes: 4 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
f3tch: {
name: "f3tch",
id: 1016388460929626174n
},
Mashiro: {
name: "Mashiro",
id: 960541228422815824n
}
} satisfies Record<string, Dev>);

Expand Down