~eliasnaur/gio-patches

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch

[PATCH] app/internal/window: x11: fix issue with space not sending key.EditEvent

Details
Message ID
<20191109145123.17551-1-db047h@gmail.com>
DKIM signature
missing
Download raw message
Patch: +46 -31
This is a general fix where keys with names differing from their UTF8
representation could not be sent as EditEvents.

Signed-off-by: Denis Bernard <db047h@gmail.com>
---
 app/internal/window/os_x11.go | 77 +++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 31 deletions(-)

diff --git a/app/internal/window/os_x11.go b/app/internal/window/os_x11.go
index c694e20..954f7ef 100644
--- a/app/internal/window/os_x11.go
+++ b/app/internal/window/os_x11.go
@@ -225,6 +225,8 @@ func (h *x11EventHandler) handleEvents() bool {
		lookup:
			// Save state then clear CTRL & Shift bits in order to have
			// Xutf8LookupString return the unmodified key name in text[:l].
			// This addresses an issue on some non US keyboard layouts where
			// CTRL-[0..9] do not behave consistently.
			//
			// Note that this enables sending a key.Event for key combinations
			// like CTRL-SHIFT-/ on QWERTY layouts, but CTRL-? is completely
@@ -247,24 +249,31 @@ func (h *x11EventHandler) handleEvents() bool {
				w.w.Event(key.EditEvent{Text: string(h.text[:l])})
			case C.XLookupKeySym:
				// Special keys.
				if r, ok := x11SpecialKeySymToRune(h.keysym); ok {
					w.w.Event(key.Event{
						Name:      r,
						Modifiers: mods,
					})
				if n, ok := x11ConvertKeysym(h.keysym); ok {
					w.w.Event(key.Event{Name: n, Modifiers: mods})
				}
			case C.XLookupBoth:
				if r, ok := x11SpecialKeySymToRune(h.keysym); ok {
					w.w.Event(key.Event{Name: r, Modifiers: mods})
				} else {
					if r, _ := utf8.DecodeRune(h.text[:l]); r != utf8.RuneError {
						w.w.Event(key.Event{Name: string(unicode.ToUpper(r)), Modifiers: mods})
					}
					// Send EditEvent only when not a CTRL key combination.
					if !mods.Contain(key.ModCtrl) {
						w.w.Event(key.EditEvent{Text: string(h.text[:l])})
				if n, ok := x11ConvertKeysym(h.keysym); ok {
					w.w.Event(key.Event{Name: n, Modifiers: mods})
				}
				// Do not send EditEvent for CTRL key combinations.
				if mods.Contain(key.ModCtrl) {
					break
				}
				str := h.text[:l]
				// Report only printable runes.
				for n := 0; n < len(str); {
					r, s := utf8.DecodeRune(str)
					if unicode.IsPrint(r) {
						n += s
					} else {
						copy(str[n:], str[n+s:])
						str = str[:len(str)-s]
					}
				}
				if len(str) > 0 {
					w.w.Event(key.EditEvent{Text: string(str)})
				}
			}
		case C.KeyRelease:
		case C.ButtonPress, C.ButtonRelease:
@@ -332,24 +341,13 @@ func (h *x11EventHandler) handleEvents() bool {
	return redraw
}

func x11KeyStateToModifiers(s C.uint) key.Modifiers {
	var m key.Modifiers
	if s&C.Mod1Mask != 0 {
		m |= key.ModAlt
	}
	if s&C.Mod4Mask != 0 {
		m |= key.ModSuper
func x11ConvertKeysym(s C.KeySym) (string, bool) {
	if '0' <= s && s <= '9' || 'A' <= s && s <= 'Z' {
		return string(s), true
	}
	if s&C.ControlMask != 0 {
		m |= key.ModCtrl
	if 'a' <= s && s <= 'z' {
		return string(s - 0x20), true
	}
	if s&C.ShiftMask != 0 {
		m |= key.ModShift
	}
	return m
}

func x11SpecialKeySymToRune(s C.KeySym) (string, bool) {
	var n string
	switch s {
	case C.XK_Escape:
@@ -402,7 +400,7 @@ func x11SpecialKeySymToRune(s C.KeySym) (string, bool) {
		n = "F11"
	case C.XK_F12:
		n = "F12"
	case C.XK_Tab:
	case C.XK_Tab, C.XK_ISO_Left_Tab:
		n = key.NameTab
	case 0x20, C.XK_KP_Space:
		n = "Space"
@@ -412,6 +410,23 @@ func x11SpecialKeySymToRune(s C.KeySym) (string, bool) {
	return n, true
}

func x11KeyStateToModifiers(s C.uint) key.Modifiers {
	var m key.Modifiers
	if s&C.Mod1Mask != 0 {
		m |= key.ModAlt
	}
	if s&C.Mod4Mask != 0 {
		m |= key.ModSuper
	}
	if s&C.ControlMask != 0 {
		m |= key.ModCtrl
	}
	if s&C.ShiftMask != 0 {
		m |= key.ModShift
	}
	return m
}

var (
	x11Threads sync.Once
)
-- 
2.17.1
Review patch Export thread (mbox)