clipboard.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package input
  3. import (
  4. "io"
  5. "gioui.org/io/clipboard"
  6. "gioui.org/io/event"
  7. )
  8. // clipboardState contains the state for clipboard event routing.
  9. type clipboardState struct {
  10. receivers []event.Tag
  11. }
  12. type clipboardQueue struct {
  13. // request avoid read clipboard every frame while waiting.
  14. requested bool
  15. mime string
  16. text []byte
  17. }
  18. // WriteClipboard returns the most recent data to be copied
  19. // to the clipboard, if any.
  20. func (q *clipboardQueue) WriteClipboard() (mime string, content []byte, ok bool) {
  21. if q.text == nil {
  22. return "", nil, false
  23. }
  24. content = q.text
  25. q.text = nil
  26. return q.mime, content, true
  27. }
  28. // ClipboardRequested reports if any new handler is waiting
  29. // to read the clipboard.
  30. func (q *clipboardQueue) ClipboardRequested(state clipboardState) bool {
  31. req := len(state.receivers) > 0 && q.requested
  32. q.requested = false
  33. return req
  34. }
  35. func (q *clipboardQueue) Push(state clipboardState, e event.Event) (clipboardState, []taggedEvent) {
  36. var evts []taggedEvent
  37. for _, r := range state.receivers {
  38. evts = append(evts, taggedEvent{tag: r, event: e})
  39. }
  40. state.receivers = nil
  41. return state, evts
  42. }
  43. func (q *clipboardQueue) ProcessWriteClipboard(req clipboard.WriteCmd) {
  44. defer req.Data.Close()
  45. content, err := io.ReadAll(req.Data)
  46. if err != nil {
  47. return
  48. }
  49. q.mime = req.Type
  50. q.text = content
  51. }
  52. func (q *clipboardQueue) ProcessReadClipboard(state clipboardState, tag event.Tag) clipboardState {
  53. for _, k := range state.receivers {
  54. if k == tag {
  55. return state
  56. }
  57. }
  58. n := len(state.receivers)
  59. state.receivers = append(state.receivers[:n:n], tag)
  60. q.requested = true
  61. return state
  62. }