1 | /* |
2 | SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> |
3 | |
4 | SPDX-License-Identifier: MIT |
5 | */ |
6 | |
7 | #ifndef KSELECTIONOWNER_H |
8 | #define KSELECTIONOWNER_H |
9 | |
10 | #include <QObject> |
11 | #include <kwindowsystem_export.h> |
12 | |
13 | #include <xcb/xcb.h> |
14 | #include <xcb/xproto.h> |
15 | |
16 | /*! |
17 | \class KSelectionOwner |
18 | \inmodule KWindowSystem |
19 | |
20 | \brief ICCCM manager selection owner. |
21 | |
22 | This class implements claiming and owning manager selections, as described |
23 | in the ICCCM, section 2.8. The selection atom is passed to the constructor, |
24 | claim() attempts to claim ownership of the selection, release() gives up |
25 | the selection ownership. Signal lostOwnership() is emitted when the selection |
26 | is claimed by another owner. |
27 | |
28 | This class is only useful on the xcb platform. On other platforms the code is only |
29 | functional if the constructor overloads taking an xcb_connection_t are used. In case |
30 | you inherit from this class ensure that you don't use xcb and/or XLib without verifying |
31 | the platform. |
32 | */ |
33 | class KWINDOWSYSTEM_EXPORT KSelectionOwner : public QObject |
34 | { |
35 | Q_OBJECT |
36 | public: |
37 | /*! |
38 | * This constructor initializes the object, but doesn't perform any |
39 | * operation on the selection. |
40 | * |
41 | * \a selection atom representing the manager selection |
42 | * |
43 | * \a screen X screen, or -1 for default |
44 | * |
45 | * \a parent parent object, or nullptr if there is none |
46 | */ |
47 | explicit KSelectionOwner(xcb_atom_t selection, int screen = -1, QObject *parent = nullptr); |
48 | |
49 | /*! |
50 | * \overload |
51 | * This constructor accepts the selection name and creates the appropriate atom |
52 | * for it automatically. |
53 | * |
54 | * \a selection name of the manager selection |
55 | * |
56 | * \a screen X screen, or -1 for default |
57 | * |
58 | * \a parent parent object, or nullptr if there is none |
59 | */ |
60 | explicit KSelectionOwner(const char *selection, int screen = -1, QObject *parent = nullptr); |
61 | /*! |
62 | * \overload |
63 | * This constructor accepts the xcb_connection_t and root window and doesn't depend on |
64 | * running on the xcb platform. Otherwise this constructor behaves like the similar one |
65 | * without the xcb_connection_t. |
66 | * |
67 | * \a selection atom representing the manager selection |
68 | * |
69 | * \a c the xcb connection this KSelectionWatcher should use |
70 | * |
71 | * \a root the root window this KSelectionWatcher should use |
72 | * |
73 | * \a parent parent object, or nullptr if there is none |
74 | * |
75 | * \since 5.8 |
76 | **/ |
77 | explicit KSelectionOwner(xcb_atom_t selection, xcb_connection_t *c, xcb_window_t root, QObject *parent = nullptr); |
78 | |
79 | /*! |
80 | * \overload |
81 | * This constructor accepts the xcb_connection_t and root window and doesn't depend on |
82 | * running on the xcb platform. Otherwise this constructor behaves like the similar one |
83 | * without the xcb_connection_t. |
84 | * |
85 | * \a selection name of the manager selection |
86 | * |
87 | * \a c the xcb connection this KSelectionWatcher should use |
88 | * |
89 | * \a root the root window this KSelectionWatcher should use |
90 | * |
91 | * \a parent parent object, or nullptr if there is none |
92 | * |
93 | * \since 5.8 |
94 | **/ |
95 | explicit KSelectionOwner(const char *selection, xcb_connection_t *c, xcb_window_t root, QObject *parent = nullptr); |
96 | |
97 | /*! |
98 | * Destructor. Calls release(). |
99 | */ |
100 | ~KSelectionOwner() override; |
101 | |
102 | /*! |
103 | * Try to claim ownership of the manager selection using the current X timestamp. |
104 | * |
105 | * This function returns immediately, but it may take up to one second for the claim |
106 | * to succeed or fail, at which point either the claimedOwnership() or |
107 | * failedToClaimOwnership() signal is emitted. The claim will not be completed until |
108 | * the caller has returned to the event loop. |
109 | * |
110 | * If \a force is false, and the selection is already owned, the selection is not claimed, |
111 | * and failedToClaimOwnership() is emitted. If \a force is true and the selection is |
112 | * owned by another client, the client will be given one second to relinquish ownership |
113 | * of the selection. If \a force_kill is true, and the previous owner fails to disown |
114 | * the selection in time, it will be forcibly killed. |
115 | */ |
116 | void claim(bool force, bool force_kill = true); |
117 | |
118 | /*! |
119 | * If the selection is owned, the ownership is given up. |
120 | */ |
121 | void release(); |
122 | |
123 | /*! |
124 | * If the selection is owned, returns the window used internally |
125 | * for owning the selection. |
126 | */ |
127 | xcb_window_t ownerWindow() const; // None if not owning the selection |
128 | |
129 | bool filterEvent(void *ev_P); // internal |
130 | |
131 | void timerEvent(QTimerEvent *event) override; |
132 | |
133 | Q_SIGNALS: |
134 | /*! |
135 | * This signal is emitted if the selection was owned and the ownership |
136 | * has been lost due to another client claiming it, this signal is emitted. |
137 | * IMPORTANT: It's not safe to delete the instance in a slot connected |
138 | * to this signal. |
139 | */ |
140 | void lostOwnership(); |
141 | |
142 | /*! |
143 | * This signal is emitted when claim() was successful in claiming |
144 | * ownership of the selection. |
145 | */ |
146 | void claimedOwnership(); |
147 | |
148 | /*! |
149 | * This signal is emitted when claim() failed to claim ownership |
150 | * of the selection. |
151 | */ |
152 | void failedToClaimOwnership(); |
153 | |
154 | protected: |
155 | /* |
156 | * Called for every X event received on the window used for owning |
157 | * the selection. If true is returned, the event is filtered out. |
158 | */ |
159 | // virtual bool handleMessage( XEvent* ev ); // removed for KF5, please shout if you need this |
160 | /*! |
161 | * Called when a SelectionRequest event is received. A reply should |
162 | * be sent using the selection handling mechanism described in the ICCCM |
163 | * section 2. |
164 | * |
165 | * \a target requested target type |
166 | * |
167 | * \a property property to use for the reply data |
168 | * |
169 | * \a requestor requestor window |
170 | */ |
171 | virtual bool genericReply(xcb_atom_t target, xcb_atom_t property, xcb_window_t requestor); |
172 | /*! |
173 | * Called to announce the supported targets, as described in the ICCCM |
174 | * section 2.6. The default implementation announces the required targets |
175 | * MULTIPLE, TIMESTAMP and TARGETS. |
176 | */ |
177 | virtual void replyTargets(xcb_atom_t property, xcb_window_t requestor); |
178 | /*! |
179 | * Called to create atoms needed for claiming the selection and |
180 | * communication using the selection handling mechanism. The default |
181 | * implementation must be called if reimplemented. This method |
182 | * may be called repeatedly. |
183 | */ |
184 | virtual void getAtoms(); |
185 | /*! |
186 | * Sets extra data to be sent in the message sent to root window |
187 | * after successfully claiming a selection. These extra data |
188 | * are in data.l[3] and data.l[4] fields of the XClientMessage. |
189 | */ |
190 | void setData(uint32_t , uint32_t ); |
191 | |
192 | private: |
193 | void filter_selection_request(void *ev_P); |
194 | bool handle_selection(xcb_atom_t target_P, xcb_atom_t property_P, xcb_window_t requestor_P); |
195 | |
196 | class Private; |
197 | Private *const d; |
198 | }; |
199 | |
200 | #endif |
201 | |