~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
2 2

[PATCH v2] gio: app: send keypress events for modifier keys in macos

Details
Message ID
<20241001021754.4116874-1-kanobe@gmail.com>
DKIM signature
pass
Download raw message
Patch: +54 -0
This change generates keypress and release events for modifier keys in
MacOS. Specifically the Control, Alt, Shift and Command keys.
---
 app/os_macos.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 app/os_macos.m  |  4 ++++
 2 files changed, 54 insertions(+)

diff --git a/app/os_macos.go b/app/os_macos.go
index d62bb645..77d69e1b 100644
--- a/app/os_macos.go
+++ b/app/os_macos.go
@@ -561,6 +561,56 @@ func gio_onKeys(h C.uintptr_t, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger,
	}
}

var lastModsOnFlagsChanged C.NSUInteger

type onFlagsChangedLogicTableEntry struct {
	modKeyMask C.NSUInteger
	modKeyName key.Name
}

var onFlagsChangedLogicTable = []onFlagsChangedLogicTableEntry{
	onFlagsChangedLogicTableEntry{
		C.NSControlKeyMask,
		key.NameCtrl,
	},
	onFlagsChangedLogicTableEntry{
		C.NSAlternateKeyMask,
		key.NameAlt,
	},
	onFlagsChangedLogicTableEntry{
		C.NSShiftKeyMask,
		key.NameShift,
	},
	onFlagsChangedLogicTableEntry{
		C.NSCommandKeyMask,
		key.NameCommand,
	},
}

//export gio_onFlagsChanged
func gio_onFlagsChanged(h C.uintptr_t, mods C.NSUInteger) {
	w := windowFor(h)
	for _, e := range onFlagsChangedLogicTable {
		if mods&e.modKeyMask != 0 {
			if lastModsOnFlagsChanged&e.modKeyMask == 0 {
				w.ProcessEvent(key.Event{Name: e.modKeyName,
					State: key.Press,
				})
			}

			continue
		}

		if lastModsOnFlagsChanged&e.modKeyMask != 0 {
			w.ProcessEvent(key.Event{Name: e.modKeyName,
				State: key.Release,
			})
		}
	}

	lastModsOnFlagsChanged = mods
}

//export gio_onText
func gio_onText(h C.uintptr_t, cstr C.CFTypeRef) {
	str := nsstringToString(cstr)
diff --git a/app/os_macos.m b/app/os_macos.m
index 9c895148..6e3438e3 100644
--- a/app/os_macos.m
+++ b/app/os_macos.m
@@ -136,6 +136,10 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
	NSString *keys = [event charactersIgnoringModifiers];
	gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
}
- (void)flagsChanged:(NSEvent *)event {
	[self interpretKeyEvents:[NSArray arrayWithObject:event]];
	gio_onFlagsChanged(self.handle, [event modifierFlags]);
}
- (void)keyUp:(NSEvent *)event {
	NSString *keys = [event charactersIgnoringModifiers];
	gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], false);
-- 
2.30.2
Details
Message ID
<D54RK2WBUFYW.3I9NTKTZZ84YV@eliasnaur.com>
In-Reply-To
<20241001021754.4116874-1-kanobe@gmail.com> (view parent)
DKIM signature
pass
Download raw message
On Tue Oct 1, 2024 at 4:17 AM CEST, Jeff Williams wrote:
> This change generates keypress and release events for modifier keys in
> MacOS. Specifically the Control, Alt, Shift and Command keys.
> ---

Thank you for working on this. I've been more than usually busy and I apologize
for the delayed review.

>  app/os_macos.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
>  app/os_macos.m  |  4 ++++
>  2 files changed, 54 insertions(+)
>
> diff --git a/app/os_macos.go b/app/os_macos.go
> index d62bb645..77d69e1b 100644
> --- a/app/os_macos.go
> +++ b/app/os_macos.go
> @@ -561,6 +561,56 @@ func gio_onKeys(h C.uintptr_t, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger,
>  	}
>  }
>  
> +var lastModsOnFlagsChanged C.NSUInteger

This global variable probably belongs to the window type as a struct field.
Perhaps shorten its name to `lastMods`.

> +
> +type onFlagsChangedLogicTableEntry struct {
> +	modKeyMask C.NSUInteger
> +	modKeyName key.Name
> +}
> +
> +var onFlagsChangedLogicTable = []onFlagsChangedLogicTableEntry{
> +	onFlagsChangedLogicTableEntry{
> +		C.NSControlKeyMask,
> +		key.NameCtrl,
> +	},
> +	onFlagsChangedLogicTableEntry{
> +		C.NSAlternateKeyMask,
> +		key.NameAlt,
> +	},
> +	onFlagsChangedLogicTableEntry{
> +		C.NSShiftKeyMask,
> +		key.NameShift,
> +	},
> +	onFlagsChangedLogicTableEntry{
> +		C.NSCommandKeyMask,
> +		key.NameCommand,
> +	},
> +}
> +
> +//export gio_onFlagsChanged
> +func gio_onFlagsChanged(h C.uintptr_t, mods C.NSUInteger) {
> +	w := windowFor(h)
> +	for _, e := range onFlagsChangedLogicTable {
> +		if mods&e.modKeyMask != 0 {
> +			if lastModsOnFlagsChanged&e.modKeyMask == 0 {
> +				w.ProcessEvent(key.Event{Name: e.modKeyName,
> +					State: key.Press,
> +				})
> +			}
> +
> +			continue
> +		}
> +
> +		if lastModsOnFlagsChanged&e.modKeyMask != 0 {
> +			w.ProcessEvent(key.Event{Name: e.modKeyName,
> +				State: key.Release,
> +			})
> +		}
> +	}

How about dropping the onFlagsChangedLogicTable and then

	mods := []C.NSUInteger{C.NSShiftKeyMask, ...}
	keys := []key.Name{key.NameShift, ...}
	for i, mod := range mods {
		wasPressed := w.lastMods&mod != 0
		isPressed := mods&mod != 0
		if wasPressed != isPressed {
			st := key.Release
			if isPressed {
				st = key.Press
			}
			w.ProcessEvent(key.Event{
				Name: keys[i],
				State: st,
			})
		}
	}

?

> +
> +	lastModsOnFlagsChanged = mods
> +}
> +
>  //export gio_onText
>  func gio_onText(h C.uintptr_t, cstr C.CFTypeRef) {
>  	str := nsstringToString(cstr)
> diff --git a/app/os_macos.m b/app/os_macos.m
> index 9c895148..6e3438e3 100644
> --- a/app/os_macos.m
> +++ b/app/os_macos.m
> @@ -136,6 +136,10 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
>  	NSString *keys = [event charactersIgnoringModifiers];
>  	gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
>  }
> +- (void)flagsChanged:(NSEvent *)event {
> +	[self interpretKeyEvents:[NSArray arrayWithObject:event]];
> +	gio_onFlagsChanged(self.handle, [event modifierFlags]);
> +}
>  - (void)keyUp:(NSEvent *)event {
>  	NSString *keys = [event charactersIgnoringModifiers];
>  	gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], false);
Details
Message ID
<CAHe4cPmSPyT58AcNAkoKswAQkLF3q_TvMqFo6Y7rHLMs_25kzQ@mail.gmail.com>
In-Reply-To
<D54RK2WBUFYW.3I9NTKTZZ84YV@eliasnaur.com> (view parent)
DKIM signature
pass
Download raw message
> Thank you for working on this. I've been more than usually busy and I apologize
> for the delayed review.

I completely understand, it's no problem at all! Thanks for reviewing it.

> > +var lastModsOnFlagsChanged C.NSUInteger
>
> This global variable probably belongs to the window type as a struct field.
> Perhaps shorten its name to `lastMods`.

Good suggestion, I'll do that.

> How about dropping the onFlagsChangedLogicTable and then ...

Yes, that's much cleaner. I'll make that change too, and then send
another patch.

Thanks!
Reply to thread Export thread (mbox)