mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
io/key: implement key.Release state
Implement key state for the following platforms: js, wayland, windows, x11. Unsupported platforms will continue to function as before, sending key.Press for all key events. Signed-off-by: Josiah Niedrauer <josiah@niedrauer.com>
This commit is contained in:
committed by
Elias Naur
parent
ef652f4922
commit
42e568775c
@@ -180,7 +180,11 @@ func (w *window) addEventListeners() {
|
||||
return nil
|
||||
})
|
||||
w.addEventListener(w.tarea, "keydown", func(this js.Value, args []js.Value) interface{} {
|
||||
w.keyEvent(args[0])
|
||||
w.keyEvent(args[0], key.Press)
|
||||
return nil
|
||||
})
|
||||
w.addEventListener(w.tarea, "keyup", func(this js.Value, args []js.Value) interface{} {
|
||||
w.keyEvent(args[0], key.Release)
|
||||
return nil
|
||||
})
|
||||
w.addEventListener(w.tarea, "compositionstart", func(this js.Value, args []js.Value) interface{} {
|
||||
@@ -215,12 +219,13 @@ func (w *window) focus() {
|
||||
w.tarea.Call("focus")
|
||||
}
|
||||
|
||||
func (w *window) keyEvent(e js.Value) {
|
||||
func (w *window) keyEvent(e js.Value, ks key.State) {
|
||||
k := e.Get("key").String()
|
||||
if n, ok := translateKey(k); ok {
|
||||
cmd := key.Event{
|
||||
Name: n,
|
||||
Modifiers: modifiersFor(e),
|
||||
State: ks,
|
||||
}
|
||||
w.w.Event(cmd)
|
||||
}
|
||||
|
||||
@@ -964,13 +964,14 @@ func gio_onKeyboardKey(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, seri
|
||||
t := time.Duration(timestamp) * time.Millisecond
|
||||
s.disp.repeat.Stop(t)
|
||||
w.resetFling()
|
||||
kc := mapXKBKeycode(uint32(keyCode))
|
||||
ks := mapXKBKeyState(uint32(state))
|
||||
for _, e := range w.disp.xkb.DispatchKey(kc, ks) {
|
||||
w.w.Event(e)
|
||||
}
|
||||
if state != C.WL_KEYBOARD_KEY_STATE_PRESSED {
|
||||
return
|
||||
}
|
||||
kc := mapXKBKeycode(uint32(keyCode))
|
||||
for _, e := range w.disp.xkb.DispatchKey(kc) {
|
||||
w.w.Event(e)
|
||||
}
|
||||
if w.disp.xkb.IsRepeatKey(kc) {
|
||||
w.disp.repeat.Start(w, kc, t)
|
||||
}
|
||||
@@ -981,6 +982,15 @@ func mapXKBKeycode(keyCode uint32) uint32 {
|
||||
return keyCode + 8
|
||||
}
|
||||
|
||||
func mapXKBKeyState(state uint32) key.State {
|
||||
switch state {
|
||||
case C.WL_KEYBOARD_KEY_STATE_RELEASED:
|
||||
return key.Release
|
||||
default:
|
||||
return key.Press
|
||||
}
|
||||
}
|
||||
|
||||
func (r *repeatState) Start(w *window, keyCode uint32, t time.Duration) {
|
||||
if r.rate <= 0 {
|
||||
return
|
||||
@@ -1046,7 +1056,7 @@ func (r *repeatState) Repeat(d *wlDisplay) {
|
||||
if r.last+delay > now {
|
||||
break
|
||||
}
|
||||
for _, e := range d.xkb.DispatchKey(r.key) {
|
||||
for _, e := range d.xkb.DispatchKey(r.key, key.Press) {
|
||||
r.win.Event(e)
|
||||
}
|
||||
r.last += delay
|
||||
|
||||
@@ -228,9 +228,17 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
|
||||
case windows.WM_ERASEBKGND:
|
||||
// Avoid flickering between GPU content and background color.
|
||||
return 1
|
||||
case windows.WM_KEYDOWN, windows.WM_SYSKEYDOWN:
|
||||
case windows.WM_KEYDOWN, windows.WM_KEYUP, windows.WM_SYSKEYDOWN, windows.WM_SYSKEYUP:
|
||||
if n, ok := convertKeyCode(wParam); ok {
|
||||
w.w.Event(key.Event{Name: n, Modifiers: getModifiers()})
|
||||
e := key.Event{
|
||||
Name: n,
|
||||
Modifiers: getModifiers(),
|
||||
State: key.Press,
|
||||
}
|
||||
if msg == windows.WM_KEYUP || msg == windows.WM_SYSKEYUP {
|
||||
e.State = key.Release
|
||||
}
|
||||
w.w.Event(e)
|
||||
}
|
||||
case windows.WM_LBUTTONDOWN:
|
||||
w.pointerButton(pointer.ButtonLeft, true, lParam, getModifiers())
|
||||
|
||||
@@ -305,12 +305,15 @@ func (h *x11EventHandler) handleEvents() bool {
|
||||
h.w.xkb.UpdateMask(uint32(state.base_mods), uint32(state.latched_mods), uint32(state.locked_mods),
|
||||
uint32(state.base_group), uint32(state.latched_group), uint32(state.locked_group))
|
||||
}
|
||||
case C.KeyPress:
|
||||
case C.KeyPress, C.KeyRelease:
|
||||
ks := key.Press
|
||||
if _type == C.KeyRelease {
|
||||
ks = key.Release
|
||||
}
|
||||
kevt := (*C.XKeyPressedEvent)(unsafe.Pointer(xev))
|
||||
for _, e := range h.w.xkb.DispatchKey(uint32(kevt.keycode)) {
|
||||
for _, e := range h.w.xkb.DispatchKey(uint32(kevt.keycode), ks) {
|
||||
w.w.Event(e)
|
||||
}
|
||||
case C.KeyRelease:
|
||||
case C.ButtonPress, C.ButtonRelease:
|
||||
bevt := (*C.XButtonEvent)(unsafe.Pointer(xev))
|
||||
ev := pointer.Event{
|
||||
|
||||
@@ -150,6 +150,7 @@ const (
|
||||
WM_SHOWWINDOW = 0x0018
|
||||
WM_SIZE = 0x0005
|
||||
WM_SYSKEYDOWN = 0x0104
|
||||
WM_SYSKEYUP = 0x0105
|
||||
WM_RBUTTONDOWN = 0x0204
|
||||
WM_RBUTTONUP = 0x0205
|
||||
WM_TIMER = 0x0113
|
||||
|
||||
@@ -150,7 +150,7 @@ func (x *Context) Modifiers() key.Modifiers {
|
||||
return mods
|
||||
}
|
||||
|
||||
func (x *Context) DispatchKey(keyCode uint32) (events []event.Event) {
|
||||
func (x *Context) DispatchKey(keyCode uint32, state key.State) (events []event.Event) {
|
||||
if x.state == nil {
|
||||
return
|
||||
}
|
||||
@@ -163,6 +163,7 @@ func (x *Context) DispatchKey(keyCode uint32) (events []event.Event) {
|
||||
cmd := key.Event{
|
||||
Name: name,
|
||||
Modifiers: x.Modifiers(),
|
||||
State: state,
|
||||
}
|
||||
// Ensure that a physical backtab key is translated to
|
||||
// Shift-Tab.
|
||||
@@ -201,7 +202,7 @@ func (x *Context) DispatchKey(keyCode uint32) (events []event.Event) {
|
||||
str = str[:len(str)-s]
|
||||
}
|
||||
}
|
||||
if len(str) > 0 {
|
||||
if state == key.Press && len(str) > 0 {
|
||||
events = append(events, key.EditEvent{Text: string(str)})
|
||||
}
|
||||
return
|
||||
|
||||
@@ -46,6 +46,8 @@ type Event struct {
|
||||
Name string
|
||||
// Modifiers is the set of active modifiers when the key was pressed.
|
||||
Modifiers Modifiers
|
||||
// State is the state of the key when the event was fired.
|
||||
State State
|
||||
}
|
||||
|
||||
// An EditEvent is generated when text is input.
|
||||
@@ -53,6 +55,19 @@ type EditEvent struct {
|
||||
Text string
|
||||
}
|
||||
|
||||
// State is the state of a key during an event.
|
||||
type State uint8
|
||||
|
||||
const (
|
||||
// Press is the state of a pressed key.
|
||||
Press State = iota
|
||||
// Release is the state of a key that has been released.
|
||||
//
|
||||
// Note: release events are only implemented on the following platforms:
|
||||
// Linux, Windows, WebAssembly.
|
||||
Release
|
||||
)
|
||||
|
||||
// Modifiers
|
||||
type Modifiers uint32
|
||||
|
||||
|
||||
Reference in New Issue
Block a user