Skip to content

Commit ee6baba

Browse files
committed
make enableKeybindingHoldMode return a promise that resolves when hold-mode is over
1 parent bf53fde commit ee6baba

File tree

7 files changed

+46
-36
lines changed

7 files changed

+46
-36
lines changed

src/vs/editor/standalone/browser/standaloneServices.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,13 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
594594
public registerSchemaContribution(contribution: KeybindingsSchemaContribution): void {
595595
// noop
596596
}
597+
598+
/**
599+
* not yet supported
600+
*/
601+
public override enableKeybindingHoldMode(commandId: string): Promise<void> | undefined {
602+
return undefined;
603+
}
597604
}
598605

599606
class DomNodeListeners extends Disposable {

src/vs/platform/keybinding/common/abstractKeybindingService.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
5353
private _ignoreSingleModifiers: KeybindingModifierSet;
5454
private _currentSingleModifier: SingleModifierChord | null;
5555
private _currentSingleModifierClearTimeout: TimeoutTimer;
56-
private _currentlyDispatchingCommandId: string | null;
57-
protected _isInKeybindingHoldMode: boolean;
56+
protected _currentlyDispatchingCommandId: string | null;
5857

5958
protected _logging: boolean;
6059

@@ -78,7 +77,6 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
7877
this._currentSingleModifier = null;
7978
this._currentSingleModifierClearTimeout = new TimeoutTimer();
8079
this._currentlyDispatchingCommandId = null;
81-
this._isInKeybindingHoldMode = false;
8280
this._logging = false;
8381
}
8482

@@ -387,14 +385,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
387385
}
388386
}
389387

390-
enableKeybindingHoldMode(commandId: string): boolean {
391-
if (this._currentlyDispatchingCommandId !== commandId) {
392-
return false;
393-
}
394-
this._isInKeybindingHoldMode = true;
395-
this._log(`+ Enabled hold-mode for ${commandId}.`);
396-
return true;
397-
}
388+
abstract enableKeybindingHoldMode(commandId: string): Promise<void> | undefined;
398389

399390
mightProducePrintableCharacter(event: IKeyboardEvent): boolean {
400391
if (event.ctrlKey || event.metaKey) {

src/vs/platform/keybinding/common/keybinding.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ export interface IKeybindingService {
6969
* Enable hold mode for this command. This is only possible if the command is current being dispatched, meaning
7070
* we are after its keydown and before is keyup event.
7171
*
72-
* @returns true is hold mode was enabled
72+
* @returns A promise that resolves when hold stops, returns undefined if hold mode could not be enabled.
7373
*/
74-
enableKeybindingHoldMode(commandId: string): boolean;
74+
enableKeybindingHoldMode(commandId: string): Promise<void> | undefined;
7575

7676
dispatchByUserSettingsLabel(userSettingsLabel: string, target: IContextKeyServiceTarget): void;
7777

src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ suite('AbstractKeybindingService', () => {
9595
public registerSchemaContribution() {
9696
// noop
9797
}
98+
99+
public enableKeybindingHoldMode() {
100+
return undefined;
101+
}
98102
}
99103

100104
let createTestKeybindingService: (items: ResolvedKeybindingItem[], contextValue?: any) => TestKeybindingService = null!;

src/vs/platform/keybinding/test/common/mockKeybindingService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ export class MockKeybindingService implements IKeybindingService {
147147
return false;
148148
}
149149

150-
public enableKeybindingHoldMode(commandId: string): boolean {
151-
return false;
150+
public enableKeybindingHoldMode(commandId: string): undefined {
151+
return undefined;
152152
}
153153

154154
public mightProducePrintableCharacter(e: IKeyboardEvent): boolean {

src/vs/workbench/contrib/inlineChat/electron-sandbox/inlineChatActions.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5-
import * as dom from 'vs/base/browser/dom';
65
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
76
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
87
import { EditorAction2 } from 'vs/editor/browser/editorExtensions';
@@ -51,31 +50,26 @@ export class StartSessionAction extends EditorAction2 {
5150

5251
if (configService.getValue<boolean>(InlineChatConfigKeys.HoldToSpeech) // enabled
5352
&& speechService.hasSpeechProvider // possible
54-
&& keybindingService.enableKeybindingHoldMode(this.desc.id) // holding keys
5553
) {
5654

55+
const holdMode = keybindingService.enableKeybindingHoldMode(this.desc.id);
56+
if (holdMode) { // holding keys
57+
let listening = false;
58+
const handle = disposableTimeout(() => {
59+
// start VOICE input
60+
commandService.executeCommand(StartVoiceChatAction.ID);
61+
listening = true;
62+
}, 100);
5763

58-
let listening = false;
59-
const handle = disposableTimeout(() => {
60-
// start VOICE input
61-
commandService.executeCommand(StartVoiceChatAction.ID);
62-
listening = true;
63-
}, 100);
64-
65-
const listener = dom.addDisposableListener(
66-
dom.getWindow(editor.getDomNode()),
67-
dom.EventType.KEY_UP,
68-
(_e: KeyboardEvent) => {
69-
listener.dispose(); // Event.once
64+
holdMode.finally(() => {
7065
if (listening) {
7166
commandService.executeCommand(StopListeningAction.ID).finally(() => {
7267
InlineChatController.get(editor)?.acceptInput();
7368
});
74-
} else {
75-
handle.dispose();
7669
}
77-
}
78-
);
70+
handle.dispose();
71+
});
72+
}
7973
}
8074

8175
let options: InlineChatRunOptions | undefined;

src/vs/workbench/services/keybinding/browser/keybindingService.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as browser from 'vs/base/browser/browser';
1010
import { BrowserFeatures, KeyboardSupport } from 'vs/base/browser/canIUse';
1111
import * as dom from 'vs/base/browser/dom';
1212
import { printKeyboardEvent, printStandardKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
13-
import { RunOnceScheduler } from 'vs/base/common/async';
13+
import { DeferredPromise, RunOnceScheduler } from 'vs/base/common/async';
1414
import { Emitter, Event } from 'vs/base/common/event';
1515
import { parse } from 'vs/base/common/json';
1616
import { IJSONSchema } from 'vs/base/common/jsonSchema';
@@ -183,6 +183,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
183183
private _cachedResolver: KeybindingResolver | null;
184184
private userKeybindings: UserKeybindings;
185185
private isComposingGlobalContextKey: IContextKey<boolean>;
186+
private _keybindingHoldMode: DeferredPromise<void> | null;
186187
private readonly _contributions: KeybindingsSchemaContribution[] = [];
187188
private readonly kbsJsonSchema: KeybindingsJsonSchema;
188189

@@ -212,6 +213,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
212213
this.updateResolver();
213214
});
214215

216+
this._keybindingHoldMode = null;
215217
this._cachedResolver = null;
216218

217219
this.userKeybindings = this._register(new UserKeybindings(userDataProfileService, uriIdentityService, fileService, logService));
@@ -269,7 +271,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
269271

270272
// for standard keybindings
271273
disposables.add(dom.addDisposableListener(window, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
272-
if (this._isInKeybindingHoldMode) {
274+
if (this._keybindingHoldMode) {
273275
return;
274276
}
275277
this.isComposingGlobalContextKey.set(e.isComposing);
@@ -285,7 +287,10 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
285287

286288
// for single modifier chord keybindings (e.g. shift shift)
287289
disposables.add(dom.addDisposableListener(window, dom.EventType.KEY_UP, (e: KeyboardEvent) => {
288-
this._isInKeybindingHoldMode = false;
290+
if (this._keybindingHoldMode) {
291+
this._keybindingHoldMode.complete();
292+
this._keybindingHoldMode = null;
293+
}
289294
this.isComposingGlobalContextKey.set(e.isComposing);
290295
const keyEvent = new StandardKeyboardEvent(e);
291296
const shouldPreventDefault = this._singleModifierDispatch(keyEvent, keyEvent.target);
@@ -395,6 +400,15 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
395400
return JSON.stringify(info, null, '\t');
396401
}
397402

403+
public override enableKeybindingHoldMode(commandId: string): Promise<void> | undefined {
404+
if (this._currentlyDispatchingCommandId !== commandId) {
405+
return undefined;
406+
}
407+
this._keybindingHoldMode = new DeferredPromise<void>();
408+
this._log(`+ Enabled hold-mode for ${commandId}.`);
409+
return this._keybindingHoldMode.p;
410+
}
411+
398412
public override customKeybindingsCount(): number {
399413
return this.userKeybindings.keybindings.length;
400414
}

0 commit comments

Comments
 (0)