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"`