improvement(shortcut): Support more keyboard shortcuts
This commit is contained in:
parent
a869857fc1
commit
23a2a6b57c
@ -56,6 +56,59 @@ function handleZoom(delta: number) {
|
||||
}
|
||||
}
|
||||
|
||||
const convertShortcutRecordedByKeyboardEventKeyValueToElectronGlobalShortcutFormat = (
|
||||
shortcut: string | string[]
|
||||
): string => {
|
||||
const accelerator = (() => {
|
||||
if (Array.isArray(shortcut)) {
|
||||
return shortcut
|
||||
} else {
|
||||
return shortcut.split('+').map((key) => key.trim())
|
||||
}
|
||||
})()
|
||||
|
||||
return accelerator
|
||||
.map((key) => {
|
||||
switch (key) {
|
||||
case 'Control':
|
||||
return 'CommandOrControl'
|
||||
case 'Ctrl':
|
||||
return 'CommandOrControl'
|
||||
case 'ArrowUp':
|
||||
return 'Up'
|
||||
case 'ArrowDown':
|
||||
return 'Down'
|
||||
case 'ArrowLeft':
|
||||
return 'Left'
|
||||
case 'ArrowRight':
|
||||
return 'Right'
|
||||
case 'AltGraph':
|
||||
return 'Alt'
|
||||
case 'Slash':
|
||||
return '/'
|
||||
case 'Semicolon':
|
||||
return ';'
|
||||
case 'BracketLeft':
|
||||
return '['
|
||||
case 'BracketRight':
|
||||
return ']'
|
||||
case 'Backslash':
|
||||
return '\\'
|
||||
case 'Quote':
|
||||
return "'"
|
||||
case 'Comma':
|
||||
return ','
|
||||
case 'Minus':
|
||||
return '-'
|
||||
case 'Equal':
|
||||
return '='
|
||||
default:
|
||||
return key
|
||||
}
|
||||
})
|
||||
.join('+')
|
||||
}
|
||||
|
||||
export function registerShortcuts(window: BrowserWindow) {
|
||||
window.webContents.setZoomFactor(configManager.getZoomFactor())
|
||||
|
||||
@ -104,7 +157,10 @@ export function registerShortcuts(window: BrowserWindow) {
|
||||
}
|
||||
|
||||
if (shortcut.enabled) {
|
||||
globalShortcut.register(formatShortcutKey(shortcut.shortcut), () => handler(window))
|
||||
const accelerator = convertShortcutRecordedByKeyboardEventKeyValueToElectronGlobalShortcutFormat(
|
||||
shortcut.shortcut
|
||||
)
|
||||
globalShortcut.register(accelerator, () => handler(window))
|
||||
}
|
||||
} catch (error) {
|
||||
Logger.error(`[ShortcutService] Failed to register shortcut ${shortcut.key}`)
|
||||
@ -120,12 +176,16 @@ export function registerShortcuts(window: BrowserWindow) {
|
||||
|
||||
if (showAppAccelerator) {
|
||||
const handler = getShortcutHandler({ key: 'show_app' } as Shortcut)
|
||||
handler && globalShortcut.register(showAppAccelerator, () => handler(window))
|
||||
const accelerator =
|
||||
convertShortcutRecordedByKeyboardEventKeyValueToElectronGlobalShortcutFormat(showAppAccelerator)
|
||||
handler && globalShortcut.register(accelerator, () => handler(window))
|
||||
}
|
||||
|
||||
if (showMiniWindowAccelerator) {
|
||||
const handler = getShortcutHandler({ key: 'mini_window' } as Shortcut)
|
||||
handler && globalShortcut.register(showMiniWindowAccelerator, () => handler(window))
|
||||
const accelerator =
|
||||
convertShortcutRecordedByKeyboardEventKeyValueToElectronGlobalShortcutFormat(showMiniWindowAccelerator)
|
||||
handler && globalShortcut.register(accelerator, () => handler(window))
|
||||
}
|
||||
} catch (error) {
|
||||
Logger.error('[ShortcutService] Failed to unregister shortcuts')
|
||||
|
||||
@ -8,7 +8,7 @@ import { initialState, resetShortcuts, toggleShortcut, updateShortcut } from '@r
|
||||
import { Shortcut } from '@renderer/types'
|
||||
import { Button, Input, InputRef, Switch, Table as AntTable, Tooltip } from 'antd'
|
||||
import type { ColumnsType } from 'antd/es/table'
|
||||
import { FC, useRef, useState } from 'react'
|
||||
import React, { FC, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
@ -92,8 +92,32 @@ const ShortcutSettings: FC = () => {
|
||||
return isMac ? '⇧' : 'Shift'
|
||||
case 'CommandOrControl':
|
||||
return isMac ? '⌘' : 'Ctrl'
|
||||
case ' ':
|
||||
return 'Space'
|
||||
case 'ArrowUp':
|
||||
return '↑'
|
||||
case 'ArrowDown':
|
||||
return '↓'
|
||||
case 'ArrowLeft':
|
||||
return '←'
|
||||
case 'ArrowRight':
|
||||
return '→'
|
||||
case 'Slash':
|
||||
return '/'
|
||||
case 'Semicolon':
|
||||
return ';'
|
||||
case 'BracketLeft':
|
||||
return '['
|
||||
case 'BracketRight':
|
||||
return ']'
|
||||
case 'Backslash':
|
||||
return '\\'
|
||||
case 'Quote':
|
||||
return "'"
|
||||
case 'Comma':
|
||||
return ','
|
||||
case 'Minus':
|
||||
return '-'
|
||||
case 'Equal':
|
||||
return '='
|
||||
default:
|
||||
return key.charAt(0).toUpperCase() + key.slice(1)
|
||||
}
|
||||
@ -101,13 +125,61 @@ const ShortcutSettings: FC = () => {
|
||||
.join(' + ')
|
||||
}
|
||||
|
||||
const usableEndKeys = (key: string): string | null => {
|
||||
if (key.length === 1) {
|
||||
return key.toUpperCase()
|
||||
}
|
||||
switch (key) {
|
||||
const usableEndKeys = (event: React.KeyboardEvent): string | null => {
|
||||
const { code } = event
|
||||
// No lock keys
|
||||
// Among the commonly used keys, not including: Escape, NumpadMultiply, NumpadDivide, NumpadSubtract, NumpadAdd, NumpadDecimal
|
||||
// The react-hotkeys-hook library does not differentiate between `Digit` and `Numpad`
|
||||
switch (code) {
|
||||
case 'KeyA':
|
||||
case 'KeyB':
|
||||
case 'KeyC':
|
||||
case 'KeyD':
|
||||
case 'KeyE':
|
||||
case 'KeyF':
|
||||
case 'KeyG':
|
||||
case 'KeyH':
|
||||
case 'KeyI':
|
||||
case 'KeyJ':
|
||||
case 'KeyK':
|
||||
case 'KeyL':
|
||||
case 'KeyM':
|
||||
case 'KeyN':
|
||||
case 'KeyO':
|
||||
case 'KeyP':
|
||||
case 'KeyQ':
|
||||
case 'KeyR':
|
||||
case 'KeyS':
|
||||
case 'KeyT':
|
||||
case 'KeyU':
|
||||
case 'KeyV':
|
||||
case 'KeyW':
|
||||
case 'KeyX':
|
||||
case 'KeyY':
|
||||
case 'KeyZ':
|
||||
case 'Digit0':
|
||||
case 'Digit1':
|
||||
case 'Digit2':
|
||||
case 'Digit3':
|
||||
case 'Digit4':
|
||||
case 'Digit5':
|
||||
case 'Digit6':
|
||||
case 'Digit7':
|
||||
case 'Digit8':
|
||||
case 'Digit9':
|
||||
case 'Numpad0':
|
||||
case 'Numpad1':
|
||||
case 'Numpad2':
|
||||
case 'Numpad3':
|
||||
case 'Numpad4':
|
||||
case 'Numpad5':
|
||||
case 'Numpad6':
|
||||
case 'Numpad7':
|
||||
case 'Numpad8':
|
||||
case 'Numpad9':
|
||||
return code.slice(-1)
|
||||
case 'Space':
|
||||
case 'Enter':
|
||||
case 'Escape':
|
||||
case 'Backspace':
|
||||
case 'Tab':
|
||||
case 'Delete':
|
||||
@ -139,10 +211,24 @@ const ShortcutSettings: FC = () => {
|
||||
case 'F17':
|
||||
case 'F18':
|
||||
case 'F19':
|
||||
case 'F20':
|
||||
return key
|
||||
case ' ':
|
||||
return 'Space'
|
||||
return code
|
||||
case 'Backquote':
|
||||
return '`'
|
||||
case 'Period':
|
||||
return '.'
|
||||
case 'NumpadEnter':
|
||||
return 'Enter'
|
||||
// The react-hotkeys-hook library does not handle the symbol strings for the following keys
|
||||
case 'Slash':
|
||||
case 'Semicolon':
|
||||
case 'BracketLeft':
|
||||
case 'BracketRight':
|
||||
case 'Backslash':
|
||||
case 'Quote':
|
||||
case 'Comma':
|
||||
case 'Minus':
|
||||
case 'Equal':
|
||||
return code
|
||||
default:
|
||||
return null
|
||||
}
|
||||
@ -156,15 +242,9 @@ const ShortcutSettings: FC = () => {
|
||||
if (e.metaKey) keys.push('Command')
|
||||
if (e.altKey) keys.push('Alt')
|
||||
if (e.shiftKey) keys.push('Shift')
|
||||
|
||||
const key = e.key
|
||||
|
||||
if (key.length === 1 && !['Control', 'Alt', 'Shift', 'Meta'].includes(key)) {
|
||||
if (key === ' ') {
|
||||
keys.push('Space')
|
||||
} else {
|
||||
keys.push(key.toUpperCase())
|
||||
}
|
||||
const endKey = usableEndKeys(e)
|
||||
if (endKey) {
|
||||
keys.push(endKey)
|
||||
}
|
||||
|
||||
if (!isValidShortcut(keys)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user