clipboard.go raw
1 // SPDX-License-Identifier: Unlicense OR MIT
2
3 package router
4
5 import (
6 "github.com/p9c/p9/pkg/gel/gio/internal/opconst"
7 "github.com/p9c/p9/pkg/gel/gio/internal/ops"
8 "github.com/p9c/p9/pkg/gel/gio/io/event"
9 )
10
11 type clipboardQueue struct {
12 receivers map[event.Tag]struct{}
13 // request avoid read clipboard every frame while waiting.
14 requested bool
15 text *string
16 reader ops.Reader
17 }
18
19 // WriteClipboard returns the most recent text to be copied
20 // to the clipboard, if any.
21 func (q *clipboardQueue) WriteClipboard() (string, bool) {
22 if q.text == nil {
23 return "", false
24 }
25 text := *q.text
26 q.text = nil
27 return text, true
28 }
29
30 // ReadClipboard reports if any new handler is waiting
31 // to read the clipboard.
32 func (q *clipboardQueue) ReadClipboard() bool {
33 if len(q.receivers) <= 0 || q.requested {
34 return false
35 }
36 q.requested = true
37 return true
38 }
39
40 func (q *clipboardQueue) Push(e event.Event, events *handlerEvents) {
41 for r := range q.receivers {
42 events.Add(r, e)
43 delete(q.receivers, r)
44 }
45 }
46
47 func (q *clipboardQueue) ProcessWriteClipboard(d []byte, refs []interface{}) {
48 if opconst.OpType(d[0]) != opconst.TypeClipboardWrite {
49 panic("invalid op")
50 }
51 q.text = refs[0].(*string)
52 }
53
54 func (q *clipboardQueue) ProcessReadClipboard(d []byte, refs []interface{}) {
55 if opconst.OpType(d[0]) != opconst.TypeClipboardRead {
56 panic("invalid op")
57 }
58 if q.receivers == nil {
59 q.receivers = make(map[event.Tag]struct{})
60 }
61 tag := refs[0].(event.Tag)
62 if _, ok := q.receivers[tag]; !ok {
63 q.receivers[tag] = struct{}{}
64 q.requested = false
65 }
66 }
67