Skip to content

Commit 1bac855

Browse files
committed
improve keybinding handling in dialogs
1 parent c61e5d9 commit 1bac855

3 files changed

Lines changed: 35 additions & 4 deletions

File tree

src/vs/base/browser/ui/dialog/dialog.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface IDialogOptions {
2020
cancelId?: number;
2121
detail?: string;
2222
type?: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending';
23+
keyEventProcessor?: (event: StandardKeyboardEvent) => void;
2324
}
2425

2526
export interface IDialogStyles extends IButtonStyles {
@@ -103,19 +104,26 @@ export class Dialog extends Disposable {
103104
return;
104105
}
105106

107+
let eventHandled = false;
106108
if (this.buttonGroup) {
107109
if (evt.equals(KeyMod.Shift | KeyCode.Tab) || evt.equals(KeyCode.LeftArrow)) {
108110
focusedButton = focusedButton + this.buttonGroup.buttons.length - 1;
109111
focusedButton = focusedButton % this.buttonGroup.buttons.length;
110112
this.buttonGroup.buttons[focusedButton].focus();
113+
eventHandled = true;
111114
} else if (evt.equals(KeyCode.Tab) || evt.equals(KeyCode.RightArrow)) {
112115
focusedButton++;
113116
focusedButton = focusedButton % this.buttonGroup.buttons.length;
114117
this.buttonGroup.buttons[focusedButton].focus();
118+
eventHandled = true;
115119
}
116120
}
117121

118-
EventHelper.stop(e, true);
122+
if (eventHandled) {
123+
EventHelper.stop(e, true);
124+
} else if (this.options.keyEventProcessor) {
125+
this.options.keyEventProcessor(evt);
126+
}
119127
}));
120128

121129
this._register(domEvent(window, 'keyup', true)((e: KeyboardEvent) => {

src/vs/platform/dialogs/browser/dialogService.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
1313
import { IThemeService } from 'vs/platform/theme/common/themeService';
1414
import { attachDialogStyler } from 'vs/platform/theme/common/styler';
1515
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
16+
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
17+
import { EventHelper } from 'vs/base/browser/dom';
1618

1719
export class DialogService implements IDialogService {
1820
_serviceBrand: any;
@@ -76,7 +78,10 @@ export class DialogService implements IDialogService {
7678
{
7779
detail: options ? options.detail : undefined,
7880
cancelId: options ? options.cancelId : undefined,
79-
type: this.getDialogType(severity)
81+
type: this.getDialogType(severity),
82+
keyEventProcessor: (event: StandardKeyboardEvent) => {
83+
EventHelper.stop(event, true);
84+
}
8085
});
8186

8287
dialogDisposables.push(dialog);

src/vs/workbench/services/progress/browser/progressService2.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
2020
import { Dialog } from 'vs/base/browser/ui/dialog/dialog';
2121
import { attachDialogStyler } from 'vs/platform/theme/common/styler';
2222
import { IThemeService } from 'vs/platform/theme/common/themeService';
23+
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
24+
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
25+
import { EventHelper } from 'vs/base/browser/dom';
2326

2427
export class ProgressService2 implements IProgressService2 {
2528

@@ -34,7 +37,8 @@ export class ProgressService2 implements IProgressService2 {
3437
@INotificationService private readonly _notificationService: INotificationService,
3538
@IStatusbarService private readonly _statusbarService: IStatusbarService,
3639
@ILayoutService private readonly _layoutService: ILayoutService,
37-
@IThemeService private readonly _themeService: IThemeService
40+
@IThemeService private readonly _themeService: IThemeService,
41+
@IKeybindingService private readonly _keybindingService: IKeybindingService
3842
) { }
3943

4044
withProgress<R = unknown>(options: IProgressOptions, task: (progress: IProgress<IProgressStep>) => Promise<R>, onDidCancel?: () => void): Promise<R> {
@@ -276,6 +280,10 @@ export class ProgressService2 implements IProgressService2 {
276280

277281
private _withDialogProgress<P extends Promise<R>, R = unknown>(options: IProgressOptions, task: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
278282
const disposables: IDisposable[] = [];
283+
const allowableCommands = [
284+
'workbench.action.quit',
285+
'workbench.action.reloadWindow'
286+
];
279287

280288
let dialog: Dialog;
281289

@@ -284,7 +292,17 @@ export class ProgressService2 implements IProgressService2 {
284292
this._layoutService.container,
285293
message,
286294
[options.cancellable ? localize('cancel', "Cancel") : localize('dismiss', "Dismiss")],
287-
{ type: 'pending' }
295+
{
296+
type: 'pending',
297+
keyEventProcessor: (event: StandardKeyboardEvent) => {
298+
const resolved = this._keybindingService.softDispatch(event, this._layoutService.container);
299+
if (resolved && resolved.commandId) {
300+
if (allowableCommands.indexOf(resolved.commandId) === -1) {
301+
EventHelper.stop(event, true);
302+
}
303+
}
304+
}
305+
}
288306
);
289307

290308
disposables.push(dialog);

0 commit comments

Comments
 (0)