forked from joejulian/gio
io/input,io/pointer: [API] make pointer grab a command
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+23
-25
@@ -63,10 +63,9 @@ type pointerInfo struct {
|
||||
}
|
||||
|
||||
type pointerHandler struct {
|
||||
area int
|
||||
active bool
|
||||
wantsGrab bool
|
||||
types pointer.Kind
|
||||
area int
|
||||
active bool
|
||||
types pointer.Kind
|
||||
// min and max horizontal/vertical scroll
|
||||
scrollRange image.Rectangle
|
||||
|
||||
@@ -269,6 +268,26 @@ func (c *pointerCollector) actionInputOp(act system.Action) {
|
||||
area.action = act
|
||||
}
|
||||
|
||||
func (q *pointerQueue) grab(req pointer.GrabCmd, events *handlerEvents) {
|
||||
for _, p := range q.pointers {
|
||||
if !p.pressed || p.id != req.ID {
|
||||
continue
|
||||
}
|
||||
for i, k2 := range p.handlers {
|
||||
if k2 == req.Tag {
|
||||
// Drop other handlers that lost their grab.
|
||||
dropped := q.scratch[:0]
|
||||
dropped = append(dropped, p.handlers[:i]...)
|
||||
dropped = append(dropped, p.handlers[i+1:]...)
|
||||
for _, tag := range dropped {
|
||||
q.dropHandler(events, tag)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *pointerCollector) inputOp(op pointer.InputOp, events *handlerEvents) {
|
||||
areaID := c.currentArea()
|
||||
area := &c.q.areas[areaID]
|
||||
@@ -281,7 +300,6 @@ func (c *pointerCollector) inputOp(op pointer.InputOp, events *handlerEvents) {
|
||||
}
|
||||
area.semantic.valid = area.semantic.content.gestures != 0
|
||||
h := c.newHandler(op.Tag, events)
|
||||
h.wantsGrab = h.wantsGrab || op.Grab
|
||||
h.types = h.types | op.Kinds
|
||||
h.scrollRange = op.ScrollBounds
|
||||
}
|
||||
@@ -560,7 +578,6 @@ func (q *pointerQueue) reset() {
|
||||
// Reset handler.
|
||||
h.active = false
|
||||
h.area = -1
|
||||
h.wantsGrab = false
|
||||
h.types = 0
|
||||
h.sourceMimes = h.sourceMimes[:0]
|
||||
h.targetMimes = h.targetMimes[:0]
|
||||
@@ -596,25 +613,6 @@ func (q *pointerQueue) Frame(events *handlerEvents) {
|
||||
q.dropHandler(nil, k)
|
||||
delete(q.handlers, k)
|
||||
}
|
||||
if h.wantsGrab {
|
||||
for _, p := range q.pointers {
|
||||
if !p.pressed {
|
||||
continue
|
||||
}
|
||||
for i, k2 := range p.handlers {
|
||||
if k2 == k {
|
||||
// Drop other handlers that lost their grab.
|
||||
dropped := q.scratch[:0]
|
||||
dropped = append(dropped, p.handlers[:i]...)
|
||||
dropped = append(dropped, p.handlers[i+1:]...)
|
||||
for _, tag := range dropped {
|
||||
q.dropHandler(events, tag)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range q.pointers {
|
||||
p := &q.pointers[i]
|
||||
|
||||
@@ -86,7 +86,7 @@ func TestPointerGrab(t *testing.T) {
|
||||
|
||||
types := pointer.Press | pointer.Release
|
||||
|
||||
pointer.InputOp{Tag: handler1, Kinds: types, Grab: true}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler1, Kinds: types}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler2, Kinds: types}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler3, Kinds: types}.Add(&ops)
|
||||
|
||||
@@ -98,6 +98,7 @@ func TestPointerGrab(t *testing.T) {
|
||||
Position: f32.Pt(50, 50),
|
||||
},
|
||||
)
|
||||
r.Source().Queue(pointer.GrabCmd{Tag: handler1})
|
||||
assertEventPointerTypeSequence(t, r.Events(handler1), pointer.Cancel, pointer.Press)
|
||||
assertEventPointerTypeSequence(t, r.Events(handler2), pointer.Cancel, pointer.Press)
|
||||
assertEventPointerTypeSequence(t, r.Events(handler3), pointer.Cancel, pointer.Press)
|
||||
@@ -120,7 +121,7 @@ func TestPointerGrabSameHandlerTwice(t *testing.T) {
|
||||
|
||||
types := pointer.Press | pointer.Release
|
||||
|
||||
pointer.InputOp{Tag: handler1, Kinds: types, Grab: true}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler1, Kinds: types}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler1, Kinds: types}.Add(&ops)
|
||||
pointer.InputOp{Tag: handler2, Kinds: types}.Add(&ops)
|
||||
|
||||
@@ -132,6 +133,7 @@ func TestPointerGrabSameHandlerTwice(t *testing.T) {
|
||||
Position: f32.Pt(50, 50),
|
||||
},
|
||||
)
|
||||
r.Source().Queue(pointer.GrabCmd{Tag: handler1})
|
||||
assertEventPointerTypeSequence(t, r.Events(handler1), pointer.Cancel, pointer.Press)
|
||||
assertEventPointerTypeSequence(t, r.Events(handler2), pointer.Cancel, pointer.Press)
|
||||
r.Frame(&ops)
|
||||
|
||||
+7
-6
@@ -226,6 +226,8 @@ func (q *Router) executeCommands() {
|
||||
q.cqueue.ProcessWriteClipboard(req)
|
||||
case clipboard.ReadCmd:
|
||||
q.cqueue.ProcessReadClipboard(req.Tag)
|
||||
case pointer.GrabCmd:
|
||||
q.pointer.queue.grab(req, &q.handlers)
|
||||
}
|
||||
}
|
||||
q.commands = nil
|
||||
@@ -470,16 +472,15 @@ func (q *Router) collect() {
|
||||
case ops.TypePointerInput:
|
||||
op := pointer.InputOp{
|
||||
Tag: encOp.Refs[0].(event.Tag),
|
||||
Grab: encOp.Data[1] != 0,
|
||||
Kinds: pointer.Kind(bo.Uint16(encOp.Data[2:])),
|
||||
Kinds: pointer.Kind(bo.Uint16(encOp.Data[1:])),
|
||||
ScrollBounds: image.Rectangle{
|
||||
Min: image.Point{
|
||||
X: int(int32(bo.Uint32(encOp.Data[4:]))),
|
||||
Y: int(int32(bo.Uint32(encOp.Data[8:]))),
|
||||
X: int(int32(bo.Uint32(encOp.Data[3:]))),
|
||||
Y: int(int32(bo.Uint32(encOp.Data[7:]))),
|
||||
},
|
||||
Max: image.Point{
|
||||
X: int(int32(bo.Uint32(encOp.Data[12:]))),
|
||||
Y: int(int32(bo.Uint32(encOp.Data[16:]))),
|
||||
X: int(int32(bo.Uint32(encOp.Data[11:]))),
|
||||
Y: int(int32(bo.Uint32(encOp.Data[15:]))),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
+13
-11
@@ -60,9 +60,6 @@ type PassStack struct {
|
||||
// events.
|
||||
type InputOp struct {
|
||||
Tag event.Tag
|
||||
// Grab, if set, request that the handler get
|
||||
// Grabbed priority.
|
||||
Grab bool
|
||||
// Kinds is a bitwise-or of event types to receive.
|
||||
Kinds Kind
|
||||
// ScrollBounds describe the maximum scrollable distances in both
|
||||
@@ -73,6 +70,12 @@ type InputOp struct {
|
||||
ScrollBounds image.Rectangle
|
||||
}
|
||||
|
||||
// GrabCmd requests a pointer grab on the pointer identified by ID.
|
||||
type GrabCmd struct {
|
||||
Tag event.Tag
|
||||
ID ID
|
||||
}
|
||||
|
||||
type ID uint16
|
||||
|
||||
// Kind of an Event.
|
||||
@@ -250,15 +253,12 @@ func (op InputOp) Add(o *op.Ops) {
|
||||
}
|
||||
data := ops.Write1(&o.Internal, ops.TypePointerInputLen, op.Tag)
|
||||
data[0] = byte(ops.TypePointerInput)
|
||||
if op.Grab {
|
||||
data[1] = 1
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
bo.PutUint16(data[2:], uint16(op.Kinds))
|
||||
bo.PutUint32(data[4:], uint32(op.ScrollBounds.Min.X))
|
||||
bo.PutUint32(data[8:], uint32(op.ScrollBounds.Min.Y))
|
||||
bo.PutUint32(data[12:], uint32(op.ScrollBounds.Max.X))
|
||||
bo.PutUint32(data[16:], uint32(op.ScrollBounds.Max.Y))
|
||||
bo.PutUint16(data[1:], uint16(op.Kinds))
|
||||
bo.PutUint32(data[3:], uint32(op.ScrollBounds.Min.X))
|
||||
bo.PutUint32(data[7:], uint32(op.ScrollBounds.Min.Y))
|
||||
bo.PutUint32(data[11:], uint32(op.ScrollBounds.Max.X))
|
||||
bo.PutUint32(data[15:], uint32(op.ScrollBounds.Max.Y))
|
||||
}
|
||||
|
||||
func (t Kind) String() string {
|
||||
@@ -404,3 +404,5 @@ func (c Cursor) String() string {
|
||||
}
|
||||
|
||||
func (Event) ImplementsEvent() {}
|
||||
|
||||
func (GrabCmd) ImplementsCommand() {}
|
||||
|
||||
Reference in New Issue
Block a user