CefSharp
CefSharp copied to clipboard
WinForms - Enter/Arrow keys not working with DevTool/Popups with MultiThreadedMessageLoop = false
- What version of the product are you using?
Multiple versions:
CefSharp.MinimalExample with Nuget package 75.1.142.
But it also reproduces with 69 and 73
- What architecture x86 or x64?
x64
- On what operating system?
Windows 10
-
Are you using
WinForms
,WPF
orOffScreen
?
WinForms
- What steps will reproduce the problem?
I used CefSharp.MinimalExample.WinForms.csproj as the base. I added MultiThreadedMessageLoop = false
and called Cef.DoMessageLoopWork()
on a timer to enable the integrated message loop.
Here is a branch with the changes: https://github.com/kiewic/CefSharp.MinimalExample/tree/kiewic/devtools-enter-key-integrated-message-loop
Once the modified sample is running:
- Open DevTools
- Write a command, for example,
console.log("Hello World")
- Press
ENTER
key, but nothing happens, the key is ignored - Press
left arrow
orright arrow
to move the cursor left or right, but the cursor does not move
- What is the expected output? What do you see instead?
It is expected that ENTER
and arrow keys work the same as in the multi-threaded message loop. ENTER key should execute the command, and arrow keys should move the cursor.
- Please provide any additional information below.
No exceptions.
Nothing relevant in debug.log.
-
Does this problem also occur in the
CEF
Sample Application from http://opensource.spotify.com/cefbuilds/index.html?
This does not reproduce with cefclient.exe
. I executed it WITHOUT --multi-threaded-message-loop
. I tried version: cef_binary_76.1.13+gf19c584+chromium-76.0.3809.132_windows64_client
For an accurate comparison you need to test with the CEF Sample application version 75.1.14
Now that I've has a few minutes to read this in detail the behaviour you are seeing is somewhat an expected one. The keys listed are actually preprocessed in WinForms see https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.isinputkey?view=netframework-4.8#remarks I will comment in more detail next time I'm in front of a PC
This method is called during window message preprocessing to determine whether the specified input key should be preprocessed or sent directly to the control. If IsInputKey returns true, the specified key is sent directly to the control. If IsInputKey returns false, the specified key is preprocessed and only sent to the control if it is not consumed by the preprocessing phase. Keys that are preprocessed include the TAB, RETURN, ESC, and the UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW keys.
As per https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.isinputkey?view=netframework-4.8#remarks WinForms
does some preprocessing
of TAB, RETURN, ESC, UP, DOWN, LEFT and RIGHT by default. Integrating CEF
into the WinForms Message Loop
and this behaviour means those keys aren't forwarded as one might expect from a user point of view (expected from a WinForms
point of view). In ChromiumWebBrowser.IsInputKey we have some fairly trivial code to override the default behaviour.
In the CefSharp.WinForms.Example
project there is a recently added example of docking DevTools
in a SplitContainer
, in this scenario a custom parent control (which is really all ChromiumWebBrowser
is in the first place) can be used to override the default behaviour, see commit https://github.com/cefsharp/CefSharp/commit/1d2fb9531f087f99e22170f1a335d7b1cee7cec5 for a very quick and not extensively tested example.
In theory you should be able to use a similar technique to host DevTools
in your own form with a similar parent control using WindowInfo.SetAsChild
to specify the parent(host) control Handle.
There is a chance this will be marked as wontfix
as it may not be practical to override the default WinForms
behaviour when CEF
hosts DevTools
. The best you might get is an example that works around the behaviour (Pull Requests
welcome).
It may well be wise to ask for help on http://stackoverflow.com/questions/tagged/winforms as there are people better versed in the deep inner workings of WinForms
who might have a more elegant solution.
Confirming this issue is present with any popup (DevTools
is just opened as a popup).
I have yet to find another means of changing how WinForms
processes the key inputs.
- [x] Add
ChromiumHostControl
to theCefSharp.WinForms
project- [x] Override IsInputKey e.g. https://github.com/cefsharp/CefSharp/commit/1d2fb9531f087f99e22170f1a335d7b1cee7cec5#diff-86315df11fee16a159c95ae8d67cf3b3a05ef6594aa84ac23f892caa2dcc2721R11
- [x] Handle resize/move notifications for hosting popups using a
Winforms
Control as the parent.
ChromiumHostControl was added in commit https://github.com/cefsharp/CefSharp/commit/3dc37b2dd2717be91e40af6a748b8057564535cb#diff-5ce832ad0887b4ba2a2fb5a8d34fe775f48b4ccd137d6031f3dcde9cb5e7339b
You can use the ShowDevToolsDocked extension method to give DevTools a specific parent, can be a form, child control, etc
https://github.com/cefsharp/CefSharp/blob/3dc37b2dd2717be91e40af6a748b8057564535cb/CefSharp.WinForms/WebBrowserExtensions.cs#L75
I haven't tested hosting with a Form as the parent, the Form on close probably needs to call CloseDevTools()