File indexing completed on 2024-05-19 05:32:50

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include <QList>
0012 #include <QObject>
0013 
0014 #include <xcb/xcb.h>
0015 
0016 struct xcb_xfixes_selection_notify_event_t;
0017 
0018 class QTimer;
0019 
0020 namespace KWin
0021 {
0022 namespace Xwl
0023 {
0024 class TransferWltoX;
0025 class TransferXtoWl;
0026 class WlSource;
0027 class X11Source;
0028 
0029 /**
0030  * Base class representing generic X selections and their respective
0031  * Wayland counter-parts.
0032  *
0033  * The class needs to be subclassed and adjusted according to the
0034  * selection, but provides common fucntionality to be expected of all
0035  * selections.
0036  *
0037  * A selection should exist through the whole runtime of an Xwayland
0038  * session.
0039  *
0040  * Independently of each other the class holds the currently active
0041  * source instance and active transfers relative to the represented
0042  * selection.
0043  */
0044 class Selection : public QObject
0045 {
0046     Q_OBJECT
0047 
0048 public:
0049     static xcb_atom_t mimeTypeToAtom(const QString &mimeType);
0050     static xcb_atom_t mimeTypeToAtomLiteral(const QString &mimeType);
0051     static QStringList atomToMimeTypes(xcb_atom_t atom);
0052     static QString atomName(xcb_atom_t atom);
0053     static void sendSelectionNotify(xcb_selection_request_event_t *event, bool success);
0054 
0055     // on selection owner changes by X clients (Xwl -> Wl)
0056     bool handleXfixesNotify(xcb_xfixes_selection_notify_event_t *event);
0057     bool filterEvent(xcb_generic_event_t *event);
0058 
0059     xcb_atom_t atom() const
0060     {
0061         return m_atom;
0062     }
0063     xcb_window_t window() const
0064     {
0065         return m_window;
0066     }
0067     void overwriteRequestorWindow(xcb_window_t window);
0068 
0069 Q_SIGNALS:
0070     void transferFinished(xcb_timestamp_t eventTime);
0071 
0072 protected:
0073     Selection(xcb_atom_t atom, QObject *parent);
0074     void registerXfixes();
0075 
0076     virtual void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) = 0;
0077     virtual void x11OfferLost() = 0;
0078     virtual void x11OffersChanged(const QStringList &added, const QStringList &removed) = 0;
0079 
0080     virtual bool handleClientMessage(xcb_client_message_event_t *event)
0081     {
0082         return false;
0083     }
0084     // sets the current provider of the selection
0085     void setWlSource(WlSource *source);
0086     WlSource *wlSource() const
0087     {
0088         return m_waylandSource;
0089     }
0090     void createX11Source(xcb_xfixes_selection_notify_event_t *event);
0091     X11Source *x11Source() const
0092     {
0093         return m_xSource;
0094     }
0095     // must be called in order to provide data from Wl to X
0096     void ownSelection(bool own);
0097     void setWindow(xcb_window_t window)
0098     {
0099         m_window = window;
0100     }
0101 
0102 private:
0103     bool handleSelectionRequest(xcb_selection_request_event_t *event);
0104     bool handleSelectionNotify(xcb_selection_notify_event_t *event);
0105     bool handlePropertyNotify(xcb_property_notify_event_t *event);
0106 
0107     void startTransferToWayland(xcb_atom_t target, qint32 fd);
0108     void startTransferToX(xcb_selection_request_event_t *event, qint32 fd);
0109 
0110     // Timeout transfers, which have become inactive due to client errors.
0111     void timeoutTransfers();
0112     void startTimeoutTransfersTimer();
0113     void endTimeoutTransfersTimer();
0114 
0115     xcb_atom_t m_atom = XCB_ATOM_NONE;
0116     xcb_window_t m_window = XCB_WINDOW_NONE;
0117     xcb_window_t m_requestorWindow = XCB_WINDOW_NONE;
0118     xcb_timestamp_t m_timestamp;
0119 
0120     // Active source, if any. Only one of them at max can exist
0121     // at the same time.
0122     WlSource *m_waylandSource = nullptr;
0123     X11Source *m_xSource = nullptr;
0124 
0125     // active transfers
0126     QList<TransferWltoX *> m_wlToXTransfers;
0127     QList<TransferXtoWl *> m_xToWlTransfers;
0128     QTimer *m_timeoutTransfers = nullptr;
0129 
0130     bool m_disownPending = false;
0131 
0132     Q_DISABLE_COPY(Selection)
0133 };
0134 
0135 } // namespace Xwl
0136 } // namespace KWin