diff --git a/app/internal/window/gl_macos.m b/app/internal/window/gl_macos.m index fdadae2b..2f477ff7 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 018bf642..dc8ab558 100644 --- a/app/internal/window/os_macos.go +++ b/app/internal/window/os_macos.go @@ -118,24 +118,14 @@ func gio_onFrameCallback(view C.CFTypeRef) { //export gio_onKeys func gio_onKeys(view C.CFTypeRef, cstr *C.char, ti C.double, mods C.NSUInteger) { str := C.GoString(cstr) - 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 - } 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.Event{Name: n, Modifiers: kmods}) + w.w.Event(key.Event{ + Name: n, + Modifiers: convertMods(mods), + }) } } }) @@ -151,7 +141,7 @@ 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 typ pointer.Type switch cdir { case C.GIO_MOUSE_MOVE: @@ -179,12 +169,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: convertMods(mods), }) }) } @@ -366,3 +357,20 @@ func convertKey(k rune) (string, bool) { } return n, true } + +func convertMods(mods C.NSUInteger) key.Modifiers { + 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 + } + return kmods +} diff --git a/gesture/gesture.go b/gesture/gesture.go index 6d264567..2714890a 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 7aeda81d..4f7d07f9 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 } // AreaOp updates the hit area to the intersection of the current