@@ -33,6 +33,28 @@ export class ShortcutManager {
33
33
} ) ;
34
34
}
35
35
36
+ /**
37
+ * Convert react-hotkey format to Electron accelerator format
38
+ * @param accelerator The accelerator string from frontend
39
+ * @returns Converted accelerator string for Electron
40
+ */
41
+ private convertAcceleratorFormat ( accelerator : string ) : string {
42
+ return accelerator
43
+ . split ( '+' )
44
+ . map ( ( key ) => {
45
+ const trimmedKey = key . trim ( ) . toLowerCase ( ) ;
46
+
47
+ // Convert react-hotkey 'mod' to Electron 'CommandOrControl'
48
+ if ( trimmedKey === 'mod' ) {
49
+ return 'CommandOrControl' ;
50
+ }
51
+
52
+ // Keep other keys as is, but preserve proper casing
53
+ return key . trim ( ) . length === 1 ? key . trim ( ) . toUpperCase ( ) : key . trim ( ) ;
54
+ } )
55
+ . join ( '+' ) ;
56
+ }
57
+
36
58
initialize ( ) {
37
59
logger . info ( 'Initializing global shortcuts' ) ;
38
60
// Load shortcuts configuration from storage
@@ -67,7 +89,11 @@ export class ShortcutManager {
67
89
return { errorType : 'INVALID_FORMAT' , success : false } ;
68
90
}
69
91
70
- const cleanAccelerator = accelerator . trim ( ) . toLowerCase ( ) ;
92
+ // 转换前端格式到 Electron 格式
93
+ const convertedAccelerator = this . convertAcceleratorFormat ( accelerator . trim ( ) ) ;
94
+ const cleanAccelerator = convertedAccelerator . toLowerCase ( ) ;
95
+
96
+ logger . debug ( `Converted accelerator from ${ accelerator } to ${ convertedAccelerator } ` ) ;
71
97
72
98
// 3. 检查是否包含 + 号(修饰键格式)
73
99
if ( ! cleanAccelerator . includes ( '+' ) ) {
@@ -100,17 +126,19 @@ export class ShortcutManager {
100
126
}
101
127
102
128
// 6. 尝试注册测试(检查是否被系统占用)
103
- const testSuccess = globalShortcut . register ( cleanAccelerator , ( ) => { } ) ;
129
+ const testSuccess = globalShortcut . register ( convertedAccelerator , ( ) => { } ) ;
104
130
if ( ! testSuccess ) {
105
- logger . error ( `Shortcut ${ cleanAccelerator } is already registered by system or other app` ) ;
131
+ logger . error (
132
+ `Shortcut ${ convertedAccelerator } is already registered by system or other app` ,
133
+ ) ;
106
134
return { errorType : 'SYSTEM_OCCUPIED' , success : false } ;
107
135
} else {
108
136
// 测试成功,立即取消注册
109
- globalShortcut . unregister ( cleanAccelerator ) ;
137
+ globalShortcut . unregister ( convertedAccelerator ) ;
110
138
}
111
139
112
140
// 7. 更新配置
113
- this . shortcutsConfig [ id ] = cleanAccelerator ;
141
+ this . shortcutsConfig [ id ] = convertedAccelerator ;
114
142
115
143
this . saveShortcutsConfig ( ) ;
116
144
this . registerConfiguredShortcuts ( ) ;
@@ -196,7 +224,34 @@ export class ShortcutManager {
196
224
this . shortcutsConfig = DEFAULT_SHORTCUTS_CONFIG ;
197
225
this . saveShortcutsConfig ( ) ;
198
226
} else {
199
- this . shortcutsConfig = config ;
227
+ // Filter out invalid shortcuts that are not in DEFAULT_SHORTCUTS_CONFIG
228
+ const filteredConfig : Record < string , string > = { } ;
229
+ let hasInvalidKeys = false ;
230
+
231
+ Object . entries ( config ) . forEach ( ( [ id , accelerator ] ) => {
232
+ if ( DEFAULT_SHORTCUTS_CONFIG [ id ] ) {
233
+ filteredConfig [ id ] = accelerator ;
234
+ } else {
235
+ hasInvalidKeys = true ;
236
+ logger . debug ( `Filtering out invalid shortcut ID: ${ id } ` ) ;
237
+ }
238
+ } ) ;
239
+
240
+ // Ensure all default shortcuts are present
241
+ Object . entries ( DEFAULT_SHORTCUTS_CONFIG ) . forEach ( ( [ id , defaultAccelerator ] ) => {
242
+ if ( ! ( id in filteredConfig ) ) {
243
+ filteredConfig [ id ] = defaultAccelerator ;
244
+ logger . debug ( `Adding missing default shortcut: ${ id } = ${ defaultAccelerator } ` ) ;
245
+ }
246
+ } ) ;
247
+
248
+ this . shortcutsConfig = filteredConfig ;
249
+
250
+ // Save the filtered configuration back to storage if we removed invalid keys
251
+ if ( hasInvalidKeys ) {
252
+ logger . debug ( 'Saving filtered shortcuts config to remove invalid keys' ) ;
253
+ this . saveShortcutsConfig ( ) ;
254
+ }
200
255
}
201
256
202
257
logger . debug ( 'Loaded shortcuts config:' , this . shortcutsConfig ) ;
0 commit comments