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

How to force WebView2 focus in WPF? #185

Closed
garrynewman opened this issue May 19, 2020 · 8 comments
Closed

How to force WebView2 focus in WPF? #185

garrynewman opened this issue May 19, 2020 · 8 comments
Labels
bug Something isn't working

Comments

@garrynewman
Copy link

I want to set up my window so that when I tab to it, it'll focus an input in the html.

This works fine from the html/js side, but I can't find a way in WebView2 to force the wpf control in focus.

Clicking it works, but obviously that isn't the solution.

@david-risney david-risney added the bug Something isn't working label May 19, 2020
@david-risney
Copy link
Contributor

Great question. Do I understand correctly that you want to programmatically set focus to the WebView2? There's a Focus method on the control but it doesn't seem to work correctly and this seems like a bug. We'll look into this, thanks!

@garrynewman
Copy link
Author

Yep that's correct - thank you ♥️

@RickStrahl
Copy link

That's always been a problem with Web Browser controls in general. I think the way you can do this today is to force focus inside of the DOM by triggering some JavaScript code to focus on a control.

@garrynewman
Copy link
Author

I think two things have to be selected.

  1. The HWND of the web control
  2. The HTML Element in the rendered page

Doing 2 is easy enough.. but it doesn't even show as focused unless the control itself is focused. I tried everything I could think of to focus it without clicking, but I couldn't make it happen, but I'm assuming that it's possible to make available on some level.

@nicholasdgoodman
Copy link

@garrynewman @david-risney

On the WPF side, calling WebView2.Focus() sends focus to the parent HwndHost window and not to the actual Chrome "top-level" window contained within:

image

It is possible to workaround (until it is properly fixed) this with an extension method:

public static class WebView2Extensions
{
    public const uint GW_CHILD = 5;

    [DllImport("user32.dll")]
    public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

    [DllImport("user32.dll")]
    public static extern IntPtr SetFocus(IntPtr hWnd);

    public static void InnerFocus(this WebView2 webView2)
    {
        var chromeWidgetWin0 = GetWindow(webView2.Handle, GW_CHILD);
        SetFocus(chromeWidgetWin0);
    }
}

This may not be 100% correct place to be setting focus, (subsequent calls to GetFocus() indicate that ChromeWidgetWin1 is the actual window that takes input - but either way, pushing focus to the topmost Chrome window does the trick.

For example if you wanted to re-focus the most recently focused (web / HTML) control on a window when it is activated (title bar click or Alt+Tab into), you could:

private void Window_Activated(object sender, EventArgs e)
{
    Dispatcher.InvokeAsync(() => webview.InnerFocus());
}

(Note: the focus call must be queued up and not invoked synchronously because WPF will attempt to set focus on its own after the Activate event has completed).

@champnic
Copy link
Member

This should be fixed in SDK 0.9.538-prerelease. You should now be able to call .Focus() on the WebView2 control. Can you give that a try and see if this fixes you issue? If not, please reopen this issue and we'll take another look. Thanks!

@champnic champnic added this to the SDK 0.9.538-prerelease milestone Jun 22, 2020
@billybooth
Copy link

billybooth commented Aug 17, 2020

Fairly confident there is a related issue still present in at least the WinForms WebView2 control. Not sure whether it justifies a separate issue, but I'll be happy to create one if it does.

I have noticed that while the reported issue seems to be addressed in 0.9.538 and higher under normal circumstances, the WebView2 control cannot be focused programatically or via the keyboard unless there is another focusable control in the same container. So I can focus the Chromium window (and default input element) by calling WebView2.Focus() only when my form contains another focusable control. For example, in the WebView2Samples WinForms sample, if you remove all controls from the form except the WebView2 control, calling Focus() on the WebView2 has no effect.

Although this might be an uncommon circumstance, it represents a further issue with the inner Chromium window focus.

@champnic
Copy link
Member

@billybooth If you could open a new issue with your bug I'd appreciate 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
Projects
None yet
Development

No branches or pull requests

6 participants