mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
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 <mail@eliasnaur.com>
This commit is contained in:
+14
-14
@@ -242,8 +242,9 @@ type window struct {
|
|||||||
displayLink *displayLink
|
displayLink *displayLink
|
||||||
// redraw is a single entry channel for making sure only one
|
// redraw is a single entry channel for making sure only one
|
||||||
// display link redraw request is in flight.
|
// display link redraw request is in flight.
|
||||||
redraw chan struct{}
|
redraw chan struct{}
|
||||||
cursor pointer.Cursor
|
cursor pointer.Cursor
|
||||||
|
pointerBtns pointer.Buttons
|
||||||
|
|
||||||
scale float32
|
scale float32
|
||||||
config Config
|
config Config
|
||||||
@@ -502,20 +503,29 @@ func gio_onText(view, cstr C.CFTypeRef) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onMouse
|
//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)
|
w := mustView(view)
|
||||||
t := time.Duration(float64(ti)*float64(time.Second) + .5)
|
t := time.Duration(float64(ti)*float64(time.Second) + .5)
|
||||||
xf, yf := float32(x)*w.scale, float32(y)*w.scale
|
xf, yf := float32(x)*w.scale, float32(y)*w.scale
|
||||||
dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale
|
dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale
|
||||||
pos := f32.Point{X: xf, Y: yf}
|
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
|
var typ pointer.Type
|
||||||
switch cdir {
|
switch cdir {
|
||||||
case C.MOUSE_MOVE:
|
case C.MOUSE_MOVE:
|
||||||
typ = pointer.Move
|
typ = pointer.Move
|
||||||
case C.MOUSE_UP:
|
case C.MOUSE_UP:
|
||||||
typ = pointer.Release
|
typ = pointer.Release
|
||||||
|
w.pointerBtns &^= btn
|
||||||
case C.MOUSE_DOWN:
|
case C.MOUSE_DOWN:
|
||||||
typ = pointer.Press
|
typ = pointer.Press
|
||||||
|
w.pointerBtns |= btn
|
||||||
act, ok := w.w.ActionAt(pos)
|
act, ok := w.w.ActionAt(pos)
|
||||||
if ok && w.config.Mode != Fullscreen {
|
if ok && w.config.Mode != Fullscreen {
|
||||||
switch act {
|
switch act {
|
||||||
@@ -529,21 +539,11 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx
|
|||||||
default:
|
default:
|
||||||
panic("invalid direction")
|
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{
|
w.w.Event(pointer.Event{
|
||||||
Type: typ,
|
Type: typ,
|
||||||
Source: pointer.Mouse,
|
Source: pointer.Mouse,
|
||||||
Time: t,
|
Time: t,
|
||||||
Buttons: btns,
|
Buttons: w.pointerBtns,
|
||||||
Position: pos,
|
Position: pos,
|
||||||
Scroll: f32.Point{X: dxf, Y: dyf},
|
Scroll: f32.Point{X: dxf, Y: dyf},
|
||||||
Modifiers: convertMods(mods),
|
Modifiers: convertMods(mods),
|
||||||
|
|||||||
+1
-1
@@ -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.
|
// Origin is in the lower left corner. Convert to upper left.
|
||||||
CGFloat height = view.bounds.size.height;
|
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 <CALayerDelegate,NSTextInputClient>
|
@interface GioView : NSView <CALayerDelegate,NSTextInputClient>
|
||||||
|
|||||||
Reference in New Issue
Block a user