mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-06 00:14:54 +00:00
- Refresh icon: use single-arrow RotateCw instead of two-arrow RefreshCw - URL bar selects all text on focus - Cmd+R now reloads the active browser pane (tracked via IPC) when the URL bar has focus, instead of reloading the Electron window - Forward Paseo shortcut keys (b, e, w, t, k, /, \, comma, digits, enter, arrows) from the embedded webview to the main window so sidebar/tab/etc. shortcuts still fire when focus is inside the loaded page
177 lines
4.6 KiB
TypeScript
177 lines
4.6 KiB
TypeScript
import { app, Menu, BrowserWindow, ipcMain, webContents } from "electron";
|
|
import {
|
|
getActivePaseoBrowserWebContents,
|
|
getPaseoBrowserIdForWebContents,
|
|
} from "./browser-webviews.js";
|
|
|
|
interface ShowContextMenuInput {
|
|
kind?: "terminal";
|
|
hasSelection?: boolean;
|
|
}
|
|
|
|
function withBrowserWindow(
|
|
callback: (win: BrowserWindow) => void,
|
|
): (_item: Electron.MenuItem, baseWin: Electron.BaseWindow | undefined) => void {
|
|
return (_item, baseWin) => {
|
|
const win = baseWin instanceof BrowserWindow ? baseWin : BrowserWindow.getFocusedWindow();
|
|
if (win) callback(win);
|
|
};
|
|
}
|
|
|
|
function getFocusedPaseoBrowserWebContents(): Electron.WebContents | null {
|
|
const focusedContents = webContents.getFocusedWebContents();
|
|
return getPaseoBrowserIdForWebContents(focusedContents) ? focusedContents : null;
|
|
}
|
|
|
|
function getReloadTargetBrowserWebContents(): Electron.WebContents | null {
|
|
return getFocusedPaseoBrowserWebContents() ?? getActivePaseoBrowserWebContents();
|
|
}
|
|
|
|
function reloadFocusedContentsOrWindow(win: BrowserWindow, options?: { ignoreCache?: boolean }) {
|
|
const browserContents = getReloadTargetBrowserWebContents();
|
|
if (browserContents) {
|
|
if (options?.ignoreCache) {
|
|
browserContents.reloadIgnoringCache();
|
|
return;
|
|
}
|
|
if (browserContents.isLoadingMainFrame()) {
|
|
browserContents.stop();
|
|
return;
|
|
}
|
|
browserContents.reload();
|
|
return;
|
|
}
|
|
|
|
if (options?.ignoreCache) {
|
|
win.webContents.reloadIgnoringCache();
|
|
return;
|
|
}
|
|
win.webContents.reload();
|
|
}
|
|
|
|
export function setupApplicationMenu(): void {
|
|
const isMac = process.platform === "darwin";
|
|
|
|
const template: Electron.MenuItemConstructorOptions[] = [
|
|
...(isMac
|
|
? [
|
|
{
|
|
label: app.name,
|
|
submenu: [
|
|
{ role: "about" as const },
|
|
{ type: "separator" as const },
|
|
{ role: "services" as const },
|
|
{ type: "separator" as const },
|
|
{ role: "hide" as const },
|
|
{ role: "hideOthers" as const },
|
|
{ role: "unhide" as const },
|
|
{ type: "separator" as const },
|
|
{ role: "quit" as const },
|
|
],
|
|
},
|
|
]
|
|
: []),
|
|
{
|
|
label: "Edit",
|
|
submenu: [
|
|
{ role: "undo" },
|
|
{ role: "redo" },
|
|
{ type: "separator" },
|
|
{ role: "cut" },
|
|
{ role: "copy" },
|
|
{ role: "paste" },
|
|
{ role: "selectAll" },
|
|
],
|
|
},
|
|
{
|
|
label: "View",
|
|
submenu: [
|
|
{
|
|
label: "Zoom In",
|
|
accelerator: "CmdOrCtrl+=",
|
|
click: withBrowserWindow((win) => {
|
|
win.webContents.setZoomLevel(win.webContents.getZoomLevel() + 0.5);
|
|
}),
|
|
},
|
|
{
|
|
label: "Zoom Out",
|
|
accelerator: "CmdOrCtrl+-",
|
|
click: withBrowserWindow((win) => {
|
|
win.webContents.setZoomLevel(win.webContents.getZoomLevel() - 0.5);
|
|
}),
|
|
},
|
|
{
|
|
label: "Actual Size",
|
|
accelerator: "CmdOrCtrl+0",
|
|
click: withBrowserWindow((win) => {
|
|
win.webContents.setZoomLevel(0);
|
|
}),
|
|
},
|
|
{ type: "separator" },
|
|
{
|
|
label: "Reload",
|
|
accelerator: "CmdOrCtrl+R",
|
|
click: withBrowserWindow((win) => {
|
|
reloadFocusedContentsOrWindow(win);
|
|
}),
|
|
},
|
|
{
|
|
label: "Force Reload",
|
|
accelerator: "CmdOrCtrl+Shift+R",
|
|
click: withBrowserWindow((win) => {
|
|
reloadFocusedContentsOrWindow(win, { ignoreCache: true });
|
|
}),
|
|
},
|
|
{ role: "toggleDevTools" },
|
|
{ type: "separator" },
|
|
{ role: "togglefullscreen" },
|
|
],
|
|
},
|
|
{
|
|
label: "Window",
|
|
submenu: [
|
|
{ role: "minimize" },
|
|
{ role: "zoom" },
|
|
...(isMac
|
|
? [{ type: "separator" as const }, { role: "front" as const }]
|
|
: [{ role: "close" as const }]),
|
|
],
|
|
},
|
|
];
|
|
|
|
const menu = Menu.buildFromTemplate(template);
|
|
Menu.setApplicationMenu(menu);
|
|
|
|
ipcMain.handle("paseo:menu:showContextMenu", (event, input?: ShowContextMenuInput) => {
|
|
const win = BrowserWindow.fromWebContents(event.sender);
|
|
if (!win) {
|
|
return;
|
|
}
|
|
|
|
if (input?.kind !== "terminal") {
|
|
return;
|
|
}
|
|
|
|
const contextMenu = Menu.buildFromTemplate([
|
|
{
|
|
label: "Copy",
|
|
role: "copy",
|
|
enabled: input.hasSelection === true,
|
|
},
|
|
{
|
|
label: "Paste",
|
|
role: "paste",
|
|
},
|
|
{
|
|
type: "separator",
|
|
},
|
|
{
|
|
label: "Select All",
|
|
role: "selectAll",
|
|
},
|
|
]);
|
|
|
|
contextMenu.popup({ window: win });
|
|
});
|
|
}
|