experiments in a post-browser web
Peek Shortcuts API#
The shortcuts API allows features and extensions to register keyboard shortcuts that trigger callbacks.
Overview#
Peek supports two types of shortcuts:
- Global shortcuts: Work system-wide, even when the app doesn't have focus. Useful for invoking the app from other applications.
- Local shortcuts: Only work when Peek has focus. Safer for actions that shouldn't be triggered accidentally from other apps.
By default, shortcuts are local (app-only). Pass { global: true } to register a global shortcut.
API Reference#
api.shortcuts.register(shortcut, callback, options)#
Register a keyboard shortcut.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
shortcut |
string | Yes | Key combination (e.g., 'Alt+1', 'CommandOrControl+Shift+P') |
callback |
function | Yes | Function to call when shortcut is triggered |
options |
object | No | Configuration options |
options.global |
boolean | No | If true, shortcut works system-wide. Default: false |
Example:
// Local shortcut (only works when app has focus)
api.shortcuts.register('Alt+Q', () => {
console.log('Quit shortcut pressed');
api.quit();
});
// Global shortcut (works even when app doesn't have focus)
api.shortcuts.register('Alt+1', () => {
console.log('Opening peek 1');
openPeek(1);
}, { global: true });
api.shortcuts.unregister(shortcut, options)#
Unregister a previously registered shortcut.
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
shortcut |
string | Yes | The shortcut to unregister |
options |
object | No | Configuration options |
options.global |
boolean | No | Must match the registration. Default: false |
Example:
// Unregister a local shortcut
api.shortcuts.unregister('Alt+Q');
// Unregister a global shortcut
api.shortcuts.unregister('Alt+1', { global: true });
Shortcut String Format#
Shortcuts use Electron's accelerator format. Common modifiers:
| Modifier | Mac | Windows/Linux |
|---|---|---|
CommandOrControl |
Cmd | Ctrl |
Command / Cmd |
Cmd | N/A |
Control / Ctrl |
Ctrl | Ctrl |
Alt / Option |
Option | Alt |
Shift |
Shift | Shift |
Meta / Super |
Cmd | Win |
Examples:
Alt+1- Option/Alt + 1CommandOrControl+Shift+P- Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)Option+Up- Option + Arrow UpCtrl+Q- Control + Q
When to Use Global vs Local#
Use Global Shortcuts For:#
- Invoking the app (e.g., opening peeks, slides, command palette)
- Quick access features that users expect to work from any context
- Features explicitly configured as system-wide by the user
Use Local Shortcuts For:#
- Destructive actions like quit - prevents accidental triggers from other apps
- Feature-internal navigation that only makes sense when the app is active
- Context-sensitive actions that depend on app state
Implementation Details#
Global Shortcuts#
Uses Electron's globalShortcut module. These shortcuts:
- Work even when the app doesn't have focus
- Are registered at the OS level
- May conflict with shortcuts from other applications
- Are unregistered when the app quits
Local Shortcuts#
Uses Electron's before-input-event on each BrowserWindow. These shortcuts:
- Only work when a Peek window has focus
- Are handled before the webpage receives the input
- Cannot conflict with other applications
- Are more secure for sensitive operations
- Use physical key codes (not characters) for matching, so Option+, works correctly on Mac even though it produces '≤'
Internal Architecture#
Renderer Process (preload.js)
│
│ api.shortcuts.register(shortcut, cb, { global: true/false })
│
▼
IPC: 'registershortcut' { shortcut, replyTopic, global }
│
▼
Main Process (index.js)
│
├─ global=true ──▶ globalShortcut.register()
│ (stored in `shortcuts` Map)
│
└─ global=false ──▶ localShortcuts Map
(handled via before-input-event)
Feature Examples#
Peeks (Global)#
Peeks use global shortcuts so users can quickly invoke them from any app:
api.shortcuts.register(`Option+${keyNum}`, () => {
openPeekWindow(item);
}, { global: true });
Quit (Local)#
The quit shortcut is local to prevent accidentally quitting the app:
api.shortcuts.register('Option+Q', () => {
app.quit();
}); // No global flag - defaults to local
Best Practices#
- Default to local - Only use global shortcuts when necessary
- Match register/unregister - Pass the same
globaloption to both calls - Clean up on uninit - Always unregister shortcuts when a feature unloads
- Track registered shortcuts - Keep a list for cleanup:
let registeredShortcuts = [];
const init = () => {
const shortcut = 'Alt+1';
api.shortcuts.register(shortcut, callback, { global: true });
registeredShortcuts.push(shortcut);
};
const uninit = () => {
registeredShortcuts.forEach(shortcut => {
api.shortcuts.unregister(shortcut, { global: true });
});
registeredShortcuts = [];
};
Future Considerations#
- UI for viewing shortcuts: Settings panel showing all registered shortcuts
- Conflict detection: Warn when a shortcut is already registered
- User customization: Allow users to rebind shortcuts
- Shortcut categories: Group shortcuts by feature for better organization