From 0f51cb9084c2cddbd3e1165e2d5cc82fb4f884a5 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 26 Jul 2022 11:47:05 +0200 Subject: [PATCH] app: [macOS] don't miss pointer presses We used to track the pressed pointer buttons through the global function [NSEvent pressedMouseButtons]. However, it's possible that at the time a pointer press event is delivered, the pointer button is up again. To ensure a consistent view of the pointer press state, track it through the buttonNumber property on delivered events. Signed-off-by: Elias Naur --- app/os_macos.go | 28 ++++++++++++++-------------- app/os_macos.m | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/os_macos.go b/app/os_macos.go index 909bd9c1..4f43f7e1 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -242,8 +242,9 @@ type window struct { displayLink *displayLink // redraw is a single entry channel for making sure only one // display link redraw request is in flight. - redraw chan struct{} - cursor pointer.Cursor + redraw chan struct{} + cursor pointer.Cursor + pointerBtns pointer.Buttons scale float32 config Config @@ -502,20 +503,29 @@ func gio_onText(view, cstr C.CFTypeRef) { } //export gio_onMouse -func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) { +func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) { w := mustView(view) t := time.Duration(float64(ti)*float64(time.Second) + .5) xf, yf := float32(x)*w.scale, float32(y)*w.scale dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale pos := f32.Point{X: xf, Y: yf} + var btn pointer.Buttons + switch cbtn { + case 0: + btn = pointer.ButtonPrimary + case 1: + btn = pointer.ButtonSecondary + } var typ pointer.Type switch cdir { case C.MOUSE_MOVE: typ = pointer.Move case C.MOUSE_UP: typ = pointer.Release + w.pointerBtns &^= btn case C.MOUSE_DOWN: typ = pointer.Press + w.pointerBtns |= btn act, ok := w.w.ActionAt(pos) if ok && w.config.Mode != Fullscreen { switch act { @@ -529,21 +539,11 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx default: panic("invalid direction") } - var btns pointer.Buttons - if cbtns&(1<<0) != 0 { - btns |= pointer.ButtonPrimary - } - if cbtns&(1<<1) != 0 { - btns |= pointer.ButtonSecondary - } - if cbtns&(1<<2) != 0 { - btns |= pointer.ButtonTertiary - } w.w.Event(pointer.Event{ Type: typ, Source: pointer.Mouse, Time: t, - Buttons: btns, + Buttons: w.pointerBtns, Position: pos, Scroll: f32.Point{X: dxf, Y: dyf}, Modifiers: convertMods(mods), diff --git a/app/os_macos.m b/app/os_macos.m index 3eb8127d..b94a568d 100644 --- a/app/os_macos.m +++ b/app/os_macos.m @@ -61,7 +61,7 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo } // Origin is in the lower left corner. Convert to upper left. CGFloat height = view.bounds.size.height; - gio_onMouse((__bridge CFTypeRef)view, (__bridge CFTypeRef)event, typ, [NSEvent pressedMouseButtons], p.x, height - p.y, dx, dy, [event timestamp], [event modifierFlags]); + gio_onMouse((__bridge CFTypeRef)view, (__bridge CFTypeRef)event, typ, event.buttonNumber, p.x, height - p.y, dx, dy, [event timestamp], [event modifierFlags]); } @interface GioView : NSView