Skip to content

Commit 07f3e6a

Browse files
authored
🐛 fix: fix update hotkey invalid when input mod in desktop (#8572)
* fix hotkey with mod * fix invalid hotkeys * add tests
1 parent 3c35edc commit 07f3e6a

File tree

2 files changed

+600
-6
lines changed

2 files changed

+600
-6
lines changed

apps/desktop/src/main/core/ui/ShortcutManager.ts

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ export class ShortcutManager {
3333
});
3434
}
3535

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+
3658
initialize() {
3759
logger.info('Initializing global shortcuts');
3860
// Load shortcuts configuration from storage
@@ -67,7 +89,11 @@ export class ShortcutManager {
6789
return { errorType: 'INVALID_FORMAT', success: false };
6890
}
6991

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}`);
7197

7298
// 3. 检查是否包含 + 号(修饰键格式)
7399
if (!cleanAccelerator.includes('+')) {
@@ -100,17 +126,19 @@ export class ShortcutManager {
100126
}
101127

102128
// 6. 尝试注册测试(检查是否被系统占用)
103-
const testSuccess = globalShortcut.register(cleanAccelerator, () => {});
129+
const testSuccess = globalShortcut.register(convertedAccelerator, () => {});
104130
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+
);
106134
return { errorType: 'SYSTEM_OCCUPIED', success: false };
107135
} else {
108136
// 测试成功,立即取消注册
109-
globalShortcut.unregister(cleanAccelerator);
137+
globalShortcut.unregister(convertedAccelerator);
110138
}
111139

112140
// 7. 更新配置
113-
this.shortcutsConfig[id] = cleanAccelerator;
141+
this.shortcutsConfig[id] = convertedAccelerator;
114142

115143
this.saveShortcutsConfig();
116144
this.registerConfiguredShortcuts();
@@ -196,7 +224,34 @@ export class ShortcutManager {
196224
this.shortcutsConfig = DEFAULT_SHORTCUTS_CONFIG;
197225
this.saveShortcutsConfig();
198226
} 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+
}
200255
}
201256

202257
logger.debug('Loaded shortcuts config:', this.shortcutsConfig);

0 commit comments

Comments
 (0)