GCC Code Coverage Report


Directory: ./
File: server/pointer_pool.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 294 315 93.3%
Branches: 125 186 67.2%

Line Branch Exec Source
1 /*
2 SPDX-FileCopyrightText: 2020 Roman Gilg <subdiff@gmail.com>
3 SPDX-FileCopyrightText: 2021 Francesco Sorrentino <francesco.sorr@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
6 */
7 #include "pointer_pool.h"
8 #include "data_device.h"
9 #include "display.h"
10 #include "pointer_p.h"
11 #include "seat.h"
12 #include "seat_p.h"
13 #include "utils.h"
14
15 #include <QHash>
16 #include <unordered_set>
17
18 #include <config-wrapland.h>
19 #include <linux/input-event-codes.h>
20
21 #include <cstdint>
22
23 namespace Wrapland::Server
24 {
25
26 enum class button_state {
27 released,
28 pressed,
29 };
30
31 157 uint32_t qtToWaylandButton(Qt::MouseButton button)
32 {
33 #if HAVE_LINUX_INPUT_H
34
20/38
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 2 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 2 times.
✗ Branch 37 not taken.
157 static QHash<Qt::MouseButton, uint32_t> const s_buttons({
35 2 {Qt::LeftButton, BTN_LEFT},
36 2 {Qt::RightButton, BTN_RIGHT},
37 2 {Qt::MiddleButton, BTN_MIDDLE},
38 2 {Qt::ExtraButton1, BTN_BACK}, // note: QtWayland maps BTN_SIDE
39 2 {Qt::ExtraButton2, BTN_FORWARD}, // note: QtWayland maps BTN_EXTRA
40 2 {Qt::ExtraButton3, BTN_TASK}, // note: QtWayland maps BTN_FORWARD
41 2 {Qt::ExtraButton4, BTN_EXTRA}, // note: QtWayland maps BTN_BACK
42 2 {Qt::ExtraButton5, BTN_SIDE}, // note: QtWayland maps BTN_TASK
43 2 {Qt::ExtraButton6, BTN_TASK + 1},
44 2 {Qt::ExtraButton7, BTN_TASK + 2},
45 2 {Qt::ExtraButton8, BTN_TASK + 3},
46 2 {Qt::ExtraButton9, BTN_TASK + 4},
47 2 {Qt::ExtraButton10, BTN_TASK + 5},
48 2 {Qt::ExtraButton11, BTN_TASK + 6},
49 2 {Qt::ExtraButton12, BTN_TASK + 7},
50 2 {Qt::ExtraButton13, BTN_TASK + 8}
51 // further mapping not possible, 0x120 is BTN_JOYSTICK
52 });
53 157 return s_buttons.value(button, 0);
54 #else
55 return 0;
56 #endif
57 }
58
59
2/4
✓ Branch 0 taken 141 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 141 times.
141 pointer_pool::pointer_pool(Seat* seat)
60 141 : seat{seat}
61 {
62 141 }
63
64 282 pointer_pool::~pointer_pool()
65 {
66
1/2
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
282 QObject::disconnect(focus.surface_lost_notifier);
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 282 times.
282 for (auto dev : devices) {
68 QObject::disconnect(dev, nullptr, seat, nullptr);
69 }
70 282 }
71
72 232 pointer_focus const& pointer_pool::get_focus() const
73 {
74 232 return focus;
75 }
76
77 6 std::vector<Pointer*> const& pointer_pool::get_devices() const
78 {
79 6 return devices;
80 }
81
82 65 void pointer_pool::create_device(Client* client, uint32_t version, uint32_t id)
83 {
84
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 auto pointer = new Pointer(client, version, id, seat);
85 65 devices.push_back(pointer);
86
87
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
65 if (focus.surface && focus.surface->client() == pointer->client()) {
88 // this is a pointer for the currently focused pointer surface
89 5 focus.devices.push_back(pointer);
90 5 pointer->setFocusedSurface(focus.serial, focus.surface);
91 5 pointer->frame();
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (focus.devices.size() == 1) {
93 // got a new pointer
94 5 Q_EMIT seat->focusedPointerChanged(pointer);
95 5 }
96 5 }
97
98 130 QObject::connect(pointer, &Pointer::resourceDestroyed, seat, [pointer, this] {
99 65 remove_one(devices, pointer);
100
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 15 times.
65 if (remove_one(focus.devices, pointer)) {
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (focus.devices.empty()) {
102 15 Q_EMIT seat->focusedPointerChanged(nullptr);
103 15 }
104 15 }
105
106
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 assert(!contains(devices, pointer));
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 assert(!contains(focus.devices, pointer));
108 65 });
109
110 65 Q_EMIT seat->pointerCreated(pointer);
111 65 }
112
113 68 void pointer_pool::update_button_serial(uint32_t button, uint32_t serial)
114 {
115 68 buttonSerials[button] = serial;
116 68 }
117
118 68 void pointer_pool::update_button_state(uint32_t button, button_state state)
119 {
120 68 buttonStates[button] = state;
121 68 }
122
123 91 QPointF pointer_pool::get_position() const
124 {
125 91 return pos;
126 }
127
128 45 void pointer_pool::set_position(QPointF const& position)
129 {
130
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 43 times.
45 if (pos != position) {
131 43 pos = position;
132
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 43 times.
57 for (auto pointer : focus.devices) {
133 14 pointer->motion(focus.transformation.map(position));
134 }
135 // TODO(romangg): should we provide the transformed position here?
136 43 Q_EMIT seat->pointerPosChanged(position);
137 43 }
138 45 }
139
140 87 void pointer_pool::set_focused_surface(Surface* surface, QPointF const& surfacePosition)
141 {
142 87 QMatrix4x4 transformation;
143 174 transformation.translate(-static_cast<float>(surfacePosition.x()),
144 87 -static_cast<float>(surfacePosition.y()));
145 87 set_focused_surface(surface, transformation);
146
147
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 15 times.
87 if (focus.surface) {
148 72 focus.offset = surfacePosition;
149 72 }
150 87 }
151
152 93 void pointer_pool::set_focused_surface(Surface* surface, QMatrix4x4 const& transformation)
153 {
154
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 91 times.
93 if (seat->drags().is_pointer_drag()) {
155 // ignore
156 2 return;
157 }
158
159 91 auto const serial = seat->d_ptr->display()->handle->nextSerial();
160 91 std::unordered_set<Pointer*> framePointers;
161
162
2/2
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 35 times.
126 for (auto pointer : focus.devices) {
163
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 pointer->setFocusedSurface(serial, nullptr);
164
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 framePointers.insert(pointer);
165 }
166
167
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 55 times.
91 if (focus.surface) {
168
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 QObject::disconnect(focus.surface_lost_notifier);
169 36 }
170
171
1/2
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
91 focus = pointer_focus();
172 91 focus.surface = surface;
173
174 91 focus.devices.clear();
175
176
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 15 times.
91 if (surface) {
177
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 focus.devices = interfacesForSurface(surface, devices);
178
179 152 focus.surface_lost_notifier
180
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
116 = QObject::connect(surface, &Surface::resourceDestroyed, seat, [this] {
181 40 focus = pointer_focus();
182 40 Q_EMIT seat->focusedPointerChanged(nullptr);
183 40 });
184 76 focus.offset = QPointF();
185 76 focus.transformation = transformation;
186 76 focus.serial = serial;
187 76 }
188
189
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 71 times.
91 if (focus.devices.empty()) {
190
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 Q_EMIT seat->focusedPointerChanged(nullptr);
191
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 20 times.
34 for (auto pointer : framePointers) {
192
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 pointer->frame();
193 }
194 20 return;
195 }
196
197 // TODO(unknown author): signal with all pointers
198
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 Q_EMIT seat->focusedPointerChanged(focus.devices.front());
199
200
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 71 times.
142 for (auto pointer : focus.devices) {
201
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 pointer->setFocusedSurface(serial, surface);
202
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 framePointers.insert(pointer);
203 }
204
205
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 71 times.
142 for (auto pointer : framePointers) {
206
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 pointer->frame();
207 }
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
93 }
209
210 void pointer_pool::set_focused_surface_position(QPointF const& surfacePosition)
211 {
212 if (focus.surface) {
213 focus.offset = surfacePosition;
214 focus.transformation = QMatrix4x4();
215 focus.transformation.translate(-static_cast<float>(surfacePosition.x()),
216 -static_cast<float>(surfacePosition.y()));
217 }
218 }
219
220 void pointer_pool::set_focused_surface_transformation(QMatrix4x4 const& transformation)
221 {
222
223 if (focus.surface) {
224 focus.transformation = transformation;
225 }
226 }
227
228 29 void pointer_pool::button_pressed(Qt::MouseButton button)
229 {
230 29 const uint32_t nativeButton = qtToWaylandButton(button);
231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (nativeButton == 0) {
232 return;
233 }
234 29 button_pressed(nativeButton);
235 29 }
236
237 38 void pointer_pool::button_pressed(uint32_t button)
238 {
239 38 auto const serial = seat->d_ptr->display()->handle->nextSerial();
240 38 update_button_serial(button, serial);
241 38 update_button_state(button, button_state::pressed);
242
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1 times.
38 if (seat->drags().is_pointer_drag()) {
243 // ignore
244 1 return;
245 }
246
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 7 times.
37 if (focus.surface) {
247
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 30 times.
59 for (auto pointer : focus.devices) {
248 29 pointer->buttonPressed(serial, button);
249 }
250 30 }
251 38 }
252
253 21 void pointer_pool::button_released(Qt::MouseButton button)
254 {
255 21 const uint32_t nativeButton = qtToWaylandButton(button);
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (nativeButton == 0) {
257 return;
258 }
259 21 button_released(nativeButton);
260 21 }
261
262 30 void pointer_pool::button_released(uint32_t button)
263 {
264 30 auto const serial = seat->d_ptr->display()->handle->nextSerial();
265 30 const uint32_t currentButtonSerial = button_serial(button);
266 30 update_button_serial(button, serial);
267 30 update_button_state(button, button_state::released);
268
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 4 times.
30 if (seat->drags().is_pointer_drag()) {
269
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (seat->drags().get_source().serial != currentButtonSerial) {
270 // not our drag button - ignore
271 1 return;
272 }
273 3 seat->drags().drop();
274 3 return;
275 }
276
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (focus.surface) {
277
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 25 times.
49 for (auto pointer : focus.devices) {
278 24 pointer->buttonReleased(serial, button);
279 }
280 25 }
281 30 }
282
283 63 bool pointer_pool::is_button_pressed(Qt::MouseButton button) const
284 {
285 63 return is_button_pressed(qtToWaylandButton(button));
286 }
287
288 143 bool pointer_pool::is_button_pressed(uint32_t button) const
289 {
290 143 auto it = buttonStates.find(button);
291
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 98 times.
143 if (it == buttonStates.end()) {
292 45 return false;
293 }
294 98 return it->second == button_state::pressed;
295 143 }
296
297 44 uint32_t pointer_pool::button_serial(Qt::MouseButton button) const
298 {
299 44 return button_serial(qtToWaylandButton(button));
300 }
301
302 123 uint32_t pointer_pool::button_serial(uint32_t button) const
303 {
304 123 auto it = buttonSerials.find(button);
305
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 120 times.
123 if (it == buttonSerials.end()) {
306 3 return 0;
307 }
308 120 return it->second;
309 123 }
310
311 4 void pointer_pool::send_axis(Qt::Orientation orientation,
312 qreal delta,
313 int32_t discreteDelta,
314 PointerAxisSource source) const
315 {
316
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (seat->drags().is_pointer_drag()) {
317 // ignore
318 return;
319 }
320
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (focus.surface) {
321
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (auto pointer : focus.devices) {
322 4 pointer->axis(orientation, delta, discreteDelta, source);
323 }
324 4 }
325 4 }
326
327 7 void pointer_pool::send_axis(Qt::Orientation orientation, uint32_t delta) const
328 {
329
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 if (seat->drags().is_pointer_drag()) {
330 // ignore
331 2 return;
332 }
333
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (focus.surface) {
334
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 for (auto pointer : focus.devices) {
335 3 pointer->axis(orientation, delta);
336 }
337 5 }
338 7 }
339
340 20 bool pointer_pool::has_implicit_grab(uint32_t serial) const
341 {
342
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8 times.
26 for (auto it : buttonSerials) {
343
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (it.second == serial) {
344 12 return is_button_pressed(it.first);
345 }
346 }
347 8 return false;
348 20 }
349
350 3 void pointer_pool::relative_motion(QSizeF const& delta,
351 QSizeF const& deltaNonAccelerated,
352 uint64_t microseconds) const
353 {
354
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (focus.surface) {
355
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for (auto pointer : focus.devices) {
356 2 pointer->relativeMotion(delta, deltaNonAccelerated, microseconds);
357 }
358 2 }
359 3 }
360
361 6 void pointer_pool::start_swipe_gesture(uint32_t fingerCount)
362 {
363
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (!setup_gesture_surface()) {
364 2 return;
365 }
366
367 4 auto const serial = seat->d_ptr->display()->handle->nextSerial();
368 8 forEachInterface(gesture.surface, devices, [serial, fingerCount](auto pointer) {
369 4 pointer->d_ptr->startSwipeGesture(serial, fingerCount);
370 4 });
371 6 }
372
373 6 void pointer_pool::update_swipe_gesture(QSizeF const& delta) const
374 {
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!gesture.surface) {
376 return;
377 }
378
379 12 forEachInterface(gesture.surface, devices, [delta](auto pointer) {
380 6 pointer->d_ptr->updateSwipeGesture(delta);
381 6 });
382 6 }
383
384 2 void pointer_pool::end_swipe_gesture()
385 {
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
387 return;
388 }
389
390 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
391 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
392 2 pointer->d_ptr->endSwipeGesture(serial);
393 2 });
394
395 2 cleanup_gesture();
396 2 }
397
398 2 void pointer_pool::cancel_swipe_gesture()
399 {
400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
401 return;
402 }
403
404 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
405 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
406 2 pointer->d_ptr->cancelSwipeGesture(serial);
407 2 });
408
409 2 cleanup_gesture();
410 2 }
411
412 6 void pointer_pool::start_pinch_gesture(uint32_t fingerCount)
413 {
414
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (!setup_gesture_surface()) {
415 2 return;
416 }
417
418 4 auto const serial = seat->d_ptr->display()->handle->nextSerial();
419 8 forEachInterface(gesture.surface, devices, [serial, fingerCount](auto pointer) {
420 4 pointer->d_ptr->startPinchGesture(serial, fingerCount);
421 4 });
422 6 }
423
424 6 void pointer_pool::update_pinch_gesture(QSizeF const& delta, qreal scale, qreal rotation) const
425 {
426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!gesture.surface) {
427 return;
428 }
429
430 12 forEachInterface(gesture.surface, devices, [delta, scale, rotation](auto pointer) {
431 6 pointer->d_ptr->updatePinchGesture(delta, scale, rotation);
432 6 });
433 6 }
434
435 2 void pointer_pool::end_pinch_gesture()
436 {
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
438 return;
439 }
440
441 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
442 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
443 2 pointer->d_ptr->endPinchGesture(serial);
444 2 });
445
446 2 cleanup_gesture();
447 2 }
448
449 2 void pointer_pool::cancel_pinch_gesture()
450 {
451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
452 return;
453 }
454
455 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
456 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
457 2 pointer->d_ptr->cancelPinchGesture(serial);
458 2 });
459
460 2 cleanup_gesture();
461 2 }
462
463 6 void pointer_pool::start_hold_gesture(uint32_t fingerCount)
464 {
465
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (!setup_gesture_surface()) {
466 2 return;
467 }
468
469 4 auto const serial = seat->d_ptr->display()->handle->nextSerial();
470 8 forEachInterface(gesture.surface, devices, [serial, fingerCount](auto pointer) {
471 4 pointer->d_ptr->startHoldGesture(serial, fingerCount);
472 4 });
473 6 }
474
475 2 void pointer_pool::end_hold_gesture()
476 {
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
478 return;
479 }
480
481 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
482 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
483 2 pointer->d_ptr->endHoldGesture(serial);
484 2 });
485
486 2 cleanup_gesture();
487 2 }
488
489 2 void pointer_pool::cancel_hold_gesture()
490 {
491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!gesture.surface) {
492 return;
493 }
494
495 2 auto const serial = seat->d_ptr->display()->handle->nextSerial();
496 4 forEachInterface(gesture.surface, devices, [serial](auto pointer) {
497 2 pointer->d_ptr->cancelHoldGesture(serial);
498 2 });
499
500 2 cleanup_gesture();
501 2 }
502
503 18 bool pointer_pool::setup_gesture_surface()
504 {
505
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
18 if (gesture.surface || !focus.surface) {
506 6 return false;
507 }
508
509 12 gesture.surface = focus.surface;
510 12 gesture.surface_destroy_notifier = QObject::connect(
511 12 gesture.surface, &Surface::resourceDestroyed, seat, [this] { cleanup_gesture(); });
512
513 12 return true;
514 18 }
515
516 12 void pointer_pool::cleanup_gesture()
517 {
518 12 QObject::disconnect(gesture.surface_destroy_notifier);
519 12 gesture.surface = nullptr;
520 12 }
521
522 11 void pointer_pool::frame() const
523 {
524
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 for (auto pointer : focus.devices) {
525 11 pointer->frame();
526 }
527 11 }
528
529 }
530