@@ -18,6 +18,7 @@ import { WebviewFindWidget } from './webviewFindWidget';
18
18
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
19
19
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
20
20
import { endsWith } from 'vs/base/common/strings' ;
21
+ import { isMacintosh } from 'vs/base/common/platform' ;
21
22
22
23
export interface WebviewOptions {
23
24
readonly allowScripts ?: boolean ;
@@ -144,6 +145,79 @@ class SvgBlocker extends Disposable {
144
145
}
145
146
}
146
147
148
+ class WebviewKeyboardHandler extends Disposable {
149
+ constructor (
150
+ private readonly _webview : Electron . WebviewTag ,
151
+ private readonly _keybindingService : IKeybindingService
152
+ ) {
153
+ super ( ) ;
154
+
155
+ if ( this . shouldToggleMenuShortcutsEnablement ) {
156
+ this . _register ( addDisposableListener ( this . _webview , 'did-start-loading' , ( ) => {
157
+ const contents = this . getWebContents ( ) ;
158
+ if ( contents ) {
159
+ contents . on ( 'before-input-event' , ( _event , input ) => {
160
+ contents . setIgnoreMenuShortcuts ( input . control || input . meta ) ;
161
+ } ) ;
162
+ }
163
+ } ) ) ;
164
+ }
165
+
166
+ this . _register ( addDisposableListener ( this . _webview , 'ipc-message' , ( event ) => {
167
+ switch ( event . channel ) {
168
+ case 'did-keydown' :
169
+ // Electron: workaround for https://github.com/electron/electron/issues/14258
170
+ // We have to detect keyboard events in the <webview> and dispatch them to our
171
+ // keybinding service because these events do not bubble to the parent window anymore.
172
+ this . handleKeydown ( event . args [ 0 ] ) ;
173
+ return ;
174
+
175
+ case 'did-blur' :
176
+ if ( this . shouldToggleMenuShortcutsEnablement ) {
177
+ const contents = this . getWebContents ( ) ;
178
+ if ( contents ) {
179
+ contents . setIgnoreMenuShortcuts ( false ) ;
180
+ }
181
+ }
182
+ return ;
183
+ }
184
+ } ) ) ;
185
+ }
186
+
187
+ private get shouldToggleMenuShortcutsEnablement ( ) {
188
+ return isMacintosh ;
189
+ }
190
+
191
+ private getWebContents ( ) : Electron . WebContents | undefined {
192
+ const contents = this . _webview . getWebContents ( ) ;
193
+ if ( contents && ! contents . isDestroyed ( ) ) {
194
+ return contents ;
195
+ }
196
+ return undefined ;
197
+ }
198
+
199
+ private handleKeydown ( event : IKeydownEvent ) : void {
200
+ // return;
201
+ // Create a fake KeyboardEvent from the data provided
202
+ const emulatedKeyboardEvent = new KeyboardEvent ( 'keydown' , {
203
+ code : event . code ,
204
+ key : event . key ,
205
+ keyCode : event . keyCode ,
206
+ shiftKey : event . shiftKey ,
207
+ altKey : event . altKey ,
208
+ ctrlKey : event . ctrlKey ,
209
+ metaKey : event . metaKey ,
210
+ repeat : event . repeat
211
+ } as KeyboardEvent ) ;
212
+
213
+ // Dispatch through our keybinding service
214
+ // Note: we set the <webview> as target of the event so that scoped context key
215
+ // services function properly to enable commands like select all and find.
216
+ this . _keybindingService . dispatchEvent ( new StandardKeyboardEvent ( emulatedKeyboardEvent ) , this . _webview ) ;
217
+ }
218
+ }
219
+
220
+
147
221
export class WebviewElement extends Disposable {
148
222
private _webview : Electron . WebviewTag ;
149
223
private _ready : Promise < void > ;
@@ -202,6 +276,8 @@ export class WebviewElement extends Disposable {
202
276
const svgBlocker = this . _register ( new SvgBlocker ( this . _webview , this . _options ) ) ;
203
277
svgBlocker . onDidBlockSvg ( ( ) => this . onDidBlockSvg ( ) ) ;
204
278
279
+ this . _register ( new WebviewKeyboardHandler ( this . _webview , this . _keybindingService ) ) ;
280
+
205
281
this . _register ( addDisposableListener ( this . _webview , 'console-message' , function ( e : { level : number ; message : string ; line : number ; sourceId : string ; } ) {
206
282
console . log ( `[Embedded Page] ${ e . message } ` ) ;
207
283
} ) ) ;
@@ -253,13 +329,6 @@ export class WebviewElement extends Disposable {
253
329
case 'did-blur' :
254
330
this . handleFocusChange ( false ) ;
255
331
return ;
256
-
257
- case 'did-keydown' :
258
- // Electron: workaround for https://github.com/electron/electron/issues/14258
259
- // We have to detect keyboard events in the <webview> and dispatch them to our
260
- // keybinding service because these events do not bubble to the parent window anymore.
261
- this . handleKeydown ( event . args [ 0 ] ) ;
262
- return ;
263
332
}
264
333
} ) ) ;
265
334
this . _register ( addDisposableListener ( this . _webview , 'devtools-opened' , ( ) => {
@@ -368,26 +437,6 @@ export class WebviewElement extends Disposable {
368
437
}
369
438
}
370
439
371
- private handleKeydown ( event : IKeydownEvent ) : void {
372
-
373
- // Create a fake KeyboardEvent from the data provided
374
- const emulatedKeyboardEvent = new KeyboardEvent ( 'keydown' , {
375
- code : event . code ,
376
- key : event . key ,
377
- keyCode : event . keyCode ,
378
- shiftKey : event . shiftKey ,
379
- altKey : event . altKey ,
380
- ctrlKey : event . ctrlKey ,
381
- metaKey : event . metaKey ,
382
- repeat : event . repeat
383
- } as KeyboardEvent ) ;
384
-
385
- // Dispatch through our keybinding service
386
- // Note: we set the <webview> as target of the event so that scoped context key
387
- // services function properly to enable commands like select all and find.
388
- this . _keybindingService . dispatchEvent ( new StandardKeyboardEvent ( emulatedKeyboardEvent ) , this . _webview ) ;
389
- }
390
-
391
440
public sendMessage ( data : any ) : void {
392
441
this . _send ( 'message' , data ) ;
393
442
}
0 commit comments