-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
win32: Don't raise TextInput event when KeyDown was handled. #7351
Conversation
On win32, returning handled from `WM_KEYDOWN` doesn't automatically prevent a `WM_CHAR` message, resulting in #5849. The `TranslateMessage` call is responsible for translating the `WM_KEYDOWN` event to a `WM_CHAR` event, so one needs to "simply" not call this function if the key down event was handled. However there's a problem: `TranslateMessage` is called before the `DispatchMessage` call which dispatches the message to the `WindowImpl. To get around this, add a `PreProcessMessage` which can be used to handle key down messages outside of the `DispatchMessage` call. This solution broadly comes from WPF, though there the solution is a bit more complicated (it's hooked into using `ComponentDispatcher` events). Fixes #5849
private protected virtual bool OnPreProcessMessage(in MSG msg) | ||
{ | ||
RawInputEventArgs e = null; | ||
uint timestamp = unchecked((uint)GetMessageTime()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not used anywhere.
@@ -189,8 +189,11 @@ public void ProcessMessage() | |||
|
|||
if (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) > -1) | |||
{ | |||
UnmanagedMethods.TranslateMessage(ref msg); | |||
UnmanagedMethods.DispatchMessage(ref msg); | |||
if (!WindowImpl.PreProcessMessage(msg)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see one problem with this - my app is running a custom window loop so I might need a way of invoking Avalonia message handling somehow. Since my app is basically doing:
while (PeekMessage(...)) {
TranslateMessage();
DispatchMessage()
}
This allows my update loop to still run and process win32 messages when I need to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're already exposing the message loop in this method, so I guess we also need to expose a public PreProcessMessage
method here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't help if custom message loop is run by Windows itself at some point, which happens quite frequently. So I think it's better to raise a flag in WindowImpl itself and check if if the next arrived message is WM_CHAR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be better (and simpler tbh). I didn't go that way because WPF does the PreProcessMessage
stuff, but it also has hacks where it sets a flag as well, so I'm guessing they encountered the same thing after implementing the pre-proccessing.
If it's guaranteed that a WM_CHAR
is always preceded by a WM_KEYDOWN
then I don't think it should cause problems.
I'll close this PR then and open another.
On win32, returning handled from `WM_KEYDOWN` doesn't automatically prevent a `WM_CHAR` message, resulting in #5849. Fix this by setting a flag after `WM_KEYDOWN` is handled which will make the following `WM_CHAR` message be ignored. This is the second attempt at fixing this after it was decided that #7351 was not the right approach. Fixes #5849
What does the pull request do?
On win32, returning handled from
WM_KEYDOWN
doesn't automatically prevent aWM_CHAR
message, resulting in #5849.The
TranslateMessage
call is responsible for translating theWM_KEYDOWN
event to aWM_CHAR
event, so one needs to "simply" not call this function if the key down event was handled. However there's a problem:TranslateMessage
is called before theDispatchMessage
call which dispatches the key down message to theWindowImpl
.To get around this, this PR adds a
PreProcessMessage
step which can be used to handle key down messages and raise events outside ofDispatchMessage
/WndProc
. This solution broadly comes from WPF, though there the solution is a bit more complicated (it's hooked into usingComponentDispatcher
events fromHwndSource
).Fixed issues
Fixes #5849