diff --git a/feature/src/views/settings/index.vue b/feature/src/views/settings/index.vue index 9cdfda3..2a02f96 100644 --- a/feature/src/views/settings/index.vue +++ b/feature/src/views/settings/index.vue @@ -274,12 +274,16 @@ const state = reactive({ custom: {}, }); +// 添加lastKeyPressTime变量来跟踪按键时间 +const lastKeyPressTime = ref(0); +const DOUBLE_CLICK_THRESHOLD = 300; // 双击时间阈值(毫秒) + const isWindows = window?.rubick?.isWindows(); const tipText = computed(() => { const optionKeyName = isWindows ? 'Alt' : 'Option、Command'; return t('feature.settings.global.addShortcutKeyTips', { optionKeyName: optionKeyName, - }); + }) + `此外你也可以双击修饰键如(Ctrl+Ctrl)`; }); const currentSelect = ref(['userInfo']); @@ -314,33 +318,60 @@ watch(state, setConfig); const changeShortCut = (e, key) => { let compose = ''; - // 添加是否包含功能键的判断 - let incluFuncKeys = false; + const currentTime = Date.now(); + const isDoubleClick = currentTime - lastKeyPressTime.value < DOUBLE_CLICK_THRESHOLD; + lastKeyPressTime.value = currentTime; + + // 处理 F1-F12 功能键 + if (e.keyCode >= 112 && e.keyCode <= 123) { + state.shortCut[key] = keycodes[e.keyCode].toUpperCase(); + return; + } + + // 处理双击功能键的情况 + if (isDoubleClick) { + if (e.keyCode === 17) { // Ctrl + state.shortCut[key] = 'Ctrl+Ctrl'; + return; + } + if (e.keyCode === 18) { // Alt + state.shortCut[key] = 'Option+Option'; + return; + } + if (e.keyCode === 16) { // Shift + state.shortCut[key] = 'Shift+Shift'; + return; + } + if (e.keyCode === 93) { // Command + state.shortCut[key] = 'Command+Command'; + return; + } + } + + // 处理功能键+普通键的组合 + let hasModifierKey = false; + if (e.ctrlKey && e.keyCode !== 17) { compose += '+Ctrl'; - incluFuncKeys = true; + hasModifierKey = true; } if (e.shiftKey && e.keyCode !== 16) { compose += '+Shift'; - incluFuncKeys = true; + hasModifierKey = true; } if (e.altKey && e.keyCode !== 18) { compose += '+Option'; - incluFuncKeys = true; + hasModifierKey = true; } if (e.metaKey && e.keyCode !== 93) { compose += '+Command'; - incluFuncKeys = true; + hasModifierKey = true; } - compose += '+' + keycodes[e.keyCode].toUpperCase(); - compose = compose.substring(1); - if ( - incluFuncKeys && - e.keyCode !== 16 && - e.keyCode !== 17 && - e.keyCode !== 18 && - e.keyCode !== 93 - ) { + + // 只有当有修饰键时才添加普通键 + if (hasModifierKey) { + compose += '+' + keycodes[e.keyCode].toUpperCase(); + compose = compose.substring(1); state.shortCut[key] = compose; } else { // 不做处理 diff --git a/package.json b/package.json index f396d44..cd34c20 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "pouchdb-load": "^1.4.6", "pouchdb-replication-stream": "^1.2.9", "simple-plist": "0.2.1", + "uiohook-napi": "^1.5.4", "vue": "^3.0.0", "vue-router": "^4.0.0-0", "vuex": "^4.0.0-0", diff --git a/src/main/common/registerHotKey.ts b/src/main/common/registerHotKey.ts index 0d76b40..fb55121 100644 --- a/src/main/common/registerHotKey.ts +++ b/src/main/common/registerHotKey.ts @@ -10,6 +10,7 @@ import { import screenCapture from '@/core/screen-capture'; import localConfig from '@/main/common/initLocalConfig'; import winPosition from './getWinPosition'; +import { uIOhook, UiohookKey } from 'uiohook-napi'; const registerHotKey = (mainWindow: BrowserWindow): void => { // 设置开机启动 @@ -57,27 +58,43 @@ const registerHotKey = (mainWindow: BrowserWindow): void => { } }; + // 显示主窗口 + function mainWindowPopUp() { + const currentShow = mainWindow.isVisible() && mainWindow.isFocused(); + if (currentShow) return mainWindow.hide(); + const { x: wx, y: wy } = winPosition.getPosition(); + mainWindow.setAlwaysOnTop(false); + mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); + mainWindow.focus(); + mainWindow.setVisibleOnAllWorkspaces(false, { + visibleOnFullScreen: true, + }); + mainWindow.setPosition(wx, wy); + mainWindow.show(); + } + const init = async () => { await setAutoLogin(); await setDarkMode(); await setTheme(); const config = await localConfig.getConfig(); globalShortcut.unregisterAll(); - // 注册偏好快捷键 - globalShortcut.register(config.perf.shortCut.showAndHidden, () => { - const currentShow = mainWindow.isVisible() && mainWindow.isFocused(); - if (currentShow) return mainWindow.hide(); - const { x: wx, y: wy } = winPosition.getPosition(); - mainWindow.setAlwaysOnTop(false); - mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); - mainWindow.focus(); - mainWindow.setVisibleOnAllWorkspaces(false, { - visibleOnFullScreen: true, - }); - mainWindow.setPosition(wx, wy); - mainWindow.show(); - }); + // 注册偏好快捷键 + // 处理显示/隐藏快捷键的注册 + const doublePressShortcuts = ['Ctrl+Ctrl', 'Option+Option', 'Shift+Shift', 'Command+Command']; + const isDoublePressShortcut = doublePressShortcuts.includes(config.perf.shortCut.showAndHidden); + + if (isDoublePressShortcut) { + // 双击快捷键(如 Ctrl+Ctrl)详见 uIOhookRegister 函数实现 + } else { + // 注册普通快捷键(如 Ctrl+Space、F8 等) + globalShortcut.register(config.perf.shortCut.showAndHidden, () => { + mainWindowPopUp(); + }); + } + + // 截图快捷键 globalShortcut.register(config.perf.shortCut.capture, () => { screenCapture(mainWindow, (data) => { data && @@ -107,9 +124,48 @@ const registerHotKey = (mainWindow: BrowserWindow): void => { }); }); }; + + uIOhookRegister(mainWindowPopUp); init(); ipcMain.on('re-register', () => { init(); }); }; export default registerHotKey; + +function uIOhookRegister(callback: () => void) { + let lastModifierPress = Date.now(); + uIOhook.on('keydown', async (uio_event) => { + const config = await localConfig.getConfig(); // 此处还有优化空间 + + if ( + ![ + 'Ctrl+Ctrl', + 'Option+Option', + 'Shift+Shift', + 'Command+Command', + ].includes(config.perf.shortCut.showAndHidden) + ) { + return; + } + + // 双击快捷键,如 Ctrl+Ctrl + const modifers = config.perf.shortCut.showAndHidden.split('+'); + const showAndHiddenKeyStr = modifers.pop(); // Ctrl + const keyStr2uioKeyCode = { + Ctrl: UiohookKey.Ctrl, + Shift: UiohookKey.Shift, + Option: UiohookKey.Alt, + Command: UiohookKey.Comma, + }; + + if (uio_event.keycode === keyStr2uioKeyCode[showAndHiddenKeyStr]) { + const currentTime = Date.now(); + if (currentTime - lastModifierPress < 300) { + callback(); // 调用 mainWindowPopUp + } + lastModifierPress = currentTime; + } + }); + uIOhook.start(); +}