2020-08-02 22:22:19 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
2018-08-21 20:06:42 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
|
2018-08-21 20:06:42 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2018-08-21 20:06:42 +00:00
|
|
|
#ifndef KWIN_XWL_SELECTION
|
|
|
|
#define KWIN_XWL_SELECTION
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QVector>
|
|
|
|
|
|
|
|
#include <xcb/xcb.h>
|
|
|
|
|
|
|
|
struct xcb_xfixes_selection_notify_event_t;
|
|
|
|
|
|
|
|
class QTimer;
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
namespace Xwl
|
|
|
|
{
|
|
|
|
class TransferWltoX;
|
|
|
|
class TransferXtoWl;
|
|
|
|
class WlSource;
|
|
|
|
class X11Source;
|
|
|
|
|
2019-07-02 19:56:03 +00:00
|
|
|
/**
|
2018-08-21 20:06:42 +00:00
|
|
|
* Base class representing generic X selections and their respective
|
|
|
|
* Wayland counter-parts.
|
|
|
|
*
|
|
|
|
* The class needs to be subclassed and adjusted according to the
|
|
|
|
* selection, but provides common fucntionality to be expected of all
|
|
|
|
* selections.
|
|
|
|
*
|
|
|
|
* A selection should exist through the whole runtime of an Xwayland
|
|
|
|
* session.
|
|
|
|
*
|
|
|
|
* Independently of each other the class holds the currently active
|
|
|
|
* source instance and active transfers relative to the represented
|
|
|
|
* selection.
|
2019-07-29 18:58:33 +00:00
|
|
|
*/
|
2018-08-21 20:06:42 +00:00
|
|
|
class Selection : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2019-07-02 19:56:03 +00:00
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
public:
|
|
|
|
static xcb_atom_t mimeTypeToAtom(const QString &mimeType);
|
|
|
|
static xcb_atom_t mimeTypeToAtomLiteral(const QString &mimeType);
|
|
|
|
static QStringList atomToMimeTypes(xcb_atom_t atom);
|
2018-08-24 21:05:35 +00:00
|
|
|
static QString atomName(xcb_atom_t atom);
|
2019-07-02 19:56:03 +00:00
|
|
|
static void sendSelectionNotify(xcb_selection_request_event_t *event, bool success);
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
// on selection owner changes by X clients (Xwl -> Wl)
|
|
|
|
bool handleXfixesNotify(xcb_xfixes_selection_notify_event_t *event);
|
|
|
|
bool filterEvent(xcb_generic_event_t *event);
|
|
|
|
|
|
|
|
xcb_atom_t atom() const {
|
|
|
|
return m_atom;
|
|
|
|
}
|
|
|
|
xcb_window_t window() const {
|
|
|
|
return m_window;
|
|
|
|
}
|
2018-08-22 12:56:48 +00:00
|
|
|
void overwriteRequestorWindow(xcb_window_t window);
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void transferFinished(xcb_timestamp_t eventTime);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Selection(xcb_atom_t atom, QObject *parent);
|
|
|
|
void registerXfixes();
|
|
|
|
|
|
|
|
virtual void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) = 0;
|
2019-07-02 19:56:03 +00:00
|
|
|
virtual void x11OffersChanged(const QStringList &added, const QStringList &removed) = 0;
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
virtual bool handleClientMessage(xcb_client_message_event_t *event) {
|
|
|
|
Q_UNUSED(event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// sets the current provider of the selection
|
2019-07-02 19:56:03 +00:00
|
|
|
void setWlSource(WlSource *source);
|
|
|
|
WlSource *wlSource() const {
|
|
|
|
return m_waylandSource;
|
2018-08-21 20:06:42 +00:00
|
|
|
}
|
|
|
|
void createX11Source(xcb_xfixes_selection_notify_event_t *event);
|
2019-07-02 19:56:03 +00:00
|
|
|
X11Source *x11Source() const {
|
|
|
|
return m_xSource;
|
2018-08-21 20:06:42 +00:00
|
|
|
}
|
|
|
|
// must be called in order to provide data from Wl to X
|
|
|
|
void ownSelection(bool own);
|
|
|
|
void setWindow(xcb_window_t window) {
|
|
|
|
m_window = window;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2019-07-02 19:56:03 +00:00
|
|
|
bool handleSelectionRequest(xcb_selection_request_event_t *event);
|
|
|
|
bool handleSelectionNotify(xcb_selection_notify_event_t *event);
|
|
|
|
bool handlePropertyNotify(xcb_property_notify_event_t *event);
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
void startTransferToWayland(xcb_atom_t target, qint32 fd);
|
|
|
|
void startTransferToX(xcb_selection_request_event_t *event, qint32 fd);
|
|
|
|
|
|
|
|
// Timeout transfers, which have become inactive due to client errors.
|
|
|
|
void timeoutTransfers();
|
|
|
|
void startTimeoutTransfersTimer();
|
|
|
|
void endTimeoutTransfersTimer();
|
|
|
|
|
|
|
|
xcb_atom_t m_atom = XCB_ATOM_NONE;
|
|
|
|
xcb_window_t m_window = XCB_WINDOW_NONE;
|
2018-08-22 12:56:48 +00:00
|
|
|
xcb_window_t m_requestorWindow = XCB_WINDOW_NONE;
|
2018-08-21 20:06:42 +00:00
|
|
|
xcb_timestamp_t m_timestamp;
|
|
|
|
|
|
|
|
// Active source, if any. Only one of them at max can exist
|
|
|
|
// at the same time.
|
2019-07-02 19:56:03 +00:00
|
|
|
WlSource *m_waylandSource = nullptr;
|
|
|
|
X11Source *m_xSource = nullptr;
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
// active transfers
|
2019-07-02 19:56:03 +00:00
|
|
|
QVector<TransferWltoX *> m_wlToXTransfers;
|
|
|
|
QVector<TransferXtoWl *> m_xToWlTransfers;
|
2018-08-21 20:06:42 +00:00
|
|
|
QTimer *m_timeoutTransfers = nullptr;
|
|
|
|
|
|
|
|
bool m_disownPending = false;
|
2019-07-02 19:56:03 +00:00
|
|
|
|
|
|
|
Q_DISABLE_COPY(Selection)
|
2018-08-21 20:06:42 +00:00
|
|
|
};
|
|
|
|
|
2019-07-02 19:56:03 +00:00
|
|
|
} // namespace Xwl
|
|
|
|
} // namespace KWin
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
#endif
|