提交 58050c8c 编写于 作者: B Benjamin Pasero

web - adopt modifier key emitter for shutdown prevention

上级 3f20baf3
......@@ -1437,18 +1437,18 @@ export namespace WebFileSystemAccess {
}
}
type ModifierKey = 'alt' | 'ctrl' | 'shift';
type ModifierKey = 'alt' | 'ctrl' | 'shift' | 'meta';
export interface IModifierKeyStatus {
altKey: boolean;
shiftKey: boolean;
ctrlKey: boolean;
metaKey: boolean;
lastKeyPressed?: ModifierKey;
lastKeyReleased?: ModifierKey;
event?: KeyboardEvent;
}
export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
private readonly _subscriptions = new DisposableStore();
......@@ -1461,7 +1461,8 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this._keyStatus = {
altKey: false,
shiftKey: false,
ctrlKey: false
ctrlKey: false,
metaKey: false
};
this._subscriptions.add(domEvent(document.body, 'keydown', true)(e => {
......@@ -1471,6 +1472,8 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this._keyStatus.lastKeyPressed = 'alt';
} else if (e.ctrlKey && !this._keyStatus.ctrlKey) {
this._keyStatus.lastKeyPressed = 'ctrl';
} else if (e.metaKey && !this._keyStatus.metaKey) {
this._keyStatus.lastKeyPressed = 'meta';
} else if (e.shiftKey && !this._keyStatus.shiftKey) {
this._keyStatus.lastKeyPressed = 'shift';
} else if (event.keyCode !== KeyCode.Alt) {
......@@ -1481,6 +1484,7 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this._keyStatus.altKey = e.altKey;
this._keyStatus.ctrlKey = e.ctrlKey;
this._keyStatus.metaKey = e.metaKey;
this._keyStatus.shiftKey = e.shiftKey;
if (this._keyStatus.lastKeyPressed) {
......@@ -1494,6 +1498,8 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this._keyStatus.lastKeyReleased = 'alt';
} else if (!e.ctrlKey && this._keyStatus.ctrlKey) {
this._keyStatus.lastKeyReleased = 'ctrl';
} else if (!e.metaKey && this._keyStatus.metaKey) {
this._keyStatus.lastKeyReleased = 'meta';
} else if (!e.shiftKey && this._keyStatus.shiftKey) {
this._keyStatus.lastKeyReleased = 'shift';
} else {
......@@ -1506,6 +1512,7 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this._keyStatus.altKey = e.altKey;
this._keyStatus.ctrlKey = e.ctrlKey;
this._keyStatus.metaKey = e.metaKey;
this._keyStatus.shiftKey = e.shiftKey;
if (this._keyStatus.lastKeyReleased) {
......@@ -1529,13 +1536,7 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
}));
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);
this.resetKeyStatus();
}));
}
......@@ -1543,14 +1544,25 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
return this._keyStatus;
}
// This method is a workaround because we do not get keyboard events while a context menu is shown #109062
get isModifierPressed(): boolean {
return this._keyStatus.altKey || this._keyStatus.ctrlKey || this._keyStatus.metaKey || this._keyStatus.shiftKey;
}
/**
* Allows to explicitly reset the key status based on more knowledge (#109062)
*/
resetKeyStatus(): void {
this.doResetKeyStatus();
this.fire(this._keyStatus);
}
private doResetKeyStatus(): void {
this._keyStatus = {
altKey: false,
shiftKey: false,
ctrlKey: false
ctrlKey: false,
metaKey: false
};
this.fire(this._keyStatus);
}
static getInstance() {
......
......@@ -860,7 +860,7 @@ export class MenuBar extends Disposable {
}
private onModifierKeyToggled(modifierKeyStatus: DOM.IModifierKeyStatus): void {
const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey;
const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey && !modifierKeyStatus.metaKey;
if (this.options.visibility === 'hidden') {
return;
......
......@@ -13,7 +13,7 @@ import { IWindowSettings, IWindowOpenable, IOpenWindowOptions, isFolderToOpen, i
import { pathsToEditors } from 'vs/workbench/common/editor';
import { IFileService } from 'vs/platform/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
import { addDisposableListener, EventType, trackFocus } from 'vs/base/browser/dom';
import { IModifierKeyStatus, ModifierKeyEmitter, trackFocus } from 'vs/base/browser/dom';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
......@@ -113,12 +113,8 @@ export class BrowserHostService extends Disposable implements IHostService {
// Veto shutdown depending on `window.confirmBeforeClose` setting
this._register(this.lifecycleService.onBeforeShutdown(e => this.onBeforeShutdown(e)));
// Track certain DOM events to detect keybinding usage
this._register(addDisposableListener(this.layoutService.container, EventType.KEY_DOWN, e => this.updateShutdownReasonFromEvent(e)));
this._register(addDisposableListener(this.layoutService.container, EventType.KEY_UP, () => this.updateShutdownReasonFromEvent(undefined)));
this._register(addDisposableListener(this.layoutService.container, EventType.MOUSE_DOWN, () => this.updateShutdownReasonFromEvent(undefined)));
this._register(addDisposableListener(this.layoutService.container, EventType.MOUSE_UP, () => this.updateShutdownReasonFromEvent(undefined)));
this._register(this.onDidChangeFocus(() => this.updateShutdownReasonFromEvent(undefined)));
// Track modifier keys to detect keybinding usage
this._register(ModifierKeyEmitter.getInstance().event(e => this.updateShutdownReasonFromEvent(e)));
}
private onBeforeShutdown(e: BeforeShutdownEvent): void {
......@@ -134,12 +130,16 @@ export class BrowserHostService extends Disposable implements IHostService {
this.shutdownReason = HostShutdownReason.Unknown;
}
private updateShutdownReasonFromEvent(e: KeyboardEvent | undefined): void {
private updateShutdownReasonFromEvent(e: IModifierKeyStatus): void {
if (this.shutdownReason === HostShutdownReason.Api) {
return; // do not overwrite any explicitly set shutdown reason
}
this.shutdownReason = e ? HostShutdownReason.Keyboard : HostShutdownReason.Unknown;
if (ModifierKeyEmitter.getInstance().isModifierPressed) {
this.shutdownReason = HostShutdownReason.Keyboard;
} else {
this.shutdownReason = HostShutdownReason.Unknown;
}
}
//#region Focus
......@@ -405,21 +405,23 @@ export class BrowserHostService extends Disposable implements IHostService {
}
async reload(): Promise<void> {
// We know that `window.location.reload` will trigger a shutdown
// so we update `shutdownReason` to reflect that
this.shutdownReason = HostShutdownReason.Api;
window.location.reload();
this.withExpectedShutdown(() => {
window.location.reload();
});
}
async close(): Promise<void> {
this.withExpectedShutdown(() => {
window.close();
});
}
private withExpectedShutdown(callback: () => void): void {
// We know that `window.close` will trigger a shutdown
// so we update `shutdownReason` to reflect that
// Update shutdown reason in a way that we do not show a dialog
this.shutdownReason = HostShutdownReason.Api;
window.close();
callback();
}
//#endregion
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册