Skip to content

Commit 6ce2521

Browse files
Merge pull request #76 from Ankesh2004/fix-shortcuts-linux
fix: use menu accelerator for shortcuts to prevent shortcut-hijacking on linux/windows
2 parents b5cc5a1 + 9222eec commit 6ce2521

File tree

5 files changed

+208
-80
lines changed

5 files changed

+208
-80
lines changed

package-lock.json

Lines changed: 0 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions.js

Lines changed: 142 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { app, BrowserWindow, globalShortcut } from "electron";
1+
import { app, BrowserWindow } from "electron";
22
import WindowManager from './window-manager.js';
33

44
export function createActions(windowManager) {
55
const actions = {
66
OpenDevTools: {
77
label: "Open Dev Tools",
88
accelerator: "CommandOrControl+Shift+I",
9-
click: (focusedWindow) => {
9+
click: () => {
10+
const focusedWindow = BrowserWindow.getFocusedWindow();
1011
if (focusedWindow) {
1112
focusedWindow.webContents.openDevTools({ mode: "detach" });
1213
}
@@ -35,7 +36,8 @@ export function createActions(windowManager) {
3536
NewTab: {
3637
label: "New Tab",
3738
accelerator: "CommandOrControl+T",
38-
click: (focusedWindow) => {
39+
click: () => {
40+
const focusedWindow = BrowserWindow.getFocusedWindow();
3941
if (focusedWindow) {
4042
focusedWindow.webContents.executeJavaScript(`{
4143
const tabBar = document.querySelector('#tabbar');
@@ -57,7 +59,8 @@ export function createActions(windowManager) {
5759
Forward: {
5860
label: "Forward",
5961
accelerator: "CommandOrControl+]",
60-
click: (focusedWindow) => {
62+
click: () => {
63+
const focusedWindow = BrowserWindow.getFocusedWindow();
6164
if (focusedWindow) {
6265
focusedWindow.webContents.executeJavaScript(`{
6366
const tabBar = document.querySelector('#tabbar');
@@ -77,7 +80,8 @@ export function createActions(windowManager) {
7780
Back: {
7881
label: "Back",
7982
accelerator: "CommandOrControl+[",
80-
click: (focusedWindow) => {
83+
click: () => {
84+
const focusedWindow = BrowserWindow.getFocusedWindow();
8185
if (focusedWindow) {
8286
focusedWindow.webContents.executeJavaScript(`{
8387
const tabBar = document.querySelector('#tabbar');
@@ -97,7 +101,8 @@ export function createActions(windowManager) {
97101
FocusURLBar: {
98102
label: "Focus URL Bar",
99103
accelerator: "CommandOrControl+L",
100-
click: (focusedWindow) => {
104+
click: () => {
105+
const focusedWindow = BrowserWindow.getFocusedWindow();
101106
if (focusedWindow) {
102107
focusedWindow.webContents.executeJavaScript(`
103108
function focusUrlBar() {
@@ -129,7 +134,8 @@ export function createActions(windowManager) {
129134
Reload: {
130135
label: "Reload",
131136
accelerator: "CommandOrControl+R",
132-
click: (focusedWindow) => {
137+
click: () => {
138+
const focusedWindow = BrowserWindow.getFocusedWindow();
133139
if (focusedWindow) {
134140
focusedWindow.webContents.executeJavaScript(`{
135141
const tabBar = document.querySelector('#tabbar');
@@ -169,7 +175,8 @@ export function createActions(windowManager) {
169175
Minimize: {
170176
label: "Minimize",
171177
accelerator: "CommandOrControl+M",
172-
click: (focusedWindow) => {
178+
click: () => {
179+
const focusedWindow = BrowserWindow.getFocusedWindow();
173180
if (focusedWindow) {
174181
focusedWindow.minimize();
175182
}
@@ -178,7 +185,8 @@ export function createActions(windowManager) {
178185
Close: {
179186
label: "Close",
180187
accelerator: "CommandOrControl+W",
181-
click: (focusedWindow) => {
188+
click: () => {
189+
const focusedWindow = BrowserWindow.getFocusedWindow();
182190
if (focusedWindow) {
183191
focusedWindow.webContents.executeJavaScript(`
184192
try {
@@ -204,7 +212,8 @@ export function createActions(windowManager) {
204212
FullScreen: {
205213
label: "Toggle Full Screen",
206214
accelerator: "F11",
207-
click: (focusedWindow) => {
215+
click: () => {
216+
const focusedWindow = BrowserWindow.getFocusedWindow();
208217
if (focusedWindow) {
209218
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
210219
}
@@ -213,7 +222,8 @@ export function createActions(windowManager) {
213222
FindInPage: {
214223
label: "Find in Page",
215224
accelerator: "CommandOrControl+F",
216-
click: (focusedWindow) => {
225+
click: () => {
226+
const focusedWindow = BrowserWindow.getFocusedWindow();
217227
if (focusedWindow) {
218228
focusedWindow.webContents.executeJavaScript(`
219229
var findMenu = document.querySelector('find-menu');
@@ -233,7 +243,8 @@ export function createActions(windowManager) {
233243
CloseTab: {
234244
label: "Close Tab",
235245
accelerator: "CommandOrControl+Shift+W",
236-
click: (focusedWindow) => {
246+
click: () => {
247+
const focusedWindow = BrowserWindow.getFocusedWindow();
237248
if (focusedWindow) {
238249
focusedWindow.webContents.executeJavaScript(`
239250
try {
@@ -258,7 +269,8 @@ export function createActions(windowManager) {
258269
accelerator: process.platform === "darwin"
259270
? "CommandOrControl+Option+Right"
260271
: "CommandOrControl+Tab",
261-
click: (focusedWindow) => {
272+
click: () => {
273+
const focusedWindow = BrowserWindow.getFocusedWindow();
262274
if (focusedWindow) {
263275
focusedWindow.webContents.executeJavaScript(`
264276
try {
@@ -284,7 +296,8 @@ export function createActions(windowManager) {
284296
accelerator: process.platform === "darwin"
285297
? "CommandOrControl+Option+Left"
286298
: "CommandOrControl+Shift+Tab",
287-
click: (focusedWindow) => {
299+
click: () => {
300+
const focusedWindow = BrowserWindow.getFocusedWindow();
288301
if (focusedWindow) {
289302
focusedWindow.webContents.executeJavaScript(`
290303
try {
@@ -310,39 +323,121 @@ export function createActions(windowManager) {
310323
return actions;
311324
}
312325

313-
export function registerShortcuts(windowManager) {
314-
const actions = createActions(windowManager);
326+
export function createMenuTemplate(windowManager) {
327+
const actions = createActions(windowManager);
328+
329+
const isMac = process.platform === 'darwin';
315330

316-
const registerFindShortcut = (focusedWindow) => {
317-
if (focusedWindow) {
318-
globalShortcut.register("CommandOrControl+F", () => {
319-
actions.FindInPage.click(focusedWindow);
320-
});
321-
}
322-
};
323-
324-
const unregisterFindShortcut = () => {
325-
globalShortcut.unregister("CommandOrControl+F");
326-
};
327-
328-
// Register and unregister `Ctrl+F` based on focus
329-
app.on("browser-window-focus", (event, win) => {
330-
registerFindShortcut(win);
331-
});
332-
333-
app.on("browser-window-blur", () => {
334-
unregisterFindShortcut();
335-
});
331+
const template = [
332+
// { role: 'appMenu' }
333+
...(isMac ? [{
334+
label: app.name,
335+
submenu: [
336+
{ role: 'about' },
337+
{ type: 'separator' },
338+
{ role: 'services' },
339+
{ type: 'separator' },
340+
{ role: 'hide' },
341+
{ role: 'hideOthers' },
342+
{ role: 'unhide' },
343+
{ type: 'separator' },
344+
{ role: 'quit' }
345+
]
346+
}] : []),
347+
// { role: 'fileMenu' }
348+
{
349+
label: 'File',
350+
submenu: [
351+
{...actions.NewWindow},
352+
{...actions.NewTab},
353+
{ type: 'separator' },
354+
{...actions.CloseTab},
355+
{...actions.Close},
356+
{ type: 'separator' },
357+
isMac ? { role: 'close' } : { role: 'quit' }
358+
]
359+
},
360+
// { role: 'editMenu' }
361+
{
362+
label: 'Edit',
363+
submenu: [
364+
{ role: 'undo' },
365+
{ role: 'redo' },
366+
{ type: 'separator' },
367+
{ role: 'cut' },
368+
{ role: 'copy' },
369+
{ role: 'paste' },
370+
...(isMac ? [
371+
{ role: 'pasteAndMatchStyle' },
372+
{ role: 'delete' },
373+
{ role: 'selectAll' },
374+
{ type: 'separator' },
375+
{
376+
label: 'Speech',
377+
submenu: [
378+
{ role: 'startSpeaking' },
379+
{ role: 'stopSpeaking' }
380+
]
381+
}
382+
] : [
383+
{ role: 'delete' },
384+
{ type: 'separator' },
385+
{ role: 'selectAll' }
386+
]),
387+
{ type: 'separator' },
388+
{...actions.FindInPage}
389+
]
390+
},
391+
// { role: 'viewMenu' }
392+
{
393+
label: 'View',
394+
submenu: [
395+
{...actions.Reload},
396+
{ type: 'separator' },
397+
{...actions.FullScreen},
398+
{...actions.OpenDevTools}
399+
]
400+
},
401+
// { role: 'windowMenu' }
402+
{
403+
label: 'Window',
404+
submenu: [
405+
{...actions.Minimize},
406+
{...actions.NextTab},
407+
{...actions.PreviousTab},
408+
...(isMac ? [
409+
{ type: 'separator' },
410+
{ role: 'front' },
411+
{ type: 'separator' },
412+
{ role: 'window' }
413+
] : [
414+
{...actions.Close}
415+
])
416+
]
417+
},
418+
// { role: 'goMenu }
419+
{
420+
label: 'Go',
421+
submenu: [
422+
{...actions.Back},
423+
{...actions.Forward},
424+
{ type: 'separator' },
425+
{...actions.FocusURLBar}
426+
]
427+
},
428+
{
429+
role: 'help',
430+
submenu: [
431+
{
432+
label: 'Learn More',
433+
click: async () => {
434+
const { shell } = require('electron');
435+
await shell.openExternal('https://peersky.xyz');
436+
}
437+
}
438+
]
439+
}
440+
];
336441

337-
// Register remaining shortcuts
338-
Object.keys(actions).forEach((key) => {
339-
const action = actions[key];
340-
if (key !== "FindInPage") {
341-
// Register other shortcuts except `Ctrl+F`
342-
globalShortcut.register(action.accelerator, () => {
343-
const focusedWindow = BrowserWindow.getFocusedWindow();
344-
if (focusedWindow) action.click(focusedWindow);
345-
});
346-
}
347-
});
442+
return template;
348443
}

src/main.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { createHandler as createIPFSHandler } from "./protocols/ipfs-handler.js"
55
import { createHandler as createHyperHandler } from "./protocols/hyper-handler.js";
66
import { createHandler as createWeb3Handler } from "./protocols/web3-handler.js";
77
import { ipfsOptions, hyperOptions } from "./protocols/config.js";
8-
import { registerShortcuts } from "./actions.js";
8+
import { createMenuTemplate } from "./actions.js";
99
import WindowManager, { createIsolatedWindow } from "./window-manager.js";
1010
import settingsManager from "./settings-manager.js";
1111
import { attachContextMenus, setWindowManager } from "./context-menu.js";
@@ -55,7 +55,10 @@ app.whenReady().then(async () => {
5555
windowManager.open({ isMainWindow: true });
5656
}
5757

58-
registerShortcuts(windowManager); // Pass windowManager to registerShortcuts
58+
// Register shortcuts from menu template (NOTE: all these shortcuts works on a window only if a window is in focus)
59+
const menuTemplate = createMenuTemplate(windowManager);
60+
const menu = Menu.buildFromTemplate(menuTemplate);
61+
Menu.setApplicationMenu(menu);
5962

6063
windowManager.startSaver();
6164

0 commit comments

Comments
 (0)