From b20942d254b581300d04fa19fedca5311a7b793a Mon Sep 17 00:00:00 2001 From: lyswhut Date: Fri, 15 May 2020 11:50:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8C=89=E9=94=AE=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 5 - package.json | 1 - src/renderer/components/material/SongList.vue | 28 +---- src/renderer/config/bindkey.js | 44 ------- src/renderer/config/event.js | 15 ++- src/renderer/utils/keyBind.js | 109 ++++++++++++++++++ src/renderer/views/Download.vue | 28 +---- src/renderer/views/List.vue | 28 +---- src/renderer/views/Search.vue | 28 +---- 9 files changed, 136 insertions(+), 150 deletions(-) delete mode 100644 src/renderer/config/bindkey.js create mode 100644 src/renderer/utils/keyBind.js diff --git a/package-lock.json b/package-lock.json index 1839de0f..8fb0cfdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10085,11 +10085,6 @@ "minimist": "^1.2.5" } }, - "mousetrap": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz", - "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==" - }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index 01ffdcd7..48563d2c 100644 --- a/package.json +++ b/package.json @@ -223,7 +223,6 @@ "image-size": "^0.8.3", "js-htmlencode": "^0.3.0", "lrc-file-parser": "^1.0.3", - "mousetrap": "^1.6.5", "needle": "^2.4.1", "node-id3": "^0.1.16", "request": "^2.88.2", diff --git a/src/renderer/components/material/SongList.vue b/src/renderer/components/material/SongList.vue index 6dc80061..0214552a 100644 --- a/src/renderer/components/material/SongList.vue +++ b/src/renderer/components/material/SongList.vue @@ -121,8 +121,6 @@ export default { keyEvent: { isShiftDown: false, isModDown: false, - isADown: false, - aDownTimeout: null, }, } }, @@ -139,7 +137,6 @@ export default { window.eventHub.$on('key_mod_down', this.handle_key_mod_down) window.eventHub.$on('key_mod_up', this.handle_key_mod_up) window.eventHub.$on('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$on('key_mod+a_up', this.handle_key_mod_a_up) }, unlistenEvent() { window.eventHub.$off('key_shift_down', this.handle_key_shift_down) @@ -147,7 +144,6 @@ export default { window.eventHub.$off('key_mod_down', this.handle_key_mod_down) window.eventHub.$off('key_mod_up', this.handle_key_mod_up) window.eventHub.$off('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$off('key_mod+a_up', this.handle_key_mod_a_up) }, handle_key_shift_down() { if (!this.keyEvent.isShiftDown) this.keyEvent.isShiftDown = true @@ -161,26 +157,10 @@ export default { handle_key_mod_up() { if (this.keyEvent.isModDown) this.keyEvent.isModDown = false }, - handle_key_mod_a_down() { - if (!this.keyEvent.isADown) { - this.keyEvent.isModDown = false - this.keyEvent.isADown = true - this.handleSelectAllData() - if (this.keyEvent.aDownTimeout) clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = setTimeout(() => { - this.keyEvent.aDownTimeout = null - this.keyEvent.isADown = false - }, 500) - } - }, - handle_key_mod_a_up() { - if (this.keyEvent.isADown) { - if (this.keyEvent.aDownTimeout) { - clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = null - } - this.keyEvent.isADown = false - } + handle_key_mod_a_down({ event }) { + if (event.repeat) return + this.keyEvent.isModDown = false + this.handleSelectAllData() }, handleDoubleClick(event, index) { if (event.target.classList.contains('select')) return diff --git a/src/renderer/config/bindkey.js b/src/renderer/config/bindkey.js deleted file mode 100644 index eaddc52d..00000000 --- a/src/renderer/config/bindkey.js +++ /dev/null @@ -1,44 +0,0 @@ -import mousetrap from 'mousetrap' - -let eventHub - -const bindKeys = [ - 'shift', - 'mod', - 'mod+a', -] - -const bindKey = () => { - mousetrap.reset() - for (const key of bindKeys) { - mousetrap.bind(key, (event, combo) => { - eventHub.$emit(`key_${key}_down`, { event, combo }) - return false - }, 'keydown') - mousetrap.bind(key, (event, combo) => { - eventHub.$emit(`key_${key}_up`, { event, combo }) - return false - }, 'keyup') - } -} - -const unbindKey = () => { - for (const key of bindKeys) { - mousetrap.unbind(key, 'keydown') - mousetrap.unbind(key, 'keyup') - } -} - -const handleFocus = () => { - for (const key of bindKeys) { - eventHub.$emit(`key_${key}_up`, { combo: key }) - } -} - -export default () => { - eventHub = window.eventHub - - eventHub.$on('bindKey', bindKey) - eventHub.$on('unbindKey', unbindKey) - eventHub.$on('focus', handleFocus) -} diff --git a/src/renderer/config/event.js b/src/renderer/config/event.js index e4e0cb6d..6cfdce17 100644 --- a/src/renderer/config/event.js +++ b/src/renderer/config/event.js @@ -1,11 +1,18 @@ import Vue from 'vue' -import bindkey from './bindkey' +import keyBind from '../utils/keyBind' import { rendererOn } from '../../common/ipc' -window.eventHub = new Vue() +const eventHub = window.eventHub = new Vue() -bindkey() +eventHub.$on('bindKey', () => { + keyBind.bindKey((key, type, event, keys) => { + // console.log(`key_${key}_${type}`) + eventHub.$emit(`key_${key}_${type}`, { event, keys, key }) + }) +}) +eventHub.$on('unbindKey', keyBind.unbindKey) rendererOn('focus', () => { - window.eventHub.$emit('focus') + keyBind.clearDownKeys() + eventHub.$emit('focus') }) diff --git a/src/renderer/utils/keyBind.js b/src/renderer/utils/keyBind.js new file mode 100644 index 00000000..6b6156e8 --- /dev/null +++ b/src/renderer/utils/keyBind.js @@ -0,0 +1,109 @@ +import { isMac, isWin } from '../../common/utils' + +const downKeys = new Set() + +const handleEvent = (type, event, keys) => { + if (isWin) { + let index = keys.indexOf('ctrl') + if (index > -1) keys.splice(index, 1, 'mod') + } else if (isMac) { + let index = keys.indexOf('meta') + if (index > -1) keys.splice(index, 1, 'mod') + } + let key = keys.join('+') + + switch (type) { + case 'down': + downKeys.add(key) + break + case 'up': + downKeys.delete(key) + break + } + handleSendEvent(key, type, event, keys) +} + +// 修饰键处理 +const eventModifiers = event => { + let modifiers = [] + if (event.ctrlKey) modifiers.push('ctrl') + if (event.shiftKey) modifiers.push('shift') + if (event.altKey) modifiers.push('alt') + if (event.metaKey) modifiers.push('meta') + + return modifiers +} + +// 是否忽略事件(表单元素等默认忽略) +const assertStopCallback = element => { + // if the element has the class "keybind" then no need to stop + if (element.classList.contains('key-bind')) return false + + // stop for input, select, and textarea + switch (element.tagName) { + case 'INPUT': + case 'SELECT': + case 'TEXTAREA': + return true + default: + return element.isContentEditable + } +} + +const handleKeyDown = event => { + if (assertStopCallback(event.target)) return + event.preventDefault() + let keys = eventModifiers(event) + switch (event.key) { + case 'Control': + case 'Alt': + case 'Meta': + case 'Shift': + break + default: + keys.push(event.key) + break + } + handleEvent('down', event, keys) +} + +const handleKeyUp = event => { + if (assertStopCallback(event.target)) return + event.preventDefault() + let keys = eventModifiers(event) + switch (event.key) { + case 'Control': + keys.push('ctrl') + break + default: + keys.push(event.key.toLowerCase()) + break + } + handleEvent('up', event, keys) +} + +let handleSendEvent + +const bindKey = (handle = () => {}) => { + handleSendEvent = handle + document.addEventListener('keydown', handleKeyDown) + document.addEventListener('keyup', handleKeyUp) +} + +const unbindKey = () => { + document.removeEventListener('keydown', handleKeyDown) + document.removeEventListener('keyup', handleKeyUp) +} + +const clearDownKeys = () => { + for (const key of downKeys) { + handleSendEvent(key, 'up') + } + downKeys.clear() +} + +export default { + bindKey, + unbindKey, + clearDownKeys, +} diff --git a/src/renderer/views/Download.vue b/src/renderer/views/Download.vue index 09a02be8..a6723d36 100644 --- a/src/renderer/views/Download.vue +++ b/src/renderer/views/Download.vue @@ -73,8 +73,6 @@ export default { keyEvent: { isShiftDown: false, isModDown: false, - isADown: false, - aDownTimeout: null, }, } }, @@ -135,7 +133,6 @@ export default { window.eventHub.$on('key_mod_down', this.handle_key_mod_down) window.eventHub.$on('key_mod_up', this.handle_key_mod_up) window.eventHub.$on('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$on('key_mod+a_up', this.handle_key_mod_a_up) }, unlistenEvent() { window.eventHub.$off('key_shift_down', this.handle_key_shift_down) @@ -143,7 +140,6 @@ export default { window.eventHub.$off('key_mod_down', this.handle_key_mod_down) window.eventHub.$off('key_mod_up', this.handle_key_mod_up) window.eventHub.$off('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$off('key_mod+a_up', this.handle_key_mod_a_up) }, handle_key_shift_down() { if (!this.keyEvent.isShiftDown) this.keyEvent.isShiftDown = true @@ -157,26 +153,10 @@ export default { handle_key_mod_up() { if (this.keyEvent.isModDown) this.keyEvent.isModDown = false }, - handle_key_mod_a_down() { - if (!this.keyEvent.isADown) { - this.keyEvent.isModDown = false - this.keyEvent.isADown = true - this.handleSelectAllData() - if (this.keyEvent.aDownTimeout) clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = setTimeout(() => { - this.keyEvent.aDownTimeout = null - this.keyEvent.isADown = false - }, 500) - } - }, - handle_key_mod_a_up() { - if (this.keyEvent.isADown) { - if (this.keyEvent.aDownTimeout) { - clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = null - } - this.keyEvent.isADown = false - } + handle_key_mod_a_down({ event }) { + if (event.repeat) return + this.keyEvent.isModDown = false + this.handleSelectAllData() }, handleDoubleClick(event, index) { if (event.target.classList.contains('select')) return diff --git a/src/renderer/views/List.vue b/src/renderer/views/List.vue index 13c91722..c7d2aede 100644 --- a/src/renderer/views/List.vue +++ b/src/renderer/views/List.vue @@ -71,8 +71,6 @@ export default { keyEvent: { isShiftDown: false, isModDown: false, - isADown: false, - aDownTimeout: null, }, } }, @@ -194,7 +192,6 @@ export default { window.eventHub.$on('key_mod_down', this.handle_key_mod_down) window.eventHub.$on('key_mod_up', this.handle_key_mod_up) window.eventHub.$on('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$on('key_mod+a_up', this.handle_key_mod_a_up) }, unlistenEvent() { window.eventHub.$off('key_shift_down', this.handle_key_shift_down) @@ -202,7 +199,6 @@ export default { window.eventHub.$off('key_mod_down', this.handle_key_mod_down) window.eventHub.$off('key_mod_up', this.handle_key_mod_up) window.eventHub.$off('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$off('key_mod+a_up', this.handle_key_mod_a_up) }, handle_key_shift_down() { if (!this.keyEvent.isShiftDown) this.keyEvent.isShiftDown = true @@ -216,26 +212,10 @@ export default { handle_key_mod_up() { if (this.keyEvent.isModDown) this.keyEvent.isModDown = false }, - handle_key_mod_a_down() { - if (!this.keyEvent.isADown) { - this.keyEvent.isModDown = false - this.keyEvent.isADown = true - this.handleSelectAllData() - if (this.keyEvent.aDownTimeout) clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = setTimeout(() => { - this.keyEvent.aDownTimeout = null - this.keyEvent.isADown = false - }, 500) - } - }, - handle_key_mod_a_up() { - if (this.keyEvent.isADown) { - if (this.keyEvent.aDownTimeout) { - clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = null - } - this.keyEvent.isADown = false - } + handle_key_mod_a_down({ event }) { + if (event.repeat) return + this.keyEvent.isModDown = false + this.handleSelectAllData() }, handleDelayShow() { this.clearDelayTimeout() diff --git a/src/renderer/views/Search.vue b/src/renderer/views/Search.vue index 76d07977..3b89c5c2 100644 --- a/src/renderer/views/Search.vue +++ b/src/renderer/views/Search.vue @@ -81,8 +81,6 @@ export default { keyEvent: { isShiftDown: false, isModDown: false, - isADown: false, - aDownTimeout: null, }, } }, @@ -172,7 +170,6 @@ export default { window.eventHub.$on('key_mod_down', this.handle_key_mod_down) window.eventHub.$on('key_mod_up', this.handle_key_mod_up) window.eventHub.$on('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$on('key_mod+a_up', this.handle_key_mod_a_up) }, unlistenEvent() { window.eventHub.$off('key_shift_down', this.handle_key_shift_down) @@ -180,7 +177,6 @@ export default { window.eventHub.$off('key_mod_down', this.handle_key_mod_down) window.eventHub.$off('key_mod_up', this.handle_key_mod_up) window.eventHub.$off('key_mod+a_down', this.handle_key_mod_a_down) - window.eventHub.$off('key_mod+a_up', this.handle_key_mod_a_up) }, handle_key_shift_down() { if (!this.keyEvent.isShiftDown) this.keyEvent.isShiftDown = true @@ -194,26 +190,10 @@ export default { handle_key_mod_up() { if (this.keyEvent.isModDown) this.keyEvent.isModDown = false }, - handle_key_mod_a_down() { - if (!this.keyEvent.isADown) { - this.keyEvent.isModDown = false - this.keyEvent.isADown = true - this.handleSelectAllData() - if (this.keyEvent.aDownTimeout) clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = setTimeout(() => { - this.keyEvent.aDownTimeout = null - this.keyEvent.isADown = false - }, 500) - } - }, - handle_key_mod_a_up() { - if (this.keyEvent.isADown) { - if (this.keyEvent.aDownTimeout) { - clearTimeout(this.keyEvent.aDownTimeout) - this.keyEvent.aDownTimeout = null - } - this.keyEvent.isADown = false - } + handle_key_mod_a_down({ event }) { + if (event.repeat) return + this.keyEvent.isModDown = false + this.handleSelectAllData() }, handleSearch(text, page) { if (text === '') return this.clearList()