File indexing completed on 2024-04-21 03:59:21

0001 /*
0002     SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #ifndef KSELECTIONOWNER_H
0008 #define KSELECTIONOWNER_H
0009 
0010 #include <QObject>
0011 #include <kwindowsystem_export.h>
0012 
0013 #include <xcb/xcb.h>
0014 #include <xcb/xproto.h>
0015 
0016 /**
0017  This class implements claiming and owning manager selections, as described
0018  in the ICCCM, section 2.8. The selection atom is passed to the constructor,
0019  claim() attempts to claim ownership of the selection, release() gives up
0020  the selection ownership. Signal lostOwnership() is emitted when the selection
0021  is claimed by another owner.
0022  @short ICCCM manager selection owner
0023 
0024  This class is only useful on the xcb platform. On other platforms the code is only
0025  functional if the constructor overloads taking an xcb_connection_t are used. In case
0026  you inherit from this class ensure that you don't use xcb and/or XLib without verifying
0027  the platform.
0028 */
0029 class KWINDOWSYSTEM_EXPORT KSelectionOwner : public QObject
0030 {
0031     Q_OBJECT
0032 public:
0033     /**
0034      * This constructor initializes the object, but doesn't perform any
0035      * operation on the selection.
0036      *
0037      * @param selection atom representing the manager selection
0038      * @param screen X screen, or -1 for default
0039      * @param parent parent object, or nullptr if there is none
0040      */
0041     explicit KSelectionOwner(xcb_atom_t selection, int screen = -1, QObject *parent = nullptr);
0042 
0043     /**
0044      * @overload
0045      * This constructor accepts the selection name and creates the appropriate atom
0046      * for it automatically.
0047      *
0048      * @param selection name of the manager selection
0049      * @param screen X screen, or -1 for default
0050      * @param parent parent object, or nullptr if there is none
0051      */
0052     explicit KSelectionOwner(const char *selection, int screen = -1, QObject *parent = nullptr);
0053     /**
0054      * @overload
0055      * This constructor accepts the xcb_connection_t and root window and doesn't depend on
0056      * running on the xcb platform. Otherwise this constructor behaves like the similar one
0057      * without the xcb_connection_t.
0058      *
0059      * @param selection atom representing the manager selection
0060      * @param c the xcb connection this KSelectionWatcher should use
0061      * @param root the root window this KSelectionWatcher should use
0062      * @param parent parent object, or nullptr if there is none
0063      * @since 5.8
0064      **/
0065     explicit KSelectionOwner(xcb_atom_t selection, xcb_connection_t *c, xcb_window_t root, QObject *parent = nullptr);
0066 
0067     /**
0068      * @overload
0069      * This constructor accepts the xcb_connection_t and root window and doesn't depend on
0070      * running on the xcb platform. Otherwise this constructor behaves like the similar one
0071      * without the xcb_connection_t.
0072      *
0073      * @param selection name of the manager selection
0074      * @param c the xcb connection this KSelectionWatcher should use
0075      * @param root the root window this KSelectionWatcher should use
0076      * @param parent parent object, or nullptr if there is none
0077      * @since 5.8
0078      **/
0079     explicit KSelectionOwner(const char *selection, xcb_connection_t *c, xcb_window_t root, QObject *parent = nullptr);
0080 
0081     /**
0082      * Destructor. Calls release().
0083      */
0084     ~KSelectionOwner() override;
0085 
0086     /**
0087      * Try to claim ownership of the manager selection using the current X timestamp.
0088      *
0089      * This function returns immediately, but it may take up to one second for the claim
0090      * to succeed or fail, at which point either the claimedOwnership() or
0091      * failedToClaimOwnership() signal is emitted. The claim will not be completed until
0092      * the caller has returned to the event loop.
0093      *
0094      * If @p force is false, and the selection is already owned, the selection is not claimed,
0095      * and failedToClaimOwnership() is emitted. If @p force is true and the selection is
0096      * owned by another client, the client will be given one second to relinquish ownership
0097      * of the selection. If @p force_kill is true, and the previous owner fails to disown
0098      * the selection in time, it will be forcibly killed.
0099      */
0100     void claim(bool force, bool force_kill = true);
0101 
0102     /**
0103      * If the selection is owned, the ownership is given up.
0104      */
0105     void release();
0106 
0107     /**
0108      * If the selection is owned, returns the window used internally
0109      * for owning the selection.
0110      */
0111     xcb_window_t ownerWindow() const; // None if not owning the selection
0112 
0113     /**
0114      * @internal
0115      */
0116     bool filterEvent(void *ev_P); // internal
0117 
0118     /**
0119      * @internal
0120      */
0121     void timerEvent(QTimerEvent *event) override;
0122 
0123 Q_SIGNALS:
0124     /**
0125      * This signal is emitted if the selection was owned and the ownership
0126      * has been lost due to another client claiming it, this signal is emitted.
0127      * IMPORTANT: It's not safe to delete the instance in a slot connected
0128      * to this signal.
0129      */
0130     void lostOwnership();
0131 
0132     /**
0133      * This signal is emitted when claim() was successful in claiming
0134      * ownership of the selection.
0135      */
0136     void claimedOwnership();
0137 
0138     /**
0139      * This signal is emitted when claim() failed to claim ownership
0140      * of the selection.
0141      */
0142     void failedToClaimOwnership();
0143 
0144 protected:
0145     /**
0146      * Called for every X event received on the window used for owning
0147      * the selection. If true is returned, the event is filtered out.
0148      */
0149     // virtual bool handleMessage( XEvent* ev ); // removed for KF5, please shout if you need this
0150     /**
0151      * Called when a SelectionRequest event is received. A reply should
0152      * be sent using the selection handling mechanism described in the ICCCM
0153      * section 2.
0154      *
0155      * @param target requested target type
0156      * @param property property to use for the reply data
0157      * @param requestor requestor window
0158      */
0159     virtual bool genericReply(xcb_atom_t target, xcb_atom_t property, xcb_window_t requestor);
0160     /**
0161      * Called to announce the supported targets, as described in the ICCCM
0162      * section 2.6. The default implementation announces the required targets
0163      * MULTIPLE, TIMESTAMP and TARGETS.
0164      */
0165     virtual void replyTargets(xcb_atom_t property, xcb_window_t requestor);
0166     /**
0167      * Called to create atoms needed for claiming the selection and
0168      * communication using the selection handling mechanism. The default
0169      * implementation must be called if reimplemented. This method
0170      * may be called repeatedly.
0171      */
0172     virtual void getAtoms();
0173     /**
0174      * Sets extra data to be sent in the message sent to root window
0175      * after successfully claiming a selection. These extra data
0176      * are in data.l[3] and data.l[4] fields of the XClientMessage.
0177      */
0178     void setData(uint32_t extra1, uint32_t extra2);
0179 
0180 private:
0181     void filter_selection_request(void *ev_P);
0182     bool handle_selection(xcb_atom_t target_P, xcb_atom_t property_P, xcb_window_t requestor_P);
0183 
0184     class Private;
0185     Private *const d;
0186 };
0187 
0188 #endif