-
Notifications
You must be signed in to change notification settings - Fork 282
Rework keyboard event / keyboard shortcut #338
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
Conversation
05dc761
to
38bf8bd
Compare
keyboard_events demo didn't work at all:
|
I've update the keyboard_events accordingly. The issue was in the example. The 2 other points needs to be address before merging this PR. |
I'm still a bit surprised by the fact that shift+arrow doesn't select text. :/ Are the MacOS one working https://i.imgur.com/YPpx9Px.png working? |
shift, control, and command results in the following:
|
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.
overall LGTM, not sure how I feel about runtime.GOOS == "darwin" vs using build tags and methods.
will need the change I opened a PR for to work properly on macs though.
@@ -0,0 +1,559 @@ | |||
package glfwkeyconversion | |||
|
|||
import "github.com/go-gl/glfw/v3.3/glfw" |
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 may be better served by making this platform specific.
internal/keyboard/keyboard_darwin.go // has all the mappings defined in these two files.
internal/keyboard/keyboard_unix.go // with a +build unix !darwin
internal/keyboard/keyboard_windows.go
each file with a single method:
func Normalize(keycode glfw.Key, scancode int) Event { /* ... */ }
// internal/keyboard/keyboard.go
// replaces keyEventMessage
type Event struct {
// ...
}
key-events.go
Outdated
utf8 := glfw.GetKeyName(key, scancode) | ||
var event keyEventMessage | ||
|
||
if runtime.GOOS == "darwin" { |
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.
if we do the build tags this code would collapse to:
event := keyboard.Normalize(key, scancode)
if err := p.keyEventChannel.Send(event); err != nil { /* .... */ }
key-events.go
Outdated
// code point will be used. There is unlikely to be more than one, but there | ||
// is no guarantee that it won't happen. | ||
func CodepointFromGLFWKey(utf8 []rune) uint32 { | ||
return uint32(utf8[0]) |
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.
lets handle the zero length here and return 0.
textinput.go
Outdated
return | ||
} | ||
// Word Backspace | ||
if (runtime.GOOS == "darwin" && mods == glfw.ModAlt) || (runtime.GOOS != "darwin" && mods == glfw.ModControl) { |
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.
if keyboard.DetectDeleteWord(key, mods) {
/* ... */
}
|
||
// AsMacOSModifiers translate the keycode to the ModifierKey | ||
func AsMacOSModifiers(keycode glfw.Key) (int, bool) { | ||
val, ok := modifierKeytoMods[keycode] |
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.
a simple switch statement is likely more performant. could be wrong 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.
It's an interesting topic. According to this blogpost the map is actually faster, but not much difference in absolute times. https://hashrocket.com/blog/posts/switch-vs-map-which-is-the-better-way-to-branch-in-go
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.
yeah, I ran across that which is why I reverted my thinking.
its actually an interesting optimization that could be done to the switch statements at the compiler level.
I suspect its because maps are hashing the key which is a fixed cost based on the key length. then doing a lookup. whereas a switch statement is doing multiple comparisons between the key and the case values.
|
||
// ToMacOSModifiers takes a glfw ModifierKey and return his MacOS equivalent | ||
// as defined in https://github.com/flutter/flutter/blob/3e63411256cc88afc48044aa5ea06c5c9c6a6846/packages/flutter/lib/src/services/raw_keyboard_macos.dart#L241 | ||
func ToMacOSModifiers(mods glfw.ModifierKey) int { |
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.
removes the need to initialize it below.
func ToMacOSModifiers(mods glfw.ModifierKey) int { | |
func ToMacOSModifiers(mods glfw.ModifierKey) (macOSmods int) { |
The flutter framework sends utf16 vectors
textinput.go
Outdated
@@ -104,7 +105,7 @@ func (p *textinputPlugin) handleSetEditingState(arguments interface{}) (reply in | |||
return nil, errors.Wrap(err, "failed to decode json arguments for handleSetEditingState") | |||
} | |||
|
|||
p.word = []rune(editingState.Text) | |||
p.word = utf16.Encode([]rune(editingState.Text)) |
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.
utf16? Is that what Flutter uses?
I'd think utf8 would be the default for modern projects.... Especially with the "utf-8 everywhere" movement that's going on.
http://utf8everywhere.org/
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.
utf16? Is that what Flutter uses?
Yes, that what uses Dart to be more specific!
Here is some readings:
- Bring Dart's String support into the modern age dart-lang/sdk#28404
- https://github.com/flutter/flutter/blob/e0c63cd35e15e407a80dc44281cc392535fcce25/packages/flutter/lib/src/services/text_formatter.dart#L197-L204
A bug we encounter: #314 due to a miss match between utf8 and utf16 indexes.
I'd think utf8 would be the default for modern projects.... Especially with the "utf-8 everywhere" movement that's going on.
Well, the glfw callback returns a utf8 code point, we then convert it to utf16 at the embedder level and then send it to flutter.
On the outside, we support as input utf8-based code point 😄... but on the inside.. it'sa Roller coaster casting character 🪂
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.
In for the ride, choo choo! 🎢
Ready for another review/fix cycle! |
return nil, errors.Wrap(err, "failed to decode json arguments for handleSetClient") | ||
} | ||
|
||
err = json.Unmarshal(args[0], &p.clientID) |
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.
Length of 'args' is never checked, will cause panic if the message format ever changes.
key-events.go
Outdated
} | ||
err := p.keyEventChannel.Send(event) | ||
if err != nil { | ||
if err := p.channel.Send(event); err != nil { |
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 prefer to never inline the assignment to err unless it's a function that only fetches some information or performs a check. In this case, the call to Send is actually important for the function a a whole, not just for this error check, so it feels off to inline it. But that could just be personal preference.
} | ||
// Opinionated: If a flutter dev uses TextCapitalization.characters | ||
// in a TextField, that means he wants only to receive | ||
// uppercase characters. |
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.
Interesting. In some cases on Android it may be possible to switch back from the uppercased keyboard to the lowercased one... Although indeed that may not be the intention of the developer. We'll have to see how this lands with go-flutter users. For now I think this is the best approach yes.
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.
Just a missing check on length of a slice.
Otherwise LGTM!
Ready for another review/fix cycle! |
fixes: #314
fixes: #332
fixes: #358
Uses UTF-16 for textencoding: ref