Register global shortcuts - fakeivchenko/lwjwae GitHub Wiki
A global shortcut reaches the application whichever application has the keyboard, such as the keys that bring a quick note window to the front. In this guide, Ctrl+Shift+Space brings the window back and tells the page when.

public class Shortcuts {
private static final DateTimeFormatter TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
public static void main(String[] args) {
Application.launch(
WindowParameters.of("Quick note", 560, 380),
window -> {
window
.application()
.globalShortcut(
"CmdOrCtrl+Shift+Space",
() -> {
window.focus();
window.emit("summoned", LocalTime.now().format(TIME));
});
window.loadResource("shortcuts/index.html");
});
}
}The page hears the event and puts the cursor into the note:
lwjwae.listen("summoned", ({ payload }) => {
document.querySelector("#log").prepend(Object.assign(document.createElement("li"), { textContent: `Summoned at ${payload}` }));
document.querySelector("#note").focus();
});globalShortcut returns an EventSubscription. Call close() on it to give the shortcut back;
otherwise, the shortcut stays with the application until it closes. The handler runs off the UI
thread, so it can block or call back into a window.
A shortcut is the modifiers and then the key, joined with +, in any case:
| Text | Keys |
|---|---|
Ctrl+Shift+K |
Ctrl, Shift, and K |
CmdOrCtrl+Alt+Space |
Command on macOS or Ctrl elsewhere, Alt, and Space |
F13 |
F13 alone |
The modifiers are Ctrl or Control, Alt or Option, Shift, Meta, Super, Win, Cmd or
Command, and CmdOrCtrl or CommandOrControl. A key other than a function key needs a modifier:
a shortcut takes its key away from every other application, so a letter alone could no longer be
typed. Shortcut.parse reads the text, and Shortcut.of(key, modifiers...) builds a shortcut
without one.
If another application already holds the shortcut, globalShortcut throws
ShortcutUnavailableException. Catch it and offer the user other keys:
try {
application.globalShortcut("CmdOrCtrl+Shift+Space", window::focus);
} catch (ShortcutUnavailableException e) {
window.emit("shortcutTaken", e.getMessage());
}| Platform | How the shortcut is registered |
|---|---|
| Windows |
RegisterHotKey. A shortcut that Windows keeps, such as Win+L, throws too. Holding the keys down runs the handler once. |
| macOS |
RegisterEventHotKey of Carbon, which needs no permission of the user. A shortcut of the system, such as Command+Space for Spotlight, can still go to the system first. |
| Linux, X11 | A grab of the key on the root window. |
| Linux, Wayland | The GlobalShortcuts portal of KDE Plasma, and of GNOME 48 and later. The desktop asks the user to confirm the shortcuts the first time, and the user can pick other keys. Without the portal, the call throws UnsupportedOperationException. |
- On Wayland,
globalShortcutreturns before the user confirms, and a shortcut that the user turns down never runs. -
window.focus()from the handler brings the window to the front where the portal hands on the activation token of the key press, as GNOME does. KDE Plasma hands none on, so there the window only asks for attention in the taskbar. - Keys that only matter while a window of the application has the keyboard belong in a menu entry with an accelerator; see Add menus.