feat: add global hotkey (#2401)

This commit is contained in:
Oliver
2025-04-30 13:49:59 -05:00
committed by GitHub
parent fc54cbbaaf
commit cb6fca2e1d
2 changed files with 73 additions and 3 deletions

View File

@@ -551,6 +551,20 @@ export default function App() {
}; };
}, []); }, []);
// Focus the first found input field
useEffect(() => {
const handleFocusInput = (_event: IpcRendererEvent) => {
const inputField = document.querySelector('input[type="text"], textarea') as HTMLInputElement;
if (inputField) {
inputField.focus();
}
};
window.electron.on('focus-input', handleFocusInput);
return () => {
window.electron.off('focus-input', handleFocusInput);
};
}, []);
// TODO: modify // TODO: modify
const handleConfirm = async () => { const handleConfirm = async () => {
if (pendingLink) { if (pendingLink) {

View File

@@ -10,6 +10,7 @@ import {
powerSaveBlocker, powerSaveBlocker,
Tray, Tray,
App, App,
globalShortcut,
} from 'electron'; } from 'electron';
import { Buffer } from 'node:buffer'; import { Buffer } from 'node:buffer';
import started from 'electron-squirrel-startup'; import started from 'electron-squirrel-startup';
@@ -720,7 +721,48 @@ ipcMain.handle('get-allowed-extensions', async () => {
} }
}); });
const createNewWindow = async (app: App, dir?: string | null) => {
const recentDirs = loadRecentDirs();
const openDir = dir || (recentDirs.length > 0 ? recentDirs[0] : undefined);
createChat(app, undefined, openDir);
};
const focusWindow = () => {
const windows = BrowserWindow.getAllWindows();
if (windows.length > 0) {
windows.forEach((win) => {
win.show();
});
windows[windows.length - 1].webContents.send('focus-input');
} else {
createNewWindow(app);
}
};
const registerGlobalHotkey = (accelerator: string) => {
// Unregister any existing shortcuts first
globalShortcut.unregisterAll();
try {
const ret = globalShortcut.register(accelerator, () => {
focusWindow();
});
if (!ret) {
console.error('Failed to register global hotkey');
return false;
}
return true;
} catch (e) {
console.error('Error registering global hotkey:', e);
return false;
}
};
app.whenReady().then(async () => { app.whenReady().then(async () => {
// Register the default global hotkey
registerGlobalHotkey('CommandOrControl+Alt+Shift+G');
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => { session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders['Origin'] = 'http://localhost:5173'; details.requestHeaders['Origin'] = 'http://localhost:5173';
callback({ cancel: false, requestHeaders: details.requestHeaders }); callback({ cancel: false, requestHeaders: details.requestHeaders });
@@ -739,9 +781,7 @@ app.whenReady().then(async () => {
const { dirPath } = parseArgs(); const { dirPath } = parseArgs();
createTray(); createTray();
const recentDirs = loadRecentDirs(); createNewWindow(app, dirPath);
let openDir = dirPath || (recentDirs.length > 0 ? recentDirs[0] : null);
createChat(app, undefined, openDir);
// Get the existing menu // Get the existing menu
const menu = Menu.getApplicationMenu(); const menu = Menu.getApplicationMenu();
@@ -817,6 +857,17 @@ app.whenReady().then(async () => {
}, },
}) })
); );
// Add menu item for hotkey
fileMenu?.submenu.append(
new MenuItem({
label: 'Focus Goose Window',
accelerator: 'CmdOrCtrl+Alt+Shift+G',
click() {
focusWindow();
},
})
);
} }
if (menu) { if (menu) {
@@ -978,6 +1029,11 @@ async function getAllowList(): Promise<string[]> {
} }
} }
app.on('will-quit', () => {
// Unregister all shortcuts when quitting
globalShortcut.unregisterAll();
});
// Quit when all windows are closed, except on macOS or if we have a tray icon. // Quit when all windows are closed, except on macOS or if we have a tray icon.
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
// Only quit if we're not on macOS or don't have a tray icon // Only quit if we're not on macOS or don't have a tray icon