blob: 98f5b6e98259d997359f49ea60b43dbc184f1206 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_X_X11_CLIPBOARD_HELPER_H_
#define UI_BASE_X_X11_CLIPBOARD_HELPER_H_
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/component_export.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include "ui/base/x/selection_owner.h"
#include "ui/base/x/selection_utils.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xproto.h"
namespace ui {
class SelectionRequestor;
// Helper class that provides core X11 clipboard integration code. Shared by
// both legacy and Ozone X11 backends.
//
// TODO(crbug.com/789065): Merge into X11ClipboardOzone class once ozone
// migration is complete and legacy backend gets removed.
class COMPONENT_EXPORT(UI_BASE_X) XClipboardHelper : public x11::EventObserver {
public:
using SelectionChangeCallback =
base::RepeatingCallback<void(ClipboardBuffer)>;
explicit XClipboardHelper(SelectionChangeCallback selection_change_callback);
XClipboardHelper(const XClipboardHelper&) = delete;
XClipboardHelper& operator=(const XClipboardHelper&) = delete;
~XClipboardHelper() override;
// As we need to collect all the data types before we tell X11 that we own a
// particular selection, we create a temporary clipboard mapping that
// InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection,
// where we save it in one of the clipboard data slots.
void CreateNewClipboardData();
// Inserts a mapping into clipboard_data_.
void InsertMapping(const std::string& key,
const scoped_refptr<base::RefCountedMemory>& memory);
// Moves the temporary |clipboard_data_| to the long term data storage for
// |buffer|.
void TakeOwnershipOfSelection(ClipboardBuffer buffer);
// Returns the first of |types| offered by the current selection holder, or
// returns nullptr if none of those types are available. Blocks until the data
// is fetched from the X server, unless we are the selection owner.
SelectionData Read(ClipboardBuffer buffer,
const std::vector<x11::Atom>& types);
// Retrieves the list of possible data types the current clipboard owner has,
// for a given |buffer|. Blocks until the data is fetched from the X server,
// unless we are the selection owner.
std::vector<std::string> GetAvailableTypes(ClipboardBuffer buffer);
// Retrieves the list of target atom names currently available for reading in
// the clipboard, for a given |buffer|. Blocks until the data is fetched from
// the X server.
std::vector<std::string> GetAvailableAtomNames(ClipboardBuffer buffer);
// Tells if |format| is currently available for reading in clipboard |buffer|.
// Blocks until the data is fetched from the X server.
bool IsFormatAvailable(ClipboardBuffer buffer,
const ClipboardFormatType& format);
// Tells if we currently own the selection for a given clipboard |buffer|.
bool IsSelectionOwner(ClipboardBuffer buffer) const;
// Returns a list of all text atoms that we handle.
std::vector<x11::Atom> GetTextAtoms() const;
// Returns a vector with a |format| converted to an X11 atom.
std::vector<x11::Atom> GetAtomsForFormat(const ClipboardFormatType& format);
// Clears a certain clipboard buffer, whether we own it or not.
void Clear(ClipboardBuffer buffer);
// If we own the CLIPBOARD selection, requests the clipboard manager to take
// ownership of it.
void StoreCopyPasteDataAndWait();
// Returns true if the event was handled.
bool DispatchEvent(const x11::Event& xev);
SelectionRequestor* GetSelectionRequestorForTest();
private:
class TargetList;
// x11::EventObserver:
void OnEvent(const x11::Event& xev) override;
TargetList GetTargetList(ClipboardBuffer buffer);
// Returns the X11 selection atom that we pass to various XSelection functions
// for the given buffer.
x11::Atom LookupSelectionForClipboardBuffer(ClipboardBuffer buffer) const;
// Returns the X11 selection atom that we pass to various XSelection functions
// for ClipboardBuffer::kCopyPaste.
x11::Atom GetCopyPasteSelection() const;
// Finds the SelectionFormatMap for the incoming selection atom.
const SelectionFormatMap& LookupStorageForAtom(x11::Atom atom);
// Our X11 state.
x11::Connection* const connection_;
const x11::Window x_root_window_;
// Input-only window used as a selection owner.
x11::Window x_window_;
// Events selected on |x_window_|.
std::unique_ptr<x11::XScopedEventSelector> x_window_events_;
// Object which requests and receives selection data.
const std::unique_ptr<SelectionRequestor> selection_requestor_;
// Temporary target map that we write to during DispatchObects.
SelectionFormatMap clipboard_data_;
// Objects which offer selection data to other windows.
SelectionOwner clipboard_owner_;
SelectionOwner primary_owner_;
};
} // namespace ui
#endif // UI_BASE_X_X11_CLIPBOARD_HELPER_H_