Keyboard shortcuts are fun. You can use them to perform an operation when a user presses any key combination of your choosing. Every app process has its own Accelerator Handler, which takes care of the accelerators, better known as keyboard shortcuts.
Registering a keyboard shortcut
Because of the way the Accelerator Handler is built, you can simply append a series of shortcuts you want to listen for to the acceleratorStore of your process, like so:
this.acceleratorStore.push({
alt: true,
ctrl: true,
key: "a",
action: (process, event) => {
// Do something here
},
})
Here are the associated types:
export interface AppKeyCombination {
alt?: boolean; // Listen for Alt?
ctrl?: boolean; // Listen for Ctrl?
shift?: boolean; // Listen for Shift?
key?: string; // A key to listen for, like 'a' or 'ArrowUp'.
// The actual event to be triggered
action(
proc: any, // The process, will always be equal to `this`.
event: KeyboardEvent // The DOM event that triggered the accelerator
): void;
global?: boolean; // true === always trigger even if window is unfocused
}
What about a lot of accelerators?
If you have a lot of accelerators, it might be worth moving them to another JS file and storing them in a function that you can call in the app process. Let's first create the accelerators.js file:
accelerators.js
// First create the function
const AcceleratorStore = (process) => {
return [
{ // Alt+S -> save changes
alt: true,
key: "s",
action: () => {
process.saveChanges();
}
},
{ // Alt+O -> open file
alt: true,
key: "o",
action: () => {
process.openFile();
}
}
];
};
// Then return it (similar to exporting in normal JS)
return { AcceleratorStore };
Next, let's do some magic in process.js:
process.js
const html = await loadHtml("body.html");
const { AcceleratorStore } = await load("accelerators.js"); // First import it
class proc extends ThirdPartyAppProcess {
acceleratorStore = AcceleratorStore(this); // Then set the store
constructor(handler, pid, parentPid, app, workingDirectory, ...args) {
super(handler, pid, parentPid, app, workingDirectory);
}
async render() {
const body = this.getBody();
body.innerHTML = html;
}
async saveChanges() { // Referenced by the Alt+S accelerator
throw new Error("Not implemented");
}
async openFile() { // Referenced by the Alt+O accelerator
throw new Error("Not implemented");
}
// . . .
}
return { proc };