~eliasnaur/gio-patches

several: add modifiers to mouse events and clicks v1 PROPOSED

Larry Clapp: 1
 several: add modifiers to mouse events and clicks

 4 files changed, 33 insertions(+), 13 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/9076/mbox | git am -3
Learn more about email & git

[PATCH] several: add modifiers to mouse events and clicks Export this patch

macOS only, for the os-specific bits.
Signed-off-by: Larry Clapp <larry@theclapp.org>
---
 app/internal/window/gl_macos.m  |  2 +-
 app/internal/window/os_macos.go | 28 +++++++++++++++++++++-------
 gesture/gesture.go              | 12 +++++++-----
 io/pointer/pointer.go           |  4 ++++
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/app/internal/window/gl_macos.m b/app/internal/window/gl_macos.m
index fdadae2..2f477ff 100644
--- a/app/internal/window/gl_macos.m
+++ b/app/internal/window/gl_macos.m
@@ -18,7 +18,7 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
 		dx *= 10;
 		dy *= 10;
 	}
-	gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp]);
+	gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp], [event modifierFlags]);
 }
 
 static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go
index c803c1f..87c64cd 100644
--- a/app/internal/window/os_macos.go
+++ b/app/internal/window/os_macos.go
@@ -151,7 +151,20 @@ func gio_onText(view C.CFTypeRef, cstr *C.char) {
 }
 
 //export gio_onMouse
-func gio_onMouse(view C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx, dy C.CGFloat, ti C.double) {
+func gio_onMouse(view C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) {
+	var kmods key.Modifiers
+	if mods&C.NSAlternateKeyMask != 0 {
+		kmods |= key.ModAlt
+	}
+	if mods&C.NSControlKeyMask != 0 {
+		kmods |= key.ModCtrl
+	}
+	if mods&C.NSCommandKeyMask != 0 {
+		kmods |= key.ModCommand
+	}
+	if mods&C.NSShiftKeyMask != 0 {
+		kmods |= key.ModShift
+	}
 	var typ pointer.Type
 	switch cdir {
 	case C.GIO_MOUSE_MOVE:
@@ -179,12 +192,13 @@ func gio_onMouse(view C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx, dy
 		x, y := float32(x)*w.scale, float32(y)*w.scale
 		dx, dy := float32(dx)*w.scale, float32(dy)*w.scale
 		w.w.Event(pointer.Event{
-			Type:     typ,
-			Source:   pointer.Mouse,
-			Time:     t,
-			Buttons:  btns,
-			Position: f32.Point{X: x, Y: y},
-			Scroll:   f32.Point{X: dx, Y: dy},
+			Type:      typ,
+			Source:    pointer.Mouse,
+			Time:      t,
+			Buttons:   btns,
+			Position:  f32.Point{X: x, Y: y},
+			Scroll:    f32.Point{X: dx, Y: dy},
+			Modifiers: kmods,
 		})
 	})
 }
diff --git a/gesture/gesture.go b/gesture/gesture.go
index 6d26456..2714890 100644
--- a/gesture/gesture.go
+++ b/gesture/gesture.go
@@ -16,6 +16,7 @@ import (
 	"gioui.org/f32"
 	"gioui.org/internal/fling"
 	"gioui.org/io/event"
+	"gioui.org/io/key"
 	"gioui.org/io/pointer"
 	"gioui.org/op"
 	"gioui.org/unit"
@@ -34,9 +35,10 @@ type ClickState uint8
 // TypePress for the beginning of a click or a
 // TypeClick for a completed click.
 type ClickEvent struct {
-	Type     ClickType
-	Position f32.Point
-	Source   pointer.Source
+	Type      ClickType
+	Position  f32.Point
+	Source    pointer.Source
+	Modifiers key.Modifiers
 }
 
 type ClickType uint8
@@ -120,7 +122,7 @@ func (c *Click) Events(q event.Queue) []ClickEvent {
 			wasPressed := c.state == StatePressed
 			c.state = StateNormal
 			if wasPressed {
-				events = append(events, ClickEvent{Type: TypeClick, Position: e.Position, Source: e.Source})
+				events = append(events, ClickEvent{Type: TypeClick, Position: e.Position, Source: e.Source, Modifiers: e.Modifiers})
 			}
 		case pointer.Cancel:
 			c.state = StateNormal
@@ -132,7 +134,7 @@ func (c *Click) Events(q event.Queue) []ClickEvent {
 				break
 			}
 			c.state = StatePressed
-			events = append(events, ClickEvent{Type: TypePress, Position: e.Position, Source: e.Source})
+			events = append(events, ClickEvent{Type: TypePress, Position: e.Position, Source: e.Source, Modifiers: e.Modifiers})
 		case pointer.Move:
 			if c.state == StatePressed && !e.Hit {
 				c.state = StateNormal
diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go
index 1dcde67..c72f758 100644
--- a/io/pointer/pointer.go
+++ b/io/pointer/pointer.go
@@ -11,6 +11,7 @@ import (
 	"gioui.org/f32"
 	"gioui.org/internal/opconst"
 	"gioui.org/io/event"
+	"gioui.org/io/key"
 	"gioui.org/op"
 )
 
@@ -40,6 +41,9 @@ type Event struct {
 	Position f32.Point
 	// Scroll is the scroll amount, if any.
 	Scroll f32.Point
+	// Modifiers is the set of active modifiers when
+	// the mouse button was pressed.
+	Modifiers key.Modifiers
 }
 
 // RectAreaOp updates the hit area to the intersection
-- 
2.23.0
View this thread in the archives