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