~eliasnaur/gio-patches

io/key: add key.UpEvent, generated when a key is released. v1 PROPOSED

Raffaele Sena
Raffaele Sena: 1
 io/key: add key.UpEvent, generated when a key is released.

 7 files changed, 70 insertions(+), 11 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/9769/mbox | git am -3
Learn more about email & git

[PATCH] io/key: add key.UpEvent, generated when a key is released. Export this patch

Raffaele Sena
Adding support for key press / key released (key.Event is generated on press and repeat, key.UpEvent is generated on key released)
Implemented generation for key.UpEvent for all platforms, but tested only on MacOS.
Signed-off-by: Raffaele Sena <raff367@gmail.com>
---
 app/internal/window/gl_macos.m    |  5 +++++
 app/internal/window/os_js.go      | 14 +++++++++++---
 app/internal/window/os_macos.go   | 17 +++++++++++++++++
 app/internal/window/os_wayland.go | 22 ++++++++++++++--------
 app/internal/window/os_windows.go |  4 ++++
 app/internal/window/os_x11.go     |  6 ++++++
 io/key/key.go                     | 13 +++++++++++++
 7 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/app/internal/window/gl_macos.m b/app/internal/window/gl_macos.m
index 8512769..58788e0 100644
--- a/app/internal/window/gl_macos.m
+++ b/app/internal/window/gl_macos.m
@@ -102,6 +102,11 @@ CVDisplayLinkRef displayLink;
	CGFloat dy = -event.scrollingDeltaY;
	handleMouse(self, event, GIO_MOUSE_MOVE, dx, dy);
}
- (void)keyUp:(NSEvent *)event {
	NSString *keys = [event charactersIgnoringModifiers];
	gio_onKeysUp((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags]);
	[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
- (void)keyDown:(NSEvent *)event {
	NSString *keys = [event charactersIgnoringModifiers];
	gio_onKeys((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags]);
diff --git a/app/internal/window/os_js.go b/app/internal/window/os_js.go
index e3ffe98..fdee20b 100644
--- a/app/internal/window/os_js.go
+++ b/app/internal/window/os_js.go
@@ -174,7 +174,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], true)
		return nil
	})
	w.addEventListener(w.tarea, "keyup", func(this js.Value, args []js.Value) interface{} {
		w.keyEvent(args[0], false)
		return nil
	})
	w.addEventListener(w.tarea, "compositionstart", func(this js.Value, args []js.Value) interface{} {
@@ -209,7 +213,7 @@ func (w *window) focus() {
	w.tarea.Call("focus")
}

func (w *window) keyEvent(e js.Value) {
func (w *window) keyEvent(e js.Value, pressed bool) {
	k := e.Get("key").String()
	if n, ok := translateKey(k); ok {
		cmd := key.Event{Name: n}
@@ -222,7 +226,11 @@ func (w *window) keyEvent(e js.Value) {
		if e.Call("getModifierState", "Shift").Bool() {
			cmd.Modifiers |= key.ModShift
		}
		w.w.Event(cmd)
		if pressed {
			w.w.Event(cmd)
		} else {
			w.w.Event(key.UpEvent{Name: cmd.Name, Modifiers: cmd.Modifiers})
		}
	}
}

diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go
index 42c23fa..b4e1b10 100644
--- a/app/internal/window/os_macos.go
+++ b/app/internal/window/os_macos.go
@@ -133,6 +133,23 @@ func gio_onKeys(view C.CFTypeRef, cstr *C.char, ti C.double, mods C.NSUInteger)
	})
}

//export gio_onKeysUp
func gio_onKeysUp(view C.CFTypeRef, cstr *C.char, ti C.double, mods C.NSUInteger) {
	str := C.GoString(cstr)
	kmods := convertMods(mods)
	viewDo(view, func(views viewMap, view C.CFTypeRef) {
		w := views[view]
		for _, k := range str {
			if n, ok := convertKey(k); ok {
				w.w.Event(key.UpEvent{
					Name:      n,
					Modifiers: kmods,
				})
			}
		}
	})
}

//export gio_onText
func gio_onText(view C.CFTypeRef, cstr *C.char) {
	str := C.GoString(cstr)
diff --git a/app/internal/window/os_wayland.go b/app/internal/window/os_wayland.go
index 7fdb921..08190e4 100644
--- a/app/internal/window/os_wayland.go
+++ b/app/internal/window/os_wayland.go
@@ -661,15 +661,21 @@ func gio_onKeyboardKey(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, seri
	w := winMap[keyboard]
	w.resetFling()
	conn.repeat.Stop(t)
	if state != C.WL_KEYBOARD_KEY_STATE_PRESSED {
		return
	}
	kc := mapXKBKeycode(uint32(keyCode))
	for _, e := range conn.xkb.DispatchKey(kc) {
		w.w.Event(e)
	}
	if conn.xkb.IsRepeatKey(kc) {
		conn.repeat.Start(w, kc, t)

	if state == C.WL_KEYBOARD_KEY_STATE_PRESSED {
		for _, e := range conn.xkb.DispatchKey(kc) {
			w.w.Event(e)
		}
		if conn.xkb.IsRepeatKey(kc) {
			conn.repeat.Start(w, kc, t)
		}
	} else {
		for _, e := range conn.xkb.DispatchKey(kc) {
			if ke, ok := e.(key.Event); ok {
				w.w.Event(key.UpEvent{Name: ke.Name, Modifiers: ke.Modifiers})
			}
		}
	}
}

diff --git a/app/internal/window/os_windows.go b/app/internal/window/os_windows.go
index d7b781a..76edf1f 100644
--- a/app/internal/window/os_windows.go
+++ b/app/internal/window/os_windows.go
@@ -158,6 +158,10 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
		if n, ok := convertKeyCode(wParam); ok {
			w.w.Event(key.Event{Name: n, Modifiers: getModifiers()})
		}
	case windows.WM_KEYUP, windows.WM_SYSKEYUP:
		if n, ok := convertKeyCode(wParam); ok {
			w.w.Event(key.UpEvent{Name: n, Modifiers: getModifiers()})
		}
	case windows.WM_LBUTTONDOWN:
		w.pointerButton(pointer.ButtonLeft, true, lParam, getModifiers())
	case windows.WM_LBUTTONUP:
diff --git a/app/internal/window/os_x11.go b/app/internal/window/os_x11.go
index 5d8406a..7908619 100644
--- a/app/internal/window/os_x11.go
+++ b/app/internal/window/os_x11.go
@@ -240,6 +240,12 @@ func (h *x11EventHandler) handleEvents() bool {
				w.w.Event(e)
			}
		case C.KeyRelease:
			kevt := (*C.XKeyReleasedEvent)(unsafe.Pointer(xev))
			for _, e := range h.w.xkb.DispatchKey(uint32(kevt.keycode)) {
				if ke, ok := e.(key.Event); ok {
					w.w.Event(key.UpEvent{Name: ke.Name, Modifiers: ke.Modifiers})
				}
			}
		case C.ButtonPress, C.ButtonRelease:
			bevt := (*C.XButtonEvent)(unsafe.Pointer(xev))
			ev := pointer.Event{
diff --git a/io/key/key.go b/io/key/key.go
index faeaf8c..bd38029 100644
--- a/io/key/key.go
+++ b/io/key/key.go
@@ -48,6 +48,18 @@ type Event struct {
	Modifiers Modifiers
}

// An UpEvent is generated when a key is released. For text input
// use EditEvent.
type UpEvent struct {
	// Name of the key. For letters, the upper case form is used, via
	// unicode.ToUpper. The shift modifier is taken into account, all other
	// modifiers are ignored. For example, the "shift-1" and "ctrl-shift-1"
	// combinations both give the Name "!" with the US keyboard layout.
	Name string
	// Modifiers is the set of active modifiers when the key was released.
	Modifiers Modifiers
}

// An EditEvent is generated when text is input.
type EditEvent struct {
	Text string
@@ -111,6 +123,7 @@ func (h HideInputOp) Add(o *op.Ops) {

func (EditEvent) ImplementsEvent()  {}
func (Event) ImplementsEvent()      {}
func (UpEvent) ImplementsEvent()    {}
func (FocusEvent) ImplementsEvent() {}

func (e Event) String() string {
-- 
2.25.0
View this thread in the archives