[eric] shortcuts: Cmd+T new tab or browser, Cmd+W closes the focused card undoably, routed through main like Cmd+R

This commit is contained in:
ciregenz
2026-08-06 12:34:29 -07:00
parent 9d0562db22
commit 19926b5dea
4 changed files with 53 additions and 1 deletions
+18
View File
@@ -2234,9 +2234,26 @@ function swallowCloseWindowShortcut(event, input) {
(input.key || '').toLowerCase() === 'w'
) {
event.preventDefault();
// Arc semantics: the swallowed close becomes "close the focused card" in the renderer (undoable via Cmd+Z).
if (!input.shift) {
try {
if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.send('openswarm:close-shortcut');
} catch (_) {}
}
}
}
// Cmd/Ctrl+T: new tab in the last-interacted browser, or a new browser card (Arc muscle memory).
function routeNewTabShortcut(event, input) {
if (input.type !== 'keyDown') return;
if (!(input.meta || input.control) || input.shift || input.alt) return;
if ((input.key || '').toLowerCase() !== 't') return;
event.preventDefault();
try {
if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.send('openswarm:newtab-shortcut');
} catch (_) {}
}
// Cmd/Ctrl+R: the default menu's Reload accelerator reloads the WHOLE app even when a browser webview is focused (the "Ctrl+R reloads OpenSwarm, not the browser" complaint). preventDefault kills that accelerator (same electron#19279 path as Cmd+W, dispatched against whichever webContents is focused, hence both main window AND guests); the renderer then reloads the last-interacted browser, or the app if none. Shift+R (force reload) is left alone.
function routeReloadShortcut(event, input) {
if (input.type !== 'keyDown') return;
@@ -2398,6 +2415,7 @@ app.on('web-contents-created', (_event, contents) => {
if (isCreatingMainWindow || contents.getType() === 'webview') {
contents.on('before-input-event', swallowCloseWindowShortcut);
contents.on('before-input-event', routeReloadShortcut);
contents.on('before-input-event', routeNewTabShortcut);
}
// The main app window (created while this flag is set) gets a text-focused native menu; OAuth
// popups are 'window' contents created with the flag OFF, so they keep the OS default.
+14
View File
@@ -188,6 +188,20 @@ contextBridge.exposeInMainWorld('openswarm', {
return () => ipcRenderer.removeListener('openswarm:reload-shortcut', listener);
},
// Cmd/Ctrl+W with the window-close swallowed in main: the renderer closes the focused card instead.
onCloseShortcut: (cb) => {
const listener = () => cb();
ipcRenderer.on('openswarm:close-shortcut', listener);
return () => ipcRenderer.removeListener('openswarm:close-shortcut', listener);
},
// Cmd/Ctrl+T: new tab in the last-interacted browser, else a new browser card.
onNewTabShortcut: (cb) => {
const listener = () => cb();
ipcRenderer.on('openswarm:newtab-shortcut', listener);
return () => ipcRenderer.removeListener('openswarm:newtab-shortcut', listener);
},
// In-page browser shortcuts (zoom/find/tab-cycle) from a focused guest webview, carrying the guest's webContents id so the renderer targets that exact browser.
onBrowserShortcut: (cb) => {
const listener = (_event, payload) => cb(payload);