Skip to content

Commit

Permalink
webview - bubble up keyboard events (workaround for #56988)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Aug 29, 2018
1 parent d8eb099 commit 34a635e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
return result.resolvedKeybinding;
}

public dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
return this._dispatch(e, target);
}

public softDispatch(e: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult {
const keybinding = this.resolveKeyboardEvent(e);
if (keybinding.isChord()) {
Expand Down
5 changes: 5 additions & 0 deletions src/vs/platform/keybinding/common/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export interface IKeybindingService {

resolveUserBinding(userBinding: string): ResolvedKeybinding[];

/**
* Resolve and dispatch `keyboardEvent` and invoke the command.
*/
dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean;

/**
* Resolve and dispatch `keyboardEvent`, but do not invoke the command or change inner state.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ export class MockKeybindingService implements IKeybindingService {
return null;
}

dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
public dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
return false;
}

mightProducePrintableCharacter(e: IKeyboardEvent): boolean {
public mightProducePrintableCharacter(e: IKeyboardEvent): boolean {
return false;
}
}
41 changes: 41 additions & 0 deletions src/vs/workbench/parts/webview/electron-browser/webviewElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/the
import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/parts/webview/electron-browser/webviewProtocols';
import { areWebviewInputOptionsEqual } from './webviewEditorService';
import { WebviewFindWidget } from './webviewFindWidget';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';

export interface WebviewOptions {
readonly allowScripts?: boolean;
Expand Down Expand Up @@ -44,6 +46,7 @@ export class WebviewElement extends Disposable {
@IThemeService private readonly _themeService: IThemeService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IFileService private readonly _fileService: IFileService,
@IKeybindingService private readonly _keybindingService: IKeybindingService
) {
super();
this._webview = document.createElement('webview');
Expand Down Expand Up @@ -123,6 +126,44 @@ export class WebviewElement extends Disposable {
}));
}

// Electron: workaround for https://github.com/electron/electron/issues/14258
// We have to detect keyboard events in the <webview> and dispatch them to our
// keybinding service because these events do not bubble to the parent window anymore.
let loaded = false;
this._register(addDisposableListener(this._webview, 'did-start-loading', () => {
if (loaded) {
return;
}
loaded = true;

const contents = this._webview.getWebContents();
if (!contents) {
return;
}

contents.on('before-input-event', (event, input) => {
if (input.type !== 'keyDown') {
return;
}

// Create a fake KeyboardEvent from the data provided
const emulatedKeyboardEvent = new KeyboardEvent('keydown', {
code: input.code,
key: input.key,
shiftKey: input.shift,
altKey: input.alt,
ctrlKey: input.control,
metaKey: input.meta,
repeat: input.isAutoRepeat
});

// Dispatch through our keybinding service
if (this._keybindingService.dispatchEvent(new StandardKeyboardEvent(emulatedKeyboardEvent), document.body)) {
event.preventDefault();
}
});
}));

this._register(addDisposableListener(this._webview, 'console-message', function (e: { level: number; message: string; line: number; sourceId: string; }) {
console.log(`[Embedded Page] ${e.message}`);
}));
Expand Down

0 comments on commit 34a635e

Please sign in to comment.