mirror of
https://github.com/Eugeny/tabby.git
synced 2024-12-02 11:44:01 +03:00
hotkey handling fixes
This commit is contained in:
parent
426606ba06
commit
08f1ad4c75
@ -64,6 +64,7 @@ export class HotkeysService {
|
|||||||
private pressedKeystroke: Keystroke|null = null
|
private pressedKeystroke: Keystroke|null = null
|
||||||
private lastKeystrokes: PastKeystroke[] = []
|
private lastKeystrokes: PastKeystroke[] = []
|
||||||
private shouldSaveNextKeystroke = true
|
private shouldSaveNextKeystroke = true
|
||||||
|
private lastEventTimestamp = 0
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
@ -75,12 +76,10 @@ export class HotkeysService {
|
|||||||
events.forEach(eventType => {
|
events.forEach(eventType => {
|
||||||
document.addEventListener(eventType, (nativeEvent: KeyboardEvent) => {
|
document.addEventListener(eventType, (nativeEvent: KeyboardEvent) => {
|
||||||
this._keyEvent.next(nativeEvent)
|
this._keyEvent.next(nativeEvent)
|
||||||
if (eventType === 'keyup' || document.querySelectorAll('input:focus').length === 0) {
|
this.pushKeyEvent(eventType, nativeEvent)
|
||||||
this.pushKeyEvent(eventType, nativeEvent)
|
if (hostApp.platform === Platform.Web && this.matchActiveHotkey(true) !== null) {
|
||||||
if (hostApp.platform === Platform.Web && this.matchActiveHotkey(true) !== null) {
|
nativeEvent.preventDefault()
|
||||||
nativeEvent.preventDefault()
|
nativeEvent.stopPropagation()
|
||||||
nativeEvent.stopPropagation()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -103,6 +102,10 @@ export class HotkeysService {
|
|||||||
* @param nativeEvent event object
|
* @param nativeEvent event object
|
||||||
*/
|
*/
|
||||||
pushKeyEvent (eventName: string, nativeEvent: KeyboardEvent): void {
|
pushKeyEvent (eventName: string, nativeEvent: KeyboardEvent): void {
|
||||||
|
if (nativeEvent.timeStamp === this.lastEventTimestamp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
nativeEvent['event'] = eventName
|
nativeEvent['event'] = eventName
|
||||||
|
|
||||||
const eventData = {
|
const eventData = {
|
||||||
@ -119,15 +122,13 @@ export class HotkeysService {
|
|||||||
|
|
||||||
for (const [key, time] of this.pressedKeyTimestamps.entries()) {
|
for (const [key, time] of this.pressedKeyTimestamps.entries()) {
|
||||||
if (time < performance.now() - 5000) {
|
if (time < performance.now() - 5000) {
|
||||||
this.pressedKeys.delete(key)
|
this.removePressedKey(key)
|
||||||
this.pressedKeyTimestamps.delete(key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyName = getKeyName(eventData)
|
const keyName = getKeyName(eventData)
|
||||||
if (eventName === 'keydown') {
|
if (eventName === 'keydown') {
|
||||||
this.pressedKeys.add(keyName)
|
this.addPressedKey(eventData)
|
||||||
this.pressedKeyTimestamps.set(keyName, eventData.registrationTime)
|
|
||||||
this.shouldSaveNextKeystroke = true
|
this.shouldSaveNextKeystroke = true
|
||||||
this.updateModifiers(eventData)
|
this.updateModifiers(eventData)
|
||||||
}
|
}
|
||||||
@ -141,8 +142,7 @@ export class HotkeysService {
|
|||||||
})
|
})
|
||||||
this.shouldSaveNextKeystroke = false
|
this.shouldSaveNextKeystroke = false
|
||||||
}
|
}
|
||||||
this.pressedKeys.delete(keyName)
|
this.removePressedKey(keyName)
|
||||||
this.pressedKeyTimestamps.delete(keyName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.pressedKeys.size) {
|
if (this.pressedKeys.size) {
|
||||||
@ -151,25 +151,25 @@ export class HotkeysService {
|
|||||||
this.pressedKeystroke = null
|
this.pressedKeystroke = null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.processKeystrokes()
|
const matched = this.matchActiveHotkey()
|
||||||
|
this.zone.run(() => {
|
||||||
|
if (matched) {
|
||||||
|
this.emitHotkeyOn(matched)
|
||||||
|
} else if (this.pressedHotkey) {
|
||||||
|
this.emitHotkeyOff(this.pressedHotkey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
this._key.next(getKeyName(eventData))
|
this._key.next(getKeyName(eventData))
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
private updateModifiers (event: KeyEventData) {
|
if (process.platform === 'darwin' && eventData.metaKey && eventName === 'keydown' && !['Ctrl', 'Shift', altKeyName, metaKeyName].includes(keyName)) {
|
||||||
for (const [prop, key] of Object.entries({
|
// macOS will swallow non-modified keyups if Cmd is held down
|
||||||
ctrlKey: 'Ctrl',
|
this.pushKeyEvent('keyup', nativeEvent)
|
||||||
metaKey: metaKeyName,
|
|
||||||
altKey: altKeyName,
|
|
||||||
shiftKey: 'Shift',
|
|
||||||
})) {
|
|
||||||
if (!event[prop] && this.pressedKeys.has(key)) {
|
|
||||||
this.pressedKeys.delete(key)
|
|
||||||
this.pressedKeyTimestamps.delete(key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.lastEventTimestamp = nativeEvent.timeStamp
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentKeystrokes (): Keystroke[] {
|
getCurrentKeystrokes (): Keystroke[] {
|
||||||
@ -262,24 +262,31 @@ export class HotkeysService {
|
|||||||
).reduce((a, b) => a.concat(b))
|
).reduce((a, b) => a.concat(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
private processKeystrokes () {
|
private updateModifiers (event: KeyEventData) {
|
||||||
const matched = this.matchActiveHotkey()
|
for (const [prop, key] of Object.entries({
|
||||||
this.zone.run(() => {
|
ctrlKey: 'Ctrl',
|
||||||
if (matched) {
|
metaKey: metaKeyName,
|
||||||
this.emitHotkeyOn(matched)
|
altKey: altKeyName,
|
||||||
} else if (this.pressedHotkey) {
|
shiftKey: 'Shift',
|
||||||
this.emitHotkeyOff(this.pressedHotkey)
|
})) {
|
||||||
|
if (!event[prop] && this.pressedKeys.has(key)) {
|
||||||
|
this.removePressedKey(key)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitHotkeyOn (hotkey: string) {
|
private emitHotkeyOn (hotkey: string) {
|
||||||
if (this.pressedHotkey) {
|
if (this.pressedHotkey) {
|
||||||
|
if (this.pressedHotkey === hotkey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.emitHotkeyOff(this.pressedHotkey)
|
this.emitHotkeyOff(this.pressedHotkey)
|
||||||
}
|
}
|
||||||
console.debug('Matched hotkey', hotkey)
|
if (document.querySelectorAll('input:focus').length === 0) {
|
||||||
this._hotkey.next(hotkey)
|
console.debug('Matched hotkey', hotkey)
|
||||||
this.pressedHotkey = hotkey
|
this._hotkey.next(hotkey)
|
||||||
|
this.pressedHotkey = hotkey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitHotkeyOff (hotkey: string) {
|
private emitHotkeyOff (hotkey: string) {
|
||||||
@ -316,4 +323,15 @@ export class HotkeysService {
|
|||||||
}
|
}
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addPressedKey (eventData: KeyEventData) {
|
||||||
|
const keyName = getKeyName(eventData)
|
||||||
|
this.pressedKeys.add(keyName)
|
||||||
|
this.pressedKeyTimestamps.set(keyName, eventData.registrationTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
private removePressedKey (key: KeyName) {
|
||||||
|
this.pressedKeys.delete(key)
|
||||||
|
this.pressedKeyTimestamps.delete(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user