jchv / go-webview2

WebView2 bindings for pure Go, without CGo, based on the webview/webview bindings.
Other
263 stars 64 forks source link

Keyboard focus not set on browser by default #32

Open jscholes opened 2 years ago

jscholes commented 2 years ago

When creating a new webview in a new window, i.e. what the demo example does, keyboard focus is set on the overarching window, and not on the document object rendered by the webview. This means that keyboard access is not available. To reproduce:

  1. Run the demo app.
  2. Wait for the Wikipedia page to render.
  3. Press Tab.

Expected result: keyboard focus will be handled by the webview, and move through the focusable elements on the page.

Actual result: nothing happens.

This is a significant issue for accessibility. Not only does it prevent keyboard-only users accessing apps built with this library (or ones based on it), it also means that screen reader software is unable to access the webview's content, unless the user can work out how to manually set focus on the document (e.g. using the Win32 API).

jscholes commented 2 years ago

I managed to resolve this by calling the MoveFocus method of ICoreWebView2Controller. But not sure if:

  1. the library should make an assumption that focus should land on the browser by default;
  2. the library should just offer a FocusBrowser method or similar; and/or
  3. where to put this method call in the code.

I feel that, if the window is being created by the library as opposed to by the caller, as the browser will be the only thing in that window, it is the most accessible approach to have the library focus the browser by default.

jscholes commented 2 years ago

Also, an additional note: while I can get focus to reliably move into the browser when the window is initially created, I can't get it to stay there. If I Alt+Tab to another window and then back, focus lands on the window again.

jchv commented 2 years ago

Sorry about this one. As far as I can tell, the most "correct" solution is simply make use of the very poorly named user32.IsDialogMessage in order to use the built-in Windows tab handling, which WebView2 can then use to give "correct" tab behavior.

The default event loop has been adjusted to do exactly this.

jscholes commented 2 years ago

@jchv Thanks, this certainly fixes the case of not being able to Tab/Shift+Tab into the webview once created. But it is still desirable to:

  1. automatically place focus inside the webview when it is the only descendant of the window; and/or
  2. allow users of the library to programmatically set focus inside it.

Additionally, some of the problematic behaviour is still present, specifically:

while I can get focus to reliably move into the browser when the window is initially created, I can't get it to stay there. If I Alt+Tab to another window and then back, focus lands on the window again.

If focus is inside the webview when the user switches away from the window, it should also still be there when they switch back.

jchv commented 2 years ago

Understood. We can call MoveFocus on WM_ACTIVATE, which would probably accomplish what you are looking for. The change that was added is still useful since it allows us to have focus move from the window to the webview, if, for example, the user were to click the title bar explicitly. I'll take a look at it later today when I am off work and have a moment.

jscholes commented 2 years ago

@jchv Thanks, sounds good.

jchv commented 2 years ago

It might be hard to fully resolve this issue, though at least it's a lot better than it was. I think the keyboard focus behavior should probably simply make sense by default, but for now I have put the new behavior behind an option, AutoFocus, which will cause go-webview2 to attempt to focus the Webview2 widget whenever the window is focused (including on initialization.) This may need to be tweaked as it is definitely not perfect, but I think it is closer.