diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 064481678a6..3562e54d8ff 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -10,12 +10,13 @@ import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { TimeoutTimer } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { FileAccess, RemoteAuthorities } from 'vs/base/common/network'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; import { insane, InsaneOptions } from 'vs/base/common/insane/insane'; +import { KeyCode } from 'vs/base/common/keyCodes'; export function clearNode(node: HTMLElement): void { while (node.firstChild) { @@ -1435,3 +1436,123 @@ export namespace WebFileSystemAccess { return false; } } + +type ModifierKey = 'alt' | 'ctrl' | 'shift'; + +export interface IModifierKeyStatus { + altKey: boolean; + shiftKey: boolean; + ctrlKey: boolean; + lastKeyPressed?: ModifierKey; + lastKeyReleased?: ModifierKey; + event?: KeyboardEvent; +} + + +export class ModifierKeyEmitter extends Emitter { + + private readonly _subscriptions = new DisposableStore(); + private _keyStatus: IModifierKeyStatus; + private static instance: ModifierKeyEmitter; + + private constructor() { + super(); + + this._keyStatus = { + altKey: false, + shiftKey: false, + ctrlKey: false + }; + + this._subscriptions.add(domEvent(document.body, 'keydown', true)(e => { + const event = new StandardKeyboardEvent(e); + + if (e.altKey && !this._keyStatus.altKey) { + this._keyStatus.lastKeyPressed = 'alt'; + } else if (e.ctrlKey && !this._keyStatus.ctrlKey) { + this._keyStatus.lastKeyPressed = 'ctrl'; + } else if (e.shiftKey && !this._keyStatus.shiftKey) { + this._keyStatus.lastKeyPressed = 'shift'; + } else if (event.keyCode !== KeyCode.Alt) { + this._keyStatus.lastKeyPressed = undefined; + } else { + return; + } + + this._keyStatus.altKey = e.altKey; + this._keyStatus.ctrlKey = e.ctrlKey; + this._keyStatus.shiftKey = e.shiftKey; + + if (this._keyStatus.lastKeyPressed) { + this._keyStatus.event = e; + this.fire(this._keyStatus); + } + })); + + this._subscriptions.add(domEvent(document.body, 'keyup', true)(e => { + if (!e.altKey && this._keyStatus.altKey) { + this._keyStatus.lastKeyReleased = 'alt'; + } else if (!e.ctrlKey && this._keyStatus.ctrlKey) { + this._keyStatus.lastKeyReleased = 'ctrl'; + } else if (!e.shiftKey && this._keyStatus.shiftKey) { + this._keyStatus.lastKeyReleased = 'shift'; + } else { + this._keyStatus.lastKeyReleased = undefined; + } + + if (this._keyStatus.lastKeyPressed !== this._keyStatus.lastKeyReleased) { + this._keyStatus.lastKeyPressed = undefined; + } + + this._keyStatus.altKey = e.altKey; + this._keyStatus.ctrlKey = e.ctrlKey; + this._keyStatus.shiftKey = e.shiftKey; + + if (this._keyStatus.lastKeyReleased) { + this._keyStatus.event = e; + this.fire(this._keyStatus); + } + })); + + this._subscriptions.add(domEvent(document.body, 'mousedown', true)(e => { + this._keyStatus.lastKeyPressed = undefined; + })); + + this._subscriptions.add(domEvent(document.body, 'mouseup', true)(e => { + this._keyStatus.lastKeyPressed = undefined; + })); + + this._subscriptions.add(domEvent(document.body, 'mousemove', true)(e => { + if (e.buttons) { + this._keyStatus.lastKeyPressed = undefined; + } + })); + + this._subscriptions.add(domEvent(window, 'blur')(e => { + this._keyStatus.lastKeyPressed = undefined; + this._keyStatus.lastKeyReleased = undefined; + this._keyStatus.altKey = false; + this._keyStatus.shiftKey = false; + this._keyStatus.shiftKey = false; + + this.fire(this._keyStatus); + })); + } + + get keyStatus(): IModifierKeyStatus { + return this._keyStatus; + } + + static getInstance() { + if (!ModifierKeyEmitter.instance) { + ModifierKeyEmitter.instance = new ModifierKeyEmitter(); + } + + return ModifierKeyEmitter.instance; + } + + dispose() { + super.dispose(); + this._subscriptions.dispose(); + } +} diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index be71339754f..f8226d5dccd 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -8,7 +8,6 @@ import * as browser from 'vs/base/browser/browser'; import * as DOM from 'vs/base/browser/dom'; import * as strings from 'vs/base/common/strings'; import * as nls from 'vs/nls'; -import { domEvent } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; import { cleanMnemonic, IMenuOptions, Menu, MENU_ESCAPED_MNEMONIC_REGEX, MENU_MNEMONIC_REGEX, IMenuStyles, Direction } from 'vs/base/browser/ui/menu/menu'; @@ -16,7 +15,7 @@ import { ActionRunner, IAction, IActionRunner, SubmenuAction, Separator } from ' import { RunOnceScheduler } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; import { KeyCode, ResolvedKeybinding, KeyMod } from 'vs/base/common/keyCodes'; -import { Disposable, dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { withNullAsUndefined } from 'vs/base/common/types'; import { asArray } from 'vs/base/common/arrays'; import { ScanCodeUtils, ScanCode } from 'vs/base/common/scanCode'; @@ -120,7 +119,7 @@ export class MenuBar extends Disposable { this.setUnfocusedState(); })); - this._register(ModifierKeyEmitter.getInstance().event(this.onModifierKeyToggled, this)); + this._register(DOM.ModifierKeyEmitter.getInstance().event(this.onModifierKeyToggled, this)); this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e as KeyboardEvent); @@ -860,7 +859,7 @@ export class MenuBar extends Disposable { } } - private onModifierKeyToggled(modifierKeyStatus: IModifierKeyStatus): void { + private onModifierKeyToggled(modifierKeyStatus: DOM.IModifierKeyStatus): void { const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey; if (this.options.visibility === 'hidden') { @@ -996,119 +995,3 @@ export class MenuBar extends Disposable { }; } } - -type ModifierKey = 'alt' | 'ctrl' | 'shift'; - -interface IModifierKeyStatus { - altKey: boolean; - shiftKey: boolean; - ctrlKey: boolean; - lastKeyPressed?: ModifierKey; - lastKeyReleased?: ModifierKey; - event?: KeyboardEvent; -} - - -class ModifierKeyEmitter extends Emitter { - - private readonly _subscriptions = new DisposableStore(); - private _keyStatus: IModifierKeyStatus; - private static instance: ModifierKeyEmitter; - - private constructor() { - super(); - - this._keyStatus = { - altKey: false, - shiftKey: false, - ctrlKey: false - }; - - this._subscriptions.add(domEvent(document.body, 'keydown', true)(e => { - const event = new StandardKeyboardEvent(e); - - if (e.altKey && !this._keyStatus.altKey) { - this._keyStatus.lastKeyPressed = 'alt'; - } else if (e.ctrlKey && !this._keyStatus.ctrlKey) { - this._keyStatus.lastKeyPressed = 'ctrl'; - } else if (e.shiftKey && !this._keyStatus.shiftKey) { - this._keyStatus.lastKeyPressed = 'shift'; - } else if (event.keyCode !== KeyCode.Alt) { - this._keyStatus.lastKeyPressed = undefined; - } else { - return; - } - - this._keyStatus.altKey = e.altKey; - this._keyStatus.ctrlKey = e.ctrlKey; - this._keyStatus.shiftKey = e.shiftKey; - - if (this._keyStatus.lastKeyPressed) { - this._keyStatus.event = e; - this.fire(this._keyStatus); - } - })); - - this._subscriptions.add(domEvent(document.body, 'keyup', true)(e => { - if (!e.altKey && this._keyStatus.altKey) { - this._keyStatus.lastKeyReleased = 'alt'; - } else if (!e.ctrlKey && this._keyStatus.ctrlKey) { - this._keyStatus.lastKeyReleased = 'ctrl'; - } else if (!e.shiftKey && this._keyStatus.shiftKey) { - this._keyStatus.lastKeyReleased = 'shift'; - } else { - this._keyStatus.lastKeyReleased = undefined; - } - - if (this._keyStatus.lastKeyPressed !== this._keyStatus.lastKeyReleased) { - this._keyStatus.lastKeyPressed = undefined; - } - - this._keyStatus.altKey = e.altKey; - this._keyStatus.ctrlKey = e.ctrlKey; - this._keyStatus.shiftKey = e.shiftKey; - - if (this._keyStatus.lastKeyReleased) { - this._keyStatus.event = e; - this.fire(this._keyStatus); - } - })); - - this._subscriptions.add(domEvent(document.body, 'mousedown', true)(e => { - this._keyStatus.lastKeyPressed = undefined; - })); - - this._subscriptions.add(domEvent(document.body, 'mouseup', true)(e => { - this._keyStatus.lastKeyPressed = undefined; - })); - - this._subscriptions.add(domEvent(document.body, 'mousemove', true)(e => { - if (e.buttons) { - this._keyStatus.lastKeyPressed = undefined; - } - })); - - this._subscriptions.add(domEvent(window, 'blur')(e => { - this._keyStatus.lastKeyPressed = undefined; - this._keyStatus.lastKeyReleased = undefined; - this._keyStatus.altKey = false; - this._keyStatus.shiftKey = false; - this._keyStatus.shiftKey = false; - - this.fire(this._keyStatus); - })); - } - - static getInstance() { - if (!ModifierKeyEmitter.instance) { - ModifierKeyEmitter.instance = new ModifierKeyEmitter(); - } - - return ModifierKeyEmitter.instance; - } - - dispose() { - super.dispose(); - this._subscriptions.dispose(); - } -}