vscode: WebViewPanel created with preserveFocus: true suffers from a focus problem.

  • VSCode Version: Version: 1.37.0-insider Commit: d50852db1af10ec100a71ad57cc3a04c8aead117 Date: 2019-07-08T05:33:31.335Z Electron: 4.2.5 Chrome: 69.0.3497.128 Node.js: 10.11.0 V8: 6.9.427.31-electron.0 OS: Darwin x64 17.7.0
  • OS Version: macOS High Sierra 10.13.6 (17G7024)

Steps to Reproduce:

  1. Execute the following sample code of extension.
  2. Execute the Hello World command.
  3. Click the tab of WebView and press the f key of the keyboard.
  4. In the conlose, only the window focused! message shown.
  5. Click the tab of WebView, again. Then, press f.
  6. The message keyboard F typed! shown.

Jul-08-2019 19-18-51

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
  const rootUrl = vscode.Uri.file(context.extensionPath)
  const disposable = vscode.commands.registerCommand('extension.helloWorld', async (args, brgs, crgs) => {
    if (!vscode.window.activeTextEditor) {
      return;
    }
    
    const panel = vscode.window.createWebviewPanel(
      'catCoding',
      'Cat Coding',
      { preserveFocus: true, viewColumn: vscode.ViewColumn.Beside },
      { enableScripts: true }
    );
    panel.webview.html = getHtml();
  });
  context.subscriptions.push(disposable);
}

function getHtml() {
	return `
<!DOCTYPE html><html><head></head>
<body>
<script>
window.onfocus = function() {
	console.log('window focused!');
}
window.addEventListener('keydown', function(evt) {
	if(evt.keyCode == 70 && evt.target.nodeName != 'INPUT') {
	  console.log('keyboard F typed!')
	}
  })
</script>
`
}


// this method is called when your extension is deactivated
export function deactivate() {}

Does this issue occur when all extensions are disabled?: Yes

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 9
  • Comments: 37 (17 by maintainers)

Commits related to this issue

Most upvoted comments

The fix for Chromium has been merged to master: https://github.com/chromium/chromium/commit/c4f0a725ff5bc078ccdf43e60b2b455ce4efafa8 🎉. It will be released in Chromium M80.

@deepak1556 @mjbvz @bpasero Is it possible for you to apply this patch to the Electron sources when you build for the next release? 🙏

I’ve made some progress on this issue, though it’s unclear still exactly why this is occurring only in VSCode vs in Chrome. I sent an email to two Chromium maintainers who work on the relevant bits hoping to get their take. For those curious, here’s what I sent them:

This summer, VSCode upgraded from Electron 4 to Electron 6, which enabled OOPIFs. This change has broken focus-on-mouse-click for all VSCode WebView extensions (https://github.com/microsoft/vscode/issues/76863).

I built debug versions of Electron 4 and 6 to figure out why focusing isn’t working. I found that in Electron 6, when a mouse clicks in the iframe we hit test and end up calling WebContentsImpl::FocusOwningWebContents on the OOPIF’s render widget host. The problem is when that method calls WebContentsImpl::GetFocusedRenderWidgetHost the first check performed is to determine if the render widget host matches the main frame’s render widget host. Because this is an OOPIF, it has a different render widget host, and the default return value ends up causing WebContentsImpl::FocusOwningWebContents to skip focusing the page.

I don’t understand why this isn’t an issue in Chrome (I tested it at http://csreis.github.io/tests/cross-site-iframe-simple.html). That said, I have a hunch that with OOPIFs this main frame check is incorrect. Based on the comment above the check, I wonder if instead of checking whether the receiving widget is the main frame it should check whether the receiving widget is a frame type (vs a select pop-up menu). I can confirm that commenting out this check makes VSCode extensions work.

Am I on the right track here? Any thoughts on why this is only broken in VSCode/Electron and not Chrome?

Is there any update on this issue? It’s currently affecting any extension that uses a webview.

Hi @deepak1556, any way I can help debug this issue? 🙏

I’ve narrowed it down to changes introduced between the June 2nd and June 5th VS Code Insiders builds. A couple unfortunate details have made this hard to track down further:

  • I can’t reproduce when I build the OSS version from github
  • Nightly builds failed between those two dates, so I can’t bisect further

It’s likely the root cause is either in the proprietary additions or in some build process or environment change between those two dates, but I can’t access either to try to fix the issue

6/2 Insiders build (good) commit: a848f18df4efa9eb947bd01cbebcede418e66148 6/5 Insiders build (bad) commit: fc294b683d88fe607d9456bc1bf774ad1d4a7ce6

@mjbvz do you have any updates here? We over million installs of our PlatformIO IDE extension and this issue blocks https://github.com/platformio/platformio-vscode-ide/issues/892

I already checked earlier today. Works beautifully! 🙏

@txase the fix is now available in latest insiders

@mjbvz If it helps, here’s a reproducible set of steps to see the issue using our extension:

  1. Install the “stackery” extension
  2. Open a folder (opening a file alone doesn’t work through our extension)
  3. Create a file called template.yaml with the following inside:
    AWSTemplateFormatVersion: 2010-09-09
    Transform: AWS::Serverless-2016-10-31
    Resources:
      Table:
        Type: AWS::DynamoDB::Table
        Properties:
          AttributeDefinitions:
            - AttributeName: id
              AttributeType: S
          KeySchema:
            - AttributeName: id
              KeyType: HASH
    
  4. Click the Stackery “S” icon at the top right of the file context menu, or otherwise execute the “Edit with Stackery” command while the template.yaml file is the active editor.
  5. Double click on the “Table” resource on the canvas to open a settings form
  6. Open the built-in terminal
  7. Click back into the form editor and notice that while you can interact with a webview element (e.g. highlighting text in a form input field) you can’t type. If you focus the terminal, then try to focus the webview form, you’ll find keyboard input still goes to the terminal.

It’s possible to fix the focus state by double clicking on the canvas editor tab.

Here’s a video showing the above:

bug

@mjbvz Here’s the steps I took:

$ git clone git@github.com:microsoft/vscode.git
$ yarn
$ scripts/code.sh

I also tried running yarn run gulp vscode-darwin and yarn run gulp vscode-darwin-min to see if the app packages they produced exhibit the bug. Unfortunately, they don’t.

I also tried the electron 6 exploration build you linked. It also has the bug.

One thing that would be interesting to try: Are you able to re-build the 6/2 commit of the insiders edition? If it had the bug after being rebuilt, then it would point to a change in the build pipeline having caused the issue. If it doesn’t have the bug, then it is a problem in the source code somewhere (OSS or proprietary).

@txase Thanks for the investigation.

We upgraded from electron 3 to electron 4 between those two commits which seems suspect. When building from master, did you do a full build (including yarn install) at those checkpoints?

Also, if this is electron related, can you try our our electron 6 exploration builds to see if that fixes the problem.

So I’m getting this bug with LaTeX-Workshop: James-Yu/LaTeX-Workshop#1481. When switching to view the pdf on a Mac via command+2, all shortcuts within VSCode seem to no longer work. What makes this even nastier is that it sometimes only happens after switching TWICE (i.e. I can go from pdf to tex to pdf via command+1 and command+2 but it eventually gets stuck focused on the pdf). I believe this focus issue is the underlying problem with the bug, as referenced earlier. Strangely, I don’t experience this on Ubuntu at all.