Hi, I've come across some unexpected behavior across platforms when key events.
Expected Behavior
A handler for the KeyDown event should be called the same number of times in the same situations for all platforms.
The value of KeyEventArgs properties should be compatible across platforms.
For example, the value of keyEvent.IsChar when keyEvent.Key is Keys.Right or Keys.G should be the same on Windows and Mac.
The value of KeyEventArgs properties should be consistent across calls when the same key is pressed.
For example, the value of keyEvent.IsChar when keyEvent.Key is Keys.Right or Keys.G should be the same across all calls of the registered handler.
Actual Behavior
On WPF or WinForms, a handler for KeyDown for a TextArea is called twice when text is input into the TextArea as a result of the event, but only once when no text is input. On Mac, however, the same handler is called only once in both situations.
On Mac, KeyEventArgs.IsChar is always true, even when KeyEventArgs.Key is something like Keys.Right, and thus KeyEventArgs.KeyChar always has a value (at least in my testing...several other unexpected keys too).
On WPF and WinForms, however, for the first call of the KeyDown handler KeyEventArgs.IsChar is always false, even when KeyEventArgs.Key is something like Keys.G.
This is because in the code that converts the native event (WPF) args to Eto KeyEventArgs, nothing is passed to the keyChar parameter:
On WPF and WinForms, the two calls made to a TextArea's KeyDown handler have different values for KeyEventArgs.IsChar and KeyEventArgs.KeyChar.
For the first call, as in (2) above, KeyEventArgs.IsChar is always false and KeyEventArgs.KeyChar is null. Also, KeyEventArgs.Key has a relevant value.
If there is a second call, however, KeyEventArgs.IsChar is true because text is inserted, and KeyEventArgs.KeyChar has an appropriate value (at least for the system). In this call, KeyEventArgs.Key is set to Keys.None.
For the second (and subsequent?) call, this is so because the code for HandleTextInput (WPF) creates aKeyEventArgs for each character input, with the value of each character passed to the keyChar parameter.
Here's a simple handler (in F#) that logs the values of KeyEventArgs.Key, KeyEventArgs.IsChar, and KeyEventArgs.KeyChar.
let textArea = new TextArea()
textArea.KeyDown.Add (fun k ->
printfn $"{k.Key}"
printfn $"{k.IsChar}"
printfn $"{k.KeyChar}"
)
The combination of these differences between platforms is making handling KeyEvents difficult. :) I'm not sure what to do about it. I haven't gotten as far as testing GTK, but I'm hoping the app I'm working on will eventually target it as well.
Hi, I've come across some unexpected behavior across platforms when key events.
Expected Behavior
A handler for the
KeyDown
event should be called the same number of times in the same situations for all platforms.The value of
KeyEventArgs
properties should be compatible across platforms.For example, the value of
keyEvent.IsChar
whenkeyEvent.Key
isKeys.Right
orKeys.G
should be the same on Windows and Mac.KeyEventArgs
properties should be consistent across calls when the same key is pressed.For example, the value of
keyEvent.IsChar
whenkeyEvent.Key
isKeys.Right
orKeys.G
should be the same across all calls of the registered handler.Actual Behavior
On WPF or WinForms, a handler for
KeyDown
for aTextArea
is called twice when text is input into theTextArea
as a result of the event, but only once when no text is input. On Mac, however, the same handler is called only once in both situations.On Mac,
KeyEventArgs.IsChar
is alwaystrue
, even whenKeyEventArgs.Key
is something likeKeys.Right
, and thusKeyEventArgs.KeyChar
always has a value (at least in my testing...several other unexpected keys too).On Mac, this is due to this line:
https://github.com/picoe/Eto/blob/ea1d236d4883d0d56daa480ebb9a979090b25321/src/Eto.Mac/MacConversions.cs#L359
This is because
theEvent.Characters
usually/always has a value. See https://developer.apple.com/documentation/appkit/nsevent/1533943-keyevent and https://developer.apple.com/documentation/appkit/nsevent/1535851-function-key_unicode_values .On WPF and WinForms, however, for the first call of the
KeyDown
handlerKeyEventArgs.IsChar
is alwaysfalse
, even whenKeyEventArgs.Key
is something likeKeys.G
.This is because in the code that converts the native event (WPF) args to Eto
KeyEventArgs
, nothing is passed to thekeyChar
parameter:https://github.com/picoe/Eto/blob/ea1d236d4883d0d56daa480ebb9a979090b25321/src/Eto.Wpf/WpfConversions.cs#L138-L145
TextArea
'sKeyDown
handler have different values forKeyEventArgs.IsChar
andKeyEventArgs.KeyChar
.For the first call, as in (2) above,
KeyEventArgs.IsChar
is alwaysfalse
andKeyEventArgs.KeyChar
is null. Also,KeyEventArgs.Key
has a relevant value.If there is a second call, however,
KeyEventArgs.IsChar
istrue
because text is inserted, andKeyEventArgs.KeyChar
has an appropriate value (at least for the system). In this call,KeyEventArgs.Key
is set toKeys.None
.For the second (and subsequent?) call, this is so because the code for
HandleTextInput
(WPF) creates aKeyEventArgs
for each character input, with the value of each character passed to thekeyChar
parameter.https://github.com/picoe/Eto/blob/ea1d236d4883d0d56daa480ebb9a979090b25321/src/Eto.Wpf/Forms/WpfFrameworkElement.cs#L766-L783
Steps to Reproduce the Problem
KeyDown
handler for aTextArea
Code that Demonstrates the Problem
Here's a simple handler (in F#) that logs the values of
KeyEventArgs.Key
,KeyEventArgs.IsChar
, andKeyEventArgs.KeyChar
.The combination of these differences between platforms is making handling KeyEvents difficult. :) I'm not sure what to do about it. I haven't gotten as far as testing GTK, but I'm hoping the app I'm working on will eventually target it as well.
Specifications