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