Skip to content

Commit 51326a1

Browse files
authored
Rework keyboard event / keyboard shortcut (#338)
* Working shortcuts on Linux/windows/macos * small refactor * fix multiple modifier * switch to utf16 The flutter framework sends utf16 vectors * support surrogate * adress review comments * fix doc * chore: PrintStack add go-flutter prefix * adress review comments * chore: remove the assumtion that dev are all male * fix keyboardLayout removal * chore: remove runtime usage in text-input * rm new line
1 parent 85b3586 commit 51326a1

15 files changed

+1055
-852
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ If you want more in-depth information about go-flutter, read the [wiki](https://
5252
- <kbd>Backspace</kbd> <kbd>ctrl-Backspace</kbd> <kbd>Delete</kbd>
5353
- Mouse-over/hovering
5454
- Mouse-buttons
55-
- RawKeyboard events (through `RawKeyEventDataLinux` regardless of the platform)
55+
- RawKeyboard events
5656
- Distribution format (windows-msi, mac-dmg, linux-appimage, and more)
5757
- Cross-compiling using docker :whale:
5858

application.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,6 @@ func (a *Application) Run() error {
237237
return glfw.GetProcAddress(procName)
238238
}
239239

240-
// Not very nice, but we can only really fix this when there's a pluggable
241-
// renderer.
242-
defaultTextinputPlugin.keyboardLayout = a.config.keyboardLayout
243-
244240
// Set the glfw window user pointer to point to the FlutterEngine so that
245241
// callback functions may obtain the FlutterEngine from the glfw window
246242
// user pointer.

embedder/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ To build this package set the `CGO_LDFLAGS` and run `go build`. For example:
88

99
On Linux:
1010
```bash
11-
export CGO_LDFLAGS="-L/home/${HOME}/.cache/hover/engine/linux/"
11+
export CGO_LDFLAGS="-L${HOME}/.cache/hover/engine/linux/"
1212
go build
1313
```
1414

internal/keyboard/keyboard.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package keyboard
2+
3+
import (
4+
"fmt"
5+
"runtime/debug"
6+
7+
"github.com/go-gl/glfw/v3.3/glfw"
8+
"github.com/pkg/errors"
9+
)
10+
11+
// Event corresponds to a Flutter (dart) compatible RawKeyEventData keyevent data.
12+
// Multi-platform keycode translation is handled withing this package.
13+
//
14+
// As input, go-flutter gets GLFW-keyevent who are only compatible with
15+
// RawKeyEventDataLinux. To fully support keyboard shortcut (like Command+C to
16+
// copy on darwin), the flutter framework expect the sent keyevent data to be
17+
// in the form of a RawKeyEventDataMacOs keyevent data.
18+
// This package maps the GLFW key-codes to the MacOS ones.
19+
//
20+
// On the flutter framework side:
21+
// RawKeyEventDataMacOs data is received for darwin
22+
// RawKeyEventDataLinux data is received for linux and windows
23+
type Event struct {
24+
// Common
25+
Keymap string `json:"keymap"` // Linux/MacOS switch
26+
Character string `json:"character"`
27+
KeyCode int `json:"keyCode"`
28+
Modifiers int `json:"modifiers"`
29+
Type string `json:"type"`
30+
31+
// Linux
32+
Toolkit string `json:"toolkit,omitempty"`
33+
ScanCode int `json:"scanCode,omitempty"`
34+
UnicodeScalarValues uint32 `json:"unicodeScalarValues,omitempty"`
35+
36+
// MacOS
37+
CharactersIgnoringModifiers string `json:"charactersIgnoringModifiers,omitempty"`
38+
Characters string `json:"characters,omitempty"`
39+
}
40+
41+
// Normalize takes a GLFW-based key and normalizes it by converting
42+
// the input to a keyboard.Event struct compatible with Flutter for the current
43+
// OS.
44+
//
45+
// RawKeyEventDataMacOs data for darwin
46+
// RawKeyEventDataLinux data for linux and windows
47+
func Normalize(key glfw.Key, scancode int, mods glfw.ModifierKey, action glfw.Action) (event Event, err error) {
48+
var typeKey string
49+
if action == glfw.Release {
50+
typeKey = "keyup"
51+
} else if action == glfw.Press {
52+
typeKey = "keydown"
53+
} else if action == glfw.Repeat {
54+
typeKey = "keydown"
55+
} else {
56+
return event, errors.Errorf("unknown key event type: %v\n", action)
57+
}
58+
59+
defer func() {
60+
p := recover()
61+
if p != nil {
62+
fmt.Printf("go-flutter: recovered from panic while handling %s event: %v\n", typeKey, p)
63+
debug.PrintStack()
64+
}
65+
}()
66+
67+
// This function call can fail with panic()
68+
utf8 := glfw.GetKeyName(key, scancode)
69+
70+
event = Event{
71+
Type: typeKey,
72+
Character: utf8,
73+
UnicodeScalarValues: codepointFromGLFWKey([]rune(utf8)),
74+
}
75+
76+
event.platfromNormalize(key, scancode, mods)
77+
78+
return event, nil
79+
}
80+
81+
// codepointFromGLFWKey Queries for the printable key name given a key.
82+
// The Flutter framework accepts only one code point, therefore, only the first
83+
// code point will be used. There is unlikely to be more than one, but there
84+
// is no guarantee that it won't happen.
85+
func codepointFromGLFWKey(utf8 []rune) uint32 {
86+
if len(utf8) == 0 {
87+
return 0
88+
}
89+
return uint32(utf8[0])
90+
}

0 commit comments

Comments
 (0)