fix(app): browser pane keyboard tweaks
- 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
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
import type { WebContents } from "electron";
|
||||
import { webContents as allWebContents, type WebContents } from "electron";
|
||||
|
||||
const browserIdsByWebContentsId = new Map<number, string>();
|
||||
let activeBrowserPaneId: string | null = null;
|
||||
|
||||
export function registerPaseoBrowserWebContents(contents: WebContents, browserId: string): void {
|
||||
browserIdsByWebContentsId.set(contents.id, browserId);
|
||||
contents.once("destroyed", () => {
|
||||
browserIdsByWebContentsId.delete(contents.id);
|
||||
if (activeBrowserPaneId === browserId) {
|
||||
activeBrowserPaneId = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,3 +19,21 @@ export function getPaseoBrowserIdForWebContents(contents: WebContents | null): s
|
||||
}
|
||||
return browserIdsByWebContentsId.get(contents.id) ?? null;
|
||||
}
|
||||
|
||||
export function setActivePaseoBrowserPaneId(browserId: string | null): void {
|
||||
activeBrowserPaneId = browserId;
|
||||
}
|
||||
|
||||
export function getActivePaseoBrowserWebContents(): WebContents | null {
|
||||
if (!activeBrowserPaneId) {
|
||||
return null;
|
||||
}
|
||||
for (const [contentsId, browserId] of browserIdsByWebContentsId) {
|
||||
if (browserId !== activeBrowserPaneId) continue;
|
||||
const contents = allWebContents.fromId(contentsId);
|
||||
if (contents && !contents.isDestroyed()) {
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { app, Menu, BrowserWindow, ipcMain, webContents } from "electron";
|
||||
import { getPaseoBrowserIdForWebContents } from "./browser-webviews.js";
|
||||
import {
|
||||
getActivePaseoBrowserWebContents,
|
||||
getPaseoBrowserIdForWebContents,
|
||||
} from "./browser-webviews.js";
|
||||
|
||||
interface ShowContextMenuInput {
|
||||
kind?: "terminal";
|
||||
@@ -20,8 +23,12 @@ function getFocusedPaseoBrowserWebContents(): Electron.WebContents | null {
|
||||
return getPaseoBrowserIdForWebContents(focusedContents) ? focusedContents : null;
|
||||
}
|
||||
|
||||
function getReloadTargetBrowserWebContents(): Electron.WebContents | null {
|
||||
return getFocusedPaseoBrowserWebContents() ?? getActivePaseoBrowserWebContents();
|
||||
}
|
||||
|
||||
function reloadFocusedContentsOrWindow(win: BrowserWindow, options?: { ignoreCache?: boolean }) {
|
||||
const browserContents = getFocusedPaseoBrowserWebContents();
|
||||
const browserContents = getReloadTargetBrowserWebContents();
|
||||
if (browserContents) {
|
||||
if (options?.ignoreCache) {
|
||||
browserContents.reloadIgnoringCache();
|
||||
|
||||
@@ -36,6 +36,7 @@ import { setupApplicationMenu } from "./features/menu.js";
|
||||
import {
|
||||
getPaseoBrowserIdForWebContents,
|
||||
registerPaseoBrowserWebContents,
|
||||
setActivePaseoBrowserPaneId,
|
||||
} from "./features/browser-webviews.js";
|
||||
import { parseOpenProjectPathFromArgv } from "./open-project-routing.js";
|
||||
import { getDesktopSettingsStore } from "./settings/desktop-settings-electron.js";
|
||||
@@ -76,6 +77,33 @@ function preventUnsafeBrowserWebviewNavigation(
|
||||
}
|
||||
const OPEN_PROJECT_EVENT = "paseo:event:open-project";
|
||||
const BROWSER_SHORTCUT_EVENT = "paseo:event:browser-shortcut";
|
||||
const BROWSER_FORWARDED_KEY_EVENT = "paseo:event:browser-forwarded-key";
|
||||
|
||||
const FORWARDED_PASEO_SHORTCUT_KEYS = new Set([
|
||||
"b",
|
||||
"e",
|
||||
"w",
|
||||
"t",
|
||||
"k",
|
||||
"/",
|
||||
"\\",
|
||||
",",
|
||||
".",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"enter",
|
||||
"arrowleft",
|
||||
"arrowright",
|
||||
"arrowup",
|
||||
"arrowdown",
|
||||
]);
|
||||
const DESKTOP_SMOKE_ENV = "PASEO_DESKTOP_SMOKE";
|
||||
const DESKTOP_SMOKE_STOP_REQUEST = "paseo-smoke-stop";
|
||||
app.setName("Paseo");
|
||||
@@ -105,6 +133,16 @@ function isBrowserLocationInput(input: Electron.Input): boolean {
|
||||
return (input.meta || input.control) && input.key.toLowerCase() === "l";
|
||||
}
|
||||
|
||||
function isForwardablePaseoShortcutInput(input: Electron.Input): boolean {
|
||||
if (input.type !== "keyDown") {
|
||||
return false;
|
||||
}
|
||||
if (!input.meta && !input.control) {
|
||||
return false;
|
||||
}
|
||||
return FORWARDED_PASEO_SHORTCUT_KEYS.has(input.key.toLowerCase());
|
||||
}
|
||||
|
||||
// In dev mode, detect git worktrees and isolate each instance so multiple
|
||||
// Electron windows can run side-by-side (separate userData = separate lock).
|
||||
let devWorktreeName: string | null = null;
|
||||
@@ -177,6 +215,10 @@ ipcMain.handle("paseo:get-pending-open-project", () => {
|
||||
return result;
|
||||
});
|
||||
|
||||
ipcMain.handle("paseo:browser:set-active-pane", (_event, browserId: unknown) => {
|
||||
setActivePaseoBrowserPaneId(typeof browserId === "string" ? browserId : null);
|
||||
});
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{ scheme: APP_SCHEME, privileges: { standard: true, secure: true, supportFetchAPI: true } },
|
||||
]);
|
||||
@@ -317,6 +359,18 @@ async function createMainWindow(): Promise<void> {
|
||||
action: "focus-url",
|
||||
...(focusedBrowserId ? { browserId: focusedBrowserId } : {}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (isForwardablePaseoShortcutInput(input)) {
|
||||
event.preventDefault();
|
||||
mainWindow.webContents.send(BROWSER_FORWARDED_KEY_EVENT, {
|
||||
key: input.key,
|
||||
code: input.code,
|
||||
meta: input.meta,
|
||||
control: input.control,
|
||||
shift: input.shift,
|
||||
alt: input.alt,
|
||||
});
|
||||
}
|
||||
});
|
||||
contents.setWindowOpenHandler(({ url }) => {
|
||||
|
||||
@@ -57,4 +57,8 @@ contextBridge.exposeInMainWorld("paseoDesktop", {
|
||||
showContextMenu: (input?: Record<string, unknown>) =>
|
||||
ipcRenderer.invoke("paseo:menu:showContextMenu", input),
|
||||
},
|
||||
browser: {
|
||||
setActivePane: (browserId: string | null) =>
|
||||
ipcRenderer.invoke("paseo:browser:set-active-pane", browserId),
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user