Skip to content

Commit 4adaf66

Browse files
API Review: AllowHostInputProcessing (#3639)
* Add spec for EnableInputPassthrough.md
1 parent 113585d commit 4adaf66

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

specs/AllowHostInputProcessing.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Background
2+
WebView2 .NET developers often encounter issues where certain default events are not raised in the WebView2 .NET control.
3+
4+
This issue occurs because user inputs are directly delivered to the browser, and the host application does not receive the corresponding messages.
5+
6+
This causes some default event handling API of .NET control not to work, such as PreProcessMessage and ProcessCmdKey in WinForms.
7+
8+
It also prevents some keys from reaching Key Event realated APIs such as OnKeyDown and ToolStripMenuItem.
9+
10+
In order to solve this type of issue, we provide an api which allows user inputs pass through the browser to the host app.
11+
12+
# Description
13+
`AllowHostInputProcessing` allows user input messages(keyboard, mouse, touch, and pen) to pass through the browser window to be received by an app process window.
14+
15+
The messages can be received by Win32 API ::GetMessage() or ::PeekMessage(). This provides the host app a chance to handle the message before dispatching to the WebView2 HWND.
16+
17+
If the host app does not handle input, it is forwarded to the browser process on the user's behalf. This API does not introduce any requirement for the developer to forward all input as is the case with visual hosting. This API should not be used with visual hosting, and has no effect when using CreateCoreWebView2CompositionControllerWithOptions to create the controller.
18+
19+
Setting `AllowHostInputProcessing` to `TRUE` makes `AcceleratorKeyPressed`(all platforms) and `OnKeyDown`(WinForms only) event asynchronous.
20+
21+
# Examples
22+
## Win32 C++
23+
```cpp
24+
// We assume WebView2 is hosted in a MFC application. CMFCApplicationApp is a CWinApp.
25+
// This function can not be triggered by default when focus is in WebView.
26+
// It can be triggered by setting 'AllowHostInputProcessing' to true.
27+
BOOL CMFCApplicationApp::PreTranslateMessage(MSG* pMsg) {
28+
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP ||
29+
pMsg->message == WM_SYSKEYDOWN || pMsg->message == WM_SYSKEYUP && webview_has_focus_)
30+
// Prehandle the message. The message will not be sent to WebView if return TRUE.
31+
return HandleMsgBeforeWebView(pMsg);
32+
return FALSE;
33+
}
34+
35+
// Create a ControllerOptions and set 'AllowHostInputProcessing' to TRUE.
36+
HRESULT CreateControllerWithInputPassthrough()
37+
{
38+
auto webViewEnvironment10 = m_webViewEnvironment.try_query<ICoreWebView2Environment10>();
39+
if (!webViewEnvironment10)
40+
{
41+
FeatureNotAvailable();
42+
return S_OK;
43+
}
44+
45+
wil::com_ptr<ICoreWebView2ControllerOptions> options;
46+
CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerOptions(options.GetAddressOf()));
47+
48+
wil::com_ptr<ICoreWebView2ControllerOptions3> webView2ControllerOptions3;
49+
if (SUCCEEDED(options->QueryInterface(IID_PPV_ARGS(&webView2ControllerOptions3))))
50+
{
51+
CHECK_FAILURE(webView2ControllerOptions3->put_AllowHostInputProcessing(TRUE));
52+
}
53+
54+
CHECK_FAILURE(webViewEnvironment10->CreateCoreWebView2ControllerWithOptions(
55+
m_mainWindow, options.get(),
56+
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
57+
this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)
58+
.Get()));
59+
60+
return S_OK;
61+
}
62+
```
63+
64+
### .NET, WinRT
65+
```c#
66+
67+
partial class BrowserForm
68+
{
69+
// This function can not be triggered by default when focus is in WebView.
70+
// It can be triggered by setting 'AllowHostInputProcessing' to true.
71+
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
72+
{
73+
//DoSomething();
74+
return base.ProcessCmdKey(ref msg, keyData);
75+
}
76+
77+
// ...
78+
private Microsoft.Web.WebView2.WinForms.WebView2 webView2Control;
79+
}
80+
81+
CoreWebView2Environment _webViewEnvironment;
82+
public CreateWebView2Controller(IntPtr parentWindow)
83+
{
84+
CoreWebView2ControllerOptions controllerOptions = _webViewEnvironment.CreateCoreWebView2ControllerOptions();
85+
controllerOptions.AllowHostInputProcessing = true;
86+
87+
CoreWebView2Controller controller = null;
88+
89+
controller = await _webViewEnvironment.CreateCoreWebView2ControllerAsync(parentWindow, controllerOptions);
90+
91+
//...
92+
}
93+
```
94+
95+
# API Details
96+
## Win32 C++
97+
```IDL
98+
interface ICoreWebView2ControllerOptions3;
99+
100+
interface ICoreWebView2ControllerOptions3 : IUnknown {
101+
/// `AllowHostInputProcessing` property is to enable/disable input passing through
102+
/// the app before being delivered to the WebView2. This property is only applicable
103+
/// to controllers created with `CoreWebView2Environment.CreateCoreWebView2ControllerAsync` and not
104+
/// composition controllers created with `CoreWebView2Environment.CreateCoreWebView2CompositionControllerAsync`.
105+
/// By default the value is `FALSE`.
106+
[propget] HRESULT AllowHostInputProcessing([out, retval] BOOL* value);
107+
/// Sets the `AllowHostInputProcessing` property.
108+
/// Setting this property has no effect when using visual hosting.
109+
[propput] HRESULT AllowHostInputProcessing([in] BOOL value);
110+
}
111+
```
112+
113+
## .NET, WinRT
114+
```c#
115+
namespace Microsoft.Web.WebView2.Core
116+
{
117+
runtimeclass CoreWebView2ControllerOptions;
118+
runtimeclass CoreWebView2Environment;
119+
runtimeclass CoreWebView2;
120+
runtimeclass CoreWebView2Profile;
121+
122+
runtimeclass CoreWebView2ControllerOptions
123+
{
124+
// ...
125+
126+
Boolean AllowHostInputProcessing { get; set; };
127+
}
128+
}
129+
```

0 commit comments

Comments
 (0)