From dbc2be1c1e9272a948ad08c20666af307eddb24c Mon Sep 17 00:00:00 2001
From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com>
Date: Tue, 17 Dec 2024 15:25:34 -0800
Subject: [PATCH] Global Hotkey Docs (#1548)
Adds the following changes:
- renames "key:globalhotkey" to "app:globalhotkey"
- adds globalhostkey documentation (especially in regard to what keys are allowed)
- improves the algorithm that converts electron keybindings from wave keybindings
- fixes some regexp problems
---
docs/docs/config.mdx | 42 ++++++++++++++++++++++
docs/docs/keybindings.mdx | 4 +++
emain/emain-util.ts | 66 +++++++++++++++++++++++++++++++++++
emain/emain.ts | 2 +-
frontend/types/gotypes.d.ts | 4 +--
pkg/wconfig/metaconsts.go | 6 ++--
pkg/wconfig/settingsconfig.go | 6 ++--
7 files changed, 121 insertions(+), 9 deletions(-)
diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx
index c960d8be5..49cada776 100644
--- a/docs/docs/config.mdx
+++ b/docs/docs/config.mdx
@@ -25,6 +25,7 @@ wsh editconfig
| Key Name | Type | Function |
| ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| app:globalhotkey | string | A systemwide keybinding to open your most recent wave window. This is a set of key names separated by `:`. For more info, see [Customizable Systemwide Global Hotkey](#customizable-systemwide-global-hotkey) |
| ai:preset | string | the default AI preset to use |
| ai:baseurl | string | Set the AI Base Url (must be OpenAI compatible) |
| ai:apitoken | string | your AI api token |
@@ -190,3 +191,44 @@ wsh editconfig termthemes.json
| background | CSS color | | | background color (default when no color code is applied), must have alpha channel (#rrggbbaa) if you want the terminal to be transparent |
| cursorAccent | CSS color | | | color for cursor |
| selectionBackground | CSS color | | | background color for selected text |
+
+### Customizable Systemwide Global Hotkey
+
+Wave allows settings a custom global hotkey to open your most recent window from anywhere in your computer. This has the name `"app:globalhotkey"` in the `settings.json` file and takes the form of a series of key names separated by the `:` character. We support the following key names:
+
+- `Ctrl`
+- `Cmd`
+- `Shift`
+- `Alt`
+- `Option`
+- `Meta`
+- `Super`
+- Digits (non-numpad) represented by `c{Digit0}` through `c{Digit9}`
+- Letters `a` though `z`
+- F keys `F1` through `F20`
+- Soft keys `Soft1` through `Soft4`. These are essentially the same as `F21` through `F24`.
+- Space represented as a literal space
+- `Enter` (This is labeled as return on Mac)
+- `Tab`
+- `CapsLock`
+- `NumLock`
+- `Backspace` (This is labeled as delete on Mac)
+- `Delete`
+- `Insert`
+- The arrow keys `ArrowUp`, `ArrowDown`, `ArrowLeft`, and `ArrowRight`
+- `Home`
+- `End`
+- `PageUp`
+- `PageDown`
+- `Esc`
+- Volume controls `AudioVolumeUp`, `AudioVolumeDown`, `AudioVolumeMute`
+- Media controls `MediaTrackNext`, `MediaTrackPrevious`, `MediaPlayPause`, and `MediaStop`
+- `PrintScreen`
+- Numpad keys represented by `c{Numpad0}` through `c{Numpad9}`
+- The numpad decimal represented by `Decimal`
+- The numpad plus/add represented by `Add`
+- The numpad minus/subtract represented by `Subtract`
+- The numpad star/multiply represented by `Multiply`
+- The numpad slash/divide represented by `Divide`
+
+As an example, to set the key to the combination of Control, Option, and the letter E, you would configure it to `"Ctrl:Opt:e"`.
diff --git a/docs/docs/keybindings.mdx b/docs/docs/keybindings.mdx
index 2313bacc3..cfb1569e5 100644
--- a/docs/docs/keybindings.mdx
+++ b/docs/docs/keybindings.mdx
@@ -71,4 +71,8 @@ replace "Cmd" with "Alt" (note that "Ctrl" is "Ctrl" on both Mac, Windows, and L
| ---------------- | ------------- |
| | Clear AI Chat |
+## Customizeable Systemwide Global Hotkey
+
+Wave allows setting a custom global hotkey to focus your most recent window from anywhere in your computer. For more information on this, see [the config docs](./config#customizable-systemwide-global-hotkey).
+
diff --git a/emain/emain-util.ts b/emain/emain-util.ts
index 16fbf9367..601b1b7f3 100644
--- a/emain/emain-util.ts
+++ b/emain/emain-util.ts
@@ -170,6 +170,9 @@ export function ensureBoundsAreVisible(bounds: electron.Rectangle): electron.Rec
export function waveKeyToElectronKey(waveKey: string): string {
const waveParts = waveKey.split(":");
const electronParts: Array = waveParts.map((part: string) => {
+ const digitRegexpMatch = new RegExp("^c{Digit([0-9])}$").exec(part);
+ const numpadRegexpMatch = new RegExp("^c{Numpad([0-9])}$").exec(part);
+ const lowercaseCharMatch = new RegExp("^([a-z])$").exec(part);
if (part == "ArrowUp") {
return "Up";
}
@@ -182,6 +185,69 @@ export function waveKeyToElectronKey(waveKey: string): string {
if (part == "ArrowRight") {
return "Right";
}
+ if (part == "Soft1") {
+ return "F21";
+ }
+ if (part == "Soft2") {
+ return "F22";
+ }
+ if (part == "Soft3") {
+ return "F23";
+ }
+ if (part == "Soft4") {
+ return "F24";
+ }
+ if (part == " ") {
+ return "Space";
+ }
+ if (part == "CapsLock") {
+ return "Capslock";
+ }
+ if (part == "NumLock") {
+ return "Numlock";
+ }
+ if (part == "ScrollLock") {
+ return "Scrolllock";
+ }
+ if (part == "AudioVolumeUp") {
+ return "VolumeUp";
+ }
+ if (part == "AudioVolumeDown") {
+ return "VolumeDown";
+ }
+ if (part == "AudioVolumeMute") {
+ return "VolumeMute";
+ }
+ if (part == "MediaTrackNext") {
+ return "MediaNextTrack";
+ }
+ if (part == "MediaTrackPrevious") {
+ return "MediaPreviousTrack";
+ }
+ if (part == "Decimal") {
+ return "numdec";
+ }
+ if (part == "Add") {
+ return "numadd";
+ }
+ if (part == "Subtract") {
+ return "numsub";
+ }
+ if (part == "Multiply") {
+ return "nummult";
+ }
+ if (part == "Divide") {
+ return "numdiv";
+ }
+ if (digitRegexpMatch && digitRegexpMatch.length > 1) {
+ return digitRegexpMatch[1];
+ }
+ if (numpadRegexpMatch && numpadRegexpMatch.length > 1) {
+ return `num${numpadRegexpMatch[1]}`;
+ }
+ if (lowercaseCharMatch && lowercaseCharMatch.length > 1) {
+ return lowercaseCharMatch[1].toUpperCase();
+ }
return part;
});
diff --git a/emain/emain.ts b/emain/emain.ts
index c5cf985be..a4511db45 100644
--- a/emain/emain.ts
+++ b/emain/emain.ts
@@ -611,7 +611,7 @@ async function appMain() {
fireAndForget(createNewWaveWindow);
}
});
- const rawGlobalHotKey = launchSettings?.["key:globalhotkey"];
+ const rawGlobalHotKey = launchSettings?.["app:globalhotkey"];
if (rawGlobalHotKey) {
registerGlobalHotkey(rawGlobalHotKey);
}
diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts
index 895494bda..c0149d01e 100644
--- a/frontend/types/gotypes.d.ts
+++ b/frontend/types/gotypes.d.ts
@@ -616,6 +616,8 @@ declare global {
// wconfig.SettingsType
type SettingsType = {
+ "app:*"?: boolean;
+ "app:globalhotkey"?: string;
"ai:*"?: boolean;
"ai:preset"?: string;
"ai:apitype"?: string;
@@ -674,8 +676,6 @@ declare global {
"window:magnifiedblocksize"?: number;
"window:magnifiedblockblurprimarypx"?: number;
"window:magnifiedblockblursecondarypx"?: number;
- "key:*"?: boolean;
- "key:globalhotkey"?: string;
"telemetry:*"?: boolean;
"telemetry:enabled"?: boolean;
"conn:*"?: boolean;
diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go
index 6e62b5c20..7e95579ad 100644
--- a/pkg/wconfig/metaconsts.go
+++ b/pkg/wconfig/metaconsts.go
@@ -6,6 +6,9 @@
package wconfig
const (
+ ConfigKey_AppClear = "app:*"
+ ConfigKey_AppGlobalHotkey = "app:globalhotkey"
+
ConfigKey_AiClear = "ai:*"
ConfigKey_AiPreset = "ai:preset"
ConfigKey_AiApiType = "ai:apitype"
@@ -75,9 +78,6 @@ const (
ConfigKey_WindowMagnifiedBlockBlurPrimaryPx = "window:magnifiedblockblurprimarypx"
ConfigKey_WindowMagnifiedBlockBlurSecondaryPx = "window:magnifiedblockblursecondarypx"
- ConfigKey_KeyClear = "key:*"
- ConfigKey_KeyGlobalHotkey = "key:globalhotkey"
-
ConfigKey_TelemetryClear = "telemetry:*"
ConfigKey_TelemetryEnabled = "telemetry:enabled"
diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go
index 6b9e58319..8b312db4b 100644
--- a/pkg/wconfig/settingsconfig.go
+++ b/pkg/wconfig/settingsconfig.go
@@ -33,6 +33,9 @@ const AnySchema = `
`
type SettingsType struct {
+ AppClear bool `json:"app:*,omitempty"`
+ AppGlobalHotkey string `json:"app:globalhotkey,omitempty"`
+
AiClear bool `json:"ai:*,omitempty"`
AiPreset string `json:"ai:preset,omitempty"`
AiApiType string `json:"ai:apitype,omitempty"`
@@ -102,9 +105,6 @@ type SettingsType struct {
WindowMagnifiedBlockBlurPrimaryPx *int64 `json:"window:magnifiedblockblurprimarypx,omitempty"`
WindowMagnifiedBlockBlurSecondaryPx *int64 `json:"window:magnifiedblockblursecondarypx,omitempty"`
- KeyClear bool `json:"key:*,omitempty"`
- KeyGlobalHotkey string `json:"key:globalhotkey,omitempty"`
-
TelemetryClear bool `json:"telemetry:*,omitempty"`
TelemetryEnabled bool `json:"telemetry:enabled,omitempty"`