Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebView2 WinForms control in Excel VSTO Task pane steals and holds on to keyboard focus #951

Open
ShaunLoganOracle opened this issue Feb 17, 2021 · 26 comments
Assignees
Labels
bug Something isn't working In-progress Dev work in progress and will update when there's progress. tracked We are tracking this work internally.

Comments

@ShaunLoganOracle
Copy link

ShaunLoganOracle commented Feb 17, 2021

Description
I have a Winforms WebView2 hosted in an Excel VSTO Task pane, There is no System.Windows.Forms.Form hosting the WebView2 control, instead, a System.Windows.Forms.UserControl is the owner/host of the control. After giving the WebView2 focus, it holds on to it after I've clicked back into the Excel worksheet.

Version
SDK: 1.0.705.50
Runtime: Evergreen RT 88.0.705.68
Framework: WinForms
OS: Win10 1909

Repro Steps

  1. Render some fairly simple static HTML in the WebView2
  2. Click in a worksheet cell, verify that keystrokes are acted on there (eg. right-arrow moves selected cell)
  3. Click in the HTML content in the WebView2 (in the task pane), verify that keystrokes are acted on there (eg. Enter toggles an expand/collapse widget)
  4. Click back in a different worksheet cell
    Observed: selected cell is changed as expected, however keystrokes are still getting captured by WebView2 (ie. Enter toggles the HTML widget instead of moving the cell selection).

AB#36775741

@ShaunLoganOracle ShaunLoganOracle added the bug Something isn't working label Feb 17, 2021
@champnic champnic added the tracked We are tracking this work internally. label Mar 2, 2021
@champnic
Copy link
Member

champnic commented Mar 2, 2021

Thanks for finding this issue @ShaunLoganOracle - we have some other bugs around VSTO Task Panes and I think they probably share a common root cause. I've created a bug on our backlog and we'll take a look.

@alaincao
Copy link

alaincao commented May 6, 2021

I have that same behaviour with a project using Custom Task Panes from ExcelDNA.

  • SDK: "1.0.865-prerelease"
  • Runtime: 90.0.818.51

FYI, a demo project to reproduce can be found there: https://github.com/alaincao/ExcelDNASamples/tree/webview2_issue_933/CustomTaskPane

@ShaunLoganOracle
Copy link
Author

@champnic
Update: I still see issues with keyboard focus getting stuck using SDK 1.0.902.49 and WV2 runtime 93.0.961.38
The bad behavior in #933 where there was a crash/hang is fixed. However the behavior of keyboard focus getting stuck in the WebView2-rendered content is still there. To add to that, the F6 and Shift-F6 keys seem to be ignored/swallowed by WV2. In Excel, these keys should move the focus from the VSTO task pane to other controls in Excel (the ribbon, worksheet grid, etc.). Since these are ignored, this makes the WebView2 control in the task pane a "keyboard trap" - thus it is an accessibility issue.

@ShaunLoganOracle
Copy link
Author

@champnic
Update: customers are still encountering this "focus getting stuck" issue using WV2 RT 98.0.1108.55 and our add-in code using the WV2 SDK 1.0.902.49. As our adoption of WebView2 gets wider distribution among our customers, the frequency (and annoyance) of this issue increases.
We would be glad to explore a code-around if there is something our code could do to avoid this issue.

@champnic
Copy link
Member

Hey @ShaunLoganOracle - Can you try this potential workaround?

Before initializing your WebView2, call:
SetEnvironmentVariable(L"COREWEBVIEW2_FORCED_HOSTING_MODE", L"COREWEBVIEW2_HOSTING_MODE_WINDOW_TO_VISUAL");

If that resolves the issue, then we are currently working on a better solution which should fix this automatically. That workaround also won't work on Win 7/8/8.1.

@ShaunLoganOracle
Copy link
Author

Thanks. My add-in supports Win 10 & 11 only so I'll try this shortly and report back.

@ShaunLoganOracle
Copy link
Author

I tried this by setting a System Environment variable (as spec'd above) in the Settings app and then running Excel and trying my use case. The stolen keyboard focus issue seems be resolved!
I did see something a little unexpected - now when I mouse click into the WebView2 hosted in the VSTO task pane - it does not appear to get keyboard focus at all (focus stays where it was, in my case: the worksheet grid). If I use F6 to activate the task pane, then the content in the WV2 control does get focus.
I will need to run additional tests to confirm no ill effects across my use cases, but this looks promising as a workaround that customers can even use without an updated add-in. Thanks!
I look forward to the "better solution which should fix this automatically".

@ShaunLoganOracle
Copy link
Author

Observation: by setting this environment variable programmatically in my add-in (running in the Excel process), any other usages of WebView2 in that process will presumably have their behavior changed too. For example if there was another add-in using WebView2, it would be affected.

@ShaunLoganOracle
Copy link
Author

ShaunLoganOracle commented Mar 11, 2022

@champnic
After some more testing, I have to report that this workaround setting the env. variable does not work for us. Yes, it appears to resolve the issue in the VSTO Task Pane, but it causes another worse issue. In addition to using WV2 in the Task Pane, we also have some modal WinForms dialog that host WV2 controls that render, for example, login pages. With the environment variable set, it seems that the html content never gets keyboard focus. So for example, tabbing from the username input box to the password input box does not work - the Tab key is ignored. This is a blocker for us. Without the env. variable set, the Tab key works as expected in these login pages in WV2.
Edit: some keys are seen by the control (Backspace, Esc), but others (Tab, left/right/up/down arrows) are not.

@champnic
Copy link
Member

@ShaunLoganOracle Thanks for trying it out. The fact that it fixes the original issue does suggest that the other work we are doing will fix this when it's completed. It's unfortunate the side effects mean you can't use the workaround yet though, sorry about that.

@sbolofsson
Copy link

@champnic I have some questions around the environment variable that I hope you can help me with.

  1. Can you please shed some light on what setting the environment variable actually does?
  2. Are there any downsides / things to be aware of when setting the environment variable?
  3. Do you have some documentation around it?
  4. Will the default behavior at some point change to what setting environment variable does? If yes, can you share an approximate timeline?
  5. Will there be a setting/enum in code to change the hosting mode without setting an environment variable? If yes, can you share an approximate timeline?

@champnic
Copy link
Member

Hey @sbolofsson!

  1. Roughly speaking, the environment variable changes how the app connects to the WebView2 control. Instead of using a child HWND, it uses a DComp visual.
  2. The main downside is that visuals are not supported on all Windows OSes. I believe the APIs we need for this to work only go down to Windows 10 (April 2018 update I think?). The other downside is that it does change the order of operations for some input and focus management, which can potentially introduce app compat issues for existing apps.
  3. No documentation. It's not really a documented feature, and more used for testing.
  4. We are working on making using the visuals a more supported feature. I don't think we've decided yet whether to make it default or not - it solves a few problems, but is a change in behavior that could cause app compat problems for existing apps relying on the existing behavior. No timeline yet on this work.
  5. There might be a setting/enum in the future as part of the work above.

@sbolofsson
Copy link

Ok, many thanks for the clarifications and details @champnic. For us, setting this environment variable solves a focus/mouse related issue in a VSTO task pane. So please don't remove this "feature" 😊

We understand that it can be hard to make this hosting mode the default, due to possibly breaking existing compat. However, looking at the release notes history and also currently open issues for WebView2, it's quite clear that there have been (and still are) quite a number of issues related to focus and/or VSTO. Now, I obviously don't know if this environment variable solves all (probably not) - and it may even introduce new issues, as also mentioned in this issue.

Therefore, I think it would very much make sense to make this officially supported (when it's ready), and then opt-in instead of default.

I think that even the limited OS support could be fine for us. 2018 is somewhat old and VSTO is Windows only anyway.

@tiagoabreu
Copy link

Hello @champnic , we also added this workaround to address a mouse issue that appeared when running our add-in in PowerPoint.
It did raise another issue, in our opinion much more impactful. It made the top left of the desktop (when everything is minimized) not available. The user cannot click on any icons while the add-ins are running. Therefore we had to remove the workaround.

Is there any alternative workaround we can pursue?

@estet
Copy link

estet commented Oct 6, 2022

@champnic @ShaunLoganOracle @alaincao Is there anything else we could do with the issue?

@ShaunLoganOracle
Copy link
Author

@champnic
This issue is still occurring using WV2 SDK 1.0.1832.23 and RT 114.0.1823.67
Is there any progress/update?

@champnic
Copy link
Member

champnic commented Jul 7, 2023

Hey @ShaunLoganOracle - I believe @zhuhaichao518 has been working on a change that's in experimental that can alleviate some of this issue. @zhuhaichao518 can you share the latest on your investigations using the hit-test transparent mode here, and the remaining issues?

@andrewkittredge
Copy link

We are still having this issue.

@novac42
Copy link
Contributor

novac42 commented Jul 14, 2023

Hi @ShaunLoganOracle @andrewkittredge does the solution mentioned in #1254 work for you? Meanwhile @zhuhaichao518 is working on adding an API into ControllerOptions, you can check the detailed spec here: #3596

@ShaunLoganOracle
Copy link
Author

does the solution mentioned in #1254 work for you?

@novac42
In a very quick test, this approach looks promising.
I added --enable-features=msWebView2BrowserHitTransparent to the CoreWebView2EnvironmentOptions.AdditionalBrowserArguments used when creating the (WinForms) WebView2 control (hosted in VSTO Excel Add-in Task Pane).

I observe now that clicking with the mouse in the HTML rendered in the WV2 control sends the mouse click to the browser (eg. HTML element gets onClick), but leaves keyboard focus where it was (in my case, the worksheet grid). If I explicitly give focus to the WV2 via the keyboard using a combination of F6 and Tab, then subsequent keystrokes are seen by the WV2 (and HTML).

I also quickly tried other cases where we host a WebView2 control in a modal WinForms Dialog: focus and keyboard access seem to behave as expected.

We will have our accessibility experts review the changes and report back if this approach introduces any issues in that domain.

@ShaunLoganOracle
Copy link
Author

There is one non-intuitive behavior: clicking the mouse in the HTML content rendered in the WV2 control does not give keyboard focus to that control. The keyboard focus stays in the worksheet grid. Previously, clicking in the HTML gave keyboard focus to the WV2 (which then did not give back the focus when clicking back on the grid).

@ShaunLoganOracle
Copy link
Author

@novac42 @zhuhaichao518
We have found a blocker issue for us with the --enable-features=msWebView2BrowserHitTransparent switch enabled:
In a WinForms modal dialog that hosts a WV2 control which renders a login form, the Tab key does not work to move focus from the username field to to the password field. Without the switch enabled, Tab works as expected.

@novac42
Copy link
Contributor

novac42 commented Jul 18, 2023

@ShaunLoganOracle Thanks for the feedback. We will take a look into it.

@novac42 novac42 added the In-progress Dev work in progress and will update when there's progress. label Jul 18, 2023
@mike3sullivan
Copy link

same scenario, same problems.

@mike-rosenblum
Copy link

mike-rosenblum commented Apr 17, 2024

Is there any update?

This is a showstopper bug, preventing any use in Microsoft Office applications like Excel.

First there was the failure to render issue, dating back to May 2020 (#187), where the successful workaround is to set the user data folder to a writeable location. So far so good.

This current issue (#951) dates to Feb 2021. The workaround above, unfortunately, shifts the focus from the WebView2 100% to the Excel worksheet 100%.

Is there a setting or another workaround that allows for focus to shift smoothly between the Excel sheet and WebView2 in a task pane?

Thanks a lot in advance.

@anthem89
Copy link

anthem89 commented Jul 17, 2024

I found a solution. In order to return keyboard focus back to Excel after a WebView2 control steals keyboard focus, you can use the Windows API to re-set the foreground window back to Excel. Here is how you do it:

Here it is in VB.Net

Add this module to your code:

Public Module NativeMethods
<DllImport("user32.dll", SetLastError:=True)>
Public Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function
Public Declare Function GetDesktopWindow Lib "user32" () As IntPtr
End Module

When you want to return focus back to Excel, just call the method FocusExcel():

Public Class YourClass
Public Sub FocusExcel()
NativeMethods.SetForegroundWindow(NativeMethods.GetDesktopWindow())
NativeMethods.SetForegroundWindow(Globals.ThisAddIn.Application.Hwnd)
End Sub
End Class

Here it is in C#

public class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}

public class YourClass
{
public void FocusExcel()
{
NativeMethods.SetForegroundWindow(NativeMethods.GetDesktopWindow());
IntPtr excelHwnd = new IntPtr(Globals.ThisAddIn.Application.Hwnd);
NativeMethods.SetForegroundWindow(excelHwnd);
}
}

I have tested this to work with WebView2 version 1.0.2592.51 in a VSTO Excel add in where the WebView2 is embedded in a Custom Task Pane

Note: You might not actually need to focus the desktop hWnd before focusing Excel. This is just overkill to ensure it works. I ran into a situation where it was necessary, so I thought I'd include it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working In-progress Dev work in progress and will update when there's progress. tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests