Changeset View
Changeset View
Standalone View
Standalone View
xwl/selection.cpp
Show First 20 Lines • Show All 77 Lines • ▼ Show 20 Line(s) | |||||
78 | } | 78 | } | ||
79 | 79 | | |||
80 | Selection::Selection(xcb_atom_t atom, QObject *parent) | 80 | Selection::Selection(xcb_atom_t atom, QObject *parent) | ||
81 | : QObject(parent), | 81 | : QObject(parent), | ||
82 | m_atom(atom) | 82 | m_atom(atom) | ||
83 | { | 83 | { | ||
84 | auto *xcbConn = kwinApp()->x11Connection(); | 84 | auto *xcbConn = kwinApp()->x11Connection(); | ||
85 | m_window = xcb_generate_id(kwinApp()->x11Connection()); | 85 | m_window = xcb_generate_id(kwinApp()->x11Connection()); | ||
86 | m_requestorWindow = m_window; | ||||
86 | xcb_flush(xcbConn); | 87 | xcb_flush(xcbConn); | ||
87 | } | 88 | } | ||
88 | 89 | | |||
89 | bool Selection::handleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) | 90 | bool Selection::handleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) | ||
90 | { | 91 | { | ||
91 | if (event->window != m_window) { | 92 | if (event->window != m_window) { | ||
92 | return false; | 93 | return false; | ||
93 | } | 94 | } | ||
Show All 12 Lines | 103 | if (event->owner == m_window && m_wlSrc) { | |||
106 | */ | 107 | */ | ||
107 | m_wlSrc->setTimestamp(event->timestamp); | 108 | m_wlSrc->setTimestamp(event->timestamp); | ||
108 | m_timestamp = event->timestamp; | 109 | m_timestamp = event->timestamp; | ||
109 | return true; | 110 | return true; | ||
110 | } | 111 | } | ||
111 | /* | 112 | /* | ||
112 | * Being here means some other X window has claimed the selection. | 113 | * Being here means some other X window has claimed the selection. | ||
113 | */ | 114 | */ | ||
114 | delete m_xSrc; | | |||
115 | m_xSrc = nullptr; | | |||
116 | const auto *ac = workspace()->activeClient(); | | |||
117 | if (!ac || !ac->inherits("KWin::Client")) { | | |||
118 | // selections are only allowed to be aquired when Xwayland has focus | | |||
119 | // TODO: can we make this stronger (window id comparision)? | | |||
120 | return true; | | |||
121 | } | | |||
122 | doHandleXfixesNotify(event); | 115 | doHandleXfixesNotify(event); | ||
123 | return true; | 116 | return true; | ||
124 | } | 117 | } | ||
125 | 118 | | |||
126 | bool Selection::filterEvent(xcb_generic_event_t *event) | 119 | bool Selection::filterEvent(xcb_generic_event_t *event) | ||
127 | { | 120 | { | ||
128 | switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { | 121 | switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { | ||
129 | case XCB_SELECTION_NOTIFY: | 122 | case XCB_SELECTION_NOTIFY: | ||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | |||||
193 | } | 186 | } | ||
194 | 187 | | |||
195 | void Selection::createX11Source(xcb_xfixes_selection_notify_event_t *event) | 188 | void Selection::createX11Source(xcb_xfixes_selection_notify_event_t *event) | ||
196 | { | 189 | { | ||
197 | delete m_wlSrc; | 190 | delete m_wlSrc; | ||
198 | delete m_xSrc; | 191 | delete m_xSrc; | ||
199 | m_wlSrc = nullptr; | 192 | m_wlSrc = nullptr; | ||
200 | m_xSrc = nullptr; | 193 | m_xSrc = nullptr; | ||
201 | if (event->owner == XCB_WINDOW_NONE) { | 194 | if (!event || event->owner == XCB_WINDOW_NONE) { | ||
202 | return; | 195 | return; | ||
203 | } | 196 | } | ||
204 | m_xSrc = new X11Source(this, event); | 197 | m_xSrc = new X11Source(this, event); | ||
205 | 198 | | |||
206 | connect(m_xSrc, &X11Source::offersChanged, this, &Selection::x11OffersChanged); | 199 | connect(m_xSrc, &X11Source::offersChanged, this, &Selection::x11OffersChanged); | ||
207 | connect(m_xSrc, &X11Source::transferReady, this, &Selection::startTransferToWayland); | 200 | connect(m_xSrc, &X11Source::transferReady, this, &Selection::startTransferToWayland); | ||
208 | } | 201 | } | ||
209 | 202 | | |||
Show All 10 Lines | 211 | } else { | |||
220 | xcb_set_selection_owner(xcbConn, | 213 | xcb_set_selection_owner(xcbConn, | ||
221 | XCB_WINDOW_NONE, | 214 | XCB_WINDOW_NONE, | ||
222 | m_atom, | 215 | m_atom, | ||
223 | m_timestamp); | 216 | m_timestamp); | ||
224 | } | 217 | } | ||
225 | xcb_flush(xcbConn); | 218 | xcb_flush(xcbConn); | ||
226 | } | 219 | } | ||
227 | 220 | | |||
221 | void Selection::overwriteRequestorWindow(xcb_window_t window) | ||||
222 | { | ||||
223 | Q_ASSERT(m_xSrc); | ||||
224 | if (window == XCB_WINDOW_NONE) { | ||||
225 | // reset | ||||
226 | window = m_window; | ||||
227 | } | ||||
228 | m_requestorWindow = window; | ||||
229 | m_xSrc->setRequestor(window); | ||||
230 | } | ||||
231 | | ||||
228 | bool Selection::handleSelRequest(xcb_selection_request_event_t *event) | 232 | bool Selection::handleSelRequest(xcb_selection_request_event_t *event) | ||
229 | { | 233 | { | ||
230 | if (event->selection != m_atom) { | 234 | if (event->selection != m_atom) { | ||
231 | return false; | 235 | return false; | ||
232 | } | 236 | } | ||
233 | 237 | | |||
234 | if (!workspace()->activeClient() || !workspace()->activeClient()->inherits("KWin::Client")) { | 238 | if (!workspace()->activeClient() || !workspace()->activeClient()->inherits("KWin::Client")) { | ||
235 | // Receiving Wayland selection not allowed when no Xwayland surface active | 239 | // Receiving Wayland selection not allowed when no Xwayland surface active | ||
Show All 40 Lines | 277 | for (auto *transfer : m_wlToXTransfers) { | |||
276 | } | 280 | } | ||
277 | } | 281 | } | ||
278 | return false; | 282 | return false; | ||
279 | } | 283 | } | ||
280 | 284 | | |||
281 | void Selection::startTransferToWayland(xcb_atom_t target, qint32 fd) | 285 | void Selection::startTransferToWayland(xcb_atom_t target, qint32 fd) | ||
282 | { | 286 | { | ||
283 | // create new x to wl data transfer object | 287 | // create new x to wl data transfer object | ||
284 | auto *transfer = new TransferXtoWl(m_atom, target, fd, m_xSrc->timestamp(), m_window, this); | 288 | auto *transfer = new TransferXtoWl(m_atom, target, fd, m_xSrc->timestamp(), m_requestorWindow, this); | ||
285 | m_xToWlTransfers << transfer; | 289 | m_xToWlTransfers << transfer; | ||
286 | 290 | | |||
287 | connect(transfer, &TransferXtoWl::finished, this, [this, transfer]() { | 291 | connect(transfer, &TransferXtoWl::finished, this, [this, transfer]() { | ||
288 | Q_EMIT transferFinished(transfer->timestamp()); | 292 | Q_EMIT transferFinished(transfer->timestamp()); | ||
289 | delete transfer; | 293 | delete transfer; | ||
290 | m_xToWlTransfers.removeOne(transfer); | 294 | m_xToWlTransfers.removeOne(transfer); | ||
291 | endTimeoutTransfersTimer(); | 295 | endTimeoutTransfersTimer(); | ||
292 | }); | 296 | }); | ||
▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines |