Directory: | ./ |
---|---|
File: | server/data_control_v1.cpp |
Date: | 2024-01-22 17:25:27 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 189 | 230 | 82.2% |
Branches: | 83 | 146 | 56.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | SPDX-FileCopyrightText: 2021 Roman Gilg <subdiff@gmail.com> | ||
3 | |||
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only | ||
5 | */ | ||
6 | #include "data_control_v1_p.h" | ||
7 | |||
8 | #include "client.h" | ||
9 | #include "data_device.h" | ||
10 | #include "data_source_p.h" | ||
11 | #include "display.h" | ||
12 | #include "primary_selection_p.h" | ||
13 | #include "selection_device_manager_p.h" | ||
14 | #include "selection_p.h" | ||
15 | #include "selection_pool.h" | ||
16 | |||
17 | #include "wayland/bind.h" | ||
18 | #include "wayland/global.h" | ||
19 | |||
20 | #include <wayland-server.h> | ||
21 | |||
22 | namespace Wrapland::Server | ||
23 | { | ||
24 | |||
25 | struct zwlr_data_control_manager_v1_interface const data_control_manager_v1::Private::s_interface | ||
26 | = { | ||
27 | cb<create_source>, | ||
28 | cb<get_device>, | ||
29 | resourceDestroyCallback, | ||
30 | }; | ||
31 | |||
32 | 38 | data_control_manager_v1::Private::Private(data_control_manager_v1* q_ptr, Display* display) | |
33 | 76 | : device_manager<data_control_manager_v1_global>(q_ptr, | |
34 | 38 | display, | |
35 | &zwlr_data_control_manager_v1_interface, | ||
36 | &s_interface) | ||
37 | 38 | { | |
38 | 38 | display->globals.data_control_manager_v1 = q_ptr; | |
39 | 38 | } | |
40 | |||
41 | 38 | data_control_manager_v1::data_control_manager_v1(Display* display) | |
42 |
2/4✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
|
38 | : d_ptr(new Private(this, display)) |
43 | 38 | { | |
44 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
38 | d_ptr->create(); |
45 | 38 | } | |
46 | |||
47 | 76 | data_control_manager_v1::~data_control_manager_v1() = default; | |
48 | |||
49 | 2 | void data_control_manager_v1::create_source(Client* client, uint32_t version, uint32_t id) | |
50 | { | ||
51 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | [[maybe_unused]] auto src_res = new data_control_source_v1_res(client, version, id); |
52 | // TODO(romangg): Catch oom. | ||
53 | |||
54 | 2 | Q_EMIT source_created(); | |
55 | 2 | } | |
56 | |||
57 | 3 | void data_control_manager_v1::get_device(Client* client, uint32_t version, uint32_t id, Seat* seat) | |
58 | { | ||
59 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | auto device = new data_control_device_v1(client, version, id, seat); |
60 | // TODO(romangg): Catch oom exception. | ||
61 | |||
62 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (auto src = seat->d_ptr->data_devices.focus.source) { |
63 | ✗ | device->send_selection(src); | |
64 | } | ||
65 | |||
66 | 7 | QObject::connect(seat, &Seat::selectionChanged, device, [seat, device] { | |
67 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
4 | if (auto source = seat->d_ptr->data_devices.focus.source; |
68 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | !source || source != device->selection()) { |
69 | 3 | device->send_selection(source); | |
70 | 3 | } | |
71 | 4 | }); | |
72 | |||
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (version >= ZWLR_DATA_CONTROL_DEVICE_V1_PRIMARY_SELECTION_SINCE_VERSION) { |
74 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (auto src = seat->d_ptr->primary_selection_devices.focus.source) { |
75 | ✗ | device->send_primary_selection(src); | |
76 | } | ||
77 | 7 | QObject::connect(seat, &Seat::primarySelectionChanged, device, [seat, device] { | |
78 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
4 | if (auto source = seat->d_ptr->primary_selection_devices.focus.source; |
79 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | !source || source != device->primary_selection()) { |
80 | 3 | device->send_primary_selection(source); | |
81 | 3 | } | |
82 | 4 | }); | |
83 | 3 | } | |
84 | |||
85 | 3 | Q_EMIT device_created(device); | |
86 | 3 | } | |
87 | |||
88 | template<typename Source> | ||
89 | 2 | data_control_offer_v1_res* data_control_device_v1::impl::send_data_offer_impl(Source source) | |
90 | { | ||
91 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | assert(source); |
92 | |||
93 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
2 | auto offer = new data_control_offer_v1_res(client->handle, version, source); |
94 | |||
95 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | if (!offer->impl->resource) { |
96 | ✗ | delete offer; | |
97 | ✗ | return nullptr; | |
98 | } | ||
99 | |||
100 | 2 | send<zwlr_data_control_device_v1_send_data_offer>(offer->impl->resource); | |
101 | 2 | offer->send_offers(); | |
102 | 2 | return offer; | |
103 | 2 | } | |
104 | |||
105 | 1 | data_control_offer_v1_res* data_control_device_v1::impl::send_data_offer(data_source* source) | |
106 | { | ||
107 | 1 | return send_data_offer_impl(source); | |
108 | } | ||
109 | |||
110 | data_control_offer_v1_res* | ||
111 | 1 | data_control_device_v1::impl::send_data_offer(primary_selection_source* source) | |
112 | { | ||
113 | 1 | return send_data_offer_impl(source); | |
114 | } | ||
115 | |||
116 | struct zwlr_data_control_device_v1_interface const data_control_device_v1::impl::s_interface = { | ||
117 | set_selection_callback, | ||
118 | destroyCallback, | ||
119 | set_primary_selection_callback, | ||
120 | }; | ||
121 | |||
122 | // Similar to set_selection in selection_p.h | ||
123 | 4 | void set_control_selection(data_control_device_v1* handle, | |
124 | selection_source_holder& holder, | ||
125 | data_control_source_v1_res* source_res) | ||
126 | { | ||
127 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | auto source = source_res ? source_res->src() : nullptr; |
128 | |||
129 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (holder.source == source) { |
130 | ✗ | return; | |
131 | } | ||
132 | |||
133 | 4 | QObject::disconnect(holder.destroyed_notifier); | |
134 | |||
135 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (holder.source) { |
136 | 2 | holder.source->cancel(); | |
137 | 2 | } | |
138 | |||
139 | 4 | holder.source = source; | |
140 | |||
141 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (source) { |
142 | 2 | holder.destroyed_notifier = QObject::connect( | |
143 | 2 | source_res, &data_control_source_v1_res::resourceDestroyed, handle, [handle, &holder] { | |
144 | ✗ | set_control_selection(handle, holder, nullptr); | |
145 | ✗ | }); | |
146 | 2 | } else { | |
147 | 2 | holder.destroyed_notifier = QMetaObject::Connection(); | |
148 | } | ||
149 | 4 | Q_EMIT handle->selection_changed(); | |
150 | 4 | } | |
151 | |||
152 |
3/6✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
|
6 | data_control_device_v1::impl::impl(Client* client, |
153 | uint32_t version, | ||
154 | uint32_t id, | ||
155 | Seat* seat, | ||
156 | data_control_device_v1* q_ptr) | ||
157 | 6 | : Wayland::Resource<data_control_device_v1>(client, | |
158 | 3 | version, | |
159 | 3 | id, | |
160 | &zwlr_data_control_device_v1_interface, | ||
161 | &s_interface, | ||
162 | 3 | q_ptr) | |
163 | 3 | , m_seat{seat} | |
164 | 3 | { | |
165 | 3 | } | |
166 | |||
167 | template<typename Source, typename Devices> | ||
168 | 4 | void data_control_device_v1::impl::set_selection_impl(Devices& seat_devices, | |
169 | selection_source_holder& selection_holder, | ||
170 | data_control_device_v1* handle, | ||
171 | wl_resource* wlSource) | ||
172 | { | ||
173 |
4/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
4 | if (!wlSource) { |
174 | 2 | set_control_selection(handle, selection_holder, nullptr); | |
175 | 2 | seat_devices.set_selection(nullptr); | |
176 | 2 | return; | |
177 | } | ||
178 | |||
179 | 2 | auto source = Resource<data_control_source_v1_res>::get_handle(wlSource); | |
180 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | if (!std::holds_alternative<std::monostate>(source->data_src)) { |
181 | ✗ | handle->d_ptr->postError(ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_USED_SOURCE, | |
182 | "Source already used"); | ||
183 | ✗ | return; | |
184 | } | ||
185 | |||
186 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
2 | auto src = std::unique_ptr<Source>(new Source); |
187 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | src->d_ptr->mimeTypes = source->src()->early_mime_types; |
188 | |||
189 | 2 | src->d_ptr->res = source; | |
190 |
4/8✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
4 | QObject::connect(source, |
191 | &data_control_source_v1_res::resourceDestroyed, | ||
192 | 2 | src.get(), | |
193 | 2 | &Source::resourceDestroyed); | |
194 | |||
195 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | set_control_selection(handle, selection_holder, source); |
196 | |||
197 | // A connection from the set_selection call accesses data_src field. So move it over before. | ||
198 | 2 | auto src_ptr = src.get(); | |
199 | 2 | source->data_src = std::move(src); | |
200 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | seat_devices.set_selection(src_ptr); |
201 | 4 | } | |
202 | |||
203 | 2 | void data_control_device_v1::impl::set_selection_callback(wl_client* /*wlClient*/, | |
204 | wl_resource* wlResource, | ||
205 | wl_resource* wlSource) | ||
206 | { | ||
207 | 2 | auto handle = Resource::get_handle(wlResource); | |
208 | 2 | auto& seat_devices = handle->d_ptr->m_seat->d_ptr->data_devices; | |
209 | 2 | auto& selection_holder = handle->d_ptr->selection; | |
210 | |||
211 | 2 | set_selection_impl<data_source>(seat_devices, selection_holder, handle, wlSource); | |
212 | 2 | } | |
213 | |||
214 | 2 | void data_control_device_v1::impl::set_primary_selection_callback(wl_client* /*wlClient*/, | |
215 | wl_resource* wlResource, | ||
216 | wl_resource* wlSource) | ||
217 | { | ||
218 | 2 | auto handle = Resource::get_handle(wlResource); | |
219 | 2 | auto& seat_devices = handle->d_ptr->m_seat->d_ptr->primary_selection_devices; | |
220 | 2 | auto& selection_holder = handle->d_ptr->primary_selection; | |
221 | |||
222 | 2 | set_selection_impl<primary_selection_source>(seat_devices, selection_holder, handle, wlSource); | |
223 | 2 | } | |
224 | |||
225 | 3 | data_control_device_v1::data_control_device_v1(Client* client, | |
226 | uint32_t version, | ||
227 | uint32_t id, | ||
228 | Seat* seat) | ||
229 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | : d_ptr(new data_control_device_v1::impl(client, version, id, seat, this)) |
230 | 3 | { | |
231 | 3 | } | |
232 | |||
233 | template<typename Source> | ||
234 | 15 | Source* data_control_device_v1::impl::get_selection(selection_source_holder const& holder) | |
235 | { | ||
236 |
4/4✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
15 | if (holder.source) { |
237 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
4 | if (auto src = std::get_if<std::unique_ptr<Source>>(&holder.source->data_src)) { |
238 | 4 | return src->get(); | |
239 | } | ||
240 | } | ||
241 | |||
242 | 11 | return nullptr; | |
243 | 15 | } | |
244 | |||
245 | 11 | data_source* data_control_device_v1::selection() const | |
246 | { | ||
247 | 11 | return d_ptr->get_selection<data_source>(d_ptr->selection); | |
248 | } | ||
249 | |||
250 | 4 | primary_selection_source* data_control_device_v1::primary_selection() const | |
251 | { | ||
252 | 4 | return d_ptr->get_selection<primary_selection_source>(d_ptr->primary_selection); | |
253 | } | ||
254 | |||
255 | 3 | void data_control_device_v1::send_selection(data_source* source) const | |
256 | { | ||
257 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if (!source) { |
258 | 2 | d_ptr->send<zwlr_data_control_device_v1_send_selection>(nullptr); | |
259 | 2 | return; | |
260 | } | ||
261 | |||
262 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (auto offer = d_ptr->send_data_offer(source)) { |
263 | 1 | d_ptr->send<zwlr_data_control_device_v1_send_selection>(offer->impl->resource); | |
264 | 1 | } | |
265 | 3 | } | |
266 | |||
267 | 3 | void data_control_device_v1::send_primary_selection(primary_selection_source* source) const | |
268 | { | ||
269 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | assert(d_ptr->version >= ZWLR_DATA_CONTROL_DEVICE_V1_PRIMARY_SELECTION_SINCE_VERSION); |
270 | |||
271 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (!source) { |
272 | 2 | d_ptr->send<zwlr_data_control_device_v1_send_primary_selection>(nullptr); | |
273 | 2 | return; | |
274 | } | ||
275 | |||
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (auto offer = d_ptr->send_data_offer(source)) { |
277 | 1 | d_ptr->send<zwlr_data_control_device_v1_send_primary_selection>(offer->impl->resource); | |
278 | 1 | } | |
279 | 3 | } | |
280 | |||
281 | 2 | data_control_source_v1_res::res_impl::res_impl(Client* client, | |
282 | uint32_t version, | ||
283 | uint32_t id, | ||
284 | data_control_source_v1_res* q_ptr) | ||
285 | 4 | : Wayland::Resource<data_control_source_v1_res>(client, | |
286 | 2 | version, | |
287 | 2 | id, | |
288 | &zwlr_data_control_source_v1_interface, | ||
289 | &s_interface, | ||
290 | 2 | q_ptr) | |
291 | 2 | , q_ptr{q_ptr} | |
292 | 2 | { | |
293 | 2 | } | |
294 | |||
295 | struct zwlr_data_control_source_v1_interface const data_control_source_v1_res::res_impl::s_interface | ||
296 | = { | ||
297 | offer_callback, | ||
298 | destroyCallback, | ||
299 | }; | ||
300 | |||
301 | template<class... Ts> | ||
302 | // NOLINTNEXTLINE(fuchsia-multiple-inheritance) | ||
303 | struct overload : Ts... { | ||
304 | using Ts::operator()...; | ||
305 | }; | ||
306 | template<class... Ts> | ||
307 | overload(Ts...) -> overload<Ts...>; | ||
308 | |||
309 | ✗ | void data_control_source_v1_res::res_impl::offer_callback(wl_client* /*wlClient*/, | |
310 | wl_resource* wlResource, | ||
311 | char const* mimeType) | ||
312 | { | ||
313 | ✗ | auto handle = Resource::get_handle(wlResource); | |
314 | |||
315 | ✗ | std::visit(overload{[&](std::unique_ptr<data_source>& src) { | |
316 | ✗ | offer_mime_type(src->d_ptr.get(), mimeType); | |
317 | ✗ | }, | |
318 | ✗ | [&](std::unique_ptr<primary_selection_source>& src) { | |
319 | ✗ | offer_mime_type(src->d_ptr.get(), mimeType); | |
320 | ✗ | }, | |
321 | ✗ | [&](std::monostate /*unused*/) { | |
322 | ✗ | handle->src()->early_mime_types.emplace_back(mimeType); | |
323 | ✗ | }}, | |
324 | ✗ | handle->data_src); | |
325 | } | ||
326 | |||
327 | 4 | data_control_source_v1_res::data_control_source_v1_res(Client* client, | |
328 | uint32_t version, | ||
329 | uint32_t id) | ||
330 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | : impl{new data_control_source_v1_res::res_impl(client, version, id, this)} |
331 | 2 | { | |
332 | 2 | } | |
333 | |||
334 | 4 | data_control_source_v1_res::~data_control_source_v1_res() = default; | |
335 | |||
336 | ✗ | void data_control_source_v1_res::request_data(std::string const& mime_type, int32_t fd) const | |
337 | { | ||
338 | // TODO(unknown author): does this require a sanity check on the possible mime type? | ||
339 | ✗ | impl->send<zwlr_data_control_source_v1_send_send>(mime_type.c_str(), fd); | |
340 | ✗ | close(fd); | |
341 | } | ||
342 | |||
343 | 4 | void data_control_source_v1_res::cancel() const | |
344 | { | ||
345 | 4 | impl->send<zwlr_data_control_source_v1_send_cancelled>(); | |
346 | 4 | } | |
347 | |||
348 | 4 | data_control_source_v1_res* data_control_source_v1_res::src() | |
349 | { | ||
350 | 4 | return this; | |
351 | } | ||
352 | |||
353 | struct zwlr_data_control_offer_v1_interface const data_control_offer_v1_res_impl::s_interface = { | ||
354 | receive_callback, | ||
355 | destroyCallback, | ||
356 | }; | ||
357 | |||
358 | 4 | data_control_offer_v1_res_impl::data_control_offer_v1_res_impl(Client* client, | |
359 | uint32_t version, | ||
360 | data_control_offer_v1_res* q_ptr) | ||
361 | 4 | : Wayland::Resource<data_control_offer_v1_res>(client, | |
362 | 2 | version, | |
363 | 0, | ||
364 | &zwlr_data_control_offer_v1_interface, | ||
365 | &s_interface, | ||
366 | 2 | q_ptr) | |
367 | 2 | { | |
368 | 2 | } | |
369 | |||
370 | ✗ | void data_control_offer_v1_res_impl::receive_callback(wl_client* /*wlClient*/, | |
371 | wl_resource* wlResource, | ||
372 | char const* mime_type, | ||
373 | int32_t fd) | ||
374 | { | ||
375 | ✗ | auto handle = Resource::get_handle(wlResource); | |
376 | |||
377 | ✗ | std::visit(overload{[&](data_source* src) { | |
378 | ✗ | assert(src); | |
379 | ✗ | receive_mime_type_offer(src, mime_type, fd); | |
380 | ✗ | }, | |
381 | ✗ | [&](primary_selection_source* src) { | |
382 | ✗ | assert(src); | |
383 | ✗ | receive_mime_type_offer(src, mime_type, fd); | |
384 | ✗ | }, | |
385 | ✗ | [&](std::monostate /*unused*/) { close(fd); }}, | |
386 | ✗ | handle->impl->src); | |
387 | } | ||
388 | |||
389 | 1 | data_control_offer_v1_res::data_control_offer_v1_res(Client* client, | |
390 | uint32_t version, | ||
391 | data_source* source) | ||
392 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : impl(new data_control_offer_v1_res_impl(client, version, this)) |
393 | 1 | { | |
394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | assert(source); |
395 | 1 | impl->src = source; | |
396 | |||
397 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | QObject::connect(source, &data_source::mime_type_offered, this, [this](auto const& mime_type) { |
398 | ✗ | impl->send<zwlr_data_control_offer_v1_send_offer>(mime_type.c_str()); | |
399 | ✗ | }); | |
400 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | QObject::connect(source, &data_source::resourceDestroyed, this, [this] { impl->src = {}; }); |
401 | 1 | } | |
402 | |||
403 | 1 | data_control_offer_v1_res::data_control_offer_v1_res(Client* client, | |
404 | uint32_t version, | ||
405 | primary_selection_source* source) | ||
406 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : impl(new data_control_offer_v1_res_impl(client, version, this)) |
407 | 1 | { | |
408 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | assert(source); |
409 | 1 | impl->src = source; | |
410 | |||
411 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | QObject::connect( |
412 | 1 | source, &primary_selection_source::mime_type_offered, this, [this](auto const& mime_type) { | |
413 | ✗ | impl->send<zwlr_data_control_offer_v1_send_offer>(mime_type.c_str()); | |
414 | ✗ | }); | |
415 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | QObject::connect( |
416 | 1 | source, &primary_selection_source::resourceDestroyed, this, [this] { impl->src = {}; }); | |
417 | 1 | } | |
418 | |||
419 | 2 | void data_control_offer_v1_res::send_offers() const | |
420 | { | ||
421 | 4 | auto send_mime_types = [this](auto const& mime_types) { | |
422 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | for (auto const& mt : mime_types) { |
423 | 2 | impl->send<zwlr_data_control_offer_v1_send_offer>(mt.c_str()); | |
424 | } | ||
425 | 2 | }; | |
426 | |||
427 | 5 | std::visit(overload{[&](data_source* src) { | |
428 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | assert(src); |
429 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | send_mime_types(src->mime_types()); |
430 | 1 | }, | |
431 | 3 | [&](primary_selection_source* src) { | |
432 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | assert(src); |
433 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | send_mime_types(src->mime_types()); |
434 | 1 | }, | |
435 | ✗ | [](std::monostate /*unused*/) { assert(false); }}, | |
436 | 2 | impl->src); | |
437 | 2 | } | |
438 | |||
439 | } | ||
440 |