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