webview: ignore Ctrl+W and Ctrl+N in webview for PWA (#164981)

This fixes closing Release Notes / Markdown Preview with Ctrl+W closing whole PWA.

PWAs can intercept the Ctrl+W/Ctrl+N keystrokes, and VSCode does this for editor tabs. However, webviews do not intercept these keystrokes.

If a webview such as Release Notes or Markdown Preview has focus:

- when the user presses Ctrl+N, another instance of the PWA is opened in a new window.
- when the user presses Ctrl+W, the whole PWA window closes.

See https://github.com/microsoft/vscode/issues/150735 for details.

This fixes the issue by ignoring Ctrl+W and Ctrl+N in webviews.

Tested on macOS 12.6 / Chrome Dev 109.0.5384.0:

- patch environmentService.ts webviewExternalEndpoint to use
  http://localhost:8080/static/sources/out/vs/workbench/contrib/webview/browser/pre/
- followed the contributing instruction to run code-web
- in Chrome, More Tools -> Create Shortcut -> Open as window
- closed and re-opened Code OSS PWA window
- opened chrome://inspect and inspected the Code OSS window
- added an uncaught exception handler
- opened file.md and chose "Open preview"
- when it hit
  `Expected '${parentOriginHash}' as hostname or subdomain!`
  manually ran `start(parentOrigin)` in console and continued
- the markdown preview now displayed
- pressed Command+W

Before: the whole window closes
After: only the Markdown preview tab closes
This commit is contained in:
zhuowei 2022-11-01 18:56:43 -04:00 committed by GitHub
parent 190db489e0
commit a9bf3117d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 1 deletions

View file

@ -589,6 +589,10 @@
} else {
return; // let the browser handle this
}
} else if (!onElectron && (isCloseTab(e) || isNewWindow(e))) {
// Prevent Ctrl+W closing window / Ctrl+N opening new window in PWA.
// (No effect in a regular browser tab.)
e.preventDefault();
}
hostMessaging.postMessage('did-keydown', {
@ -655,6 +659,24 @@
return hasMeta && e.key.toLowerCase() === 'f';
}
/**
* @param {KeyboardEvent} e
* @return {boolean}
*/
function isCloseTab(e) {
const hasMeta = e.ctrlKey || e.metaKey;
return hasMeta && e.key.toLowerCase() === 'w';
}
/**
* @param {KeyboardEvent} e
* @return {boolean}
*/
function isNewWindow(e) {
const hasMeta = e.ctrlKey || e.metaKey;
return hasMeta && e.key.toLowerCase() === 'n';
}
let isHandlingScroll = false;
/**

View file

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'sha256-lC8sxUeeYqUtmkCpPt/OX/HQdE0JbHG1Z3dzrilsRU0=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
content="default-src 'none'; script-src 'sha256-DmsqQtB7vkf/ey+8HeQmSYaMMdiE0Au1IXEkLBE+OtY=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@ -590,6 +590,10 @@
} else {
return; // let the browser handle this
}
} else if (!onElectron && (isCloseTab(e) || isNewWindow(e))) {
// Prevent Ctrl+W closing window / Ctrl+N opening new window in PWA.
// (No effect in a regular browser tab.)
e.preventDefault();
}
hostMessaging.postMessage('did-keydown', {
@ -665,6 +669,24 @@
return hasMeta && e.key.toLowerCase() === 's';
}
/**
* @param {KeyboardEvent} e
* @return {boolean}
*/
function isCloseTab(e) {
const hasMeta = e.ctrlKey || e.metaKey;
return hasMeta && e.key.toLowerCase() === 'w';
}
/**
* @param {KeyboardEvent} e
* @return {boolean}
*/
function isNewWindow(e) {
const hasMeta = e.ctrlKey || e.metaKey;
return hasMeta && e.key.toLowerCase() === 'n';
}
let isHandlingScroll = false;
/**