x11_clipboard_helper.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_BASE_X_X11_CLIPBOARD_HELPER_H_
  5. #define UI_BASE_X_X11_CLIPBOARD_HELPER_H_
  6. #include <cstdint>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/callback_forward.h"
  11. #include "base/component_export.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/ref_counted_memory.h"
  14. #include "base/memory/scoped_refptr.h"
  15. #include "ui/base/clipboard/clipboard_buffer.h"
  16. #include "ui/base/clipboard/clipboard_format_type.h"
  17. #include "ui/base/x/selection_owner.h"
  18. #include "ui/base/x/selection_utils.h"
  19. #include "ui/gfx/x/connection.h"
  20. #include "ui/gfx/x/xproto.h"
  21. namespace ui {
  22. class SelectionRequestor;
  23. // Helper class that provides core X11 clipboard integration code. Shared by
  24. // both legacy and Ozone X11 backends.
  25. //
  26. // TODO(crbug.com/789065): Merge into X11ClipboardOzone class once ozone
  27. // migration is complete and legacy backend gets removed.
  28. class COMPONENT_EXPORT(UI_BASE_X) XClipboardHelper : public x11::EventObserver {
  29. public:
  30. using SelectionChangeCallback =
  31. base::RepeatingCallback<void(ClipboardBuffer)>;
  32. explicit XClipboardHelper(SelectionChangeCallback selection_change_callback);
  33. XClipboardHelper(const XClipboardHelper&) = delete;
  34. XClipboardHelper& operator=(const XClipboardHelper&) = delete;
  35. ~XClipboardHelper() override;
  36. // As we need to collect all the data types before we tell X11 that we own a
  37. // particular selection, we create a temporary clipboard mapping that
  38. // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection,
  39. // where we save it in one of the clipboard data slots.
  40. void CreateNewClipboardData();
  41. // Inserts a mapping into clipboard_data_.
  42. void InsertMapping(const std::string& key,
  43. const scoped_refptr<base::RefCountedMemory>& memory);
  44. // Moves the temporary |clipboard_data_| to the long term data storage for
  45. // |buffer|.
  46. void TakeOwnershipOfSelection(ClipboardBuffer buffer);
  47. // Returns the first of |types| offered by the current selection holder, or
  48. // returns nullptr if none of those types are available. Blocks until the data
  49. // is fetched from the X server, unless we are the selection owner.
  50. SelectionData Read(ClipboardBuffer buffer,
  51. const std::vector<x11::Atom>& types);
  52. // Retrieves the list of possible data types the current clipboard owner has,
  53. // for a given |buffer|. Blocks until the data is fetched from the X server,
  54. // unless we are the selection owner.
  55. std::vector<std::string> GetAvailableTypes(ClipboardBuffer buffer);
  56. // Retrieves the list of target atom names currently available for reading in
  57. // the clipboard, for a given |buffer|. Blocks until the data is fetched from
  58. // the X server.
  59. std::vector<std::string> GetAvailableAtomNames(ClipboardBuffer buffer);
  60. // Tells if |format| is currently available for reading in clipboard |buffer|.
  61. // Blocks until the data is fetched from the X server.
  62. bool IsFormatAvailable(ClipboardBuffer buffer,
  63. const ClipboardFormatType& format);
  64. // Tells if we currently own the selection for a given clipboard |buffer|.
  65. bool IsSelectionOwner(ClipboardBuffer buffer) const;
  66. // Returns a list of all text atoms that we handle.
  67. std::vector<x11::Atom> GetTextAtoms() const;
  68. // Returns a vector with a |format| converted to an X11 atom.
  69. std::vector<x11::Atom> GetAtomsForFormat(const ClipboardFormatType& format);
  70. // Clears a certain clipboard buffer, whether we own it or not.
  71. void Clear(ClipboardBuffer buffer);
  72. // If we own the CLIPBOARD selection, requests the clipboard manager to take
  73. // ownership of it.
  74. void StoreCopyPasteDataAndWait();
  75. // Returns true if the event was handled.
  76. bool DispatchEvent(const x11::Event& xev);
  77. SelectionRequestor* GetSelectionRequestorForTest();
  78. private:
  79. class TargetList;
  80. // x11::EventObserver:
  81. void OnEvent(const x11::Event& xev) override;
  82. TargetList GetTargetList(ClipboardBuffer buffer);
  83. // Returns the X11 selection atom that we pass to various XSelection functions
  84. // for the given buffer.
  85. x11::Atom LookupSelectionForClipboardBuffer(ClipboardBuffer buffer) const;
  86. // Returns the X11 selection atom that we pass to various XSelection functions
  87. // for ClipboardBuffer::kCopyPaste.
  88. x11::Atom GetCopyPasteSelection() const;
  89. // Finds the SelectionFormatMap for the incoming selection atom.
  90. const SelectionFormatMap& LookupStorageForAtom(x11::Atom atom);
  91. // Our X11 state.
  92. const raw_ptr<x11::Connection> connection_;
  93. const x11::Window x_root_window_;
  94. // Input-only window used as a selection owner.
  95. x11::Window x_window_;
  96. // Events selected on |x_window_|.
  97. std::unique_ptr<x11::XScopedEventSelector> x_window_events_;
  98. // Object which requests and receives selection data.
  99. const std::unique_ptr<SelectionRequestor> selection_requestor_;
  100. // Temporary target map that we write to during DispatchObects.
  101. SelectionFormatMap clipboard_data_;
  102. // Objects which offer selection data to other windows.
  103. SelectionOwner clipboard_owner_;
  104. SelectionOwner primary_owner_;
  105. };
  106. } // namespace ui
  107. #endif // UI_BASE_X_X11_CLIPBOARD_HELPER_H_